[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libmicrohttpd] Create a server that returns string sent in request
From: |
Christian Grothoff |
Subject: |
Re: [libmicrohttpd] Create a server that returns string sent in request payload |
Date: |
Mon, 3 Jun 2019 23:55:03 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 |
Hi Dawid,
A few issues with your code:
1) upload_data may not be 0-terminated (that's why you have
upload_data_size!), so your puts() is already unsafe;
2) upload_data is *not* persistent, so you must use
"MHD_RESPMEM_MUST_COPY". And again, no strlen() but instead
"*upload_data_size" for the first argument.
3) That said, you are not allowed to use the upload data like this:
You may only queue a response either upon first call (where you always
only return MHD_YES), or upon last call (where you again only return
MHD_YES). You must not queue a response at the time when 0 !=
*upload_data_size, which is exactly the case where you do so! Hence
"MHD_queue_response" will fail (returns MHD_NO), which you ignore at
your peril.
4) Finally, you leak 'res' as you don't call MHD_destroy_response().
So to really fix this, you need to buffer the upload_data in some data
structure of your choice (to be associated with "*conn_cls") and then
generate the response only once the upload is actually complete!
I hope this helps!
Happy hacking!
-Christian
On 6/3/19 8:47 PM, Dawid Czeluśniak wrote:
> Hi!
>
> I would like to create a simple webserver that returns the exact payload
> that was sent with request. Here is the code that I wrote:
>
> """
> #include <stdio.h>
> #include <string.h>
> #include <microhttpd.h>
>
> #define PORT 8080
>
> int on_connection(void *cls, struct MHD_Connection *conn, const char *url,
> const char *method, const char *version, const char
> *upload_data,
> size_t *upload_data_size, void **conn_cls) {
>
> if (strcmp(method, "POST") == 0) {
> if (*upload_data_size == 0) {
> return MHD_YES;
> } else {
> *upload_data_size = 0;
> }
> }
>
> puts(upload_data);
> puts(method);
>
> struct MHD_Response *res =
> MHD_create_response_from_buffer(strlen(upload_data),
> (void
> *)upload_data,
>
> MHD_RESPMEM_PERSISTENT);
> return MHD_queue_response(conn, MHD_HTTP_OK, res);
> }
>
> int main() {
> struct MHD_Daemon *daemon;
> daemon = MHD_start_daemon(MHD_USE_INTERNAL_POLLING_THREAD, PORT,
> NULL, NULL,
> &on_connection, NULL,
> MHD_OPTION_END);
> getchar();
> MHD_stop_daemon(daemon);
> return 0;
> }
> """
>
> But the problem with this code is that it does not return any response.
> When I try to send a request with curl:
> curl -X POST localhost:8080 -d "Hello"
>
> I see in that server itself prints:
>
> Hello
> POST
>
> every time I make a request, but curl command returns:
> curl: (52) Empty reply from server
>
> I have already noticed that when I sent POST request on_connection
> function is called twice: first time with *upload_data_size = 0 and the
> second time with *upload_data_size equals the size of the payload.
>
> Could you help me with that?
> Thanks,
> czelusniakdawid
signature.asc
Description: OpenPGP digital signature