Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / socket / http.c
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * (C) 2008 Collabora Ltd.
5  *  Contact: Youness Alaoui
6  * (C) 2008 Nokia Corporation. All rights reserved.
7  *
8  * The contents of this file are subject to the Mozilla Public License Version
9  * 1.1 (the "License"); you may not use this file except in compliance with
10  * the License. You may obtain a copy of the License at
11  * http://www.mozilla.org/MPL/
12  *
13  * Software distributed under the License is distributed on an "AS IS" basis,
14  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15  * for the specific language governing rights and limitations under the
16  * License.
17  *
18  * The Original Code is the Nice GLib ICE library.
19  *
20  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21  * Corporation. All Rights Reserved.
22  *
23  * Contributors:
24  *   Youness Alaoui, Collabora Ltd.
25  *
26  * Alternatively, the contents of this file may be used under the terms of the
27  * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28  * case the provisions of LGPL are applicable instead of those above. If you
29  * wish to allow use of your version of this file only under the terms of the
30  * LGPL and not to allow others to use your version of this file under the
31  * MPL, indicate your decision by deleting the provisions above and replace
32  * them with the notice and other provisions required by the LGPL. If you do
33  * not delete the provisions above, a recipient may use your version of this
34  * file under either the MPL or the LGPL.
35  */
36
37 /*
38  * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See
39  * http://en.wikipedia.org/wiki/Berkeley_sockets.)
40  */
41 #ifdef HAVE_CONFIG_H
42 # include "config.h"
43 #endif
44
45 #include "http.h"
46 #include "agent-priv.h"
47 #include "socket-priv.h"
48
49 #include <string.h>
50 #include <stdlib.h>
51
52
53 #ifndef G_OS_WIN32
54 #include <unistd.h>
55 #endif
56
57
58 #define HTTP_USER_AGENT "libnice"
59
60 typedef enum {
61   HTTP_STATE_INIT,
62   HTTP_STATE_HEADERS,
63   HTTP_STATE_BODY,
64   HTTP_STATE_CONNECTED,
65   HTTP_STATE_ERROR
66 } HttpState;
67
68 typedef struct {
69   HttpState state;
70   NiceSocket *base_socket;
71   NiceAddress addr;
72   gchar *username;
73   gchar *password;
74   GQueue send_queue;
75
76   /* Ring buffer for receiving HTTP headers into before they’re parsed. */
77   guint8 *recv_buf;
78   gsize recv_buf_length;  /* allocation size of @recv_buf */
79   gsize recv_buf_pos;  /* offset from @recv_buf of the 0th byte in the buffer */
80   gsize recv_buf_fill;  /* number of bytes occupied in the buffer */
81
82   /* Parsed from the Content-Length header provided by the other endpoint. */
83   gsize content_length;
84 } HttpPriv;
85
86
87 static void socket_close (NiceSocket *sock);
88 static gint socket_recv_messages (NiceSocket *sock,
89     NiceInputMessage *recv_messages, guint n_recv_messages);
90 static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to,
91     const NiceOutputMessage *messages, guint n_messages);
92 static gint socket_send_messages_reliable (NiceSocket *sock,
93     const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages);
94 static gboolean socket_is_reliable (NiceSocket *sock);
95 static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr);
96 static void socket_set_writable_callback (NiceSocket *sock,
97     NiceSocketWritableCb callback, gpointer user_data);
98 static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other);
99
100 NiceSocket *
101 nice_http_socket_new (NiceSocket *base_socket,
102     NiceAddress *addr, gchar *username, gchar *password)
103 {
104   HttpPriv *priv;
105   NiceSocket *sock = NULL;
106
107   if (addr) {
108     sock = g_slice_new0 (NiceSocket);
109     sock->priv = priv = g_slice_new0 (HttpPriv);
110
111     priv->base_socket = base_socket;
112     priv->addr = *addr;
113     priv->username = g_strdup (username);
114     priv->password = g_strdup (password);
115     priv->recv_buf = NULL;
116     priv->recv_buf_length = 0;
117     priv->recv_buf_pos = 0;
118     priv->recv_buf_fill = 0;
119     priv->content_length = 0;
120
121     sock->type = NICE_SOCKET_TYPE_HTTP;
122     sock->fileno = priv->base_socket->fileno;
123     sock->addr = priv->base_socket->addr;
124     sock->send_messages = socket_send_messages;
125     sock->send_messages_reliable = socket_send_messages_reliable;
126     sock->recv_messages = socket_recv_messages;
127     sock->is_reliable = socket_is_reliable;
128     sock->can_send = socket_can_send;
129     sock->set_writable_callback = socket_set_writable_callback;
130     sock->is_based_on = socket_is_based_on;
131     sock->close = socket_close;
132
133     /* Send HTTP CONNECT */
134     {
135       gchar *msg = NULL;
136       gchar *credential = NULL;
137       gchar host[INET6_ADDRSTRLEN];
138       gint port = nice_address_get_port (&priv->addr);
139       GOutputVector local_bufs;
140       NiceOutputMessage local_messages;
141
142       nice_address_to_string (&priv->addr, host);
143
144       if (username) {
145         gchar * userpass = g_strdup_printf ("%s:%s", username,
146             password ? password : "");
147         gchar * auth = g_base64_encode ((guchar *)userpass, strlen (userpass));
148         credential = g_strdup_printf ("Proxy-Authorization: Basic %s\r\n", auth);
149         g_free (auth);
150         g_free (userpass);
151       }
152       msg = g_strdup_printf ("CONNECT %s:%d HTTP/1.0\r\n"
153           "Host: %s\r\n"
154           "User-Agent: %s\r\n"
155           "Content-Length: 0\r\n"
156           "Proxy-Connection: Keep-Alive\r\n"
157           "Connection: Keep-Alive\r\n"
158           "Cache-Control: no-cache\r\n"
159           "Pragma: no-cache\r\n"
160           "%s\r\n", host, port, host, HTTP_USER_AGENT,
161           credential? credential : "" );
162       g_free (credential);
163
164       local_bufs.buffer = msg;
165       local_bufs.size = strlen (msg);
166       local_messages.buffers = &local_bufs;
167       local_messages.n_buffers = 1;
168
169       nice_socket_send_messages_reliable (priv->base_socket, NULL,
170           &local_messages, 1);
171       priv->state = HTTP_STATE_INIT;
172       g_free (msg);
173     }
174   }
175
176   return sock;
177 }
178
179
180 static void
181 socket_close (NiceSocket *sock)
182 {
183   HttpPriv *priv = sock->priv;
184
185   if (priv->base_socket)
186     nice_socket_free (priv->base_socket);
187
188   if (priv->username)
189     g_free (priv->username);
190
191   if (priv->password)
192     g_free (priv->password);
193
194   if (priv->recv_buf)
195     g_free (priv->recv_buf);
196
197   nice_socket_free_send_queue (&priv->send_queue);
198
199   g_slice_free(HttpPriv, sock->priv);
200   sock->priv = NULL;
201 }
202
203 static void
204 assert_ring_buffer_valid (HttpPriv *priv)
205 {
206   g_assert_cmpint (priv->recv_buf_fill, <=, priv->recv_buf_length);
207   g_assert (priv->recv_buf_pos == 0 ||
208       priv->recv_buf_pos < priv->recv_buf_length);
209   g_assert (priv->recv_buf_length == 0 || priv->recv_buf != NULL);
210 }
211
212 /* Pops up to @buffer_length bytes off the ring buffer and copies them into
213  * @buffer. Returns the number of bytes copied. */
214 static gsize
215 memcpy_ring_buffer_to_buffer (HttpPriv *priv,
216     guint8 *buffer, gsize buffer_length)
217 {
218   gsize len, consumed = 0;
219   gboolean has_wrapped;
220
221   has_wrapped =
222       (priv->recv_buf_pos + priv->recv_buf_fill) > priv->recv_buf_length;
223
224   if (has_wrapped) {
225     len = MIN (priv->recv_buf_length - priv->recv_buf_pos, buffer_length);
226     memcpy (buffer, priv->recv_buf + priv->recv_buf_pos, len);
227     consumed += len;
228
229     buffer += len;
230     buffer_length -= len;
231
232     len = MIN (priv->recv_buf_fill - len, buffer_length);
233     memcpy (buffer, priv->recv_buf, len);
234     consumed += len;
235   } else {
236     len = MIN (priv->recv_buf_fill, buffer_length);
237     memcpy (buffer, priv->recv_buf + priv->recv_buf_pos, len);
238     consumed += len;
239   }
240
241   priv->recv_buf_pos =
242       (priv->recv_buf_pos + consumed) % priv->recv_buf_length;
243   priv->recv_buf_fill -= consumed;
244
245   return consumed;
246 }
247
248 /* Returns the number of messages touched. Silently drops any data from @buffer
249  * which doesn’t fit in @messages. Updates the ring buffer to pop the copied
250  * data off it. Treats all #GInputVectors in @messages the same; there is no
251  * differentiation between different #NiceInputMessages. */
252 static gint
253 memcpy_ring_buffer_to_input_messages (HttpPriv *priv,
254     NiceInputMessage *messages, guint n_messages)
255 {
256   guint i, j;
257
258   for (i = 0; priv->recv_buf_fill > 0 && i < n_messages; i++) {
259     NiceInputMessage *message = &messages[i];
260
261     for (j = 0;
262          priv->recv_buf_fill > 0 &&
263          ((message->n_buffers >= 0 && j < (guint) message->n_buffers) ||
264           (message->n_buffers < 0 && message->buffers[j].buffer != NULL));
265          j++) {
266       message->buffers[j].size =
267           memcpy_ring_buffer_to_buffer (priv,
268               message->buffers[j].buffer, message->buffers[j].size);
269     }
270   }
271
272   return i;
273 }
274
275 /* FIXME: The current implementation of socket_recv_message() is a fast
276  * pass-through to nice_socket_recv_message() if the HTTP socket is connected,
277  * but is a slow state machine otherwise, using multiple memcpy()s. Spruce it up
278  * to better to use the recv_messages to avoid the memcpy()s. */
279 static gint
280 socket_recv_messages (NiceSocket *sock,
281     NiceInputMessage *recv_messages, guint n_recv_messages)
282 {
283   HttpPriv *priv = sock->priv;
284   gint ret = -1;
285
286   /* Make sure socket has not been freed: */
287   g_assert (sock->priv != NULL);
288
289   if (priv->state == HTTP_STATE_CONNECTED) {
290     guint i;
291
292     /* Fast path: pass through to the base socket once we’re connected. */
293     if (priv->base_socket) {
294       ret = nice_socket_recv_messages (priv->base_socket,
295           recv_messages, n_recv_messages);
296     }
297
298     if (ret <= 0)
299       return ret;
300
301     /* After successfully receiving into at least one NiceInputMessage,
302      * update the from address in each valid NiceInputMessage. */
303     for (i = 0; i < (guint) ret; i++) {
304       if (recv_messages[i].from != NULL)
305         *recv_messages[i].from = priv->addr;
306     }
307
308     return ret;
309   } else {
310     /* Slow path: read into a local ring buffer until we’re parsed enough of the
311      * headers. Double the buffer in size every time it fills up. */
312     gboolean has_wrapped;
313     GInputVector local_recv_bufs[2];
314     NiceInputMessage local_recv_message = { local_recv_bufs, 2, NULL, 0 };
315
316     /* Has the buffer filled up? Start with an initial buffer of 1KB, which
317      * should cover the average size of HTTP response headers. Source:
318      * http://dev.chromium.org/spdy/spdy-whitepaper */
319     if (priv->recv_buf_fill == priv->recv_buf_length) {
320       priv->recv_buf_length = MAX (priv->recv_buf_length * 2, 1024);
321       priv->recv_buf = g_realloc (priv->recv_buf, priv->recv_buf_length);
322     }
323
324     assert_ring_buffer_valid (priv);
325
326     /* Read some data into the buffer. Use two GInputVectors: one for the tail
327      * of the buffer and one for the head. */
328     has_wrapped =
329         (priv->recv_buf_pos + priv->recv_buf_fill) > priv->recv_buf_length;
330
331     if (has_wrapped) {
332       local_recv_bufs[0].buffer =
333            priv->recv_buf + (priv->recv_buf_pos + priv->recv_buf_fill) %
334            priv->recv_buf_length;
335       local_recv_bufs[0].size = priv->recv_buf_length - priv->recv_buf_fill;
336       local_recv_bufs[1].buffer = NULL;
337       local_recv_bufs[1].size = 0;
338     } else {
339       local_recv_bufs[0].buffer =
340           priv->recv_buf + priv->recv_buf_pos + priv->recv_buf_fill;
341       local_recv_bufs[0].size =
342           priv->recv_buf_length - (priv->recv_buf_pos + priv->recv_buf_fill);
343       local_recv_bufs[1].buffer = priv->recv_buf;
344       local_recv_bufs[1].size = priv->recv_buf_pos;
345     }
346
347     if (priv->base_socket) {
348       ret = nice_socket_recv_messages (priv->base_socket,
349           &local_recv_message, 1);
350     }
351
352     if (ret <= 0)
353       return ret;
354
355     /* Update the buffer’s metadata. */
356     priv->recv_buf_fill += local_recv_message.length;
357     assert_ring_buffer_valid (priv);
358
359     /* Fall through and try parsing the newly received data. */
360   }
361
362 #define GET_BYTE(pos) \
363   priv->recv_buf[(pos + priv->recv_buf_pos) % priv->recv_buf_length]
364 #define EAT_WHITESPACE(pos) \
365   while (pos < priv->recv_buf_fill && GET_BYTE(pos) == ' ') \
366     pos++; \
367   if (pos >= priv->recv_buf_fill) \
368     goto not_enough_data;
369
370 retry:
371   nice_debug ("Receiving from HTTP proxy (state %d) : %" G_GSSIZE_FORMAT " \n"
372       "'%s'", priv->state, priv->recv_buf_fill,
373       priv->recv_buf + priv->recv_buf_pos);
374
375   switch (priv->state) {
376     case HTTP_STATE_INIT:
377       {
378         /* This is a logical position in the recv_buf; add
379          * (priv->recv_buf + priv->recv_buf_pos) to get the actual byte in
380          * memory. */
381         guint pos = 0;
382
383         /* Eat leading whitespace and check we have enough data. */
384         EAT_WHITESPACE (pos);
385
386         if (pos + 7 > priv->recv_buf_fill)
387           goto not_enough_data;
388         if (GET_BYTE (pos + 0) != 'H' ||
389             GET_BYTE (pos + 1) != 'T' ||
390             GET_BYTE (pos + 2) != 'T' ||
391             GET_BYTE (pos + 3) != 'P' ||
392             GET_BYTE (pos + 4) != '/' ||
393             GET_BYTE (pos + 5) != '1' ||
394             GET_BYTE (pos + 6) != '.')
395           goto error;
396         pos += 7;
397
398         if (pos >= priv->recv_buf_fill)
399           goto not_enough_data;
400         if (GET_BYTE (pos) != '0' && GET_BYTE (pos) != '1')
401           goto error;
402         pos++;
403
404         /* Make sure we have a space after the HTTP version */
405         if (pos >= priv->recv_buf_fill)
406           goto not_enough_data;
407         if (GET_BYTE (pos) != ' ')
408           goto error;
409
410         EAT_WHITESPACE (pos);
411
412         /* Check for a successful 2xx code */
413         if (pos + 3 > priv->recv_buf_fill)
414           goto not_enough_data;
415         if (GET_BYTE (pos) != '2' ||
416             GET_BYTE (pos + 1) < '0' || GET_BYTE (pos + 1) > '9' ||
417             GET_BYTE (pos + 2) < '0' || GET_BYTE (pos + 2) > '9')
418           goto error;
419
420         /* Clear any trailing chars */
421         while (pos + 1 < priv->recv_buf_fill &&
422             GET_BYTE (pos) != '\r' && GET_BYTE (pos + 1) != '\n')
423           pos++;
424         if (pos + 1 >= priv->recv_buf_fill)
425           goto not_enough_data;
426         pos += 2;
427
428         /* Consume the data we just parsed. */
429         priv->recv_buf_pos = (priv->recv_buf_pos + pos) % priv->recv_buf_length;
430         priv->recv_buf_fill -= pos;
431
432         priv->content_length = 0;
433         priv->state = HTTP_STATE_HEADERS;
434
435         goto retry;
436       }
437       break;
438     case HTTP_STATE_HEADERS:
439       {
440         guint pos = 0;
441
442         if (pos + 15 < priv->recv_buf_fill &&
443             (GET_BYTE (pos +  0) == 'C' || GET_BYTE (pos +  0) == 'c') &&
444             (GET_BYTE (pos +  1) == 'o' || GET_BYTE (pos +  1) == 'O') &&
445             (GET_BYTE (pos +  2) == 'n' || GET_BYTE (pos +  2) == 'N') &&
446             (GET_BYTE (pos +  3) == 't' || GET_BYTE (pos +  3) == 'T') &&
447             (GET_BYTE (pos +  4) == 'e' || GET_BYTE (pos +  4) == 'E') &&
448             (GET_BYTE (pos +  5) == 'n' || GET_BYTE (pos +  5) == 'N') &&
449             (GET_BYTE (pos +  6) == 't' || GET_BYTE (pos +  6) == 'T') &&
450              GET_BYTE (pos +  7) == '-' &&
451             (GET_BYTE (pos +  8) == 'L' || GET_BYTE (pos +  8) == 'l') &&
452             (GET_BYTE (pos +  9) == 'e' || GET_BYTE (pos +  9) == 'E') &&
453             (GET_BYTE (pos + 10) == 'n' || GET_BYTE (pos + 10) == 'N') &&
454             (GET_BYTE (pos + 11) == 'g' || GET_BYTE (pos + 11) == 'G') &&
455             (GET_BYTE (pos + 12) == 't' || GET_BYTE (pos + 12) == 'T') &&
456             (GET_BYTE (pos + 13) == 'h' || GET_BYTE (pos + 13) == 'H') &&
457              GET_BYTE (pos + 14) == ':') {
458           /* Found a Content-Length header. Parse and store the value. Note that
459            * the HTTP standard allows for arbitrarily-big content lengths. We
460            * limit it to G_MAXSIZE for sanity’s sake.
461            *
462            * The code below is equivalent to strtoul(input, NULL, 10), but
463            * operates on a ring buffer. */
464           pos += 15;
465           EAT_WHITESPACE (pos);
466           priv->content_length = 0;
467
468           while (TRUE) {
469             guint8 byte = GET_BYTE (pos);
470             gint val = g_ascii_digit_value (byte);
471
472             if (byte == '\r') {
473               /* Reached the end of the value; fall out to the code below which
474                * will grab the \n. */
475               break;
476             } else if (val == -1) {
477               priv->content_length = 0;
478               goto error;
479             }
480
481             /* Check for overflow. Don’t flag it as an error; just fall through
482              * to the code below which will skip to the \r\n. */
483             if (priv->content_length > G_MAXSIZE / 10 ||
484                 priv->content_length * 10 > G_MAXSIZE - val) {
485               priv->content_length = 0;
486               break;
487             }
488
489             priv->content_length = (priv->content_length * 10) + val;
490
491             if (pos + 1 > priv->recv_buf_fill)
492               goto not_enough_data;
493             pos++;
494           }
495         }
496
497         /* Skip over the header. */
498         while (pos + 1 < priv->recv_buf_fill &&
499             GET_BYTE (pos) != '\r' && GET_BYTE (pos + 1) != '\n')
500           pos++;
501
502         nice_debug ("pos = %u, fill = %" G_GSSIZE_FORMAT,
503             pos, priv->recv_buf_fill);
504
505         if (pos + 1 >= priv->recv_buf_fill)
506           goto not_enough_data;
507         pos += 2;
508
509         /* Consume the data we just parsed. */
510         priv->recv_buf_pos = (priv->recv_buf_pos + pos) % priv->recv_buf_length;
511         priv->recv_buf_fill -= pos;
512
513         if (pos == 2)
514           priv->state = HTTP_STATE_BODY;
515
516         goto retry;
517       }
518       break;
519     case HTTP_STATE_BODY:
520       {
521         gsize consumed;
522
523         if (priv->content_length == 0) {
524           priv->state = HTTP_STATE_CONNECTED;
525           goto retry;
526         }
527
528         if (priv->recv_buf_fill == 0)
529           goto not_enough_data;
530
531         consumed = MIN (priv->content_length, priv->recv_buf_fill);
532
533         priv->recv_buf_pos =
534             (priv->recv_buf_pos + consumed) % priv->recv_buf_length;
535         priv->recv_buf_fill -= consumed;
536         priv->content_length -= consumed;
537
538         goto retry;
539       }
540       break;
541     case HTTP_STATE_CONNECTED:
542       {
543         gsize len;
544
545         len = memcpy_ring_buffer_to_input_messages (priv,
546             recv_messages, n_recv_messages);
547
548         /* Send the pending data */
549         nice_socket_flush_send_queue (priv->base_socket,
550             &priv->send_queue);
551
552         return len;
553       }
554       break;
555     case HTTP_STATE_ERROR:
556     default:
557       /* Unknown status */
558       goto error;
559   }
560
561  not_enough_data:
562   return 0;
563
564  error:
565   nice_debug ("http error");
566   if (priv->base_socket)
567     nice_socket_free (priv->base_socket);
568   priv->base_socket = NULL;
569   priv->state = HTTP_STATE_ERROR;
570
571   return -1;
572 }
573
574 static gint
575 socket_send_messages (NiceSocket *sock, const NiceAddress *to,
576     const NiceOutputMessage *messages, guint n_messages)
577 {
578   HttpPriv *priv = sock->priv;
579
580   /* Make sure socket has not been freed: */
581   g_assert (sock->priv != NULL);
582
583   if (priv->state == HTTP_STATE_CONNECTED) {
584     /* Fast path. */
585     if (!priv->base_socket)
586       return -1;
587
588     return nice_socket_send_messages (priv->base_socket, to, messages,
589         n_messages);
590   } else if (priv->state == HTTP_STATE_ERROR) {
591     return -1;
592   } else {
593     return 0;
594   }
595
596   return n_messages;
597 }
598
599 static gint
600 socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to,
601     const NiceOutputMessage *messages, guint n_messages)
602 {
603   HttpPriv *priv = sock->priv;
604
605   if (priv->state == HTTP_STATE_CONNECTED) {
606     /* Fast path. */
607     if (!priv->base_socket)
608       return -1;
609
610     return nice_socket_send_messages_reliable (priv->base_socket, to, messages,
611         n_messages);
612   } else if (priv->state == HTTP_STATE_ERROR) {
613     return -1;
614   } else {
615     nice_socket_queue_send (&priv->send_queue, to, messages, n_messages);
616   }
617
618   return n_messages;
619 }
620
621 static gboolean
622 socket_is_reliable (NiceSocket *sock)
623 {
624   HttpPriv *priv = sock->priv;
625
626   return nice_socket_is_reliable (priv->base_socket);
627 }
628
629 static gboolean
630 socket_can_send (NiceSocket *sock, NiceAddress *addr)
631 {
632   HttpPriv *priv = sock->priv;
633
634   return nice_socket_can_send (priv->base_socket, addr);
635 }
636
637 static void
638 socket_set_writable_callback (NiceSocket *sock,
639     NiceSocketWritableCb callback, gpointer user_data)
640 {
641   HttpPriv *priv = sock->priv;
642
643   nice_socket_set_writable_callback (priv->base_socket, callback, user_data);
644 }
645
646 static gboolean
647 socket_is_based_on (NiceSocket *sock, NiceSocket *other)
648 {
649   HttpPriv *priv = sock->priv;
650
651   return (sock == other) ||
652       (priv && nice_socket_is_based_on (priv->base_socket, other));
653 }