问题
I've to use libmicrohttpd to set up a REST server. There is no problem with the GET request, but I don't understand what I'm doing wrong to handle POST (PUT actually) request (JSON format). Here is the code :
int MHD_answer_to_connection (void* cls, struct MHD_Connection* connection,
const char* url,
const char* method, const char* version,
const char* upload_data,
size_t* upload_data_size, void** con_cls) {
// Initializes parser/camera/settings...
static Parser parser;
// The first time only the headers are valid, do not respond in the first round
static int dummy;
if (*con_cls != &dummy) {
*con_cls = &dummy;
return MHD_YES;
}
// Parse URL to get the resource
int resource = parser.getRequestedResource(url);
// Check wether if it's a GET or a POST method
if(strcmp(method, MHD_HTTP_METHOD_GET) == 0) {
parser.processGetRequest(resource);
}
else {
parser.processPutRequest(upload_data, *upload_data_size);
}
// Building HTTP response (headers+data)
MHD_Response* httpResponse = parser.getResponse();
int ret = MHD_queue_response (connection, MHD_HTTP_OK, httpResponse);
if (ret != MHD_YES) {
Logger::get().error("Error queuing message");
}
MHD_destroy_response (httpResponse);
// Clear context pointer
*con_cls = NULL;
return ret;
}
Everytime I try to send a PUT request with some data, I get the "Internal application error, closing connection". The problem may come from one of these things:
posting/not-posting response at the first call of the fucntion
modifying or not the *upload_data_size (to indicate that processing is done)
the good location of
*con_cls = NULL
instruction
Thanks!
回答1:
I ran into this same problem and discovered the solution through some debugging.
When the library calls your handler with request_data
, you're not allowed to queue any responses (MHD_queue_response
returns MHD_NO
). You need to wait until the final handler call with no request_data
to call MHD_queue_response
.
This behavior isn't documented as far as I can tell.
回答2:
I'm using GNU libmicrohttpd too, and I found a simple POST demo on its repository.
The demo is a little bit simple: it has a form that asks about your name, so when you type your name and click in the "Send" button, the posted data is processed in the answer_to_connection()
function:
static int answer_to_connection (void *cls, struct MHD_Connection *connection,
const char *url, const char *method,
const char *version, const char *upload_data,
size_t *upload_data_size, void **con_cls)
{
...
if (0 == strcmp (method, "POST"))
{
struct connection_info_struct *con_info = *con_cls;
if (*upload_data_size != 0)
{
MHD_post_process (con_info->postprocessor, upload_data,
*upload_data_size);
*upload_data_size = 0;
return MHD_YES;
}
else if (NULL != con_info->answerstring)
return send_page (connection, con_info->answerstring);
}
...
来源:https://stackoverflow.com/questions/29700380/handling-a-post-request-with-libmicrohttpd