Do not discard the request body after sending, even if !accumulate
[platform/upstream/libsoup.git] / libsoup / soup-message-io.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-message-io.c: HTTP message I/O
4  *
5  * Copyright (C) 2000-2003, Ximian, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "soup-connection.h"
16 #include "soup-message.h"
17 #include "soup-message-private.h"
18 #include "soup-misc.h"
19 #include "soup-socket.h"
20 #include "soup-ssl.h"
21
22 typedef enum {
23         SOUP_MESSAGE_IO_CLIENT,
24         SOUP_MESSAGE_IO_SERVER
25 } SoupMessageIOMode;
26
27 typedef enum {
28         SOUP_MESSAGE_IO_STATE_NOT_STARTED,
29         SOUP_MESSAGE_IO_STATE_HEADERS,
30         SOUP_MESSAGE_IO_STATE_BLOCKING,
31         SOUP_MESSAGE_IO_STATE_BODY,
32         SOUP_MESSAGE_IO_STATE_CHUNK_SIZE,
33         SOUP_MESSAGE_IO_STATE_CHUNK,
34         SOUP_MESSAGE_IO_STATE_CHUNK_END,
35         SOUP_MESSAGE_IO_STATE_TRAILERS,
36         SOUP_MESSAGE_IO_STATE_FINISHING,
37         SOUP_MESSAGE_IO_STATE_DONE
38 } SoupMessageIOState;
39
40 #define SOUP_MESSAGE_IO_STATE_ACTIVE(state) \
41         (state != SOUP_MESSAGE_IO_STATE_NOT_STARTED && \
42          state != SOUP_MESSAGE_IO_STATE_BLOCKING && \
43          state != SOUP_MESSAGE_IO_STATE_DONE)
44
45 typedef struct {
46         SoupSocket           *sock;
47         SoupConnection       *conn;
48         SoupMessageIOMode     mode;
49
50         SoupMessageIOState    read_state;
51         SoupEncoding          read_encoding;
52         GByteArray           *read_meta_buf;
53         SoupMessageBody      *read_body;
54         goffset               read_length;
55
56         gboolean              need_content_sniffed, need_got_chunk;
57         SoupMessageBody      *sniff_data;
58
59         SoupMessageIOState    write_state;
60         SoupEncoding          write_encoding;
61         GString              *write_buf;
62         SoupMessageBody      *write_body;
63         SoupBuffer           *write_chunk;
64         gsize                 write_body_offset;
65         goffset               write_length;
66         goffset               written;
67
68         guint read_tag, write_tag, err_tag;
69         GSource *unpause_source;
70
71         SoupMessageGetHeadersFn   get_headers_cb;
72         SoupMessageParseHeadersFn parse_headers_cb;
73         gpointer                  user_data;
74 } SoupMessageIOData;
75         
76
77 /* Put these around callback invocation if there is code afterward
78  * that depends on the IO having not been cancelled.
79  */
80 #define dummy_to_make_emacs_happy {
81 #define SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK { gboolean cancelled; g_object_ref (msg);
82 #define SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED cancelled = (priv->io_data != io); g_object_unref (msg); if (cancelled || (!io->read_tag && !io->write_tag)) return; }
83 #define SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED(val) cancelled = (priv->io_data != io); g_object_unref (msg); if (cancelled || (!io->read_tag && !io->write_tag)) return val; }
84
85 #define RESPONSE_BLOCK_SIZE 8192
86
87 void
88 soup_message_io_cleanup (SoupMessage *msg)
89 {
90         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
91         SoupMessageIOData *io;
92
93         soup_message_io_stop (msg);
94
95         io = priv->io_data;
96         if (!io)
97                 return;
98         priv->io_data = NULL;
99
100         if (io->sock)
101                 g_object_unref (io->sock);
102         if (io->conn)
103                 g_object_unref (io->conn);
104
105         g_byte_array_free (io->read_meta_buf, TRUE);
106
107         g_string_free (io->write_buf, TRUE);
108         if (io->write_chunk)
109                 soup_buffer_free (io->write_chunk);
110
111         if (io->sniff_data)
112                 soup_message_body_free (io->sniff_data);
113
114         g_slice_free (SoupMessageIOData, io);
115 }
116
117 /**
118  * soup_message_io_stop:
119  * @msg: a #SoupMessage
120  *
121  * Immediately stops I/O on msg; if the connection would be left in an
122  * inconsistent state, it will be closed.
123  *
124  * Note: this is a low-level function that does not cause any signals
125  * to be emitted on @msg; it is up to the caller to make sure that
126  * @msg doesn't get "stranded".
127  **/
128 void
129 soup_message_io_stop (SoupMessage *msg)
130 {
131         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
132         SoupMessageIOData *io = priv->io_data;
133
134         if (!io)
135                 return;
136
137         if (io->read_tag) {
138                 g_signal_handler_disconnect (io->sock, io->read_tag);
139                 io->read_tag = 0;
140         }
141         if (io->write_tag) {
142                 g_signal_handler_disconnect (io->sock, io->write_tag);
143                 io->write_tag = 0;
144         }
145         if (io->err_tag) {
146                 g_signal_handler_disconnect (io->sock, io->err_tag);
147                 io->err_tag = 0;
148         }
149
150         if (io->unpause_source) {
151                 g_source_destroy (io->unpause_source);
152                 io->unpause_source = NULL;
153         }
154
155         if (io->read_state < SOUP_MESSAGE_IO_STATE_FINISHING)
156                 soup_socket_disconnect (io->sock);
157         else if (io->conn) {
158                 SoupConnection *conn = io->conn;
159                 io->conn = NULL;
160                 soup_connection_set_state (conn, SOUP_CONNECTION_IDLE);
161                 g_object_unref (conn);
162         }
163 }
164
165 #define SOUP_MESSAGE_IO_EOL            "\r\n"
166 #define SOUP_MESSAGE_IO_EOL_LEN        2
167
168 static void
169 soup_message_io_finished (SoupMessage *msg)
170 {
171         g_object_ref (msg);
172         soup_message_io_cleanup (msg);
173         if (SOUP_MESSAGE_IS_STARTING (msg))
174                 soup_message_restarted (msg);
175         else
176                 soup_message_finished (msg);
177         g_object_unref (msg);
178 }
179
180 static void io_read (SoupSocket *sock, SoupMessage *msg);
181
182 static void
183 io_error (SoupSocket *sock, SoupMessage *msg, GError *error)
184 {
185         if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
186                 if (error && error->domain == SOUP_SSL_ERROR) {
187                         soup_message_set_status_full (msg,
188                                                       SOUP_STATUS_SSL_FAILED,
189                                                       error->message);
190                 } else
191                         soup_message_set_status (msg, SOUP_STATUS_IO_ERROR);
192         }
193         if (error)
194                 g_error_free (error);
195
196         soup_message_io_finished (msg);
197 }
198
199 static void
200 io_disconnected (SoupSocket *sock, SoupMessage *msg)
201 {
202         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
203         SoupMessageIOData *io = priv->io_data;
204
205         /* Closing the connection to signify EOF is sometimes ok */
206         if (io->read_state == SOUP_MESSAGE_IO_STATE_BODY &&
207             io->read_encoding == SOUP_ENCODING_EOF) {
208                 io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
209                 io_read (sock, msg);
210                 return;
211         }
212
213         io_error (sock, msg, NULL);
214 }
215
216 static gboolean
217 io_handle_sniffing (SoupMessage *msg, gboolean done_reading)
218 {
219         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
220         SoupMessageIOData *io = priv->io_data;
221         SoupBuffer *sniffed_buffer;
222         char *sniffed_mime_type;
223         GHashTable *params = NULL;
224
225         if (!priv->sniffer)
226                 return TRUE;
227
228         if (!io->sniff_data) {
229                 io->sniff_data = soup_message_body_new ();
230                 io->need_content_sniffed = TRUE;
231         }
232
233         if (io->need_content_sniffed) {
234                 if (io->sniff_data->length < priv->bytes_for_sniffing &&
235                     !done_reading)
236                         return TRUE;
237
238                 io->need_content_sniffed = FALSE;
239                 sniffed_buffer = soup_message_body_flatten (io->sniff_data);
240                 sniffed_mime_type = soup_content_sniffer_sniff (priv->sniffer, msg, sniffed_buffer, &params);
241
242                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
243                 soup_message_content_sniffed (msg, sniffed_mime_type, params);
244                 g_free (sniffed_mime_type);
245                 if (params)
246                         g_hash_table_destroy (params);
247                 if (sniffed_buffer)
248                         soup_buffer_free (sniffed_buffer);
249                 SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
250         }
251
252         if (io->need_got_chunk) {
253                 io->need_got_chunk = FALSE;
254                 sniffed_buffer = soup_message_body_flatten (io->sniff_data);
255
256                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
257                 soup_message_got_chunk (msg, sniffed_buffer);
258                 soup_buffer_free (sniffed_buffer);
259                 SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
260         }
261
262         return TRUE;
263 }
264
265 /* Reads data from io->sock into io->read_meta_buf. If @to_blank is
266  * %TRUE, it reads up until a blank line ("CRLF CRLF" or "LF LF").
267  * Otherwise, it reads up until a single CRLF or LF.
268  *
269  * This function is used to read metadata, and read_body_chunk() is
270  * used to read the message body contents.
271  *
272  * read_metadata, read_body_chunk, and write_data all use the same
273  * convention for return values: if they return %TRUE, it means
274  * they've completely finished the requested read/write, and the
275  * caller should move on to the next step. If they return %FALSE, it
276  * means that either (a) the socket returned SOUP_SOCKET_WOULD_BLOCK,
277  * so the caller should give up for now and wait for the socket to
278  * emit a signal, or (b) the socket returned an error, and io_error()
279  * was called to process it and cancel the I/O. So either way, if the
280  * function returns %FALSE, the caller should return immediately.
281  */
282 static gboolean
283 read_metadata (SoupMessage *msg, gboolean to_blank)
284 {
285         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
286         SoupMessageIOData *io = priv->io_data;
287         SoupSocketIOStatus status;
288         guchar read_buf[RESPONSE_BLOCK_SIZE];
289         gsize nread;
290         gboolean got_lf;
291         GError *error = NULL;
292
293         while (1) {
294                 status = soup_socket_read_until (io->sock, read_buf,
295                                                  sizeof (read_buf),
296                                                  "\n", 1, &nread, &got_lf,
297                                                  NULL, &error);
298                 switch (status) {
299                 case SOUP_SOCKET_OK:
300                         g_byte_array_append (io->read_meta_buf, read_buf, nread);
301                         break;
302
303                 case SOUP_SOCKET_ERROR:
304                 case SOUP_SOCKET_EOF:
305                         io_error (io->sock, msg, error);
306                         return FALSE;
307
308                 case SOUP_SOCKET_WOULD_BLOCK:
309                         return FALSE;
310                 }
311
312                 if (got_lf) {
313                         if (!to_blank)
314                                 break;
315                         if (nread == 1 &&
316                             !strncmp ((char *)io->read_meta_buf->data +
317                                       io->read_meta_buf->len - 2,
318                                       "\n\n", 2))
319                                 break;
320                         else if (nread == 2 &&
321                                  !strncmp ((char *)io->read_meta_buf->data +
322                                            io->read_meta_buf->len - 3,
323                                            "\n\r\n", 3))
324                                 break;
325                 }
326         }
327
328         return TRUE;
329 }
330
331 /* Reads as much message body data as is available on io->sock (but no
332  * further than the end of the current message body or chunk). On a
333  * successful read, emits "got_chunk" (possibly multiple times), and
334  * (unless told not to) appends the chunk to io->read_body.
335  *
336  * See the note at read_metadata() for an explanation of the return
337  * value.
338  */
339 static gboolean
340 read_body_chunk (SoupMessage *msg)
341 {
342         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
343         SoupMessageIOData *io = priv->io_data;
344         SoupSocketIOStatus status;
345         guchar *stack_buf = NULL;
346         gsize len;
347         gboolean read_to_eof = (io->read_encoding == SOUP_ENCODING_EOF);
348         gsize nread;
349         GError *error = NULL;
350         SoupBuffer *buffer;
351
352         if (!io_handle_sniffing (msg, FALSE))
353                 return FALSE;
354
355         while (read_to_eof || io->read_length > 0) {
356                 if (priv->chunk_allocator) {
357                         buffer = priv->chunk_allocator (msg, io->read_length, priv->chunk_allocator_data);
358                         if (!buffer) {
359                                 soup_message_io_pause (msg);
360                                 return FALSE;
361                         }
362                 } else {
363                         if (!stack_buf)
364                                 stack_buf = alloca (RESPONSE_BLOCK_SIZE);
365                         buffer = soup_buffer_new (SOUP_MEMORY_TEMPORARY,
366                                                   stack_buf,
367                                                   RESPONSE_BLOCK_SIZE);
368                 }
369
370                 if (read_to_eof)
371                         len = buffer->length;
372                 else
373                         len = MIN (buffer->length, io->read_length);
374
375                 status = soup_socket_read (io->sock,
376                                            (guchar *)buffer->data, len,
377                                            &nread, NULL, &error);
378
379                 if (status == SOUP_SOCKET_OK && nread) {
380                         buffer->length = nread;
381                         soup_message_body_got_chunk (io->read_body, buffer);
382
383                         io->read_length -= nread;
384
385                         if (io->need_content_sniffed) {
386                                 soup_message_body_append_buffer (io->sniff_data, buffer);
387                                 io->need_got_chunk = TRUE;
388                                 if (!io_handle_sniffing (msg, FALSE))
389                                         return FALSE;
390                                 continue;
391                         }
392
393                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
394                         soup_message_got_chunk (msg, buffer);
395                         soup_buffer_free (buffer);
396                         SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
397                         continue;
398                 }
399
400                 soup_buffer_free (buffer);
401                 switch (status) {
402                 case SOUP_SOCKET_OK:
403                         break;
404
405                 case SOUP_SOCKET_EOF:
406                         if (read_to_eof)
407                                 return TRUE;
408                         /* else fall through */
409
410                 case SOUP_SOCKET_ERROR:
411                         io_error (io->sock, msg, error);
412                         return FALSE;
413
414                 case SOUP_SOCKET_WOULD_BLOCK:
415                         return FALSE;
416                 }
417         }
418
419         return TRUE;
420 }
421
422 /* Attempts to write @len bytes from @data. See the note at
423  * read_metadata() for an explanation of the return value.
424  */
425 static gboolean
426 write_data (SoupMessage *msg, const char *data, guint len, gboolean body)
427 {
428         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
429         SoupMessageIOData *io = priv->io_data;
430         SoupSocketIOStatus status;
431         gsize nwrote;
432         GError *error = NULL;
433         SoupBuffer *chunk;
434         const char *start;
435
436         while (len > io->written) {
437                 status = soup_socket_write (io->sock,
438                                             data + io->written,
439                                             len - io->written,
440                                             &nwrote, NULL, &error);
441                 switch (status) {
442                 case SOUP_SOCKET_EOF:
443                 case SOUP_SOCKET_ERROR:
444                         io_error (io->sock, msg, error);
445                         return FALSE;
446
447                 case SOUP_SOCKET_WOULD_BLOCK:
448                         return FALSE;
449
450                 case SOUP_SOCKET_OK:
451                         start = data + io->written;
452                         io->written += nwrote;
453
454                         if (body) {
455                                 if (io->write_length)
456                                         io->write_length -= nwrote;
457
458                                 chunk = soup_buffer_new (SOUP_MEMORY_TEMPORARY,
459                                                          start, nwrote);
460                                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
461                                 soup_message_wrote_body_data (msg, chunk);
462                                 soup_buffer_free (chunk);
463                                 SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
464                         }
465                         break;
466                 }
467         }
468
469         io->written = 0;
470         return TRUE;
471 }
472
473 static inline SoupMessageIOState
474 io_body_state (SoupEncoding encoding)
475 {
476         if (encoding == SOUP_ENCODING_CHUNKED)
477                 return SOUP_MESSAGE_IO_STATE_CHUNK_SIZE;
478         else
479                 return SOUP_MESSAGE_IO_STATE_BODY;
480 }
481
482 /*
483  * There are two request/response formats: the basic request/response,
484  * possibly with one or more unsolicited informational responses (such
485  * as the WebDAV "102 Processing" response):
486  *
487  *     Client                            Server
488  *      W:HEADERS  / R:NOT_STARTED    ->  R:HEADERS  / W:NOT_STARTED
489  *      W:BODY     / R:NOT_STARTED    ->  R:BODY     / W:NOT_STARTED
490  *     [W:DONE     / R:HEADERS (1xx)  <-  R:DONE     / W:HEADERS (1xx) ...]
491  *      W:DONE     / R:HEADERS        <-  R:DONE     / W:HEADERS
492  *      W:DONE     / R:BODY           <-  R:DONE     / W:BODY
493  *      W:DONE     / R:DONE               R:DONE     / W:DONE
494  *     
495  * and the "Expect: 100-continue" request/response, with the client
496  * blocking halfway through its request, and then either continuing or
497  * aborting, depending on the server response:
498  *
499  *     Client                            Server
500  *      W:HEADERS  / R:NOT_STARTED    ->  R:HEADERS  / W:NOT_STARTED
501  *      W:BLOCKING / R:HEADERS        <-  R:BLOCKING / W:HEADERS
502  *     [W:BODY     / R:BLOCKING       ->  R:BODY     / W:BLOCKING]
503  *     [W:DONE     / R:HEADERS        <-  R:DONE     / W:HEADERS]
504  *      W:DONE     / R:BODY           <-  R:DONE     / W:BODY
505  *      W:DONE     / R:DONE               R:DONE     / W:DONE
506  */
507
508 static void
509 io_write (SoupSocket *sock, SoupMessage *msg)
510 {
511         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
512         SoupMessageIOData *io = priv->io_data;
513
514  write_more:
515         switch (io->write_state) {
516         case SOUP_MESSAGE_IO_STATE_NOT_STARTED:
517                 return;
518
519
520         case SOUP_MESSAGE_IO_STATE_HEADERS:
521                 if (!io->write_buf->len) {
522                         io->get_headers_cb (msg, io->write_buf,
523                                             &io->write_encoding,
524                                             io->user_data);
525                         if (!io->write_buf->len) {
526                                 soup_message_io_pause (msg);
527                                 return;
528                         }
529                 }
530
531                 if (!write_data (msg, io->write_buf->str,
532                                  io->write_buf->len, FALSE))
533                         return;
534
535                 g_string_truncate (io->write_buf, 0);
536
537                 if (io->write_encoding == SOUP_ENCODING_CONTENT_LENGTH) {
538                         SoupMessageHeaders *hdrs =
539                                 (io->mode == SOUP_MESSAGE_IO_CLIENT) ?
540                                 msg->request_headers : msg->response_headers;
541                         io->write_length = soup_message_headers_get_content_length (hdrs);
542                 }
543
544                 if (io->mode == SOUP_MESSAGE_IO_SERVER &&
545                     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
546                         if (msg->status_code == SOUP_STATUS_CONTINUE) {
547                                 /* Stop and wait for the body now */
548                                 io->write_state =
549                                         SOUP_MESSAGE_IO_STATE_BLOCKING;
550                                 io->read_state = io_body_state (io->read_encoding);
551                         } else {
552                                 /* We just wrote a 1xx response
553                                  * header, so stay in STATE_HEADERS.
554                                  * (The caller will pause us from the
555                                  * wrote_informational callback if he
556                                  * is not ready to send the final
557                                  * response.)
558                                  */
559                         }
560                 } else if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
561                            soup_message_headers_get_expectations (msg->request_headers) & SOUP_EXPECTATION_CONTINUE) {
562                         /* Need to wait for the Continue response */
563                         io->write_state = SOUP_MESSAGE_IO_STATE_BLOCKING;
564                         io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
565                 } else {
566                         io->write_state = io_body_state (io->write_encoding);
567
568                         /* If the client was waiting for a Continue
569                          * but we sent something else, then they're
570                          * now done writing.
571                          */
572                         if (io->mode == SOUP_MESSAGE_IO_SERVER &&
573                             io->read_state == SOUP_MESSAGE_IO_STATE_BLOCKING)
574                                 io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
575                 }
576
577                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
578                 if (SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
579                         soup_message_wrote_informational (msg);
580                         soup_message_cleanup_response (msg);
581                 } else
582                         soup_message_wrote_headers (msg);
583                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
584                 break;
585
586
587         case SOUP_MESSAGE_IO_STATE_BLOCKING:
588                 io_read (sock, msg);
589
590                 /* If io_read reached a point where we could write
591                  * again, it would have recursively called io_write.
592                  * So (a) we don't need to try to keep writing, and
593                  * (b) we can't anyway, because msg may have been
594                  * destroyed.
595                  */
596                 return;
597
598
599         case SOUP_MESSAGE_IO_STATE_BODY:
600                 if (!io->write_length && io->write_encoding != SOUP_ENCODING_EOF) {
601                 wrote_body:
602                         io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING;
603
604                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
605                         soup_message_wrote_body (msg);
606                         SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
607                         break;
608                 }
609
610                 if (!io->write_chunk) {
611                         io->write_chunk = soup_message_body_get_chunk (io->write_body, io->write_body_offset);
612                         if (!io->write_chunk) {
613                                 soup_message_io_pause (msg);
614                                 return;
615                         }
616                         if (io->write_chunk->length > io->write_length &&
617                             io->write_encoding != SOUP_ENCODING_EOF) {
618                                 /* App is trying to write more than it
619                                  * claimed it would; we have to truncate.
620                                  */
621                                 SoupBuffer *truncated =
622                                         soup_buffer_new_subbuffer (io->write_chunk,
623                                                                    0, io->write_length);
624                                 soup_buffer_free (io->write_chunk);
625                                 io->write_chunk = truncated;
626                         } else if (io->write_encoding == SOUP_ENCODING_EOF &&
627                                    !io->write_chunk->length)
628                                 goto wrote_body;
629                 }
630
631                 if (!write_data (msg, io->write_chunk->data,
632                                  io->write_chunk->length, TRUE))
633                         return;
634
635                 if (io->mode == SOUP_MESSAGE_IO_SERVER)
636                         soup_message_body_wrote_chunk (io->write_body, io->write_chunk);
637                 io->write_body_offset += io->write_chunk->length;
638                 soup_buffer_free (io->write_chunk);
639                 io->write_chunk = NULL;
640
641                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
642                 soup_message_wrote_chunk (msg);
643                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
644                 break;
645
646         case SOUP_MESSAGE_IO_STATE_CHUNK_SIZE:
647                 if (!io->write_chunk) {
648                         io->write_chunk = soup_message_body_get_chunk (io->write_body, io->write_body_offset);
649                         if (!io->write_chunk) {
650                                 soup_message_io_pause (msg);
651                                 return;
652                         }
653                         g_string_append_printf (io->write_buf, "%lx\r\n",
654                                                 (unsigned long) io->write_chunk->length);
655                         io->write_body_offset += io->write_chunk->length;
656                 }
657
658                 if (!write_data (msg, io->write_buf->str,
659                                  io->write_buf->len, FALSE))
660                         return;
661
662                 g_string_truncate (io->write_buf, 0);
663
664                 if (io->write_chunk->length == 0) {
665                         /* The last chunk has no CHUNK_END... */
666                         io->write_state = SOUP_MESSAGE_IO_STATE_TRAILERS;
667                         break;
668                 }
669
670                 io->write_state = SOUP_MESSAGE_IO_STATE_CHUNK;
671                 /* fall through */
672
673
674         case SOUP_MESSAGE_IO_STATE_CHUNK:
675                 if (!write_data (msg, io->write_chunk->data,
676                                  io->write_chunk->length, TRUE))
677                         return;
678
679                 if (io->mode == SOUP_MESSAGE_IO_SERVER)
680                         soup_message_body_wrote_chunk (io->write_body, io->write_chunk);
681                 soup_buffer_free (io->write_chunk);
682                 io->write_chunk = NULL;
683
684                 io->write_state = SOUP_MESSAGE_IO_STATE_CHUNK_END;
685
686                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
687                 soup_message_wrote_chunk (msg);
688                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
689
690                 /* fall through */
691
692
693         case SOUP_MESSAGE_IO_STATE_CHUNK_END:
694                 if (!write_data (msg, SOUP_MESSAGE_IO_EOL,
695                                  SOUP_MESSAGE_IO_EOL_LEN, FALSE))
696                         return;
697
698                 io->write_state = SOUP_MESSAGE_IO_STATE_CHUNK_SIZE;
699                 break;
700
701
702         case SOUP_MESSAGE_IO_STATE_TRAILERS:
703                 if (!write_data (msg, SOUP_MESSAGE_IO_EOL,
704                                  SOUP_MESSAGE_IO_EOL_LEN, FALSE))
705                         return;
706
707                 io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING;
708
709                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
710                 soup_message_wrote_body (msg);
711                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
712                 /* fall through */
713
714
715         case SOUP_MESSAGE_IO_STATE_FINISHING:
716                 if (io->write_tag) {
717                         g_signal_handler_disconnect (io->sock, io->write_tag);
718                         io->write_tag = 0;
719                 }
720                 io->write_state = SOUP_MESSAGE_IO_STATE_DONE;
721
722                 if (io->mode == SOUP_MESSAGE_IO_CLIENT) {
723                         io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
724                         io_read (sock, msg);
725                 } else
726                         soup_message_io_finished (msg);
727                 return;
728
729
730         case SOUP_MESSAGE_IO_STATE_DONE:
731         default:
732                 g_return_if_reached ();
733         }
734
735         goto write_more;
736 }
737
738 static void
739 io_read (SoupSocket *sock, SoupMessage *msg)
740 {
741         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
742         SoupMessageIOData *io = priv->io_data;
743         guint status;
744
745  read_more:
746         switch (io->read_state) {
747         case SOUP_MESSAGE_IO_STATE_NOT_STARTED:
748                 return;
749
750
751         case SOUP_MESSAGE_IO_STATE_HEADERS:
752                 if (!read_metadata (msg, TRUE))
753                         return;
754
755                 /* We need to "rewind" io->read_meta_buf back one line.
756                  * That SHOULD be two characters (CR LF), but if the
757                  * web server was stupid, it might only be one.
758                  */
759                 if (io->read_meta_buf->len < 3 ||
760                     io->read_meta_buf->data[io->read_meta_buf->len - 2] == '\n')
761                         io->read_meta_buf->len--;
762                 else
763                         io->read_meta_buf->len -= 2;
764                 io->read_meta_buf->data[io->read_meta_buf->len] = '\0';
765                 status = io->parse_headers_cb (msg, (char *)io->read_meta_buf->data,
766                                                io->read_meta_buf->len,
767                                                &io->read_encoding,
768                                                io->user_data);
769                 g_byte_array_set_size (io->read_meta_buf, 0);
770
771                 if (status != SOUP_STATUS_OK) {
772                         /* Either we couldn't parse the headers, or they
773                          * indicated something that would mean we wouldn't
774                          * be able to parse the body. (Eg, unknown
775                          * Transfer-Encoding.). Skip the rest of the
776                          * reading, and make sure the connection gets
777                          * closed when we're done.
778                          */
779                         soup_message_set_status (msg, status);
780                         soup_message_headers_append (msg->request_headers,
781                                                      "Connection", "close");
782                         io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
783                         break;
784                 }
785
786                 if (io->read_encoding == SOUP_ENCODING_CONTENT_LENGTH) {
787                         SoupMessageHeaders *hdrs =
788                                 (io->mode == SOUP_MESSAGE_IO_CLIENT) ?
789                                 msg->response_headers : msg->request_headers;
790                         io->read_length = soup_message_headers_get_content_length (hdrs);
791                 }
792
793                 if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
794                     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
795                         if (msg->status_code == SOUP_STATUS_CONTINUE &&
796                             io->write_state == SOUP_MESSAGE_IO_STATE_BLOCKING) {
797                                 /* Pause the reader, unpause the writer */
798                                 io->read_state =
799                                         SOUP_MESSAGE_IO_STATE_BLOCKING;
800                                 io->write_state =
801                                         io_body_state (io->write_encoding);
802                         } else {
803                                 /* Just stay in HEADERS */
804                                 io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
805                         }
806                 } else if (io->mode == SOUP_MESSAGE_IO_SERVER &&
807                            soup_message_headers_get_expectations (msg->request_headers) & SOUP_EXPECTATION_CONTINUE) {
808                         /* The client requested a Continue response. The
809                          * got_headers handler may change this to something
810                          * else though.
811                          */
812                         soup_message_set_status (msg, SOUP_STATUS_CONTINUE);
813                         io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
814                         io->read_state = SOUP_MESSAGE_IO_STATE_BLOCKING;
815                 } else {
816                         io->read_state = io_body_state (io->read_encoding);
817
818                         /* If the client was waiting for a Continue
819                          * but got something else, then it's done
820                          * writing.
821                          */
822                         if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
823                             io->write_state == SOUP_MESSAGE_IO_STATE_BLOCKING)
824                                 io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING;
825                 }
826
827                 if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
828                     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
829                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
830                         soup_message_got_informational (msg);
831                         soup_message_cleanup_response (msg);
832                         SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
833                 } else {
834                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
835                         soup_message_got_headers (msg);
836                         SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
837                 }
838                 break;
839
840
841         case SOUP_MESSAGE_IO_STATE_BLOCKING:
842                 io_write (sock, msg);
843
844                 /* As in the io_write case, we *must* return here. */
845                 return;
846
847
848         case SOUP_MESSAGE_IO_STATE_BODY:
849                 if (!read_body_chunk (msg))
850                         return;
851
852         got_body:
853                 if (!io_handle_sniffing (msg, TRUE)) {
854                         /* If the message was paused (as opposed to
855                          * cancelled), we need to make sure we wind up
856                          * back here when it's unpaused, even if it
857                          * was doing a chunked or EOF-terminated read
858                          * before.
859                          */
860                         if (io == priv->io_data) {
861                                 io->read_state = SOUP_MESSAGE_IO_STATE_BODY;
862                                 io->read_encoding = SOUP_ENCODING_CONTENT_LENGTH;
863                                 io->read_length = 0;
864                         }
865                         return;
866                 }
867
868                 io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
869
870                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
871                 soup_message_got_body (msg);
872                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
873                 break;
874
875
876         case SOUP_MESSAGE_IO_STATE_CHUNK_SIZE:
877                 if (!read_metadata (msg, FALSE))
878                         return;
879
880                 io->read_length = strtoul ((char *)io->read_meta_buf->data, NULL, 16);
881                 g_byte_array_set_size (io->read_meta_buf, 0);
882
883                 if (io->read_length > 0)
884                         io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK;
885                 else
886                         io->read_state = SOUP_MESSAGE_IO_STATE_TRAILERS;
887                 break;
888
889
890         case SOUP_MESSAGE_IO_STATE_CHUNK:
891                 if (!read_body_chunk (msg))
892                         return;
893
894                 io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK_END;
895                 break;
896
897
898         case SOUP_MESSAGE_IO_STATE_CHUNK_END:
899                 if (!read_metadata (msg, FALSE))
900                         return;
901
902                 g_byte_array_set_size (io->read_meta_buf, 0);
903                 io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK_SIZE;
904                 break;
905
906
907         case SOUP_MESSAGE_IO_STATE_TRAILERS:
908                 if (!read_metadata (msg, FALSE))
909                         return;
910
911                 if (io->read_meta_buf->len <= SOUP_MESSAGE_IO_EOL_LEN)
912                         goto got_body;
913
914                 /* FIXME: process trailers */
915                 g_byte_array_set_size (io->read_meta_buf, 0);
916                 break;
917
918
919         case SOUP_MESSAGE_IO_STATE_FINISHING:
920                 if (io->read_tag) {
921                         g_signal_handler_disconnect (io->sock, io->read_tag);
922                         io->read_tag = 0;
923                 }
924                 io->read_state = SOUP_MESSAGE_IO_STATE_DONE;
925
926                 if (io->mode == SOUP_MESSAGE_IO_SERVER) {
927                         io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
928                         io_write (sock, msg);
929                 } else
930                         soup_message_io_finished (msg);
931                 return;
932
933
934         case SOUP_MESSAGE_IO_STATE_DONE:
935         default:
936                 g_return_if_reached ();
937         }
938
939         goto read_more;
940 }
941
942 static SoupMessageIOData *
943 new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
944              SoupMessageGetHeadersFn get_headers_cb,
945              SoupMessageParseHeadersFn parse_headers_cb,
946              gpointer user_data)
947 {
948         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
949         SoupMessageIOData *io;
950
951         io = g_slice_new0 (SoupMessageIOData);
952         io->sock = g_object_ref (sock);
953         io->mode = mode;
954         io->get_headers_cb   = get_headers_cb;
955         io->parse_headers_cb = parse_headers_cb;
956         io->user_data        = user_data;
957
958         io->read_meta_buf    = g_byte_array_new ();
959         io->write_buf        = g_string_new (NULL);
960
961         io->read_tag  = g_signal_connect (io->sock, "readable",
962                                           G_CALLBACK (io_read), msg);
963         io->write_tag = g_signal_connect (io->sock, "writable",
964                                           G_CALLBACK (io_write), msg);
965         io->err_tag   = g_signal_connect (io->sock, "disconnected",
966                                           G_CALLBACK (io_disconnected), msg);
967
968         io->read_state  = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
969         io->write_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
970
971         if (priv->io_data)
972                 soup_message_io_cleanup (msg);
973         priv->io_data = io;
974         return io;
975 }
976
977 void
978 soup_message_io_client (SoupMessage *msg, SoupSocket *sock,
979                         SoupConnection *conn,
980                         SoupMessageGetHeadersFn get_headers_cb,
981                         SoupMessageParseHeadersFn parse_headers_cb,
982                         gpointer user_data)
983 {
984         SoupMessageIOData *io;
985
986         io = new_iostate (msg, sock, SOUP_MESSAGE_IO_CLIENT,
987                           get_headers_cb, parse_headers_cb, user_data);
988
989         if (conn)
990                 io->conn = g_object_ref (conn);
991
992         io->read_body       = msg->response_body;
993         io->write_body      = msg->request_body;
994
995         io->write_state     = SOUP_MESSAGE_IO_STATE_HEADERS;
996         io_write (sock, msg);
997 }
998
999 void
1000 soup_message_io_server (SoupMessage *msg, SoupSocket *sock,
1001                         SoupMessageGetHeadersFn get_headers_cb,
1002                         SoupMessageParseHeadersFn parse_headers_cb,
1003                         gpointer user_data)
1004 {
1005         SoupMessageIOData *io;
1006
1007         io = new_iostate (msg, sock, SOUP_MESSAGE_IO_SERVER,
1008                           get_headers_cb, parse_headers_cb, user_data);
1009
1010         io->read_body       = msg->request_body;
1011         io->write_body      = msg->response_body;
1012
1013         io->read_state      = SOUP_MESSAGE_IO_STATE_HEADERS;
1014         io_read (sock, msg);
1015 }
1016
1017 void  
1018 soup_message_io_pause (SoupMessage *msg)
1019 {
1020         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1021         SoupMessageIOData *io = priv->io_data;
1022
1023         g_return_if_fail (io != NULL);
1024
1025         if (io->write_tag) {
1026                 g_signal_handler_disconnect (io->sock, io->write_tag);
1027                 io->write_tag = 0;
1028         }
1029         if (io->read_tag) {
1030                 g_signal_handler_disconnect (io->sock, io->read_tag);
1031                 io->read_tag = 0;
1032         }
1033
1034         if (io->unpause_source) {
1035                 g_source_destroy (io->unpause_source);
1036                 io->unpause_source = NULL;
1037         }
1038 }
1039
1040 static gboolean
1041 io_unpause_internal (gpointer msg)
1042 {
1043         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1044         SoupMessageIOData *io = priv->io_data;
1045
1046         g_return_val_if_fail (io != NULL, FALSE);
1047         io->unpause_source = NULL;
1048
1049         if (io->write_tag || io->read_tag)
1050                 return FALSE;
1051
1052         if (io->write_state != SOUP_MESSAGE_IO_STATE_DONE) {
1053                 io->write_tag = g_signal_connect (io->sock, "writable",
1054                                                   G_CALLBACK (io_write), msg);
1055         }
1056
1057         if (io->read_state != SOUP_MESSAGE_IO_STATE_DONE) {
1058                 io->read_tag = g_signal_connect (io->sock, "readable",
1059                                                  G_CALLBACK (io_read), msg);
1060         }
1061
1062         if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->write_state))
1063                 io_write (io->sock, msg);
1064         else if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state))
1065                 io_read (io->sock, msg);
1066
1067         return FALSE;
1068 }
1069
1070 void
1071 soup_message_io_unpause (SoupMessage *msg)
1072 {
1073         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1074         SoupMessageIOData *io = priv->io_data;
1075         gboolean non_blocking;
1076         GMainContext *async_context;
1077
1078         g_return_if_fail (io != NULL);
1079
1080         g_object_get (io->sock,
1081                       SOUP_SOCKET_FLAG_NONBLOCKING, &non_blocking,
1082                       SOUP_SOCKET_ASYNC_CONTEXT, &async_context,
1083                       NULL);
1084         if (non_blocking) {
1085                 if (!io->unpause_source) {
1086                         io->unpause_source = soup_add_completion (
1087                                 async_context, io_unpause_internal, msg);
1088                 }
1089         } else
1090                 io_unpause_internal (msg);
1091         if (async_context)
1092                 g_main_context_unref (async_context);
1093 }
1094
1095 /**
1096  * soup_message_io_in_progress:
1097  * @msg: a #SoupMessage
1098  *
1099  * Tests whether or not I/O is currently in progress on @msg.
1100  *
1101  * Return value: whether or not I/O is currently in progress.
1102  **/
1103 gboolean
1104 soup_message_io_in_progress (SoupMessage *msg)
1105 {
1106         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1107
1108         return priv->io_data != NULL;
1109 }