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