Add SoupMessage:tls-certificate and SoupMessage:tls-errors
[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-message-queue.h"
20 #include "soup-misc.h"
21 #include "soup-socket.h"
22 #include "soup-ssl.h"
23
24 typedef enum {
25         SOUP_MESSAGE_IO_CLIENT,
26         SOUP_MESSAGE_IO_SERVER
27 } SoupMessageIOMode;
28
29 typedef enum {
30         SOUP_MESSAGE_IO_STATE_NOT_STARTED,
31         SOUP_MESSAGE_IO_STATE_HEADERS,
32         SOUP_MESSAGE_IO_STATE_BLOCKING,
33         SOUP_MESSAGE_IO_STATE_BODY,
34         SOUP_MESSAGE_IO_STATE_CHUNK_SIZE,
35         SOUP_MESSAGE_IO_STATE_CHUNK,
36         SOUP_MESSAGE_IO_STATE_CHUNK_END,
37         SOUP_MESSAGE_IO_STATE_TRAILERS,
38         SOUP_MESSAGE_IO_STATE_FINISHING,
39         SOUP_MESSAGE_IO_STATE_DONE
40 } SoupMessageIOState;
41
42 #define SOUP_MESSAGE_IO_STATE_ACTIVE(state) \
43         (state != SOUP_MESSAGE_IO_STATE_NOT_STARTED && \
44          state != SOUP_MESSAGE_IO_STATE_BLOCKING && \
45          state != SOUP_MESSAGE_IO_STATE_DONE)
46
47 typedef struct {
48         SoupSocket           *sock;
49         SoupMessageQueueItem *item;
50         SoupMessageIOMode     mode;
51
52         SoupMessageIOState    read_state;
53         SoupEncoding          read_encoding;
54         GByteArray           *read_meta_buf;
55         SoupMessageBody      *read_body;
56         goffset               read_length;
57         gboolean              read_eof_ok;
58
59         gboolean              need_content_sniffed, need_got_chunk;
60         SoupMessageBody      *sniff_data;
61
62         SoupMessageIOState    write_state;
63         SoupEncoding          write_encoding;
64         GString              *write_buf;
65         SoupMessageBody      *write_body;
66         SoupBuffer           *write_chunk;
67         gsize                 write_body_offset;
68         goffset               write_length;
69         goffset               written;
70
71         guint read_tag, write_tag, err_tag;
72         GSource *unpause_source;
73
74         SoupMessageGetHeadersFn   get_headers_cb;
75         SoupMessageParseHeadersFn parse_headers_cb;
76         gpointer                  header_data;
77         SoupMessageCompletionFn   completion_cb;
78         gpointer                  completion_data;
79 } SoupMessageIOData;
80         
81
82 /* Put these around callback invocation if there is code afterward
83  * that depends on the IO having not been cancelled.
84  */
85 #define dummy_to_make_emacs_happy {
86 #define SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK { gboolean cancelled; g_object_ref (msg);
87 #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; }
88 #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; }
89
90 #define RESPONSE_BLOCK_SIZE 8192
91
92 void
93 soup_message_io_cleanup (SoupMessage *msg)
94 {
95         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
96         SoupMessageIOData *io;
97
98         soup_message_io_stop (msg);
99
100         io = priv->io_data;
101         if (!io)
102                 return;
103         priv->io_data = NULL;
104
105         if (io->sock)
106                 g_object_unref (io->sock);
107         if (io->item)
108                 soup_message_queue_item_unref (io->item);
109
110         g_byte_array_free (io->read_meta_buf, TRUE);
111
112         g_string_free (io->write_buf, TRUE);
113         if (io->write_chunk)
114                 soup_buffer_free (io->write_chunk);
115
116         if (io->sniff_data)
117                 soup_message_body_free (io->sniff_data);
118
119         g_slice_free (SoupMessageIOData, io);
120 }
121
122 void
123 soup_message_io_stop (SoupMessage *msg)
124 {
125         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
126         SoupMessageIOData *io = priv->io_data;
127
128         if (!io)
129                 return;
130
131         if (io->read_tag) {
132                 g_signal_handler_disconnect (io->sock, io->read_tag);
133                 io->read_tag = 0;
134         }
135         if (io->write_tag) {
136                 g_signal_handler_disconnect (io->sock, io->write_tag);
137                 io->write_tag = 0;
138         }
139         if (io->err_tag) {
140                 g_signal_handler_disconnect (io->sock, io->err_tag);
141                 io->err_tag = 0;
142         }
143
144         if (io->unpause_source) {
145                 g_source_destroy (io->unpause_source);
146                 io->unpause_source = NULL;
147         }
148
149         if (io->read_state < SOUP_MESSAGE_IO_STATE_FINISHING)
150                 soup_socket_disconnect (io->sock);
151         else if (io->item && io->item->conn)
152                 soup_connection_set_state (io->item->conn, SOUP_CONNECTION_IDLE);
153 }
154
155 #define SOUP_MESSAGE_IO_EOL            "\r\n"
156 #define SOUP_MESSAGE_IO_EOL_LEN        2
157
158 void
159 soup_message_io_finished (SoupMessage *msg)
160 {
161         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
162         SoupMessageIOData *io = priv->io_data;
163         SoupMessageCompletionFn completion_cb = io->completion_cb;
164         gpointer completion_data = io->completion_data;
165
166         g_object_ref (msg);
167         soup_message_io_cleanup (msg);
168         if (completion_cb)
169                 completion_cb (msg, completion_data);
170         g_object_unref (msg);
171 }
172
173 static void io_read (SoupSocket *sock, SoupMessage *msg);
174
175 static gboolean
176 request_is_idempotent (SoupMessage *msg)
177 {
178         /* FIXME */
179         return (msg->method == SOUP_METHOD_GET);
180 }
181
182 static void
183 io_error (SoupSocket *sock, SoupMessage *msg, GError *error)
184 {
185         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
186         SoupMessageIOData *io = priv->io_data;
187
188         if (error && error->domain == G_TLS_ERROR) {
189                 soup_message_set_status_full (msg,
190                                               SOUP_STATUS_SSL_FAILED,
191                                               error->message);
192         } else if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
193                    io->read_state <= SOUP_MESSAGE_IO_STATE_HEADERS &&
194                    io->read_meta_buf->len == 0 &&
195                    soup_connection_get_ever_used (io->item->conn) &&
196                    !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) &&
197                    request_is_idempotent (msg)) {
198                 /* Connection got closed, but we can safely try again */
199                 io->item->state = SOUP_MESSAGE_RESTARTING;
200         } else if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
201                 soup_message_set_status (msg, SOUP_STATUS_IO_ERROR);
202
203         if (error)
204                 g_error_free (error);
205
206         soup_message_io_finished (msg);
207 }
208
209 static void
210 io_disconnected (SoupSocket *sock, SoupMessage *msg)
211 {
212         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
213         SoupMessageIOData *io = priv->io_data;
214
215         /* Closing the connection to signify EOF is sometimes ok */
216         if (io->read_state == SOUP_MESSAGE_IO_STATE_BODY && io->read_eof_ok) {
217                 io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
218                 io_read (sock, msg);
219                 return;
220         }
221
222         io_error (sock, msg, NULL);
223 }
224
225 static gboolean
226 io_handle_sniffing (SoupMessage *msg, gboolean done_reading)
227 {
228         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
229         SoupMessageIOData *io = priv->io_data;
230         SoupBuffer *sniffed_buffer;
231         char *sniffed_mime_type;
232         GHashTable *params = NULL;
233
234         if (!priv->sniffer)
235                 return TRUE;
236
237         if (!io->sniff_data) {
238                 io->sniff_data = soup_message_body_new ();
239                 io->need_content_sniffed = TRUE;
240         }
241
242         if (io->need_content_sniffed) {
243                 if (io->sniff_data->length < priv->bytes_for_sniffing &&
244                     !done_reading)
245                         return TRUE;
246
247                 io->need_content_sniffed = FALSE;
248                 sniffed_buffer = soup_message_body_flatten (io->sniff_data);
249                 sniffed_mime_type = soup_content_sniffer_sniff (priv->sniffer, msg, sniffed_buffer, &params);
250
251                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
252                 soup_message_content_sniffed (msg, sniffed_mime_type, params);
253                 g_free (sniffed_mime_type);
254                 if (params)
255                         g_hash_table_destroy (params);
256                 if (sniffed_buffer)
257                         soup_buffer_free (sniffed_buffer);
258                 SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
259         }
260
261         if (io->need_got_chunk) {
262                 io->need_got_chunk = FALSE;
263                 sniffed_buffer = soup_message_body_flatten (io->sniff_data);
264
265                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
266                 soup_message_got_chunk (msg, sniffed_buffer);
267                 soup_buffer_free (sniffed_buffer);
268                 SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
269         }
270
271         return TRUE;
272 }
273
274 /* Reads data from io->sock into io->read_meta_buf. If @to_blank is
275  * %TRUE, it reads up until a blank line ("CRLF CRLF" or "LF LF").
276  * Otherwise, it reads up until a single CRLF or LF.
277  *
278  * This function is used to read metadata, and read_body_chunk() is
279  * used to read the message body contents.
280  *
281  * read_metadata, read_body_chunk, and write_data all use the same
282  * convention for return values: if they return %TRUE, it means
283  * they've completely finished the requested read/write, and the
284  * caller should move on to the next step. If they return %FALSE, it
285  * means that either (a) the socket returned SOUP_SOCKET_WOULD_BLOCK,
286  * so the caller should give up for now and wait for the socket to
287  * emit a signal, or (b) the socket returned an error, and io_error()
288  * was called to process it and cancel the I/O. So either way, if the
289  * function returns %FALSE, the caller should return immediately.
290  */
291 static gboolean
292 read_metadata (SoupMessage *msg, gboolean to_blank)
293 {
294         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
295         SoupMessageIOData *io = priv->io_data;
296         SoupSocketIOStatus status;
297         guchar read_buf[RESPONSE_BLOCK_SIZE];
298         gsize nread;
299         gboolean got_lf;
300         GError *error = NULL;
301
302         while (1) {
303                 status = soup_socket_read_until (io->sock, read_buf,
304                                                  sizeof (read_buf),
305                                                  "\n", 1, &nread, &got_lf,
306                                                  NULL, &error);
307                 switch (status) {
308                 case SOUP_SOCKET_OK:
309                         g_byte_array_append (io->read_meta_buf, read_buf, nread);
310                         break;
311
312                 case SOUP_SOCKET_EOF:
313                         /* More lame server handling... deal with
314                          * servers that don't send the final chunk.
315                          */
316                         if (io->read_state == SOUP_MESSAGE_IO_STATE_CHUNK_SIZE &&
317                             io->read_meta_buf->len == 0) {
318                                 g_byte_array_append (io->read_meta_buf,
319                                                      (guchar *)"0\r\n", 3);
320                                 got_lf = TRUE;
321                                 break;
322                         } else if (io->read_state == SOUP_MESSAGE_IO_STATE_TRAILERS &&
323                                    io->read_meta_buf->len == 0) {
324                                 g_byte_array_append (io->read_meta_buf,
325                                                      (guchar *)"\r\n", 2);
326                                 got_lf = TRUE;
327                                 break;
328                         }
329                         /* else fall through */
330
331                 case SOUP_SOCKET_ERROR:
332                         io_error (io->sock, msg, error);
333                         return FALSE;
334
335                 case SOUP_SOCKET_WOULD_BLOCK:
336                         return FALSE;
337                 }
338
339                 if (got_lf) {
340                         if (!to_blank)
341                                 break;
342                         if (nread == 1 &&
343                             !strncmp ((char *)io->read_meta_buf->data +
344                                       io->read_meta_buf->len - 2,
345                                       "\n\n", 2))
346                                 break;
347                         else if (nread == 2 &&
348                                  !strncmp ((char *)io->read_meta_buf->data +
349                                            io->read_meta_buf->len - 3,
350                                            "\n\r\n", 3))
351                                 break;
352                 }
353         }
354
355         return TRUE;
356 }
357
358 static SoupBuffer *
359 content_decode (SoupMessage *msg, SoupBuffer *buf)
360 {
361         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
362         SoupCoding *decoder;
363         SoupBuffer *decoded;
364         GError *error = NULL;
365         GSList *d;
366
367         for (d = priv->decoders; d; d = d->next) {
368                 decoder = d->data;
369
370                 decoded = soup_coding_apply (decoder, buf->data, buf->length,
371                                              FALSE, &error);
372                 if (error) {
373                         if (g_error_matches (error, SOUP_CODING_ERROR, SOUP_CODING_ERROR_INTERNAL_ERROR))
374                                 g_warning ("Content-Decoding error: %s\n", error->message);
375                         g_error_free (error);
376
377                         soup_message_set_flags (msg, priv->msg_flags & ~SOUP_MESSAGE_CONTENT_DECODED);
378                         break;
379                 }
380                 if (buf)
381                         soup_buffer_free (buf);
382
383                 if (decoded)
384                         buf = decoded;
385                 else
386                         return NULL;
387         }
388
389         return buf;
390 }
391
392 /* Reads as much message body data as is available on io->sock (but no
393  * further than the end of the current message body or chunk). On a
394  * successful read, emits "got_chunk" (possibly multiple times), and
395  * (unless told not to) appends the chunk to io->read_body.
396  *
397  * See the note at read_metadata() for an explanation of the return
398  * value.
399  */
400 static gboolean
401 read_body_chunk (SoupMessage *msg)
402 {
403         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
404         SoupMessageIOData *io = priv->io_data;
405         SoupSocketIOStatus status;
406         guchar *stack_buf = NULL;
407         gsize len;
408         gboolean read_to_eof = (io->read_encoding == SOUP_ENCODING_EOF);
409         gsize nread;
410         GError *error = NULL;
411         SoupBuffer *buffer;
412
413         if (!io_handle_sniffing (msg, FALSE))
414                 return FALSE;
415
416         while (read_to_eof || io->read_length > 0) {
417                 if (priv->chunk_allocator) {
418                         buffer = priv->chunk_allocator (msg, io->read_length, priv->chunk_allocator_data);
419                         if (!buffer) {
420                                 soup_message_io_pause (msg);
421                                 return FALSE;
422                         }
423                 } else {
424                         if (!stack_buf)
425                                 stack_buf = alloca (RESPONSE_BLOCK_SIZE);
426                         buffer = soup_buffer_new (SOUP_MEMORY_TEMPORARY,
427                                                   stack_buf,
428                                                   RESPONSE_BLOCK_SIZE);
429                 }
430
431                 if (read_to_eof)
432                         len = buffer->length;
433                 else
434                         len = MIN (buffer->length, io->read_length);
435
436                 status = soup_socket_read (io->sock,
437                                            (guchar *)buffer->data, len,
438                                            &nread, NULL, &error);
439
440                 if (status == SOUP_SOCKET_OK && nread) {
441                         buffer->length = nread;
442                         io->read_length -= nread;
443
444                         buffer = content_decode (msg, buffer);
445                         if (!buffer)
446                                 continue;
447
448                         soup_message_body_got_chunk (io->read_body, buffer);
449
450                         if (io->need_content_sniffed) {
451                                 soup_message_body_append_buffer (io->sniff_data, buffer);
452                                 soup_buffer_free (buffer);
453                                 io->need_got_chunk = TRUE;
454                                 if (!io_handle_sniffing (msg, FALSE))
455                                         return FALSE;
456                                 continue;
457                         }
458
459                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
460                         soup_message_got_chunk (msg, buffer);
461                         soup_buffer_free (buffer);
462                         SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
463                         continue;
464                 }
465
466                 soup_buffer_free (buffer);
467                 switch (status) {
468                 case SOUP_SOCKET_OK:
469                         break;
470
471                 case SOUP_SOCKET_EOF:
472                         if (io->read_eof_ok) {
473                                 io->read_length = 0;
474                                 return TRUE;
475                         }
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->header_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                 if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
824                     soup_socket_is_ssl (io->sock)) {
825                         GTlsCertificate *certificate;
826                         GTlsCertificateFlags errors;
827
828                         g_object_get (io->sock,
829                                       SOUP_SOCKET_TLS_CERTIFICATE, &certificate,
830                                       SOUP_SOCKET_TLS_ERRORS, &errors,
831                                       NULL);
832                         if (certificate) {
833                                 g_object_set (msg,
834                                               SOUP_MESSAGE_TLS_CERTIFICATE, certificate,
835                                               SOUP_MESSAGE_TLS_ERRORS, errors,
836                                               NULL);
837                                 g_object_unref (certificate);
838                         }
839                 }
840
841                 /* We need to "rewind" io->read_meta_buf back one line.
842                  * That SHOULD be two characters (CR LF), but if the
843                  * web server was stupid, it might only be one.
844                  */
845                 if (io->read_meta_buf->len < 3 ||
846                     io->read_meta_buf->data[io->read_meta_buf->len - 2] == '\n')
847                         io->read_meta_buf->len--;
848                 else
849                         io->read_meta_buf->len -= 2;
850                 io->read_meta_buf->data[io->read_meta_buf->len] = '\0';
851                 status = io->parse_headers_cb (msg, (char *)io->read_meta_buf->data,
852                                                io->read_meta_buf->len,
853                                                &io->read_encoding,
854                                                io->header_data);
855                 g_byte_array_set_size (io->read_meta_buf, 0);
856
857                 if (status != SOUP_STATUS_OK) {
858                         /* Either we couldn't parse the headers, or they
859                          * indicated something that would mean we wouldn't
860                          * be able to parse the body. (Eg, unknown
861                          * Transfer-Encoding.). Skip the rest of the
862                          * reading, and make sure the connection gets
863                          * closed when we're done.
864                          */
865                         soup_message_set_status (msg, status);
866                         soup_message_headers_append (msg->request_headers,
867                                                      "Connection", "close");
868                         io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
869                         break;
870                 }
871
872                 if (io->read_encoding == SOUP_ENCODING_EOF)
873                         io->read_eof_ok = TRUE;
874
875                 if (io->read_encoding == SOUP_ENCODING_CONTENT_LENGTH) {
876                         SoupMessageHeaders *hdrs =
877                                 (io->mode == SOUP_MESSAGE_IO_CLIENT) ?
878                                 msg->response_headers : msg->request_headers;
879                         io->read_length = soup_message_headers_get_content_length (hdrs);
880
881                         if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
882                             !soup_message_is_keepalive (msg)) {
883                                 /* Some servers suck and send
884                                  * incorrect Content-Length values, so
885                                  * allow EOF termination in this case
886                                  * (iff the message is too short) too.
887                                  */
888                                 io->read_eof_ok = TRUE;
889                         }
890                 }
891
892                 if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
893                     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
894                         if (msg->status_code == SOUP_STATUS_CONTINUE &&
895                             io->write_state == SOUP_MESSAGE_IO_STATE_BLOCKING) {
896                                 /* Pause the reader, unpause the writer */
897                                 io->read_state =
898                                         SOUP_MESSAGE_IO_STATE_BLOCKING;
899                                 io->write_state =
900                                         io_body_state (io->write_encoding);
901                         } else {
902                                 /* Just stay in HEADERS */
903                                 io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
904                         }
905                 } else if (io->mode == SOUP_MESSAGE_IO_SERVER &&
906                            soup_message_headers_get_expectations (msg->request_headers) & SOUP_EXPECTATION_CONTINUE) {
907                         /* The client requested a Continue response. The
908                          * got_headers handler may change this to something
909                          * else though.
910                          */
911                         soup_message_set_status (msg, SOUP_STATUS_CONTINUE);
912                         io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
913                         io->read_state = SOUP_MESSAGE_IO_STATE_BLOCKING;
914                 } else {
915                         io->read_state = io_body_state (io->read_encoding);
916
917                         /* If the client was waiting for a Continue
918                          * but got something else, then it's done
919                          * writing.
920                          */
921                         if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
922                             io->write_state == SOUP_MESSAGE_IO_STATE_BLOCKING)
923                                 io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING;
924                 }
925
926                 if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
927                     SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
928                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
929                         soup_message_got_informational (msg);
930                         soup_message_cleanup_response (msg);
931                         SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
932                 } else {
933                         SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
934                         soup_message_got_headers (msg);
935                         SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
936                 }
937                 break;
938
939
940         case SOUP_MESSAGE_IO_STATE_BLOCKING:
941                 io_write (sock, msg);
942
943                 /* As in the io_write case, we *must* return here. */
944                 return;
945
946
947         case SOUP_MESSAGE_IO_STATE_BODY:
948                 if (!read_body_chunk (msg))
949                         return;
950
951         got_body:
952                 if (!io_handle_sniffing (msg, TRUE)) {
953                         /* If the message was paused (as opposed to
954                          * cancelled), we need to make sure we wind up
955                          * back here when it's unpaused, even if it
956                          * was doing a chunked or EOF-terminated read
957                          * before.
958                          */
959                         if (io == priv->io_data) {
960                                 io->read_state = SOUP_MESSAGE_IO_STATE_BODY;
961                                 io->read_encoding = SOUP_ENCODING_CONTENT_LENGTH;
962                                 io->read_length = 0;
963                         }
964                         return;
965                 }
966
967                 io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
968
969                 SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
970                 soup_message_got_body (msg);
971                 SOUP_MESSAGE_IO_RETURN_IF_CANCELLED_OR_PAUSED;
972                 break;
973
974
975         case SOUP_MESSAGE_IO_STATE_CHUNK_SIZE:
976                 if (!read_metadata (msg, FALSE))
977                         return;
978
979                 io->read_length = strtoul ((char *)io->read_meta_buf->data, NULL, 16);
980                 g_byte_array_set_size (io->read_meta_buf, 0);
981
982                 if (io->read_length > 0)
983                         io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK;
984                 else
985                         io->read_state = SOUP_MESSAGE_IO_STATE_TRAILERS;
986                 break;
987
988
989         case SOUP_MESSAGE_IO_STATE_CHUNK:
990                 if (!read_body_chunk (msg))
991                         return;
992
993                 io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK_END;
994                 break;
995
996
997         case SOUP_MESSAGE_IO_STATE_CHUNK_END:
998                 if (!read_metadata (msg, FALSE))
999                         return;
1000
1001                 g_byte_array_set_size (io->read_meta_buf, 0);
1002                 io->read_state = SOUP_MESSAGE_IO_STATE_CHUNK_SIZE;
1003                 break;
1004
1005
1006         case SOUP_MESSAGE_IO_STATE_TRAILERS:
1007                 if (!read_metadata (msg, FALSE))
1008                         return;
1009
1010                 if (io->read_meta_buf->len <= SOUP_MESSAGE_IO_EOL_LEN)
1011                         goto got_body;
1012
1013                 /* FIXME: process trailers */
1014                 g_byte_array_set_size (io->read_meta_buf, 0);
1015                 break;
1016
1017
1018         case SOUP_MESSAGE_IO_STATE_FINISHING:
1019                 if (io->read_tag) {
1020                         g_signal_handler_disconnect (io->sock, io->read_tag);
1021                         io->read_tag = 0;
1022                 }
1023                 io->read_state = SOUP_MESSAGE_IO_STATE_DONE;
1024
1025                 if (io->mode == SOUP_MESSAGE_IO_SERVER) {
1026                         io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
1027                         io_write (sock, msg);
1028                 } else
1029                         soup_message_io_finished (msg);
1030                 return;
1031
1032
1033         case SOUP_MESSAGE_IO_STATE_DONE:
1034         default:
1035                 g_return_if_reached ();
1036         }
1037
1038         goto read_more;
1039 }
1040
1041 static SoupMessageIOData *
1042 new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
1043              SoupMessageGetHeadersFn get_headers_cb,
1044              SoupMessageParseHeadersFn parse_headers_cb,
1045              gpointer header_data,
1046              SoupMessageCompletionFn completion_cb,
1047              gpointer completion_data)
1048 {
1049         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1050         SoupMessageIOData *io;
1051
1052         io = g_slice_new0 (SoupMessageIOData);
1053         io->sock = g_object_ref (sock);
1054         io->mode = mode;
1055         io->get_headers_cb   = get_headers_cb;
1056         io->parse_headers_cb = parse_headers_cb;
1057         io->header_data      = header_data;
1058         io->completion_cb    = completion_cb;
1059         io->completion_data  = completion_data;
1060
1061         io->read_meta_buf    = g_byte_array_new ();
1062         io->write_buf        = g_string_new (NULL);
1063
1064         io->read_tag  = g_signal_connect (io->sock, "readable",
1065                                           G_CALLBACK (io_read), msg);
1066         io->write_tag = g_signal_connect (io->sock, "writable",
1067                                           G_CALLBACK (io_write), msg);
1068         io->err_tag   = g_signal_connect (io->sock, "disconnected",
1069                                           G_CALLBACK (io_disconnected), msg);
1070
1071         io->read_state  = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
1072         io->write_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
1073
1074         if (priv->io_data)
1075                 soup_message_io_cleanup (msg);
1076         priv->io_data = io;
1077         return io;
1078 }
1079
1080 void
1081 soup_message_io_client (SoupMessageQueueItem *item,
1082                         SoupMessageGetHeadersFn get_headers_cb,
1083                         SoupMessageParseHeadersFn parse_headers_cb,
1084                         gpointer header_data,
1085                         SoupMessageCompletionFn completion_cb,
1086                         gpointer completion_data)
1087 {
1088         SoupMessageIOData *io;
1089         SoupSocket *sock = soup_connection_get_socket (item->conn);
1090
1091         io = new_iostate (item->msg, sock, SOUP_MESSAGE_IO_CLIENT,
1092                           get_headers_cb, parse_headers_cb, header_data,
1093                           completion_cb, completion_data);
1094
1095         io->item = item;
1096         soup_message_queue_item_ref (item);
1097
1098         io->read_body       = item->msg->response_body;
1099         io->write_body      = item->msg->request_body;
1100
1101         io->write_state     = SOUP_MESSAGE_IO_STATE_HEADERS;
1102         io_write (sock, item->msg);
1103 }
1104
1105 void
1106 soup_message_io_server (SoupMessage *msg, SoupSocket *sock,
1107                         SoupMessageGetHeadersFn get_headers_cb,
1108                         SoupMessageParseHeadersFn parse_headers_cb,
1109                         gpointer header_data,
1110                         SoupMessageCompletionFn completion_cb,
1111                         gpointer completion_data)
1112 {
1113         SoupMessageIOData *io;
1114
1115         io = new_iostate (msg, sock, SOUP_MESSAGE_IO_SERVER,
1116                           get_headers_cb, parse_headers_cb, header_data,
1117                           completion_cb, completion_data);
1118
1119         io->read_body       = msg->request_body;
1120         io->write_body      = msg->response_body;
1121
1122         io->read_state      = SOUP_MESSAGE_IO_STATE_HEADERS;
1123         io_read (sock, msg);
1124 }
1125
1126 void  
1127 soup_message_io_pause (SoupMessage *msg)
1128 {
1129         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1130         SoupMessageIOData *io = priv->io_data;
1131
1132         g_return_if_fail (io != NULL);
1133
1134         if (io->write_tag) {
1135                 g_signal_handler_disconnect (io->sock, io->write_tag);
1136                 io->write_tag = 0;
1137         }
1138         if (io->read_tag) {
1139                 g_signal_handler_disconnect (io->sock, io->read_tag);
1140                 io->read_tag = 0;
1141         }
1142
1143         if (io->unpause_source) {
1144                 g_source_destroy (io->unpause_source);
1145                 io->unpause_source = NULL;
1146         }
1147 }
1148
1149 static gboolean
1150 io_unpause_internal (gpointer msg)
1151 {
1152         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1153         SoupMessageIOData *io = priv->io_data;
1154
1155         g_return_val_if_fail (io != NULL, FALSE);
1156         io->unpause_source = NULL;
1157
1158         if (io->write_tag || io->read_tag)
1159                 return FALSE;
1160
1161         if (io->write_state != SOUP_MESSAGE_IO_STATE_DONE) {
1162                 io->write_tag = g_signal_connect (io->sock, "writable",
1163                                                   G_CALLBACK (io_write), msg);
1164         }
1165
1166         if (io->read_state != SOUP_MESSAGE_IO_STATE_DONE) {
1167                 io->read_tag = g_signal_connect (io->sock, "readable",
1168                                                  G_CALLBACK (io_read), msg);
1169         }
1170
1171         if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->write_state))
1172                 io_write (io->sock, msg);
1173         else if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state))
1174                 io_read (io->sock, msg);
1175
1176         return FALSE;
1177 }
1178
1179 void
1180 soup_message_io_unpause (SoupMessage *msg)
1181 {
1182         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1183         SoupMessageIOData *io = priv->io_data;
1184         gboolean non_blocking;
1185         GMainContext *async_context;
1186
1187         g_return_if_fail (io != NULL);
1188
1189         g_object_get (io->sock,
1190                       SOUP_SOCKET_FLAG_NONBLOCKING, &non_blocking,
1191                       SOUP_SOCKET_ASYNC_CONTEXT, &async_context,
1192                       NULL);
1193         if (non_blocking) {
1194                 if (!io->unpause_source) {
1195                         io->unpause_source = soup_add_completion (
1196                                 async_context, io_unpause_internal, msg);
1197                 }
1198         } else
1199                 io_unpause_internal (msg);
1200         if (async_context)
1201                 g_main_context_unref (async_context);
1202 }
1203
1204 /**
1205  * soup_message_io_in_progress:
1206  * @msg: a #SoupMessage
1207  *
1208  * Tests whether or not I/O is currently in progress on @msg.
1209  *
1210  * Return value: whether or not I/O is currently in progress.
1211  **/
1212 gboolean
1213 soup_message_io_in_progress (SoupMessage *msg)
1214 {
1215         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1216
1217         return priv->io_data != NULL;
1218 }