diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c index 1313ba4..12bc4ae 100644 --- a/src/server/e-ews-connection.c +++ b/src/server/e-ews-connection.c @@ -247,7 +247,7 @@ ews_next_request (gpointer _cnc) node = (EwsNode *) l->data; - if (g_getenv ("EWS_DEBUG") && (atoi (g_getenv ("EWS_DEBUG")) >= 1)) { + if (0 && g_getenv ("EWS_DEBUG") && (atoi (g_getenv ("EWS_DEBUG")) >= 1)) { soup_buffer_free (soup_message_body_flatten (SOUP_MESSAGE (node->msg)->request_body)); /* print request's body */ printf ("\n The request headers"); diff --git a/src/server/e-soap-message.c b/src/server/e-soap-message.c index ed776d8..cdd6081 100644 --- a/src/server/e-soap-message.c +++ b/src/server/e-soap-message.c @@ -23,6 +23,10 @@ typedef struct { xmlChar *env_uri; gboolean body_started; gchar *action; + gchar *body; + int bodylen; + int body_wrote; + int offset; } ESoapMessagePrivate; #define E_SOAP_MESSAGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_SOAP_MESSAGE, ESoapMessagePrivate)) @@ -44,7 +48,7 @@ finalize (GObject *object) xmlFree (priv->env_uri); if (priv->env_prefix) xmlFree (priv->env_prefix); - + g_free (priv->body); G_OBJECT_CLASS (e_soap_message_parent_class)->finalize (object); } @@ -90,7 +94,37 @@ static void soap_restarted (SoupMessage *msg, gpointer data) { ESoapMessagePrivate *priv = E_SOAP_MESSAGE_GET_PRIVATE (msg); - /* Discard the existing context, if there is one, and start again */ + printf("restarted\n"); + + /* OUTBOUND : Reset the request_body and start again */ +#if 0 + /* This ought to work, but soup_message_body_truncate() doesn't + reset priv->base_offset, so libsoup gets confused */ + soup_message_body_truncate (msg->request_body); +#elif 0 + /* This doesn't work *either*, because it's been cached in the + SoupMessageIOData and we can't change it from there */ + soup_message_body_free (msg->request_body); + msg->request_body = soup_message_body_new (); + soup_message_body_set_accumulate (msg->request_body, FALSE); +#else + /* OH GOD SHOOT ME NOW */ + SoupBuffer *chunk; + + soup_message_body_complete (msg->request_body); + chunk = soup_message_body_get_chunk (msg->request_body, priv->offset); + printf("complete chunk %p\n", chunk); + if (chunk) { + chunk->length = -priv->body_wrote; + soup_message_body_wrote_chunk(msg->request_body, chunk); + } + printf("do truncate after screwing with base_offset\n"); + soup_message_body_truncate (msg->request_body); +#endif + priv->offset = 0; + priv->body_wrote = 0; + + /* INCOMING : Discard any existing XML parsing context */ if (priv->ctxt) { if (priv->ctxt->myDoc) xmlFreeDoc (priv->ctxt->myDoc); @@ -113,6 +147,55 @@ static void soap_got_chunk (SoupMessage *msg, SoupBuffer *chunk, gpointer data) xmlParseChunk (priv->ctxt, chunk->data, chunk->length, 0); } +static void soap_wrote_headers (SoupMessage *msg, gpointer *data) +{ + ESoapMessagePrivate *priv = E_SOAP_MESSAGE_GET_PRIVATE (msg); + int j = priv->bodylen - priv->offset; + + if (j < 0) { + printf("Already written it all to msg %p\n", msg); + return; + } + + if (j > 1024) + j = 1024; + + if (!j) { + printf("No chunk to append to msg %p\n", msg); + soup_message_body_complete (SOUP_MESSAGE (msg)->request_body); + j++; + return; + } + + soup_message_body_append (SOUP_MESSAGE (msg)->request_body, + SOUP_MEMORY_COPY, + priv->body + priv->offset, j); + priv->offset += j; +} + +static void soap_wrote_chunk (SoupMessage *msg, gpointer *data) +{ + ESoapMessagePrivate *priv = E_SOAP_MESSAGE_GET_PRIVATE (msg); + SoupBuffer *chunk; + + /* Remove the data chunks that have already been written. + But don't remove the last one; it seems to confuse libsoup */ + chunk = soup_message_body_get_chunk (msg->request_body, + priv->body_wrote); + printf("chunk at %d is %p\n", priv->body_wrote, chunk); + + if (chunk) { + printf("Wipe chunk at %d (%d bytes);\n", + priv->body_wrote, chunk->length); + priv->body_wrote += chunk->length; + soup_message_body_wrote_chunk (msg->request_body, + chunk); + soup_buffer_free (chunk); + } + + soap_wrote_headers (msg, data); +} + /** * e_soap_message_new: * @method: the HTTP method for the created request. @@ -150,8 +233,12 @@ e_soap_message_new (const gchar *method, const gchar *uri_string, Instead, parse it as it arrives. */ soup_message_body_set_accumulate (SOUP_MESSAGE (msg)->response_body, FALSE); + soup_message_body_set_accumulate (SOUP_MESSAGE (msg)->request_body, + FALSE); g_signal_connect (msg, "got-chunk", G_CALLBACK (soap_got_chunk), NULL); g_signal_connect (msg, "restarted", G_CALLBACK (soap_restarted), NULL); + g_signal_connect (msg, "wrote-headers", G_CALLBACK (soap_wrote_headers), NULL); + g_signal_connect (msg, "wrote-chunk", G_CALLBACK (soap_wrote_chunk), NULL); return msg; } @@ -838,15 +925,28 @@ e_soap_message_persist (ESoapMessage *msg) ESoapMessagePrivate *priv; xmlChar *body; gint len; + int i, j = 0; g_return_if_fail (E_IS_SOAP_MESSAGE (msg)); priv = E_SOAP_MESSAGE_GET_PRIVATE (msg); xmlDocDumpMemory (priv->doc, &body, &len); +#if 0 /* serialize to SoupMessage class */ soup_message_set_request (SOUP_MESSAGE (msg), "text/xml", SOUP_MEMORY_TAKE, (gchar *)body, len); +#else + soup_message_headers_replace (SOUP_MESSAGE (msg)->request_headers, + "Content-Type", "text/xml"); + soup_message_headers_set_encoding (SOUP_MESSAGE (msg)->request_headers, + SOUP_ENCODING_CHUNKED); + + priv->body = body; + priv->bodylen = len; + priv->offset = 0; + +#endif } /**