-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 04/26/2012 05:50 AM, Martin Dluhos wrote: > On 04/25/2012 09:22 AM, Christian Grothoff wrote: >> The first call to the "test_send_response_helper" is made *before* >> the upload data is available (after we just got the headers) so >> that you can choose not to send 100 CONTINUE for http/1.1. You >> need to change your function to return an 'int' and return >> 'MHD_YES' to get the next call which will contain upload data. >> Furthermore, 'upload_data' is NOT a 0-terminated string so you >> *must* limit your processing manually to the first >> '*upload_data_size' bytes in that buffer. Finally, you then need >> to reduce '*upload_data_size' (i.e. to zero) to indicate how many >> bytes of 'upload_data' you did process (so you don't get them >> again). Finally, if you are eventually called a *second* time with >> '0 == *upload_data_size', you can be sure that the upload is >> complete. > > Thank you for your help, Christian. I forgot that the function behaves > in this way. > > I actually have a follow up question. Inside test_send_response_helper > I make a call to a function called send_response, which uses > microhttpd library functions to create and send an MHD_Response. Here > is the code: > > int > test_send_response_helper (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) > { > int ret_val; > > /* The first time through only headers are processed. Only the second > * time this function is called can we access upload_data. > */ > if (*con_cls == NULL) > { > struct connection_info_struct *con_info; > con_info = malloc (sizeof (struct connection_info_struct)); > > /* Process POST and GET request separately. Signal an error > * on any other method. > */ > if (strcmp (method, "POST") == 0) > con_info->connection_type = POST; > else if (strcmp (method, "GET") == 0) > con_info->connection_type = GET; > > *con_cls = (void *) con_info; > return MHD_YES; > } // if > > /* This gets executed the second time the function is called. Only > * now can we access upload_data. > */ > printf ("SECOND: URL: %s DATA: %s\n", url, upload_data); > > /* Response strings for the server to return. */ > const char *busy_page = > "The server is too busy to handle the verification request."; > > /* The server is too busy to respond. */ > ret_val = send_response(connection, busy_page, > MHD_HTTP_SERVICE_UNAVAILABLE); > > return MHD_YES; > } > > int > send_response (struct MHD_Connection *connection, const char > *response_data, int status_code) > { > int return_value; > struct MHD_Response *response; > > response = MHD_create_response_from_data (strlen(response_data), > (void*) response_data, MHD_NO, MHD_NO); > > if (response == NULL) > { > return MHD_NO; > } > > return_value = MHD_queue_response (connection, status_code, response); > MHD_destroy_response (response); > > return return_value; > } > > For some reason, MHD_queue_response returns MHD_NO indicating an error > instead of MHD_YES. Is there a way for me to find out what kind of > error I am getting here? Can you see what I am doing wrong here?
Yes, there are only two times where you're allowed to queue a response - ---either the FIRST time you're called (for queueing errors like service unavailable). Those should be done *before* you receive upload data. Alternatively, you must wait until you have received *all* upload data and then queue your response once "*upload_data_size" is *again* zero. You don't wait for the upload to finish, so MHD tells you that you're using the API the wrong way. The only error you get from MHD_queue_response is pretty much "API misuse" (called too early, called twice). Happy hacking! Christian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk+Y4NYACgkQv2Bwi0hCbH5jrwCfeVcjMP01kJZanRFIlvcnHy1B 8V8AoJ2oAD1bWGoI9IeHXM7jBlvSpjmA =LYY2 -----END PGP SIGNATURE-----