Hi Mohamed,

> This patch just to start on how best to implement POST with
> chunk encoding.
> In start_request we call input->func callbak if it returns FALSE
> then do POST the normal way with Content-Length set to length,
> else we set Transfer-Encoding to chunked and we send the POST
> request in chunks, I send the chunk to sock once ready. After
> the chunk was sent I call input_func again and repeat until
> FALSE is returned and send the last chunk.

yes, basically that is the idea.

> ---
>  gweb/gweb.c |  417 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 388 insertions(+), 29 deletions(-)
> 
> diff --git a/gweb/gweb.c b/gweb/gweb.c
> index 295b93f..c15ea42 100644
> --- a/gweb/gweb.c
> +++ b/gweb/gweb.c
> @@ -465,6 +465,7 @@ static void start_request(struct web_session *session)
>       gsize length;
>       gsize count, bytes_written;
>       GIOStatus status;
> +     gboolean more_data, use_chunk;
>  
>       debug(session->web, "request %s from %s",
>                                       session->request, session->host);
> @@ -484,27 +485,69 @@ static void start_request(struct web_session *session)
>       if (session->web->accept_option != NULL)
>               g_string_append_printf(buf, "Accept: %s\r\n",
>                                               session->web->accept_option);
> +     use_chunk = FALSE;
> +
>       if (session->content_type != NULL) {
>               g_string_append_printf(buf, "Content-Type: %s\r\n",
>                                               session->content_type);
>               if (session->input_func != NULL)
> -                     session->input_func(&body, &length, session->user_data);
> +                     use_chunk = session->input_func(&body, &length,
> +                                                     session->user_data);
>               else
>                       length = 0;
>  
> -             g_string_append_printf(buf, "Content-Length: %zu\r\n", length);
> +             if (use_chunk == FALSE)
> +                     g_string_append_printf(buf, "Content-Length: %zu\r\n",
> +                                                                     length);
> +             else
> +                     g_string_append(buf, "Transfer-Encoding: chunked\r\n");
>       }
>       if (session->web->close_connection == TRUE)
>               g_string_append(buf, "Connection: close\r\n");
>       g_string_append(buf, "\r\n");
>  
> -     count = buf->len;
> -
>       if (session->content_type != NULL && length > 0) {
> -             g_string_append_len(buf, (char *) body, length);
> -             count += length;
> +             more_data = use_chunk;
> +
> +             while (more_data) {
> +                     g_string_append_printf(buf, "%x\r\n", length);
> +                     g_string_append_len(buf, (char *) body, length);
> +                     g_string_append(buf, "\r\n");

This is just the thing you can not do. This is a busy loop. We are
single threaded mainloop driven application and this will not work for
any large body.

So what you have to do is to have a write watch on the socket and every
time it is ready to write new data, call the input_func and process its
results.

You call the input_func one time from this function to get the initial
body data and if it suppose to be chunked or not, but from there on you
need to go via a watch and via the mainloop.

> +                     count = buf->len;
> +                     str = buf->str;
> +
> +                     status = g_io_channel_write_chars(
> +                                     session->transport_channel,
> +                                     str, count, &bytes_written, NULL);
> +
> +                     debug(session->web, "status %u bytes written %zu",
> +                                                     status, bytes_written);
> +
> +                     more_data = session->input_func(&body, &length,
> +                                                     session->user_data);
> +
> +                      g_string_truncate(buf, 0);

You have a whitespace damage here ;)

Regards

Marcel


_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to