Misc SoupConnection API improvements
[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 (error && error->domain == SOUP_SSL_ERROR) {
197                 soup_message_set_status_full (msg,
198                                               SOUP_STATUS_SSL_FAILED,
199                                               error->message);
200         } else if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
201                    io->read_state <= SOUP_MESSAGE_IO_STATE_HEADERS &&
202                    io->read_meta_buf->len == 0 &&
203                    soup_connection_get_ever_used (io->conn) &&
204                    !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) &&
205                    request_is_idempotent (msg)) {
206                 /* Connection got closed, but we can safely try again */
207                 priv->io_status = SOUP_MESSAGE_IO_STATUS_QUEUED;
208         } else if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
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         if (soup_socket_is_ssl (io->sock)) {
347                 gboolean trusted_certificate;
348
349                 g_object_get (io->sock,
350                               SOUP_SOCKET_TRUSTED_CERTIFICATE, &trusted_certificate,
351                               NULL);
352
353                 if (trusted_certificate)
354                         soup_message_set_flags (msg, priv->msg_flags | SOUP_MESSAGE_CERTIFICATE_TRUSTED);
355         }
356
357         return TRUE;
358 }
359
360 static SoupBuffer *
361 content_decode (SoupMessage *msg, SoupBuffer *buf)
362 {
363         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
364         SoupCoding *decoder;
365         SoupBuffer *decoded;
366         GError *error = NULL;
367         GSList *d;
368
369         for (d = priv->decoders; d; d = d->next) {
370                 decoder = d->data;
371
372                 decoded = soup_coding_apply (decoder, buf->data, buf->length,
373                                              FALSE, &error);
374                 if (error) {
375                         if (g_error_matches (error, SOUP_CODING_ERROR, SOUP_CODING_ERROR_INTERNAL_ERROR))
376                                 g_warning ("Content-Decoding error: %s\n", error->message);
377                         g_error_free (error);
378
379                         soup_message_set_flags (msg, priv->msg_flags & ~SOUP_MESSAGE_CONTENT_DECODED);
380                         break;
381                 }
382                 if (buf)
383                         soup_buffer_free (buf);
384
385                 if (decoded)
386                         buf = decoded;
387                 else
388                         return NULL;
389         }
390
391         return buf;
392 }
393
394 /* Reads as much message body data as is available on io->sock (but no
395  * further than the end of the current message body or chunk). On a
396  * successful read, emits "got_chunk" (possibly multiple times), and
397  * (unless told not to) appends the chunk to io->read_body.
398  *
399  * See the note at read_metadata() for an explanation of the return
400  * value.
401  */
402 static gboolean
403 read_body_chunk (SoupMessage *msg)
404 {
405         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
406         SoupMessageIOData *io = priv->io_data;
407         SoupSocketIOStatus status;
408         guchar *stack_buf = NULL;
409         gsize len;
410         gboolean read_to_eof = (io->read_encoding == SOUP_ENCODING_EOF);
411         gsize nread;
412         GError *error = NULL;
413         SoupBuffer *buffer;
414
415         if (!io_handle_sniffing (msg, FALSE))
416                 return FALSE;
417
418         while (read_to_eof || io->read_length > 0) {
419                 if (priv->chunk_allocator) {
420                         buffer = priv->chunk_allocator (msg, io->read_length, priv->chunk_allocator_data);
421                         if (!buffer) {
422                                 soup_message_io_pause (msg);
423                                 return FALSE;
424                         }
425                 } else {
426                         if (!stack_buf)
427                                 stack_buf = alloca (RESPONSE_BLOCK_SIZE);
428                         buffer = soup_buffer_new (SOUP_MEMORY_TEMPORARY,
429                                                   stack_buf,
430                                                   RESPONSE_BLOCK_SIZE);
431                 }
432
433                 if (read_to_eof)
434                         len = buffer->length;
435                 else
436                         len = MIN (buffer->length, io->read_length);
437
438                 status = soup_socket_read (io->sock,
439                                            (guchar *)buffer->data, len,
440                                            &nread, NULL, &error);
441
442                 if (status == SOUP_SOCKET_OK && nread) {
443                         buffer->length = nread;
444                         io->read_length -= nread;
445
446                         buffer = content_decode (msg, buffer);
447                         if (!buffer)
448                                 continue;
449
450                         soup_message_body_got_chunk (io->read_body, buffer);
451
452                         if (io->need_content_sniffed) {
453                                 soup_message_body_append_buffer (io->sniff_data, buffer);
454                                 soup_buffer_free (buffer);
455                                 io->need_got_chunk = TRUE;
456                                 if (!io_handle_sniffing (msg, FALSE))
457                                         return FALSE;
458                                 continue;
459                         }
460
461                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
462                         soup_message_got_chunk (msg, buffer);
463                         soup_buffer_free (buffer);
464                         SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
465                         continue;
466                 }
467
468                 soup_buffer_free (buffer);
469                 switch (status) {
470                 case SOUP_SOCKET_OK:
471                         break;
472
473                 case SOUP_SOCKET_EOF:
474                         if (read_to_eof)
475                                 return TRUE;
476                         /* else fall through */
477
478                 case SOUP_SOCKET_ERROR:
479                         io_error (io->sock, msg, error);
480                         return FALSE;
481
482                 case SOUP_SOCKET_WOULD_BLOCK:
483                         return FALSE;
484                 }
485         }
486
487         return TRUE;
488 }
489
490 /* Attempts to write @len bytes from @data. See the note at
491  * read_metadata() for an explanation of the return value.
492  */
493 static gboolean
494 write_data (SoupMessage *msg, const char *data, guint len, gboolean body)
495 {
496         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
497         SoupMessageIOData *io = priv->io_data;
498         SoupSocketIOStatus status;
499         gsize nwrote;
500         GError *error = NULL;
501         SoupBuffer *chunk;
502         const char *start;
503
504         while (len > io->written) {
505                 status = soup_socket_write (io->sock,
506                                             data + io->written,
507                                             len - io->written,
508                                             &nwrote, NULL, &error);
509                 switch (status) {
510                 case SOUP_SOCKET_EOF:
511                 case SOUP_SOCKET_ERROR:
512                         io_error (io->sock, msg, error);
513                         return FALSE;
514
515                 case SOUP_SOCKET_WOULD_BLOCK:
516                         return FALSE;
517
518                 case SOUP_SOCKET_OK:
519                         start = data + io->written;
520                         io->written += nwrote;
521
522                         if (body) {
523                                 if (io->write_length)
524                                         io->write_length -= nwrote;
525
526                                 chunk = soup_buffer_new (SOUP_MEMORY_TEMPORARY,
527                                                          start, nwrote);
528                                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
529                                 soup_message_wrote_body_data (msg, chunk);
530                                 soup_buffer_free (chunk);
531                                 SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
532                         }
533                         break;
534                 }
535         }
536
537         io->written = 0;
538         return TRUE;
539 }
540
541 static inline SoupMessageIOState
542 io_body_state (SoupEncoding encoding)
543 {
544         if (encoding == SOUP_ENCODING_CHUNKED)
545                 return SOUP_MESSAGE_IO_STATE_CHUNK_SIZE;
546         else
547                 return SOUP_MESSAGE_IO_STATE_BODY;
548 }
549
550 /*
551  * There are two request/response formats: the basic request/response,
552  * possibly with one or more unsolicited informational responses (such
553  * as the WebDAV "102 Processing" response):
554  *
555  *     Client                            Server
556  *      W:HEADERS  / R:NOT_STARTED    ->  R:HEADERS  / W:NOT_STARTED
557  *      W:BODY     / R:NOT_STARTED    ->  R:BODY     / W:NOT_STARTED
558  *     [W:DONE     / R:HEADERS (1xx)  <-  R:DONE     / W:HEADERS (1xx) ...]
559  *      W:DONE     / R:HEADERS        <-  R:DONE     / W:HEADERS
560  *      W:DONE     / R:BODY           <-  R:DONE     / W:BODY
561  *      W:DONE     / R:DONE               R:DONE     / W:DONE
562  *     
563  * and the "Expect: 100-continue" request/response, with the client
564  * blocking halfway through its request, and then either continuing or
565  * aborting, depending on the server response:
566  *
567  *     Client                            Server
568  *      W:HEADERS  / R:NOT_STARTED    ->  R:HEADERS  / W:NOT_STARTED
569  *      W:BLOCKING / R:HEADERS        <-  R:BLOCKING / W:HEADERS
570  *     [W:BODY     / R:BLOCKING       ->  R:BODY     / W:BLOCKING]
571  *     [W:DONE     / R:HEADERS        <-  R:DONE     / W:HEADERS]
572  *      W:DONE     / R:BODY           <-  R:DONE     / W:BODY
573  *      W:DONE     / R:DONE               R:DONE     / W:DONE
574  */
575
576 static void
577 io_write (SoupSocket *sock, SoupMessage *msg)
578 {
579         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
580         SoupMessageIOData *io = priv->io_data;
581
582  write_more:
583         switch (io->write_state) {
584         case SOUP_MESSAGE_IO_STATE_NOT_STARTED:
585                 return;
586
587
588         case SOUP_MESSAGE_IO_STATE_HEADERS:
589                 if (!io->write_buf->len) {
590                         io->get_headers_cb (msg, io->write_buf,
591                                             &io->write_encoding,
592                                             io->user_data);
593                         if (!io->write_buf->len) {
594                                 soup_message_io_pause (msg);
595                                 return;
596                         }
597                 }
598
599                 if (!write_data (msg, io->write_buf->str,
600                                  io->write_buf->len, FALSE))
601                         return;
602
603                 g_string_truncate (io->write_buf, 0);
604
605                 if (io->write_encoding == SOUP_ENCODING_CONTENT_LENGTH) {
606                         SoupMessageHeaders *hdrs =
607                                 (io->mode == SOUP_MESSAGE_IO_CLIENT) ?
608                                 msg->request_headers : msg->response_headers;
609                         io->write_length = soup_message_headers_get_content_length (hdrs);
610                 }
611
612                 if (io->mode == SOUP_MESSAGE_IO_SERVER &&
613                     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
614                         if (msg->status_code == SOUP_STATUS_CONTINUE) {
615                                 /* Stop and wait for the body now */
616                                 io->write_state =
617                                         SOUP_MESSAGE_IO_STATE_BLOCKING;
618                                 io->read_state = io_body_state (io->read_encoding);
619                         } else {
620                                 /* We just wrote a 1xx response
621                                  * header, so stay in STATE_HEADERS.
622                                  * (The caller will pause us from the
623                                  * wrote_informational callback if he
624                                  * is not ready to send the final
625                                  * response.)
626                                  */
627                         }
628                 } else if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
629                            soup_message_headers_get_expectations (msg->request_headers) & SOUP_EXPECTATION_CONTINUE) {
630                         /* Need to wait for the Continue response */
631                         io->write_state = SOUP_MESSAGE_IO_STATE_BLOCKING;
632                         io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
633                 } else {
634                         io->write_state = io_body_state (io->write_encoding);
635
636                         /* If the client was waiting for a Continue
637                          * but we sent something else, then they're
638                          * now done writing.
639                          */
640                         if (io->mode == SOUP_MESSAGE_IO_SERVER &&
641                             io->read_state == SOUP_MESSAGE_IO_STATE_BLOCKING)
642                                 io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
643                 }
644
645                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
646                 if (SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
647                         soup_message_wrote_informational (msg);
648                         soup_message_cleanup_response (msg);
649                 } else
650                         soup_message_wrote_headers (msg);
651                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
652                 break;
653
654
655         case SOUP_MESSAGE_IO_STATE_BLOCKING:
656                 io_read (sock, msg);
657
658                 /* If io_read reached a point where we could write
659                  * again, it would have recursively called io_write.
660                  * So (a) we don't need to try to keep writing, and
661                  * (b) we can't anyway, because msg may have been
662                  * destroyed.
663                  */
664                 return;
665
666
667         case SOUP_MESSAGE_IO_STATE_BODY:
668                 if (!io->write_length && io->write_encoding != SOUP_ENCODING_EOF) {
669                 wrote_body:
670                         io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING;
671
672                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
673                         soup_message_wrote_body (msg);
674                         SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
675                         break;
676                 }
677
678                 if (!io->write_chunk) {
679                         io->write_chunk = soup_message_body_get_chunk (io->write_body, io->write_body_offset);
680                         if (!io->write_chunk) {
681                                 soup_message_io_pause (msg);
682                                 return;
683                         }
684                         if (io->write_chunk->length > io->write_length &&
685                             io->write_encoding != SOUP_ENCODING_EOF) {
686                                 /* App is trying to write more than it
687                                  * claimed it would; we have to truncate.
688                                  */
689                                 SoupBuffer *truncated =
690                                         soup_buffer_new_subbuffer (io->write_chunk,
691                                                                    0, io->write_length);
692                                 soup_buffer_free (io->write_chunk);
693                                 io->write_chunk = truncated;
694                         } else if (io->write_encoding == SOUP_ENCODING_EOF &&
695                                    !io->write_chunk->length)
696                                 goto wrote_body;
697                 }
698
699                 if (!write_data (msg, io->write_chunk->data,
700                                  io->write_chunk->length, TRUE))
701                         return;
702
703                 if (io->mode == SOUP_MESSAGE_IO_SERVER)
704                         soup_message_body_wrote_chunk (io->write_body, io->write_chunk);
705                 io->write_body_offset += io->write_chunk->length;
706                 soup_buffer_free (io->write_chunk);
707                 io->write_chunk = NULL;
708
709                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
710                 soup_message_wrote_chunk (msg);
711                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
712                 break;
713
714         case SOUP_MESSAGE_IO_STATE_CHUNK_SIZE:
715                 if (!io->write_chunk) {
716                         io->write_chunk = soup_message_body_get_chunk (io->write_body, io->write_body_offset);
717                         if (!io->write_chunk) {
718                                 soup_message_io_pause (msg);
719                                 return;
720                         }
721                         g_string_append_printf (io->write_buf, "%lx\r\n",
722                                                 (unsigned long) io->write_chunk->length);
723                         io->write_body_offset += io->write_chunk->length;
724                 }
725
726                 if (!write_data (msg, io->write_buf->str,
727                                  io->write_buf->len, FALSE))
728                         return;
729
730                 g_string_truncate (io->write_buf, 0);
731
732                 if (io->write_chunk->length == 0) {
733                         /* The last chunk has no CHUNK_END... */
734                         io->write_state = SOUP_MESSAGE_IO_STATE_TRAILERS;
735                         break;
736                 }
737
738                 io->write_state = SOUP_MESSAGE_IO_STATE_CHUNK;
739                 /* fall through */
740
741
742         case SOUP_MESSAGE_IO_STATE_CHUNK:
743                 if (!write_data (msg, io->write_chunk->data,
744                                  io->write_chunk->length, TRUE))
745                         return;
746
747                 if (io->mode == SOUP_MESSAGE_IO_SERVER)
748                         soup_message_body_wrote_chunk (io->write_body, io->write_chunk);
749                 soup_buffer_free (io->write_chunk);
750                 io->write_chunk = NULL;
751
752                 io->write_state = SOUP_MESSAGE_IO_STATE_CHUNK_END;
753
754                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
755                 soup_message_wrote_chunk (msg);
756                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
757
758                 /* fall through */
759
760
761         case SOUP_MESSAGE_IO_STATE_CHUNK_END:
762                 if (!write_data (msg, SOUP_MESSAGE_IO_EOL,
763                                  SOUP_MESSAGE_IO_EOL_LEN, FALSE))
764                         return;
765
766                 io->write_state = SOUP_MESSAGE_IO_STATE_CHUNK_SIZE;
767                 break;
768
769
770         case SOUP_MESSAGE_IO_STATE_TRAILERS:
771                 if (!write_data (msg, SOUP_MESSAGE_IO_EOL,
772                                  SOUP_MESSAGE_IO_EOL_LEN, FALSE))
773                         return;
774
775                 io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING;
776
777                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
778                 soup_message_wrote_body (msg);
779                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
780                 /* fall through */
781
782
783         case SOUP_MESSAGE_IO_STATE_FINISHING:
784                 if (io->write_tag) {
785                         g_signal_handler_disconnect (io->sock, io->write_tag);
786                         io->write_tag = 0;
787                 }
788                 io->write_state = SOUP_MESSAGE_IO_STATE_DONE;
789
790                 if (io->mode == SOUP_MESSAGE_IO_CLIENT) {
791                         io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
792                         io_read (sock, msg);
793                 } else
794                         soup_message_io_finished (msg);
795                 return;
796
797
798         case SOUP_MESSAGE_IO_STATE_DONE:
799         default:
800                 g_return_if_reached ();
801         }
802
803         goto write_more;
804 }
805
806 static void
807 io_read (SoupSocket *sock, SoupMessage *msg)
808 {
809         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
810         SoupMessageIOData *io = priv->io_data;
811         guint status;
812
813  read_more:
814         switch (io->read_state) {
815         case SOUP_MESSAGE_IO_STATE_NOT_STARTED:
816                 return;
817
818
819         case SOUP_MESSAGE_IO_STATE_HEADERS:
820                 if (!read_metadata (msg, TRUE))
821                         return;
822
823                 /* We need to "rewind" io->read_meta_buf back one line.
824                  * That SHOULD be two characters (CR LF), but if the
825                  * web server was stupid, it might only be one.
826                  */
827                 if (io->read_meta_buf->len < 3 ||
828                     io->read_meta_buf->data[io->read_meta_buf->len - 2] == '\n')
829                         io->read_meta_buf->len--;
830                 else
831                         io->read_meta_buf->len -= 2;
832                 io->read_meta_buf->data[io->read_meta_buf->len] = '\0';
833                 status = io->parse_headers_cb (msg, (char *)io->read_meta_buf->data,
834                                                io->read_meta_buf->len,
835                                                &io->read_encoding,
836                                                io->user_data);
837                 g_byte_array_set_size (io->read_meta_buf, 0);
838
839                 if (status != SOUP_STATUS_OK) {
840                         /* Either we couldn't parse the headers, or they
841                          * indicated something that would mean we wouldn't
842                          * be able to parse the body. (Eg, unknown
843                          * Transfer-Encoding.). Skip the rest of the
844                          * reading, and make sure the connection gets
845                          * closed when we're done.
846                          */
847                         soup_message_set_status (msg, status);
848                         soup_message_headers_append (msg->request_headers,
849                                                      "Connection", "close");
850                         io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
851                         break;
852                 }
853
854                 if (io->read_encoding == SOUP_ENCODING_CONTENT_LENGTH) {
855                         SoupMessageHeaders *hdrs =
856                                 (io->mode == SOUP_MESSAGE_IO_CLIENT) ?
857                                 msg->response_headers : msg->request_headers;
858                         io->read_length = soup_message_headers_get_content_length (hdrs);
859                 }
860
861                 if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
862                     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
863                         if (msg->status_code == SOUP_STATUS_CONTINUE &&
864                             io->write_state == SOUP_MESSAGE_IO_STATE_BLOCKING) {
865                                 /* Pause the reader, unpause the writer */
866                                 io->read_state =
867                                         SOUP_MESSAGE_IO_STATE_BLOCKING;
868                                 io->write_state =
869                                         io_body_state (io->write_encoding);
870                         } else {
871                                 /* Just stay in HEADERS */
872                                 io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
873                         }
874                 } else if (io->mode == SOUP_MESSAGE_IO_SERVER &&
875                            soup_message_headers_get_expectations (msg->request_headers) & SOUP_EXPECTATION_CONTINUE) {
876                         /* The client requested a Continue response. The
877                          * got_headers handler may change this to something
878                          * else though.
879                          */
880                         soup_message_set_status (msg, SOUP_STATUS_CONTINUE);
881                         io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
882                         io->read_state = SOUP_MESSAGE_IO_STATE_BLOCKING;
883                 } else {
884                         io->read_state = io_body_state (io->read_encoding);
885
886                         /* If the client was waiting for a Continue
887                          * but got something else, then it's done
888                          * writing.
889                          */
890                         if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
891                             io->write_state == SOUP_MESSAGE_IO_STATE_BLOCKING)
892                                 io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING;
893                 }
894
895                 if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
896                     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
897                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
898                         soup_message_got_informational (msg);
899                         soup_message_cleanup_response (msg);
900                         SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
901                 } else {
902                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
903                         soup_message_got_headers (msg);
904                         SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
905                 }
906                 break;
907
908
909         case SOUP_MESSAGE_IO_STATE_BLOCKING:
910                 io_write (sock, msg);
911
912                 /* As in the io_write case, we *must* return here. */
913                 return;
914
915
916         case SOUP_MESSAGE_IO_STATE_BODY:
917                 if (!read_body_chunk (msg))
918                         return;
919
920         got_body:
921                 if (!io_handle_sniffing (msg, TRUE)) {
922                         /* If the message was paused (as opposed to
923                          * cancelled), we need to make sure we wind up
924                          * back here when it's unpaused, even if it
925                          * was doing a chunked or EOF-terminated read
926                          * before.
927                          */
928                         if (io == priv->io_data) {
929                                 io->read_state = SOUP_MESSAGE_IO_STATE_BODY;
930                                 io->read_encoding = SOUP_ENCODING_CONTENT_LENGTH;
931                                 io->read_length = 0;
932                         }
933                         return;
934                 }
935
936                 io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
937
938                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
939                 soup_message_got_body (msg);
940                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
941                 break;
942
943
944         case SOUP_MESSAGE_IO_STATE_CHUNK_SIZE:
945                 if (!read_metadata (msg, FALSE))
946                         return;
947
948                 io->read_length = strtoul ((char *)io->read_meta_buf->data, NULL, 16);
949                 g_byte_array_set_size (io->read_meta_buf, 0);
950
951                 if (io->read_length > 0)
952                         io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK;
953                 else
954                         io->read_state = SOUP_MESSAGE_IO_STATE_TRAILERS;
955                 break;
956
957
958         case SOUP_MESSAGE_IO_STATE_CHUNK:
959                 if (!read_body_chunk (msg))
960                         return;
961
962                 io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK_END;
963                 break;
964
965
966         case SOUP_MESSAGE_IO_STATE_CHUNK_END:
967                 if (!read_metadata (msg, FALSE))
968                         return;
969
970                 g_byte_array_set_size (io->read_meta_buf, 0);
971                 io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK_SIZE;
972                 break;
973
974
975         case SOUP_MESSAGE_IO_STATE_TRAILERS:
976                 if (!read_metadata (msg, FALSE))
977                         return;
978
979                 if (io->read_meta_buf->len <= SOUP_MESSAGE_IO_EOL_LEN)
980                         goto got_body;
981
982                 /* FIXME: process trailers */
983                 g_byte_array_set_size (io->read_meta_buf, 0);
984                 break;
985
986
987         case SOUP_MESSAGE_IO_STATE_FINISHING:
988                 if (io->read_tag) {
989                         g_signal_handler_disconnect (io->sock, io->read_tag);
990                         io->read_tag = 0;
991                 }
992                 io->read_state = SOUP_MESSAGE_IO_STATE_DONE;
993
994                 if (io->mode == SOUP_MESSAGE_IO_SERVER) {
995                         io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
996                         io_write (sock, msg);
997                 } else
998                         soup_message_io_finished (msg);
999                 return;
1000
1001
1002         case SOUP_MESSAGE_IO_STATE_DONE:
1003         default:
1004                 g_return_if_reached ();
1005         }
1006
1007         goto read_more;
1008 }
1009
1010 static SoupMessageIOData *
1011 new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
1012              SoupMessageGetHeadersFn get_headers_cb,
1013              SoupMessageParseHeadersFn parse_headers_cb,
1014              gpointer user_data)
1015 {
1016         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1017         SoupMessageIOData *io;
1018
1019         io = g_slice_new0 (SoupMessageIOData);
1020         io->sock = g_object_ref (sock);
1021         io->mode = mode;
1022         io->get_headers_cb   = get_headers_cb;
1023         io->parse_headers_cb = parse_headers_cb;
1024         io->user_data        = user_data;
1025
1026         io->read_meta_buf    = g_byte_array_new ();
1027         io->write_buf        = g_string_new (NULL);
1028
1029         io->read_tag  = g_signal_connect (io->sock, "readable",
1030                                           G_CALLBACK (io_read), msg);
1031         io->write_tag = g_signal_connect (io->sock, "writable",
1032                                           G_CALLBACK (io_write), msg);
1033         io->err_tag   = g_signal_connect (io->sock, "disconnected",
1034                                           G_CALLBACK (io_disconnected), msg);
1035
1036         io->read_state  = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
1037         io->write_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
1038
1039         if (priv->io_data)
1040                 soup_message_io_cleanup (msg);
1041         priv->io_data = io;
1042         return io;
1043 }
1044
1045 void
1046 soup_message_io_client (SoupMessage *msg, SoupConnection *conn,
1047                         SoupMessageGetHeadersFn get_headers_cb,
1048                         SoupMessageParseHeadersFn parse_headers_cb,
1049                         gpointer user_data)
1050 {
1051         SoupMessageIOData *io;
1052         SoupSocket *sock = soup_connection_get_socket (conn);
1053
1054         io = new_iostate (msg, sock, SOUP_MESSAGE_IO_CLIENT,
1055                           get_headers_cb, parse_headers_cb, user_data);
1056
1057         io->conn = g_object_ref (conn);
1058
1059         io->read_body       = msg->response_body;
1060         io->write_body      = msg->request_body;
1061
1062         io->write_state     = SOUP_MESSAGE_IO_STATE_HEADERS;
1063         io_write (sock, msg);
1064 }
1065
1066 void
1067 soup_message_io_server (SoupMessage *msg, SoupSocket *sock,
1068                         SoupMessageGetHeadersFn get_headers_cb,
1069                         SoupMessageParseHeadersFn parse_headers_cb,
1070                         gpointer user_data)
1071 {
1072         SoupMessageIOData *io;
1073
1074         io = new_iostate (msg, sock, SOUP_MESSAGE_IO_SERVER,
1075                           get_headers_cb, parse_headers_cb, user_data);
1076
1077         io->read_body       = msg->request_body;
1078         io->write_body      = msg->response_body;
1079
1080         io->read_state      = SOUP_MESSAGE_IO_STATE_HEADERS;
1081         io_read (sock, msg);
1082 }
1083
1084 void  
1085 soup_message_io_pause (SoupMessage *msg)
1086 {
1087         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1088         SoupMessageIOData *io = priv->io_data;
1089
1090         g_return_if_fail (io != NULL);
1091
1092         if (io->write_tag) {
1093                 g_signal_handler_disconnect (io->sock, io->write_tag);
1094                 io->write_tag = 0;
1095         }
1096         if (io->read_tag) {
1097                 g_signal_handler_disconnect (io->sock, io->read_tag);
1098                 io->read_tag = 0;
1099         }
1100
1101         if (io->unpause_source) {
1102                 g_source_destroy (io->unpause_source);
1103                 io->unpause_source = NULL;
1104         }
1105 }
1106
1107 static gboolean
1108 io_unpause_internal (gpointer msg)
1109 {
1110         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1111         SoupMessageIOData *io = priv->io_data;
1112
1113         g_return_val_if_fail (io != NULL, FALSE);
1114         io->unpause_source = NULL;
1115
1116         if (io->write_tag || io->read_tag)
1117                 return FALSE;
1118
1119         if (io->write_state != SOUP_MESSAGE_IO_STATE_DONE) {
1120                 io->write_tag = g_signal_connect (io->sock, "writable",
1121                                                   G_CALLBACK (io_write), msg);
1122         }
1123
1124         if (io->read_state != SOUP_MESSAGE_IO_STATE_DONE) {
1125                 io->read_tag = g_signal_connect (io->sock, "readable",
1126                                                  G_CALLBACK (io_read), msg);
1127         }
1128
1129         if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->write_state))
1130                 io_write (io->sock, msg);
1131         else if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state))
1132                 io_read (io->sock, msg);
1133
1134         return FALSE;
1135 }
1136
1137 void
1138 soup_message_io_unpause (SoupMessage *msg)
1139 {
1140         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1141         SoupMessageIOData *io = priv->io_data;
1142         gboolean non_blocking;
1143         GMainContext *async_context;
1144
1145         g_return_if_fail (io != NULL);
1146
1147         g_object_get (io->sock,
1148                       SOUP_SOCKET_FLAG_NONBLOCKING, &non_blocking,
1149                       SOUP_SOCKET_ASYNC_CONTEXT, &async_context,
1150                       NULL);
1151         if (non_blocking) {
1152                 if (!io->unpause_source) {
1153                         io->unpause_source = soup_add_completion (
1154                                 async_context, io_unpause_internal, msg);
1155                 }
1156         } else
1157                 io_unpause_internal (msg);
1158         if (async_context)
1159                 g_main_context_unref (async_context);
1160 }
1161
1162 /**
1163  * soup_message_io_in_progress:
1164  * @msg: a #SoupMessage
1165  *
1166  * Tests whether or not I/O is currently in progress on @msg.
1167  *
1168  * Return value: whether or not I/O is currently in progress.
1169  **/
1170 gboolean
1171 soup_message_io_in_progress (SoupMessage *msg)
1172 {
1173         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1174
1175         return priv->io_data != NULL;
1176 }