libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] post processing question


From: Christian Grothoff
Subject: Re: [libmicrohttpd] post processing question
Date: Wed, 29 Aug 2012 11:51:30 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.4) Gecko/20120510 Icedove/10.0.4

Dear Martin,

You can totally do it later (the disadvantage being that then the client will have started the upload, and if you're then out-of-memory and cannot handle the request, bandwidth will be wasted). So the question is if it is worse to put the test on filepost1 vs. filepost2 into the PP callback vs. delaying creating the PP. That's a very minor engineering decision IMO.

You also do not have to use the post processor at all --- if you are in a setting where parsing of the upload data is not required or trivial, you can also handle it yourself and never create a post processor. For very, very small systems (< 128k RAM/ROM), this might be the best option.

Happy hacking!

Christian

On 08/29/2012 11:42 AM, Martin Velek wrote:
Hello,

is it mandatory to create MHD_create_post_processor during the first
call of function MHD_AccessHandlerCallback? In all post examples, it
is done in  if (NULL == *con_cls){ ... }.

Or can I create it later (second call of MHD_AccessHandlerCallback)?:
if (0 == strcmp (method, "POST"))
{
   if(false == was_not_alredy_created)
   {
           con_info->postprocessor = MHD_create_post_processor
(connection, POSTBUFFERSIZE, iterate_post, (void *) con_info);
    }
    if (0 != *upload_data_size)
         {
           MHD_post_process (con_info->postprocessor, upload_data,
*upload_data_size);
           *upload_data_size = 0;
           return MHD_YES;
         }
}

Thanks You for answer(s)
Martin

-------------------------------- A very very long reason
--------------------------
I am trying to create a small web server based on libmicrohttpd
handling also SSI and CGI requests (a function which returns buffer).
It offers own interface e.g. only http_server_start(). Internals of
Libmicrohttpd are mostly hidden, e.g. the function
http_server_set_credentials(const char * username, const char *
password) sets user and password for basic http auth and
http_server_setup_handler() sets user callback for handling requests.

My AccessHandlerCallback is a static function and call user's callback.

#define         HTTP_NEW_CONNECTION     ((void *)(~0))
static int AccessHandlerCallback(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 = MHD_NO;
        char *user = NULL;
        char *pass = NULL;

        if (NULL == *con_cls)
        {
                /*
                 * Thus, we will generate no response until the parameter is
non-null—implying the callback was called before at least once.
                 * We do not need to share information between different calls 
of
the callback, so we can set the parameter to any adress
                 * that is assured to be not null.
                 */
                *con_cls = HTTP_NEW_CONNECTION;
                return MHD_YES;
        }
        // get username and password
        user = MHD_basic_auth_get_username_password (connection,&pass);
        // check if it is valid
        if (false == check_credentials(user, pass))
        {
                // no, send denied reply
                struct MHD_Response * response =
MHD_create_response_from_buffer(strlen(AUTH_FAIL_PAGE), (void *)
AUTH_FAIL_PAGE, MHD_RESPMEM_PERSISTENT);
                MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
"text/html""; charset=iso-8859-2");
                // Set headers to always close connection
                MHD_add_response_header (response,MHD_HTTP_HEADER_CONNECTION, 
"close");
                ret = MHD_queue_basic_auth_fail_response(connection,
AUTHENTICATION_REALM_MESSAGE, response);
                MHD_destroy_response (response);
        }
        else
        {
                if(NULL != url_handler.url_callback)
                {
                        ret = url_handler.url_callback(connection,
url_handler.url_callback_cls, url, method, upload_data,
upload_data_size, con_cls);
                }
                else
                {
                        ret = MHD_NO;
                }
        }
        // Dealocate because of MHD.
        free (user);
        free (pass);

        return ret;
}

I would like to handle more than one page (1 ... n files) e.g. from
this GET request.

"<html><body>Upload a file, please!<br>
                        <form action=\"/filepost1\" method=\"post\"
enctype=\"multipart/form-data\">
                        <input name=\"file\" type=\"file\">
                        <input type=\"submit\" value=\" Send \"></form>

          <form action=\"/filepost2\" method=\"post\"
enctype=\"multipart/form-data\">
                        <input name=\"file\" type=\"file\">
                        <input type=\"submit\" value=\" Send \"></form>

</body></html>";

Both files /filepost1 and /filepost2 have different
MHD_PostDataIterator, filepost1 stores file onto harddisk, filepost2
to memory.

Which MHD_PostDataIterator will be used, it is defined in a user
callback called from AccessHandlerCallback. This is the reason of my
question.





reply via email to

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