libmicrohttpd
[Top][All Lists]
Advanced

[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

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]