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