http.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:67k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * http.c - HTTP protocol implementation
  3.  *
  4.  * Lars Wirzenius
  5.  */
  6.  
  7. /* XXX re-implement socket pools, with idle connection killing to 
  8.      save sockets */
  9. /* XXX implement http_abort */
  10. /* XXX give maximum input size */
  11. /* XXX kill http_get_real */
  12. /* XXX the proxy exceptions list should be a dict, I guess */
  13. /* XXX set maximum number of concurrent connections to same host, total? */
  14. /* XXX basic auth is missing */
  15. /* XXX 100 status codes. */
  16. /* XXX stop destroying persistent connections when a request is redirected */
  17. #include <ctype.h>
  18. #include <errno.h>
  19. #include <unistd.h>
  20. #include <string.h>
  21. #include <signal.h>
  22. #include <sys/types.h>
  23. #include <sys/socket.h>
  24. #include "gwlib.h"
  25. #define USE_KEEPALIVE 1
  26. /***********************************************************************
  27.  * Stuff used in several sub-modules.
  28.  */
  29. /*
  30.  * Default port to connect to for HTTP connections.
  31.  */
  32. enum { HTTP_PORT = 80,
  33.        HTTPS_PORT = 443 };
  34. /*
  35.  * Status of this module.
  36.  */
  37. static enum { 
  38.     limbo, 
  39.     running, 
  40.     terminating 
  41. } run_status = limbo;
  42. /*
  43.  * Read some headers, i.e., until the first empty line (read and discard
  44.  * the empty line as well). Return -1 for error, 0 for all headers read,
  45.  * 1 for more headers to follow.
  46.  */
  47. static int read_some_headers(Connection *conn, List *headers)
  48. {
  49.     Octstr *line, *prev;
  50.     if (list_len(headers) == 0)
  51.         prev = NULL;
  52.     else
  53.      prev = list_get(headers, list_len(headers) - 1);
  54.     for (;;) {
  55. line = conn_read_line(conn);
  56. if (line == NULL) {
  57.     if (conn_eof(conn))
  58.      return -1;
  59.     return 1;
  60. }
  61.         if (octstr_len(line) == 0) {
  62.             octstr_destroy(line);
  63.             break;
  64.         }
  65.         if (isspace(octstr_get_char(line, 0)) && prev != NULL) {
  66.             octstr_append(prev, line);
  67.             octstr_destroy(line);
  68.         } else {
  69.             list_append(headers, line);
  70.             prev = line;
  71.         }
  72.     }
  73.     return 0;
  74. }
  75. /*
  76.  * Check that the HTTP version string is valid. Return -1 for invalid,
  77.  * 0 for version 1.0, 1 for 1.x.
  78.  */
  79. static int parse_http_version(Octstr *version)
  80. {
  81.     Octstr *prefix;
  82.     long prefix_len;
  83.     int digit;
  84.     
  85.     prefix = octstr_imm("HTTP/1.");
  86.     prefix_len = octstr_len(prefix);
  87.     if (octstr_ncompare(version, prefix, prefix_len) != 0)
  88.      return -1;
  89.     if (octstr_len(version) != prefix_len + 1)
  90.      return -1;
  91.     digit = octstr_get_char(version, prefix_len);
  92.     if (!isdigit(digit))
  93.      return -1;
  94.     if (digit == '0')
  95.      return 0;
  96.     return 1;
  97. }
  98. /***********************************************************************
  99.  * Proxy support.
  100.  */
  101. /*
  102.  * Data and functions needed to support proxy operations. If proxy_hostname 
  103.  * is NULL, no proxy is used.
  104.  */
  105. static Mutex *proxy_mutex = NULL;
  106. static Octstr *proxy_hostname = NULL;
  107. static int proxy_port = 0;
  108. static Octstr *proxy_username = NULL;
  109. static Octstr *proxy_password = NULL;
  110. static List *proxy_exceptions = NULL;
  111. static void proxy_add_authentication(List *headers)
  112. {
  113.     Octstr *os;
  114.     
  115.     if (proxy_username == NULL || proxy_password == NULL)
  116.      return;
  117.     os = octstr_format("%S:%S", proxy_username, proxy_password);
  118.     octstr_binary_to_base64(os);
  119.     octstr_strip_blanks(os);
  120.     octstr_insert(os, octstr_imm("Basic "), 0);
  121.     http_header_add(headers, "Proxy-Authorization", octstr_get_cstr(os));
  122.     octstr_destroy(os);
  123. }
  124. static void proxy_init(void)
  125. {
  126.     proxy_mutex = mutex_create();
  127.     proxy_exceptions = list_create();
  128. }
  129. static void proxy_shutdown(void)
  130. {
  131.     http_close_proxy();
  132.     mutex_destroy(proxy_mutex);
  133.     proxy_mutex = NULL;
  134. }
  135. static int proxy_used_for_host(Octstr *host)
  136. {
  137.     int i;
  138.     mutex_lock(proxy_mutex);
  139.     if (proxy_hostname == NULL) {
  140.         mutex_unlock(proxy_mutex);
  141.         return 0;
  142.     }
  143.     for (i = 0; i < list_len(proxy_exceptions); ++i) {
  144.         if (octstr_compare(host, list_get(proxy_exceptions, i)) == 0) {
  145.             mutex_unlock(proxy_mutex);
  146.             return 0;
  147.         }
  148.     }
  149.     mutex_unlock(proxy_mutex);
  150.     return 1;
  151. }
  152. void http_use_proxy(Octstr *hostname, int port, List *exceptions,
  153.               Octstr *username, Octstr *password)
  154. {
  155.     Octstr *e;
  156.     int i;
  157.     gw_assert(run_status == running);
  158.     gw_assert(hostname != NULL);
  159.     gw_assert(octstr_len(hostname) > 0);
  160.     gw_assert(port > 0);
  161.     http_close_proxy();
  162.     mutex_lock(proxy_mutex);
  163.     proxy_hostname = octstr_duplicate(hostname);
  164.     proxy_port = port;
  165.     proxy_exceptions = list_create();
  166.     for (i = 0; i < list_len(exceptions); ++i) {
  167.         e = list_get(exceptions, i);
  168. debug("gwlib.http", 0, "HTTP: Proxy exception `%s'.",
  169.       octstr_get_cstr(e));
  170.         list_append(proxy_exceptions, octstr_duplicate(e));
  171.     }
  172.     proxy_username = octstr_duplicate(username);
  173.     proxy_password = octstr_duplicate(password);
  174.     debug("gwlib.http", 0, "Using proxy <%s:%d>", 
  175.        octstr_get_cstr(proxy_hostname), proxy_port);
  176.     mutex_unlock(proxy_mutex);
  177. }
  178. void http_close_proxy(void)
  179. {
  180.     gw_assert(run_status == running || run_status == terminating);
  181.     mutex_lock(proxy_mutex);
  182.     proxy_port = 0;
  183.     octstr_destroy(proxy_hostname);
  184.     octstr_destroy(proxy_username);
  185.     octstr_destroy(proxy_password);
  186.     proxy_hostname = NULL;
  187.     proxy_username = NULL;
  188.     proxy_password = NULL;
  189.     list_destroy(proxy_exceptions, octstr_destroy_item);
  190.     proxy_exceptions = NULL;
  191.     mutex_unlock(proxy_mutex);
  192. }
  193. /***********************************************************************
  194.  * Common functions for reading request or result entities.
  195.  */
  196. /*
  197.  * Value to pass to entity_create.
  198.  */
  199. enum body_expectation {
  200.    /*
  201.     * Message must not have a body, even if the headers indicate one.
  202.     * (i.e. response to HEAD method).
  203.     */
  204.    expect_no_body,
  205.    /*
  206.     * Message will have a body if Content-Length or Transfer-Encoding
  207.     * headers are present (i.e. most request methods).
  208.     */
  209.    expect_body_if_indicated,
  210.    /*
  211.     * Message will have a body, possibly zero-length.
  212.     * (i.e. 200 OK responses to a GET method.)
  213.     */
  214.    expect_body
  215. };
  216. enum entity_state {
  217.     reading_headers,
  218.     reading_chunked_body_len,
  219.     reading_chunked_body_data,
  220.     reading_chunked_body_crlf,
  221.     reading_chunked_body_trailer,
  222.     reading_body_until_eof,
  223.     reading_body_with_length,
  224.     body_error,
  225.     entity_done
  226. };
  227. typedef struct {
  228.     List *headers;
  229.     Octstr *body;
  230.     enum body_expectation expect_state;
  231.     enum entity_state state;
  232.     long chunked_body_chunk_len;
  233.     long expected_body_len;
  234. } HTTPEntity;
  235. /*
  236.  * The rules for message bodies (length and presence) are defined
  237.  * in RFC2616 paragraph 4.3 and 4.4.
  238.  */
  239. static void deduce_body_state(HTTPEntity *ent)
  240. {
  241.     Octstr *h = NULL;
  242.     if (ent->expect_state == expect_no_body) {
  243. ent->state = entity_done;
  244. return;
  245.     }
  246.     ent->state = body_error;  /* safety net */
  247.     h = http_header_find_first(ent->headers, "Transfer-Encoding");
  248.     if (h != NULL) {
  249.         octstr_strip_blanks(h);
  250.         if (octstr_str_compare(h, "chunked") != 0) {
  251.             error(0, "HTTP: Unknown Transfer-Encoding <%s>",
  252.                   octstr_get_cstr(h));
  253.     ent->state = body_error;
  254.         } else {
  255.             ent->state = reading_chunked_body_len;
  256. }
  257.         octstr_destroy(h);
  258. return;
  259.     }
  260.     h = http_header_find_first(ent->headers, "Content-Length");
  261.     if (h != NULL) {
  262.         if (octstr_parse_long(&ent->expected_body_len, h, 0, 10) == -1) {
  263.     error(0, "HTTP: Content-Length header wrong: <%s>",
  264.   octstr_get_cstr(h));
  265.     ent->state = body_error;
  266.         } else {
  267.             ent->state = reading_body_with_length;
  268. }
  269.         octstr_destroy(h);
  270. return;
  271.     }
  272.     if (ent->expect_state == expect_body)
  273.         ent->state = reading_body_until_eof;
  274.     else
  275. ent->state = entity_done;
  276. }
  277. /*
  278.  * Create a HTTPEntity structure suitable for reading the expected
  279.  * result or request message and decoding the transferred entity (if any).
  280.  * See the definition of enum body_expectation for the possible values
  281.  * of exp.
  282.  */
  283. static HTTPEntity *entity_create(enum body_expectation exp)
  284. {
  285.     HTTPEntity *ent;
  286.     ent = gw_malloc(sizeof(*ent));
  287.     ent->headers = http_create_empty_headers();
  288.     ent->body = octstr_create("");
  289.     ent->chunked_body_chunk_len = -1;
  290.     ent->expected_body_len = -1;
  291.     ent->state = reading_headers;
  292.     ent->expect_state = exp;
  293.     return ent;
  294. }
  295. static void entity_destroy(HTTPEntity *ent)
  296. {
  297.     if (ent == NULL)
  298.         return;
  299.     http_destroy_headers(ent->headers);
  300.     octstr_destroy(ent->body);
  301.     gw_free(ent);
  302. }
  303. static void read_chunked_body_len(HTTPEntity *ent, Connection *conn)
  304. {
  305.     Octstr *os;
  306.     long len;
  307.     
  308.     os = conn_read_line(conn);
  309.     if (os == NULL) {
  310.         if (conn_read_error(conn) || conn_eof(conn))
  311.     ent->state = body_error;
  312.         return;
  313.     }
  314.     if (octstr_parse_long(&len, os, 0, 16) == -1) {
  315.         octstr_destroy(os);
  316. ent->state = body_error;
  317.         return;
  318.     }
  319.     octstr_destroy(os);
  320.     if (len == 0)
  321.         ent->state = reading_chunked_body_trailer;
  322.     else {
  323.         ent->state = reading_chunked_body_data;
  324.         ent->chunked_body_chunk_len = len;
  325.     }
  326. }
  327. static void read_chunked_body_data(HTTPEntity *ent, Connection *conn)
  328. {
  329.     Octstr *os;
  330.     os = conn_read_fixed(conn, ent->chunked_body_chunk_len);
  331.     if (os == NULL) {
  332.         if (conn_read_error(conn) || conn_eof(conn))
  333.     ent->state = body_error;
  334.     } else {
  335.         octstr_append(ent->body, os);
  336.         octstr_destroy(os);
  337.         ent->state = reading_chunked_body_crlf;
  338.     }
  339. }
  340. static void read_chunked_body_crlf(HTTPEntity *ent, Connection *conn)
  341. {
  342.     Octstr *os;
  343.     os = conn_read_line(conn);
  344.     if (os == NULL) {
  345.         if (conn_read_error(conn) || conn_eof(conn))
  346.     ent->state = body_error;
  347.     } else {
  348.         octstr_destroy(os);
  349.         ent->state = reading_chunked_body_len;
  350.     }
  351. }
  352. static void read_chunked_body_trailer(HTTPEntity *ent, Connection *conn)
  353. {
  354.     int ret;
  355.     ret = read_some_headers(conn, ent->headers);
  356.     if (ret == -1)
  357. ent->state = body_error;
  358.     if (ret == 0)
  359.         ent->state = entity_done;
  360. }
  361. static void read_body_until_eof(HTTPEntity *ent, Connection *conn)
  362. {
  363.     Octstr *os;
  364.     while ((os = conn_read_everything(conn)) != NULL) {
  365.         octstr_append(ent->body, os);
  366.         octstr_destroy(os);
  367.     }
  368.     if (conn_read_error(conn))
  369. ent->state = body_error;
  370.     if (conn_eof(conn))
  371. ent->state = entity_done;
  372. }
  373. static void read_body_with_length(HTTPEntity *ent, Connection *conn)
  374. {
  375.     Octstr *os;
  376.     os = conn_read_fixed(conn, ent->expected_body_len);
  377.     if (os == NULL)
  378.         return;
  379.     octstr_destroy(ent->body);
  380.     ent->body = os;
  381.     ent->state = entity_done;
  382. }
  383. /*
  384.  * Read headers and body (if any) from this connection.  Return 0 if it's
  385.  * complete, 1 if we expect more input, and -1 if there is something wrong.
  386.  */
  387. static int entity_read(HTTPEntity *ent, Connection *conn)
  388. {
  389.     int ret;
  390.     enum entity_state old_state;
  391.     /*
  392.      * In this loop, each state will process as much input as it needs
  393.      * and then switch to the next state, unless it's a final state in
  394.      * which case it returns directly, or unless it needs more input.
  395.      * So keep looping as long as the state changes.
  396.      */
  397.     do {
  398. old_state = ent->state;
  399. switch (ent->state) {
  400. case reading_headers:
  401.     ret = read_some_headers(conn, ent->headers);
  402.             if (ret == 0)
  403.         deduce_body_state(ent);
  404.     if (ret < 0)
  405. return -1;
  406.     break;
  407. case reading_chunked_body_len:
  408.     read_chunked_body_len(ent, conn);
  409.     break;
  410. case reading_chunked_body_data:
  411.     read_chunked_body_data(ent, conn);
  412.     break;
  413. case reading_chunked_body_crlf:
  414.     read_chunked_body_crlf(ent, conn);
  415.     break;
  416. case reading_chunked_body_trailer:
  417.     read_chunked_body_trailer(ent, conn);
  418.     break;
  419. case reading_body_until_eof:
  420.     read_body_until_eof(ent, conn);
  421.     break;
  422. case reading_body_with_length:
  423.     read_body_with_length(ent, conn);
  424.     break;
  425. case body_error:
  426.     return -1;
  427. case entity_done:
  428.     return 0;
  429. default:
  430.     panic(0, "Internal error: Invalid HTTPEntity state.");
  431. }
  432.     } while (ent->state != old_state);
  433.     /*
  434.      * If we got here, then the loop ended because a non-final state
  435.      * needed more input.
  436.      */
  437.     return 1;
  438. }
  439. /***********************************************************************
  440.  * HTTP client interface.
  441.  */
  442. /*
  443.  * Maximum number of HTTP redirections to follow. Making this infinite
  444.  * could cause infinite looping if the redirections loop.
  445.  */
  446. enum { HTTP_MAX_FOLLOW = 5 };
  447. /*
  448.  * The implemented HTTP method strings
  449.  * Order is sequenced by the enum in the header
  450.  */
  451. static char *http_methods[] = {
  452.     "GET", "POST", "HEAD"
  453. };
  454. /*
  455.  * Information about a server we've connected to.
  456.  */
  457. typedef struct {
  458.     HTTPCaller *caller;
  459.     void *request_id;
  460.     int method;             /* uses enums from http.h for the HTTP methods */
  461.     Octstr *url;
  462.     List *request_headers;
  463.     Octstr *request_body;   /* NULL for GET or HEAD, non-NULL for POST */
  464.     enum {
  465. request_not_sent,
  466. reading_status,
  467. reading_entity,
  468. transaction_done
  469.     } state;
  470.     long status;
  471.     int persistent;
  472.     HTTPEntity *response; /* Can only be NULL if status < 0 */
  473.     Connection *conn;
  474.     Octstr *host;
  475.     long port;
  476.     int retrying;
  477.     int follow_remaining;
  478.     Octstr *certkeyfile;
  479.     int ssl;
  480.     Octstr *username; /* For basic authentication */
  481.     Octstr *password;
  482. } HTTPServer;
  483. static HTTPServer *server_create(HTTPCaller *caller, int method, Octstr *url,
  484.                                  List *headers, Octstr *body, int follow_remaining,
  485.                                  Octstr *certkeyfile)
  486. {
  487.     HTTPServer *trans;
  488.     
  489.     trans = gw_malloc(sizeof(*trans));
  490.     trans->caller = caller;
  491.     trans->request_id = NULL;
  492.     trans->method = method;
  493.     trans->url = octstr_duplicate(url);
  494.     trans->request_headers = http_header_duplicate(headers);
  495.     trans->request_body = octstr_duplicate(body);
  496.     trans->state = request_not_sent;
  497.     trans->status = -1;
  498.     trans->persistent = 0;
  499.     trans->response = NULL;
  500.     trans->conn = NULL;
  501.     trans->host = NULL;
  502.     trans->port = 0;
  503.     trans->username = NULL;
  504.     trans->password = NULL;
  505.     trans->retrying = 0;
  506.     trans->follow_remaining = follow_remaining;
  507.     trans->certkeyfile = certkeyfile;
  508.     trans->ssl = 0;
  509.     return trans;
  510. }
  511. static void server_destroy(void *p)
  512. {
  513.     HTTPServer *trans;
  514.     
  515.     trans = p;
  516.     octstr_destroy(trans->url);
  517.     http_destroy_headers(trans->request_headers);
  518.     trans->request_headers = NULL;
  519.     octstr_destroy(trans->request_body);
  520.     entity_destroy(trans->response);
  521.     octstr_destroy(trans->host);
  522.     gw_free(trans);
  523. }
  524. /*
  525.  * Pool of open, but unused connections to servers or proxies. Key is
  526.  * "servername:port", value is List with Connection objects.
  527.  */
  528. static Dict *conn_pool = NULL;
  529. static Mutex *conn_pool_lock = NULL;
  530. static void conn_pool_item_destroy(void *item)
  531. {
  532.     Connection *conn;
  533.     
  534.     while ((conn = list_extract_first(item)) != NULL)
  535.      conn_destroy(conn);
  536.     list_destroy(item, NULL);
  537. }
  538. static void conn_pool_init(void)
  539. {
  540.     conn_pool = dict_create(1024, conn_pool_item_destroy);
  541.     conn_pool_lock = mutex_create();
  542. }
  543. static void conn_pool_shutdown(void)
  544. {
  545.     dict_destroy(conn_pool);
  546.     mutex_destroy(conn_pool_lock);
  547. }
  548. static Octstr *conn_pool_key(Octstr *host, int port)
  549. {
  550.     return octstr_format("%S:%d", host, port);
  551. }
  552. static Connection *conn_pool_get(Octstr *host, int port, int ssl, Octstr *certkeyfile,
  553. Octstr *our_host)
  554. {
  555.     Octstr *key;
  556.     List *list;
  557.     Connection *conn;
  558.     mutex_lock(conn_pool_lock);
  559.     key = conn_pool_key(host, port);
  560.     list = dict_get(conn_pool, key);
  561.     octstr_destroy(key);
  562.     if (list == NULL)
  563.      conn = NULL;
  564.     else {
  565. while (1) {
  566.     conn = list_extract_first(list);
  567.     if (conn == NULL)
  568. break;
  569.     /* Check whether the server has closed the connection while
  570.      * it has been in the pool. */
  571.     conn_wait(conn, 0);
  572.     if (!conn_eof(conn) && !conn_read_error(conn))
  573. break;
  574.     conn_destroy(conn);
  575. }
  576.     }
  577.     mutex_unlock(conn_pool_lock);
  578.     
  579.     if (conn == NULL) {
  580. #ifdef HAVE_LIBSSL
  581. if (ssl) 
  582.     conn = conn_open_ssl(host, port, certkeyfile, our_host);
  583. else
  584. #endif /* HAVE_LIBSSL */
  585.     conn = conn_open_tcp(host, port, our_host);
  586. debug("gwlib.http", 0, "HTTP: Opening connection to `%s:%d' (fd=%d).",
  587.       octstr_get_cstr(host), port, conn_get_id(conn));
  588.     } else {
  589. debug("gwlib.http", 0, "HTTP: Reusing connection to `%s:%d' (fd=%d).",
  590.       octstr_get_cstr(host), port, conn_get_id(conn)); 
  591.     }
  592.     
  593.     return conn;
  594. }
  595. #ifdef USE_KEEPALIVE
  596. static void conn_pool_put(Connection *conn, Octstr *host, int port)
  597. {
  598.     Octstr *key;
  599.     List *list;
  600.     
  601.     mutex_lock(conn_pool_lock);
  602.     key = conn_pool_key(host, port);
  603.     list = dict_get(conn_pool, key);
  604.     if (list == NULL) {
  605.      list = list_create();
  606. dict_put(conn_pool, key, list);
  607.     }
  608.     list_append(list, conn);
  609.     octstr_destroy(key);
  610.     mutex_unlock(conn_pool_lock);
  611. }
  612. #endif
  613. /*
  614.  * Internal lists of completely unhandled requests and requests for which
  615.  * a request has been sent but response has not yet been read.
  616.  */
  617. static List *pending_requests = NULL;
  618. /*
  619.  * Have background threads been started?
  620.  */
  621. static Mutex *client_thread_lock = NULL;
  622. static volatile sig_atomic_t client_threads_are_running = 0;
  623. /*
  624.  * Set of all connections to all servers. Used with conn_register to
  625.  * do I/O on several connections with a single thread.
  626.  */
  627. static FDSet *client_fdset = NULL;
  628. HTTPCaller *http_caller_create(void)
  629. {
  630.     HTTPCaller *caller;
  631.     
  632.     caller = list_create();
  633.     list_add_producer(caller);
  634.     return caller;
  635. }
  636. void http_caller_destroy(HTTPCaller *caller)
  637. {
  638.     list_destroy(caller, server_destroy);
  639. }
  640. void http_caller_signal_shutdown(HTTPCaller *caller)
  641. {
  642.     list_remove_producer(caller);
  643. }
  644. static Octstr *get_redirection_location(HTTPServer *trans)
  645. {
  646.     if (trans->status < 0 || trans->follow_remaining <= 0)
  647.      return NULL;
  648.     if (trans->status != HTTP_MOVED_PERMANENTLY &&
  649.      trans->status != HTTP_FOUND && trans->status != HTTP_SEE_OTHER)
  650. return NULL;
  651.     if (trans->response == NULL)
  652.         return NULL;
  653.     return http_header_find_first(trans->response->headers, "Location");
  654. }
  655. /*
  656.  * Read and parse the status response line from an HTTP server.
  657.  * Fill in trans->persistent and trans->status with the findings.
  658.  * Return -1 for error, 1 for status line not yet available, 0 for OK.
  659.  */
  660. static int client_read_status(HTTPServer *trans)
  661. {
  662.     Octstr *line, *version;
  663.     long space;
  664.     int ret;
  665.     line = conn_read_line(trans->conn);
  666.     if (line == NULL) {
  667. if (conn_eof(trans->conn) || conn_read_error(trans->conn))
  668.     return -1;
  669.      return 1;
  670.     }
  671.     debug("gwlib.http", 0, "HTTP: Status line: <%s>", octstr_get_cstr(line));
  672.     space = octstr_search_char(line, ' ', 0);
  673.     if (space == -1)
  674.      goto error;
  675.     version = octstr_copy(line, 0, space);
  676.     ret = parse_http_version(version);
  677.     octstr_destroy(version);
  678.     if (ret == -1)
  679.      goto error;
  680.     trans->persistent = ret;
  681.     octstr_delete(line, 0, space + 1);
  682.     space = octstr_search_char(line, ' ', 0);
  683.     if (space == -1)
  684.      goto error;
  685.     octstr_truncate(line, space);
  686.     if (octstr_parse_long(&trans->status, line, 0, 10) == -1)
  687.         goto error;
  688.     octstr_destroy(line);
  689.     return 0;
  690. error:
  691.     error(0, "HTTP: Malformed status line from HTTP server: <%s>",
  692.   octstr_get_cstr(line));
  693.     octstr_destroy(line);
  694.     return -1;
  695. }
  696. static int response_expectation(int method, int status)
  697. {
  698.     if (status == HTTP_NO_CONTENT ||
  699.         status == HTTP_NOT_MODIFIED ||
  700.         http_status_class(status) == HTTP_STATUS_PROVISIONAL ||
  701.         method == HTTP_METHOD_HEAD)
  702. return expect_no_body;
  703.     else
  704.         return expect_body;
  705. }
  706. static void handle_transaction(Connection *conn, void *data)
  707. {
  708.     HTTPServer *trans;
  709.     int ret;
  710.     Octstr *h;
  711.     
  712.     trans = data;
  713.     if (run_status != running) {
  714. conn_unregister(conn);
  715. return;
  716.     }
  717.     while (trans->state != transaction_done) {
  718. switch (trans->state) {
  719. case reading_status:
  720.     ret = client_read_status(trans);
  721.     if (ret < 0) {
  722. /*
  723.  * Couldn't read the status from the socket. This may mean 
  724.  * that the socket had been closed by the server after an 
  725.  * idle timeout, so we close the connection and try again, 
  726.  * opening a new socket, but only once.
  727.  */
  728. if (trans->retrying) {
  729.     goto error;
  730. } else {
  731.     conn_destroy(trans->conn);
  732.     trans->conn = NULL;
  733.     trans->retrying = 1;
  734.     trans->state = request_not_sent;
  735.     list_produce(pending_requests, trans);
  736.     return;
  737. }
  738.     } else if (ret == 0) {
  739. /* Got the status, go read headers and body next. */
  740. trans->state = reading_entity;
  741. trans->response =
  742.     entity_create(response_expectation(trans->method, trans->status));
  743.     } else
  744. return;
  745.     break;
  746.     
  747. case reading_entity:
  748.     ret = entity_read(trans->response, conn);
  749.     if (ret < 0) {
  750. goto error;
  751.     } else if (ret == 0 && http_status_class(trans->status)
  752.                                   == HTTP_STATUS_PROVISIONAL) {
  753.                     /* This was a provisional reply; get the real one now. */
  754.                     trans->state = reading_status;
  755.             } else if (ret == 0) {
  756.     trans->state = transaction_done;
  757.     } else {
  758. return;
  759.             }
  760.     break;
  761. default:
  762.     panic(0, "Internal error: Invalid HTTPServer state.");
  763. }
  764.     }
  765.     conn_unregister(trans->conn);
  766.     h = http_header_find_first(trans->response->headers, "Connection");
  767.     if (h != NULL && octstr_compare(h, octstr_imm("close")) == 0)
  768. trans->persistent = 0;
  769.     octstr_destroy(h);
  770. #ifdef USE_KEEPALIVE 
  771.     if (trans->persistent)
  772.         conn_pool_put(trans->conn, trans->host, trans->port);
  773.     else
  774. #endif
  775.      conn_destroy(trans->conn);
  776.     trans->conn = NULL;
  777.     h = get_redirection_location(trans);
  778.     if (h != NULL) {
  779. octstr_strip_blanks(h);
  780. octstr_destroy(trans->url);
  781. trans->url = h;
  782. trans->state = request_not_sent;
  783. trans->status = -1;
  784. http_destroy_headers(trans->response->headers);
  785. trans->response->headers = list_create();
  786. octstr_destroy(trans->response->body);
  787. trans->response->body = octstr_create("");
  788. --trans->follow_remaining;
  789. conn_destroy(trans->conn);
  790. trans->conn = NULL;
  791. list_produce(pending_requests, trans);
  792.     } else
  793. list_produce(trans->caller, trans);
  794.     return;
  795. error:
  796.     conn_destroy(trans->conn);
  797.     trans->conn = NULL;
  798.     error(0, "Couldn't fetch <%s>", octstr_get_cstr(trans->url));
  799.     trans->status = -1;
  800.     list_produce(trans->caller, trans);
  801. }
  802. /*
  803.  * Build a complete HTTP request given the host, port, path and headers. 
  804.  * Add Host: and Content-Length: headers (and others that may be necessary).
  805.  * Return the request as an Octstr.
  806.  */
  807. static Octstr *build_request(char *method_name, Octstr *path_or_url, 
  808.                              Octstr *host, long port, List *headers, 
  809.                              Octstr *request_body)
  810. {
  811.     /* XXX headers missing */
  812.     Octstr *request;
  813.     int i;
  814.     request = octstr_format("%s %S HTTP/1.1rn",
  815.                             method_name, path_or_url);
  816.     octstr_format_append(request, "Host: %S", host);
  817.     if (port != HTTP_PORT)
  818.         octstr_format_append(request, ":%ld", port);
  819.     octstr_append(request, octstr_imm("rn"));
  820.     for (i = 0; headers != NULL && i < list_len(headers); ++i) {
  821.         octstr_append(request, list_get(headers, i));
  822.         octstr_append(request, octstr_imm("rn"));
  823.     }
  824.     octstr_append(request, octstr_imm("rn"));
  825.     if (request_body != NULL)
  826.         octstr_append(request, request_body);
  827.     return request;
  828. }
  829. /*
  830.  * Parse the URL to get the hostname and the port to connect to and the
  831.  * path within the host.
  832.  *
  833.  * Return -1 if the URL seems malformed.
  834.  *
  835.  * We assume HTTP URLs of the form specified in "3.2.2 http URL" in
  836.  * RFC 2616:
  837.  * 
  838.  *  http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
  839.  */
  840. static int parse_url(Octstr *url, Octstr **host, long *port, Octstr **path, 
  841.      int *ssl, Octstr **username, Octstr **password)
  842. {
  843.     Octstr *prefix, *prefix_https;
  844.     long prefix_len;
  845.     int host_len, colon, slash, at, auth_sep = 0;
  846.     prefix = octstr_imm("http://");
  847.     prefix_https = octstr_imm("https://");
  848.     prefix_len = octstr_len(prefix);
  849.     if (octstr_case_search(url, prefix, 0) != 0) {
  850.         if (octstr_case_search(url, prefix_https, 0) == 0) {
  851. #ifdef HAVE_LIBSSL
  852.             debug("gwlib.http", 0, "HTTPS URL; Using SSL for the connection");
  853.             prefix = prefix_https;
  854.             prefix_len = octstr_len(prefix_https);
  855.             *ssl = 1;
  856. #else
  857.             error(0, "Attempt to use HTTPS <%s> but SSL not compiled in", 
  858.                   octstr_get_cstr(url));
  859.             return -1;
  860. #endif
  861.         } else {
  862.             error(0, "URL <%s> doesn't start with `%s' nor `%s'",
  863.             octstr_get_cstr(url), octstr_get_cstr(prefix),
  864.             octstr_get_cstr(prefix_https));
  865.             return -1;
  866.         }
  867.     }
  868.     if (octstr_len(url) == prefix_len) {
  869.         error(0, "URL <%s> is malformed.", octstr_get_cstr(url));
  870.         return -1;
  871.     }
  872.     colon = octstr_search_char(url, ':', prefix_len);
  873.     slash = octstr_search_char(url, '/', prefix_len);
  874.     if (colon == prefix_len || slash == prefix_len) {
  875.         error(0, "URL <%s> is malformed.", octstr_get_cstr(url));
  876.         return -1;
  877.     }
  878.     at = octstr_search_char(url, '@', prefix_len);
  879.     if ( at != -1 ) {
  880. if ((slash == -1 || ( slash != -1 && at < slash))) {
  881.     auth_sep = octstr_search_char(url, ':', prefix_len);
  882.     if (auth_sep != -1 && (auth_sep < at)) {
  883. octstr_set_char(url, auth_sep, '@');
  884. colon = octstr_search_char(url, ':', prefix_len);
  885.     }
  886. } else {
  887.     at = -1;
  888. }
  889.     }
  890.     
  891.     if (slash == -1 && colon == -1) {
  892.         /* Just the hostname, no port or path. */
  893.         host_len = octstr_len(url) - prefix_len;
  894. #ifdef HAVE_LIBSSL
  895.         *port = *ssl ? HTTPS_PORT : HTTP_PORT;
  896. #else
  897.         *port = HTTP_PORT;
  898. #endif /* HAVE_LIBSSL */
  899.     } else if (slash == -1) {
  900.         /* Port, but not path. */
  901.         host_len = colon - prefix_len;
  902.         if (octstr_parse_long(port, url, colon + 1, 10) == -1) {
  903.             error(0, "URL <%s> has malformed port number.",
  904.                   octstr_get_cstr(url));
  905.             return -1;
  906.         }
  907.     } else if (colon == -1 || colon > slash) {
  908.         /* Path, but not port. */
  909.         host_len = slash - prefix_len;
  910. #ifdef HAVE_LIBSSL
  911.         *port = *ssl ? HTTPS_PORT : HTTP_PORT;
  912. #else
  913.         *port = HTTP_PORT;
  914. #endif /* HAVE_LIBSSL */
  915.     } else if (colon < slash) {
  916.         /* Both path and port. */
  917.         host_len = colon - prefix_len;
  918.         if (octstr_parse_long(port, url, colon + 1, 10) == -1) {
  919.             error(0, "URL <%s> has malformed port number.",
  920.                   octstr_get_cstr(url));
  921.             return -1;
  922.         }
  923.     } else {
  924.         error(0, "Internal error in URL parsing logic.");
  925.         return -1;
  926.     }
  927.     if (at != -1) {
  928. int at2, i;
  929. at2 = octstr_search_char(url, '@', prefix_len);
  930. *username = octstr_copy(url, prefix_len, at2 - prefix_len);
  931. if (at2 != at)
  932.     *password = octstr_copy(url, at2 + 1, at - at2 - 1);
  933. else
  934.     *password = NULL;
  935. octstr_set_char(url, auth_sep, ':');
  936. for(i = at2 + 1; i < at ; i++)
  937.     octstr_set_char(url, i, '*');
  938. host_len = host_len - at + prefix_len - 1;
  939. prefix_len = at + 1;
  940.     }
  941.     *host = octstr_copy(url, prefix_len, host_len);
  942.     if (slash == -1)
  943.         *path = octstr_create("/");
  944.     else
  945.         *path = octstr_copy(url, slash, octstr_len(url) - slash);
  946.     return 0;
  947. }
  948. /*
  949.  * Build and send the HTTP request. Return socket from which the
  950.  * response can be read or -1 for error.
  951.  */
  952. static Connection *send_request(HTTPServer *trans)
  953. {
  954.     Octstr *path, *request;
  955.     Connection *conn;
  956.     Octstr *host, *our_host = NULL;
  957.     int port;
  958.     path = NULL;
  959.     request = NULL;
  960.     conn = NULL;
  961.     /* May not be NULL if we're retrying this transaction. */
  962.     octstr_destroy(trans->host);
  963.     trans->host = NULL;
  964.     if(trans->request_headers == NULL)
  965.      trans->request_headers = http_create_empty_headers();
  966.     if (parse_url(trans->url, &trans->host, &trans->port, &path, &trans->ssl,
  967.                   &trans->username, &trans->password) == -1)
  968.         goto error;
  969.     if (trans->username != NULL)
  970.         http_add_basic_auth(trans->request_headers, trans->username,
  971.                             trans->password);
  972.     if (proxy_used_for_host(trans->host)) {
  973.         proxy_add_authentication(trans->request_headers);
  974.         request = build_request(http_method2name(trans->method), 
  975.                                 trans->url, trans->host, trans->port, 
  976.                                 trans->request_headers, trans->request_body);
  977.         host = proxy_hostname;
  978.         port = proxy_port;
  979.     } else {
  980.         request = build_request(http_method2name(trans->method), path, trans->host, 
  981.                                 trans->port, trans->request_headers,
  982.                                 trans->request_body);
  983.         host = trans->host;
  984.         port = trans->port;
  985.     }
  986.     if (trans->retrying) {
  987. #ifdef HAVE_LIBSSL
  988.         if (trans->ssl) 
  989.             conn = conn_open_ssl(host, port, trans->certkeyfile, our_host);
  990.         else
  991. #endif /* HAVE_LIBSSL */
  992.             conn = conn_open_tcp(host, port, our_host);
  993.             debug("gwlib.http", 0, "HTTP: Opening NEW connection to `%s:%d' (fd=%d).",
  994.                   octstr_get_cstr(host), port, conn_get_id(conn));
  995.     } else
  996.         conn = conn_pool_get(host, port, trans->ssl, trans->certkeyfile, our_host);
  997.     if (conn == NULL)
  998.         goto error;
  999.     debug("wsp.http", 0, "HTTP: Sending request:");
  1000.     octstr_dump(request, 0);
  1001.     if (conn_write(conn, request) == -1)
  1002.         goto error;
  1003.     octstr_destroy(path);
  1004.     octstr_destroy(request);
  1005.     return conn;
  1006. error:
  1007.     conn_destroy(conn);
  1008.     octstr_destroy(path);
  1009.     octstr_destroy(request);
  1010.     error(0, "Couldn't send request to <%s>", octstr_get_cstr(trans->url));
  1011.     return NULL;
  1012. }
  1013. /*
  1014.  * This thread starts the transaction: it connects to the server and sends
  1015.  * the request. It then sends the transaction to the read_response_thread
  1016.  * via started_requests_queue.
  1017.  */
  1018. static void write_request_thread(void *arg)
  1019. {
  1020.     HTTPServer *trans;
  1021.     char buf[128];    
  1022.     while (run_status == running) {
  1023.         trans = list_consume(pending_requests);
  1024.         if (trans == NULL)
  1025.             break;
  1026.         gw_assert(trans->state == request_not_sent);
  1027.         if (trans->method == HTTP_METHOD_POST) {
  1028.             /* 
  1029.              * Add a Content-Length header.  Override an existing one, if
  1030.              * necessary.  We must have an accurate one in order to use the
  1031.              * connection for more than a single request.
  1032.              */
  1033.             http_header_remove_all(trans->request_headers, "Content-Length");
  1034.             sprintf(buf, "%ld", octstr_len(trans->request_body));
  1035.             http_header_add(trans->request_headers, "Content-Length", buf);
  1036.         } 
  1037.             /* 
  1038.              * ok, this has to be an GET or HEAD request method then,
  1039.              * if it contains a body, then this is not HTTP conform, so at
  1040.              * least warn the user 
  1041.              */
  1042.         else if (trans->request_body != NULL) {
  1043.             warning(0, "HTTP: GET or HEAD method request contains body:");
  1044.             octstr_dump(trans->request_body, 0);
  1045.         }
  1046.         trans->conn = send_request(trans);
  1047.         if (trans->conn == NULL)
  1048.             list_produce(trans->caller, trans);
  1049.         else {
  1050.             trans->state = reading_status;
  1051.             conn_register(trans->conn, client_fdset, handle_transaction, trans);
  1052.         }
  1053.     }
  1054. }
  1055. static void start_client_threads(void)
  1056. {
  1057.     if (!client_threads_are_running) {
  1058. /* 
  1059.  * To be really certain, we must repeat the test, but use the
  1060.  * lock first. If the test failed, however, we _know_ we've
  1061.  * already initialized. This strategy of double testing avoids
  1062.  * using the lock more than a few times at startup.
  1063.  */
  1064. mutex_lock(client_thread_lock);
  1065. if (!client_threads_are_running) {
  1066.     client_fdset = fdset_create();
  1067.     gwthread_create(write_request_thread, NULL);
  1068.     client_threads_are_running = 1;
  1069. }
  1070. mutex_unlock(client_thread_lock);
  1071.     }
  1072. }
  1073. void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers,
  1074.                Octstr *body, int follow, void *id, Octstr *certkeyfile)
  1075. {
  1076.     HTTPServer *trans;
  1077.     int follow_remaining;
  1078.     
  1079.     if (follow)
  1080.      follow_remaining = HTTP_MAX_FOLLOW;
  1081.     else
  1082.      follow_remaining = 0;
  1083.     trans = server_create(caller, method, url, headers, body, follow_remaining, 
  1084.   certkeyfile);
  1085.     if (id == NULL)
  1086. /* We don't leave this NULL so http_receive_result can use NULL
  1087.  * to signal no more requests */
  1088. trans->request_id = http_start_request;
  1089.     else
  1090. trans->request_id = id;
  1091.     list_produce(pending_requests, trans);
  1092.     start_client_threads();
  1093. }
  1094. void *http_receive_result(HTTPCaller *caller, int *status, Octstr **final_url,
  1095.                 List **headers, Octstr **body)
  1096. {
  1097.     HTTPServer *trans;
  1098.     void *request_id;
  1099.     trans = list_consume(caller);
  1100.     if (trans == NULL)
  1101.      return NULL;
  1102.     request_id = trans->request_id;
  1103.     *status = trans->status;
  1104.     
  1105.     if (trans->status >= 0) {
  1106. *final_url = trans->url;
  1107. *headers = trans->response->headers;
  1108. *body = trans->response->body;
  1109. trans->url = NULL;
  1110. trans->response->headers = NULL;
  1111. trans->response->body = NULL;
  1112.     } else {
  1113. *final_url = NULL;
  1114. *headers = NULL;
  1115. *body = NULL;
  1116.     }
  1117.     server_destroy(trans);
  1118.     return request_id;
  1119. }
  1120. int http_get_real(int method, Octstr *url, List *request_headers, Octstr **final_url,
  1121.                   List **reply_headers, Octstr **reply_body)
  1122. {
  1123.     HTTPCaller *caller;
  1124.     int status;
  1125.     void *ret;
  1126.     
  1127.     caller = http_caller_create();
  1128.     http_start_request(caller, method, url, request_headers, 
  1129.                        NULL, 1, http_get_real, NULL);
  1130.     ret = http_receive_result(caller, &status, final_url, 
  1131.                      reply_headers, reply_body);
  1132.     http_caller_destroy(caller);
  1133.     if (ret == NULL)
  1134.      return -1;
  1135.     return status;
  1136. }
  1137. static void client_init(void)
  1138. {
  1139.     pending_requests = list_create();
  1140.     list_add_producer(pending_requests);
  1141.     client_thread_lock = mutex_create();
  1142. }
  1143. static void client_shutdown(void)
  1144. {
  1145.     list_remove_producer(pending_requests);
  1146.     gwthread_join_every(write_request_thread);
  1147.     list_destroy(pending_requests, server_destroy);
  1148.     mutex_destroy(client_thread_lock);
  1149.     fdset_destroy(client_fdset);
  1150. }
  1151. /***********************************************************************
  1152.  * HTTP server interface.
  1153.  */
  1154. /*
  1155.  * Information about a client that has connected to the server we implement.
  1156.  */
  1157. struct HTTPClient {
  1158.     int port;
  1159.     Connection *conn;
  1160.     Octstr *ip;
  1161.     enum {
  1162.         reading_request_line,
  1163.         reading_request,
  1164.         request_is_being_handled,
  1165. sending_reply
  1166.     } state;
  1167.     int method;  /* HTTP_METHOD_ value */
  1168.     Octstr *url;
  1169.     int use_version_1_0;
  1170.     int persistent_conn;
  1171.     HTTPEntity *request;
  1172. };
  1173. static HTTPClient *client_create(int port, Connection *conn, Octstr *ip)
  1174. {
  1175.     HTTPClient *p;
  1176.     
  1177. #ifdef HAVE_LIBSSL
  1178.     if (conn_get_ssl(conn)) 
  1179.         debug("gwlib.http", 0, "HTTP: Creating SSL-enabled HTTPClient for `%s', using cipher '%s'.",
  1180.            octstr_get_cstr(ip), SSL_get_cipher_version(conn_get_ssl(conn)));
  1181.     else
  1182. #endif    
  1183.     debug("gwlib.http", 0, "HTTP: Creating HTTPClient for `%s'.",
  1184.        octstr_get_cstr(ip));
  1185.     p = gw_malloc(sizeof(*p));
  1186.     p->port = port;
  1187.     p->conn = conn;
  1188.     p->ip = ip;
  1189.     p->state = reading_request_line;
  1190.     p->url = NULL;
  1191.     p->use_version_1_0 = 0;
  1192.     p->persistent_conn = 1;
  1193.     p->request = NULL;
  1194.     return p;
  1195. }
  1196. static void client_destroy(void *client)
  1197. {
  1198.     HTTPClient *p;
  1199.     
  1200.     if (client == NULL)
  1201.      return;
  1202.     p = client;
  1203.     debug("gwlib.http", 0, "HTTP: Destroying HTTPClient area %p.", p);
  1204.     gw_assert_allocated(p, __FILE__, __LINE__, __func__);
  1205.     debug("gwlib.http", 0, "HTTP: Destroying HTTPClient for `%s'.",
  1206.        octstr_get_cstr(p->ip));
  1207.     conn_destroy(p->conn);
  1208.     octstr_destroy(p->ip);
  1209.     octstr_destroy(p->url);
  1210.     entity_destroy(p->request);
  1211.     gw_free(p);
  1212. }
  1213. static void client_reset(HTTPClient *p)
  1214. {
  1215.     debug("gwlib.http", 0, "HTTP: Resetting HTTPClient for `%s'.",
  1216.        octstr_get_cstr(p->ip));
  1217.     p->state = reading_request_line;
  1218.     gw_assert(p->request == NULL);
  1219. }
  1220. /*
  1221.  * Checks whether the client connection is meant to be persistent or not.
  1222.  * Returns 1 for true, 0 for false.
  1223.  */
  1224. static int client_is_persistent(List *headers, int use_version_1_0)
  1225. {
  1226.     Octstr *h = http_header_find_first(headers, "Connection");
  1227.     if (h == NULL) {
  1228.         return !use_version_1_0;
  1229.     } else {
  1230.         if (!use_version_1_0) {
  1231.             if (octstr_case_compare(h, octstr_imm("keep-alive")) == 0) {
  1232.                 octstr_destroy(h);
  1233.                 return 1;
  1234.             } else {
  1235.                 octstr_destroy(h);
  1236.                 return 0;
  1237.             }
  1238.     } else if (octstr_case_compare(h, octstr_imm("close")) == 0) {
  1239.             octstr_destroy(h);
  1240.             return 0;
  1241.         }
  1242.         octstr_destroy(h);
  1243.     }
  1244.     return 1;
  1245. }
  1246. /*
  1247.  * Port specific lists of clients with requests.
  1248.  */
  1249. struct port {
  1250.     List *clients_with_requests;
  1251.     Counter *active_consumers;
  1252. };
  1253. static Mutex *port_mutex = NULL;
  1254. static Dict *port_collection = NULL;
  1255. static void port_init(void)
  1256. {
  1257.     port_mutex = mutex_create();
  1258.     port_collection = dict_create(1024, NULL);
  1259. }
  1260. static void port_shutdown(void)
  1261. {
  1262.     mutex_destroy(port_mutex);
  1263.     dict_destroy(port_collection);
  1264. }
  1265. static Octstr *port_key(int port)
  1266. {
  1267.     return octstr_format("%d", port);
  1268. }
  1269. static void port_add(int port)
  1270. {
  1271.     Octstr *key;
  1272.     struct port *p;
  1273.     p = gw_malloc(sizeof(*p));
  1274.     p->clients_with_requests = list_create();
  1275.     list_add_producer(p->clients_with_requests);
  1276.     p->active_consumers = counter_create();
  1277.     key = port_key(port);
  1278.     mutex_lock(port_mutex);
  1279.     dict_put(port_collection, key, p);
  1280.     mutex_unlock(port_mutex);
  1281.     octstr_destroy(key);
  1282. }
  1283. static void port_remove(int port)
  1284. {
  1285.     Octstr *key;
  1286.     struct port *p;
  1287.     key = port_key(port);
  1288.     mutex_lock(port_mutex);
  1289.     p = dict_remove(port_collection, key);
  1290.     mutex_unlock(port_mutex);
  1291.     octstr_destroy(key);
  1292.     list_remove_producer(p->clients_with_requests);
  1293.     while (counter_value(p->active_consumers) > 0)
  1294.        gwthread_sleep(0.1);    /* Reasonable use of busy waiting. */
  1295.     list_destroy(p->clients_with_requests, client_destroy);
  1296.     counter_destroy(p->active_consumers);
  1297.     gw_free(p);
  1298. }
  1299. static void port_put_request(HTTPClient *client)
  1300. {
  1301.     Octstr *key;
  1302.     struct port *p;
  1303.     mutex_lock(port_mutex);
  1304.     key = port_key(client->port);
  1305.     p = dict_get(port_collection, key);
  1306.     gw_assert(p != NULL);
  1307.     list_produce(p->clients_with_requests, client);
  1308.     octstr_destroy(key);
  1309.     mutex_unlock(port_mutex);
  1310. }
  1311. static HTTPClient *port_get_request(int port)
  1312. {
  1313.     Octstr *key;
  1314.     struct port *p;
  1315.     HTTPClient *client;
  1316.     
  1317.     mutex_lock(port_mutex);
  1318.     key = port_key(port);
  1319.     p = dict_get(port_collection, key);
  1320.     octstr_destroy(key);
  1321.     if (p == NULL) {
  1322.        client = NULL;
  1323.        mutex_unlock(port_mutex);
  1324.     } else {
  1325.        counter_increase(p->active_consumers);
  1326.        mutex_unlock(port_mutex);   /* Placement of this unlock is tricky. */
  1327.        client = list_consume(p->clients_with_requests);
  1328.        counter_decrease(p->active_consumers);
  1329.     }
  1330.     return client;
  1331. }
  1332. /*
  1333.  * Maximum number of servers (ports) we have open at the same time.
  1334.  */
  1335. enum { MAX_SERVERS = 32 };
  1336. /*
  1337.  * Variables related to server side implementation.
  1338.  */
  1339. static Mutex *server_thread_lock = NULL;
  1340. static volatile sig_atomic_t server_thread_is_running = 0;
  1341. static long server_thread_id = -1;
  1342. static FDSet *server_fdset = NULL;
  1343. static List *new_server_sockets = NULL;
  1344. static List *closed_server_sockets = NULL;
  1345. static int keep_servers_open = 0;
  1346. static int parse_request_line(int *method, Octstr **url,
  1347.                               int *use_version_1_0, Octstr *line)
  1348. {
  1349.     List *words;
  1350.     Octstr *version;
  1351.     Octstr *method_str;
  1352.     int ret;
  1353.     words = octstr_split_words(line);
  1354.     if (list_len(words) != 3) {
  1355.         list_destroy(words, octstr_destroy_item);
  1356. return -1;
  1357.     }
  1358.     method_str = list_get(words, 0);
  1359.     *url = list_get(words, 1);
  1360.     version = list_get(words, 2);
  1361.     list_destroy(words, NULL);
  1362.     if (octstr_compare(method_str, octstr_imm("GET")) == 0)
  1363. *method = HTTP_METHOD_GET;
  1364.     else if (octstr_compare(method_str, octstr_imm("POST")) == 0)
  1365. *method = HTTP_METHOD_POST;
  1366.     else if (octstr_compare(method_str, octstr_imm("HEAD")) == 0)
  1367. *method = HTTP_METHOD_HEAD;
  1368.     else
  1369.         goto error;
  1370.     ret = parse_http_version(version);
  1371.     if (ret < 0)
  1372.         goto error;
  1373.     *use_version_1_0 = !ret;
  1374.     octstr_destroy(method_str);
  1375.     octstr_destroy(version);
  1376.     return 0;
  1377. error:
  1378.     octstr_destroy(method_str);
  1379.     octstr_destroy(*url);
  1380.     octstr_destroy(version);
  1381.     *url = NULL;
  1382.     return -1;
  1383. }
  1384. static void receive_request(Connection *conn, void *data)
  1385. {
  1386.     HTTPClient *client;
  1387.     Octstr *line;
  1388.     int ret;
  1389.     if (run_status != running) {
  1390. conn_unregister(conn);
  1391. return;
  1392.     }
  1393.     client = data;
  1394.     
  1395.     for (;;) {
  1396. switch (client->state) {
  1397. case reading_request_line:
  1398.          line = conn_read_line(conn);
  1399.     if (line == NULL) {
  1400. if (conn_eof(conn) || conn_read_error(conn))
  1401.     goto error;
  1402.      return;
  1403.     }
  1404.     ret = parse_request_line(&client->method, &client->url,
  1405.                                      &client->use_version_1_0, line);
  1406.     octstr_destroy(line);
  1407.     if (ret == -1)
  1408.      goto error;
  1409.         /*
  1410.      * RFC2616 (4.3) says we should read a message body if there
  1411.      * is one, even on GET requests.
  1412.      */
  1413.     client->request = entity_create(expect_body_if_indicated);
  1414.     client->state = reading_request;
  1415.     break;
  1416.     
  1417. case reading_request:
  1418.     ret = entity_read(client->request, conn);
  1419.     if (ret < 0)
  1420. goto error;
  1421.     if (ret == 0) {
  1422.      client->state = request_is_being_handled;
  1423. conn_unregister(conn);
  1424. port_put_request(client);
  1425.     }
  1426.     return;
  1427. case sending_reply:
  1428.     if (conn_outbuf_len(conn) > 0)
  1429. return;
  1430.     /* Reply has been sent completely */
  1431.     if (!client->persistent_conn) {
  1432. client_destroy(client);
  1433. return;
  1434.     }
  1435.     /* Start reading another request */
  1436.     client_reset(client);
  1437.     break;
  1438.      default:
  1439.     panic(0, "Internal error: HTTPClient state is wrong.");
  1440. }
  1441.     }
  1442.     
  1443. error:
  1444.     client_destroy(client);
  1445. }
  1446. struct server {
  1447.     int fd;
  1448.     int port;
  1449.     int ssl;
  1450. };
  1451. static void server_thread(void *dummy)
  1452. {
  1453.     struct pollfd tab[MAX_SERVERS];
  1454.     int ports[MAX_SERVERS];
  1455.     int ssl[MAX_SERVERS];
  1456.     long i, j, n, fd;
  1457.     int *portno;
  1458.     struct server *p;
  1459.     struct sockaddr_in addr;
  1460.     int addrlen;
  1461.     Connection *conn;
  1462.     HTTPClient *client;
  1463.     int ret;
  1464.     n = 0;
  1465.     while (run_status == running && keep_servers_open) {
  1466. if (n == 0 || (n < MAX_SERVERS && list_len(new_server_sockets) > 0)) {
  1467.     p = list_consume(new_server_sockets);
  1468.     if (p == NULL) {
  1469. debug("gwlib.http", 0, "HTTP: No new servers. Quitting.");
  1470.      break;
  1471.     }
  1472.     tab[n].fd = p->fd;
  1473.     tab[n].events = POLLIN;
  1474.     ports[n] = p->port;
  1475.         ssl[n] = p->ssl;
  1476.     ++n;
  1477.     gw_free(p);
  1478. }
  1479. if ((ret = gwthread_poll(tab, n, -1.0)) == -1) {
  1480.     if (errno != EINTR)
  1481.         warning(0, "HTTP: gwthread_poll failed.");
  1482.     continue;
  1483. }
  1484.      for (i = 0; i < n; ++i) {
  1485.     if (tab[i].revents & POLLIN) {
  1486. addrlen = sizeof(addr);
  1487. fd = accept(tab[i].fd, (struct sockaddr *) &addr, &addrlen);
  1488. if (fd == -1) {
  1489.     error(errno, "HTTP: Error accepting a client.");
  1490.               (void) close(tab[i].fd);
  1491.     port_remove(ports[i]);
  1492.     tab[i].fd = -1;
  1493.     ports[i] = -1;
  1494.             ssl[i] = 0;
  1495. } else {
  1496.             /*
  1497.              * Be aware that conn_wrap_fd() will return NULL if SSL handshake
  1498.              * has failed, so we only client_create() if there is an conn.
  1499.              */             
  1500.             if ((conn = conn_wrap_fd(fd, ssl[i]))) {
  1501.              client = client_create(ports[i], conn, host_ip(addr));
  1502.         conn_register(conn, server_fdset, receive_request, 
  1503.                 client);
  1504.             } else {
  1505.                 error(0, "HTTP: unsuccessfull SSL handshake for client `%s'",
  1506.                       octstr_get_cstr(host_ip(addr)));
  1507.             }
  1508. }
  1509.     }
  1510. }
  1511. while ((portno = list_extract_first(closed_server_sockets)) != NULL) {
  1512.     for (i = 0; i < n; ++i) {
  1513. if (ports[i] == *portno) {
  1514.     (void) close(tab[i].fd);
  1515.     port_remove(ports[i]);
  1516.     tab[i].fd = -1;
  1517.     ports[i] = -1;
  1518.             ssl[i] = 0;
  1519. }
  1520.     }
  1521.     gw_free(portno);
  1522. }
  1523.        
  1524.      j = 0;
  1525. for (i = 0; i < n; ++i) {
  1526.     if (tab[i].fd != -1) {
  1527.      tab[j] = tab[i];
  1528. ports[j] = ports[i];
  1529.         ssl[j] = ssl[i];
  1530. ++j;
  1531.     }
  1532. }
  1533. n = j;
  1534.     }
  1535.     
  1536.     for (i = 0; i < n; ++i) {
  1537. (void) close(tab[i].fd);
  1538. port_remove(ports[i]);
  1539.     }
  1540. }
  1541. static void start_server_thread(void)
  1542. {
  1543.     if (!server_thread_is_running) {
  1544. /* 
  1545.  * To be really certain, we must repeat the test, but use the
  1546.  * lock first. If the test failed, however, we _know_ we've
  1547.  * already initialized. This strategy of double testing avoids
  1548.  * using the lock more than a few times at startup.
  1549.  */
  1550. mutex_lock(server_thread_lock);
  1551. if (!server_thread_is_running) {
  1552.     server_fdset = fdset_create();
  1553.     server_thread_id = gwthread_create(server_thread, NULL);
  1554.     server_thread_is_running = 1;
  1555. }
  1556. mutex_unlock(server_thread_lock);
  1557.     }
  1558. }
  1559. int http_open_port(int port, int ssl)
  1560. {
  1561.     struct server *p;
  1562.     if (ssl) debug("gwlib.http", 0, "HTTP: Opening SSL server at port %d.", port);
  1563.     else debug("gwlib.http", 0, "HTTP: Opening server at port %d.", port);
  1564.     p = gw_malloc(sizeof(*p));
  1565.     p->port = port;
  1566.     p->ssl = ssl;
  1567.     p->fd = make_server_socket(port, NULL);
  1568. /* XXX add interface_name if required */
  1569.     if (p->fd == -1) {
  1570. gw_free(p);
  1571.      return -1;
  1572.     }
  1573.     port_add(port);
  1574.     list_produce(new_server_sockets, p);
  1575.     keep_servers_open = 1;
  1576.     start_server_thread();
  1577.     gwthread_wakeup(server_thread_id);
  1578.     return 0;
  1579. }
  1580. void http_close_port(int port)
  1581. {
  1582.     int *p;
  1583.     
  1584.     p = gw_malloc(sizeof(*p));
  1585.     *p = port;
  1586.     list_produce(closed_server_sockets, p);
  1587.     gwthread_wakeup(server_thread_id);
  1588. }
  1589. void http_close_all_ports(void)
  1590. {
  1591.     if (server_thread_id != -1) {
  1592. keep_servers_open = 0;
  1593. gwthread_wakeup(server_thread_id);
  1594. gwthread_join_every(server_thread);
  1595. fdset_destroy(server_fdset);
  1596. server_fdset = NULL;
  1597.     }
  1598. }
  1599. /*
  1600.  * Parse CGI variables from the path given in a GET. Return a list
  1601.  * of HTTPCGIvar pointers. Modify the url so that the variables are
  1602.  * removed.
  1603.  */
  1604. static List *parse_cgivars(Octstr *url)
  1605. {
  1606.     HTTPCGIVar *v;
  1607.     List *list;
  1608.     int query, et, equals;
  1609.     Octstr *arg, *args;
  1610.     query = octstr_search_char(url, '?', 0);
  1611.     if (query == -1)
  1612.         return list_create();
  1613.     args = octstr_copy(url, query + 1, octstr_len(url));
  1614.     octstr_truncate(url, query);
  1615.     list = list_create();
  1616.     while (octstr_len(args) > 0) {
  1617.         et = octstr_search_char(args, '&', 0);
  1618.         if (et == -1)
  1619.             et = octstr_len(args);
  1620.         arg = octstr_copy(args, 0, et);
  1621.         octstr_delete(args, 0, et + 1);
  1622.         equals = octstr_search_char(arg, '=', 0);
  1623.         if (equals == -1)
  1624.             equals = octstr_len(arg);
  1625.         v = gw_malloc(sizeof(HTTPCGIVar));
  1626.         v->name = octstr_copy(arg, 0, equals);
  1627.         v->value = octstr_copy(arg, equals + 1, octstr_len(arg));
  1628.         octstr_url_decode(v->name);
  1629.         octstr_url_decode(v->value);
  1630.         octstr_destroy(arg);
  1631.         list_append(list, v);
  1632.     }
  1633.     octstr_destroy(args);
  1634.     return list;
  1635. }
  1636. HTTPClient *http_accept_request(int port, Octstr **client_ip, Octstr **url, 
  1637.                     List **headers, Octstr **body, 
  1638. List **cgivars)
  1639. {
  1640.     HTTPClient *client;
  1641.     client = port_get_request(port);
  1642.     if (client == NULL) {
  1643. debug("gwlib.http", 0, "HTTP: No clients with requests, quitting.");
  1644.      return NULL;
  1645.     }
  1646.     *client_ip = octstr_duplicate(client->ip);
  1647.     *url = client->url;
  1648.     *headers = client->request->headers;
  1649.     *body = client->request->body;
  1650.     *cgivars = parse_cgivars(client->url);
  1651.     if (client->method != HTTP_METHOD_POST) {
  1652. octstr_destroy(*body);
  1653. *body = NULL;
  1654.     }
  1655.     client->persistent_conn = client_is_persistent(client->request->headers,
  1656.    client->use_version_1_0);
  1657.     
  1658.     client->url = NULL;
  1659.     client->request->headers = NULL;
  1660.     client->request->body = NULL;
  1661.     entity_destroy(client->request);
  1662.     client->request = NULL;
  1663.     return client;
  1664. }
  1665. void http_send_reply(HTTPClient *client, int status, List *headers, 
  1666.                Octstr *body)
  1667. {
  1668.     Octstr *response;
  1669.     long i;
  1670.     int ret;
  1671.     if (client->use_version_1_0)
  1672.      response = octstr_format("HTTP/1.0 %d Foorn", status);
  1673.     else
  1674.      response = octstr_format("HTTP/1.1 %d Foorn", status);
  1675.     /* identify ourselfs */
  1676.     octstr_format_append(response, "Server: " GW_NAME "/%srn", VERSION);
  1677.     octstr_format_append(response, "Content-Length: %ldrn",
  1678.  octstr_len(body));
  1679.     /* 
  1680.      * RFC2616, sec. 8.1.2.1 says that if the server chooses to close the 
  1681.      * connection, it *should* send a coresponding header
  1682.      */
  1683.     if (!client->use_version_1_0 && !client->persistent_conn)
  1684.         octstr_format_append(response, "Connection: closern");
  1685.     for (i = 0; i < list_len(headers); ++i)
  1686.      octstr_format_append(response, "%Srn", list_get(headers, i));
  1687.     octstr_format_append(response, "rn");
  1688.     
  1689.     if (body != NULL && client->method != HTTP_METHOD_HEAD)
  1690.      octstr_append(response, body);
  1691.     ret = conn_write(client->conn, response);
  1692.     octstr_destroy(response);
  1693.     if (ret == 0) { /* Sent already */
  1694. if (!client->persistent_conn)
  1695.     client_destroy(client);
  1696. else {
  1697.     client_reset(client);
  1698.     conn_register(client->conn, server_fdset, receive_request, client);
  1699. }
  1700.     }
  1701.     else if (ret == 1) {      /* Queued for sending, we don't want to block */
  1702. client->state = sending_reply;
  1703. conn_register(client->conn, server_fdset, receive_request, client);
  1704.     }
  1705.     else /* Error */
  1706. client_destroy(client);
  1707. }
  1708. void http_close_client(HTTPClient *client)
  1709. {
  1710.     client_destroy(client);
  1711. }
  1712. static void server_init(void)
  1713. {
  1714.     new_server_sockets = list_create();
  1715.     list_add_producer(new_server_sockets);
  1716.     closed_server_sockets = list_create();
  1717.     server_thread_lock = mutex_create();
  1718. }
  1719. static void destroy_struct_server(void *p)
  1720. {
  1721.     struct server *pp;
  1722.     
  1723.     pp = p;
  1724.     (void) close(pp->fd);
  1725.     gw_free(pp);
  1726. }
  1727. static void destroy_int_pointer(void *p)
  1728. {
  1729.     (void) close(*(int *) p);
  1730.     gw_free(p);
  1731. }
  1732. static void server_shutdown(void)
  1733. {
  1734.     list_remove_producer(new_server_sockets);
  1735.     if (server_thread_id != -1) {
  1736. gwthread_wakeup(server_thread_id);
  1737. gwthread_join_every(server_thread);
  1738.     }
  1739.     mutex_destroy(server_thread_lock);
  1740.     fdset_destroy(server_fdset);
  1741.     list_destroy(new_server_sockets, destroy_struct_server);
  1742.     list_destroy(closed_server_sockets, destroy_int_pointer);
  1743. }
  1744. /***********************************************************************
  1745.  * CGI variable manipulation.
  1746.  */
  1747. void http_destroy_cgiargs(List *args)
  1748. {
  1749.     HTTPCGIVar *v;
  1750.     gwlib_assert_init();
  1751.     if (args == NULL)
  1752.         return ;
  1753.     while ((v = list_extract_first(args)) != NULL) {
  1754.         octstr_destroy(v->name);
  1755.         octstr_destroy(v->value);
  1756.         gw_free(v);
  1757.     }
  1758.     list_destroy(args, NULL);
  1759. }
  1760. Octstr *http_cgi_variable(List *list, char *name)
  1761. {
  1762.     int i;
  1763.     HTTPCGIVar *v;
  1764.     gwlib_assert_init();
  1765.     gw_assert(list != NULL);
  1766.     gw_assert(name != NULL);
  1767.     for (i = 0; i < list_len(list); ++i) {
  1768.         v = list_get(list, i);
  1769.         if (octstr_str_compare(v->name, name) == 0)
  1770.             return v->value;
  1771.     }
  1772.     return NULL;
  1773. }
  1774. /***********************************************************************
  1775.  * Header manipulation.
  1776.  */
  1777. static int header_is_called(Octstr *header, char *name)
  1778. {
  1779.     long colon;
  1780.     colon = octstr_search_char(header, ':', 0);
  1781.     if (colon == -1)
  1782.         return 0;
  1783.     if ((long) strlen(name) != colon)
  1784.         return 0;
  1785.     return strncasecmp(octstr_get_cstr(header), name, colon) == 0;
  1786. }
  1787. List *http_create_empty_headers(void)
  1788. {
  1789.     gwlib_assert_init();
  1790.     return list_create();
  1791. }
  1792. void http_destroy_headers(List *headers)
  1793. {
  1794.     gwlib_assert_init();
  1795.     list_destroy(headers, octstr_destroy_item);
  1796. }
  1797. void http_header_add(List *headers, char *name, char *contents)
  1798. {
  1799.     gwlib_assert_init();
  1800.     gw_assert(headers != NULL);
  1801.     gw_assert(name != NULL);
  1802.     gw_assert(contents != NULL);
  1803.     list_append(headers, octstr_format("%s: %s", name, contents));
  1804. }
  1805. void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
  1806. {
  1807.     Octstr *os;
  1808.     long colon;
  1809.     gwlib_assert_init();
  1810.     gw_assert(i >= 0);
  1811.     gw_assert(name != NULL);
  1812.     gw_assert(value != NULL);
  1813.     os = list_get(headers, i);
  1814.     if (os == NULL)
  1815.         colon = -1;
  1816.     else
  1817.         colon = octstr_search_char(os, ':', 0);
  1818.     if (colon == -1) {
  1819.         error(0, "HTTP: Header does not contain a colon. BAD.");
  1820.         *name = octstr_create("X-Unknown");
  1821.         *value = octstr_duplicate(os);
  1822.     } else {
  1823.         *name = octstr_copy(os, 0, colon);
  1824.         *value = octstr_copy(os, colon + 1, octstr_len(os));
  1825.         octstr_strip_blanks(*value);
  1826.     }
  1827. }
  1828. Octstr *http_header_value(List *headers, Octstr *name)
  1829. {
  1830.     Octstr *value;
  1831.     long i;
  1832.     Octstr *os;
  1833.     long colon;
  1834.     Octstr *current_name;
  1835.     
  1836.     gwlib_assert_init();
  1837.     gw_assert(name);
  1838.     
  1839.     value = NULL;
  1840.     i = 0;
  1841.     while (i < list_len(headers)) {
  1842.         os = list_get(headers, i);
  1843.         if (os == NULL)
  1844.             colon = -1;
  1845.         else
  1846.             colon = octstr_search_char(os, ':', 0);
  1847.         if (colon == -1) {
  1848.             return NULL;      
  1849.         } else {
  1850.             current_name = octstr_copy(os, 0, colon);
  1851.         }
  1852.         if (octstr_case_compare(current_name, name) == 0) {
  1853.             value = octstr_copy(os, colon + 1, octstr_len(os));
  1854.             octstr_strip_blanks(value);
  1855.             return value;
  1856.         }
  1857.         ++i;
  1858.     }
  1859.     
  1860.     return value;
  1861. }
  1862. List *http_header_duplicate(List *headers)
  1863. {
  1864.     List *new;
  1865.     long i;
  1866.     gwlib_assert_init();
  1867.     if (headers == NULL)
  1868.         return NULL;
  1869.     new = http_create_empty_headers();
  1870.     for (i = 0; i < list_len(headers); ++i)
  1871.         list_append(new, octstr_duplicate(list_get(headers, i)));
  1872.     return new;
  1873. }
  1874. void http_header_pack(List *headers)
  1875. {
  1876.     gwlib_assert_init();
  1877.     gw_assert(headers != NULL);
  1878.     /* XXX not implemented yet. */
  1879. }
  1880. void http_append_headers(List *to, List *from)
  1881. {
  1882.     Octstr *header;
  1883.     long i;
  1884.     gwlib_assert_init();
  1885.     gw_assert(to != NULL);
  1886.     gw_assert(from != NULL);
  1887.     for (i = 0; i < list_len(from); ++i) {
  1888.         header = list_get(from, i);
  1889.         list_append(to, octstr_duplicate(header));
  1890.     }
  1891. }
  1892. void http_header_combine(List *old_headers, List *new_headers)
  1893. {
  1894.     long i;
  1895.     Octstr *name;
  1896.     Octstr *value;
  1897.     /*
  1898.      * Avoid doing this scan if old_headers is empty anyway.
  1899.      */
  1900.     if (list_len(old_headers) > 0) {
  1901.         for (i = 0; i < list_len(new_headers); i++) {
  1902.        http_header_get(new_headers, i, &name, &value);
  1903.     http_header_remove_all(old_headers, octstr_get_cstr(name));
  1904.             octstr_destroy(name);
  1905.             octstr_destroy(value);
  1906.         }
  1907.     }
  1908.     http_append_headers(old_headers, new_headers);
  1909. }
  1910. Octstr *http_header_find_first(List *headers, char *name)
  1911. {
  1912.     long i, name_len;
  1913.     Octstr *h, *value;
  1914.     gwlib_assert_init();
  1915.     gw_assert(headers != NULL);
  1916.     gw_assert(name != NULL);
  1917.     name_len = strlen(name);
  1918.     for (i = 0; i < list_len(headers); ++i) {
  1919.         h = list_get(headers, i);
  1920.         if (header_is_called(h, name)) {
  1921.             value = octstr_copy(h, name_len + 1, octstr_len(h));
  1922.     octstr_strip_blanks(value);
  1923.     return value;
  1924. }
  1925.     }
  1926.     return NULL;
  1927. }
  1928. List *http_header_find_all(List *headers, char *name)
  1929. {
  1930.     List *list;
  1931.     long i;
  1932.     Octstr *h;
  1933.     gwlib_assert_init();
  1934.     gw_assert(headers != NULL);
  1935.     gw_assert(name != NULL);
  1936.     list = list_create();
  1937.     for (i = 0; i < list_len(headers); ++i) {
  1938.         h = list_get(headers, i);
  1939.         if (header_is_called(h, name))
  1940.             list_append(list, octstr_duplicate(h));
  1941.     }
  1942.     return list;
  1943. }
  1944. long http_header_remove_all(List *headers, char *name)
  1945. {
  1946.     long i;
  1947.     Octstr *h;
  1948.     long count;
  1949.     gwlib_assert_init();
  1950.     gw_assert(headers != NULL);
  1951.     gw_assert(name != NULL);
  1952.     i = 0;
  1953.     count = 0;
  1954.     while (i < list_len(headers)) {
  1955. h = list_get(headers, i);
  1956. if (header_is_called(h, name)) {
  1957.     list_delete(headers, i, 1);
  1958.     octstr_destroy(h);
  1959.     count++;
  1960. } else
  1961.     i++;
  1962.     }
  1963.     return count;
  1964. }
  1965. void http_remove_hop_headers(List *headers)
  1966. {
  1967.     Octstr *h;
  1968.     List *connection_headers;
  1969.     gwlib_assert_init();
  1970.     gw_assert(headers != NULL);
  1971.     /*
  1972.      * The hop-by-hop headers are a standard list, plus those named
  1973.      * in the Connection header(s).
  1974.      */
  1975.     connection_headers = http_header_find_all(headers, "Connection");
  1976.     while ((h = list_consume(connection_headers))) {
  1977. List *hop_headers;
  1978. Octstr *e;
  1979. octstr_delete(h, 0, strlen("Connection:"));
  1980. hop_headers = http_header_split_value(h);
  1981. octstr_destroy(h);
  1982. while ((e = list_consume(hop_headers))) {
  1983.     http_header_remove_all(headers, octstr_get_cstr(e));
  1984.     octstr_destroy(e);
  1985. }
  1986. list_destroy(hop_headers, NULL);
  1987.     }
  1988.     list_destroy(connection_headers, NULL);
  1989.    
  1990.     http_header_remove_all(headers, "Connection");
  1991.     http_header_remove_all(headers, "Keep-Alive");
  1992.     http_header_remove_all(headers, "Proxy-Authenticate");
  1993.     http_header_remove_all(headers, "Proxy-Authorization");
  1994.     http_header_remove_all(headers, "TE");
  1995.     http_header_remove_all(headers, "Trailers");
  1996.     http_header_remove_all(headers, "Transfer-Encoding");
  1997.     http_header_remove_all(headers, "Upgrade");
  1998. }
  1999. void http_header_mark_transformation(List *headers,
  2000.                          Octstr *new_body, Octstr *new_type)
  2001. {
  2002.     Octstr *new_length = NULL;
  2003.     /* Remove all headers that no longer apply to the new body. */
  2004.     http_header_remove_all(headers, "Content-Length");
  2005.     http_header_remove_all(headers, "Content-MD5");
  2006.     http_header_remove_all(headers, "Content-Type");
  2007.     /* Add headers that we need to describe the new body. */
  2008.     new_length = octstr_format("%ld", octstr_len(new_body));
  2009.     http_header_add(headers, "Content-Length", octstr_get_cstr(new_length));
  2010.     http_header_add(headers, "Content-Type", octstr_get_cstr(new_type));
  2011.     /* Perhaps we should add Warning: 214 "Transformation applied" too? */
  2012.     octstr_destroy(new_length);
  2013. }
  2014. void http_header_get_content_type(List *headers, Octstr **type,
  2015.                                   Octstr **charset)
  2016. {
  2017.     Octstr *h;
  2018.     long semicolon, equals, len;
  2019.     gwlib_assert_init();
  2020.     gw_assert(headers != NULL);
  2021.     gw_assert(type != NULL);
  2022.     gw_assert(charset != NULL);
  2023.     h = http_header_find_first(headers, "Content-Type");
  2024.     if (h == NULL) {
  2025.         *type = octstr_create("application/octet-stream");
  2026.         *charset = octstr_create("");
  2027.     } else {
  2028.         octstr_strip_blanks(h);
  2029.         semicolon = octstr_search_char(h, ';', 0);
  2030.         if (semicolon == -1) {
  2031.             *type = h;
  2032.             *charset = octstr_create("");
  2033.         } else {
  2034.             *charset = octstr_duplicate(h);
  2035.             octstr_delete(*charset, 0, semicolon + 1);
  2036.             octstr_strip_blanks(*charset);
  2037.             equals = octstr_search_char(*charset, '=', 0);
  2038.             if (equals == -1)
  2039.                 octstr_truncate(*charset, 0);
  2040.             else {
  2041.                 octstr_delete(*charset, 0, equals + 1);
  2042.                 if (octstr_get_char(*charset, 0) == '"')
  2043.                     octstr_delete(*charset, 0, 1);
  2044.                 len = octstr_len(*charset);
  2045.                 if (octstr_get_char(*charset, len - 1) == '"')
  2046.                     octstr_truncate(*charset, len - 1);
  2047.             }
  2048.             octstr_truncate(h, semicolon);
  2049.             octstr_strip_blanks(h);
  2050.             *type = h;
  2051.         }
  2052.     }
  2053. }
  2054. static void http_header_add_element(List *list, Octstr *value,
  2055.     long start, long end)
  2056. {
  2057.     Octstr *element;
  2058.     element = octstr_copy(value, start, end - start);
  2059.     octstr_strip_blanks(element);
  2060.     if (octstr_len(element) == 0)
  2061. octstr_destroy(element);
  2062.     else
  2063.      list_append(list, element);
  2064. }
  2065. long http_header_quoted_string_len(Octstr *header, long start)
  2066. {
  2067.     long len;
  2068.     long pos;
  2069.     int c;
  2070.     if (octstr_get_char(header, start) != '"')
  2071. return -1;
  2072.     len = octstr_len(header);
  2073.     for (pos = start + 1; pos < len; pos++) {
  2074. c = octstr_get_char(header, pos);
  2075. if (c == '\')    /* quoted-pair */
  2076.     pos++;
  2077. else if (c == '"')
  2078.     return pos - start + 1;
  2079.     }
  2080.     warning(0, "Header contains unterminated quoted-string:");
  2081.     warning(0, "%s", octstr_get_cstr(header));
  2082.     return len - start;
  2083. }
  2084. List *http_header_split_value(Octstr *value)
  2085. {
  2086.     long start;  /* start of current element */
  2087.     long pos;
  2088.     long len;
  2089.     List *result;
  2090.     int c;
  2091.     /*
  2092.      * According to RFC2616 section 4.2, a field-value is either *TEXT
  2093.      * (the caller is responsible for not feeding us one of those) or
  2094.      * combinations of token, separators, and quoted-string.  We're
  2095.      * looking for commas which are separators, and have to skip
  2096.      * commas in quoted-strings.
  2097.      */
  2098.  
  2099.     result = list_create();
  2100.     len = octstr_len(value);
  2101.     start = 0;
  2102.     for (pos = 0; pos < len; pos++) {
  2103. c = octstr_get_char(value, pos);
  2104. if (c == ',') {
  2105.     http_header_add_element(result, value, start, pos);
  2106.     start = pos + 1;
  2107. } else if (c == '"') {
  2108.             pos += http_header_quoted_string_len(value, pos);
  2109.     pos--; /* compensate for the loop's pos++ */
  2110.         }
  2111.     }
  2112.     http_header_add_element(result, value, start, len);
  2113.     return result;
  2114. }
  2115. List *http_header_split_auth_value(Octstr *value)
  2116. {
  2117.     List *result;
  2118.     Octstr *auth_scheme;
  2119.     Octstr *element;
  2120.     long i;
  2121.     /*
  2122.      * According to RFC2617, both "challenge" and "credentials"
  2123.      * consist of an auth-scheme followed by a list of auth-param.
  2124.      * Since we have to parse a list of challenges or credentials,
  2125.      * we have to look for auth-scheme to signal the start of
  2126.      * a new element.  (We can't just split on commas because
  2127.      * they are also used to separate the auth-params.)
  2128.      *
  2129.      * An auth-scheme is a single token, while an auth-param is
  2130.      * always a key=value pair.  So we can recognize an auth-scheme
  2131.      * as a token that is not followed by a '=' sign.
  2132.      *
  2133.      * Simple approach: First split at all commas, then recombine
  2134.      * the elements that belong to the same challenge or credential.
  2135.      * This is somewhat expensive but saves programmer thinking time.
  2136.      *
  2137.      * Richard Braakman
  2138.      */
  2139.  
  2140.     result = http_header_split_value(value);
  2141.     auth_scheme = list_get(result, 0);
  2142.     i = 1;
  2143.     while (i < list_len(result)) {
  2144. int c;
  2145. long pos;
  2146. element = list_get(result, i);
  2147. /*
  2148.  * If the element starts with: token '='
  2149.  * then it's just an auth_param; append it to the current
  2150.  * auth_scheme.  If it starts with: token token '='
  2151.  * then it's the start of a new auth scheme.
  2152.  * 
  2153.  * To make the scan easier, we consider anything other
  2154.  * than whitespace or '=' to be part of a token.
  2155.  */
  2156. /* Skip first token */
  2157. for (pos = 0; pos < octstr_len(element); pos++) {
  2158.     c = octstr_get_char(element, pos);
  2159.     if (isspace(c) || c == '=')
  2160. break;
  2161. }
  2162. /* Skip whitespace, if any */
  2163. while (isspace(octstr_get_char(element, pos)))
  2164.     pos++;
  2165. if (octstr_get_char(element, pos) == '=') {
  2166. octstr_append_char(auth_scheme, ';');
  2167. octstr_append(auth_scheme, element);
  2168. list_delete(result, i, 1);
  2169. octstr_destroy(element);
  2170. } else {
  2171. unsigned char semicolon = ';';
  2172. octstr_insert_data(element, pos, &semicolon, 1);
  2173. auth_scheme = element;
  2174. i++;
  2175. }
  2176.     }
  2177.     return result;
  2178. }
  2179. void http_header_dump(List *headers)
  2180. {
  2181.     long i;
  2182.     gwlib_assert_init();
  2183.     debug("gwlib.http", 0, "Dumping HTTP headers:");
  2184.     for (i = 0; headers != NULL && i < list_len(headers); ++i)
  2185.         octstr_dump(list_get(headers, i), 1);
  2186.     debug("gwlib.http", 0, "End of dump.");
  2187. }
  2188. void http_cgivar_dump(List *cgiargs)
  2189. {
  2190.     long i;
  2191.     Octstr *arg;
  2192.     gwlib_assert_init();
  2193.     debug("gwlib.http", 0, "Dumping %ld cgi variables:", list_len(cgiargs));
  2194.     for (i = 0; cgiargs != NULL && i < list_len(cgiargs); ++i) {
  2195.          if (octstr_len(arg = list_get(cgiargs, i)) != 0)
  2196.              octstr_dump(arg, 0);
  2197.          else
  2198.      debug("gwlib.http", 0, "Got an empty cgi arg");
  2199.     }
  2200.     debug("gwlib.http", 0, "End of dump.");
  2201. }
  2202. /* XXX this needs to go away */
  2203. static char *istrdup(char *orig)
  2204. {
  2205.     int i, len = strlen(orig);
  2206.     char *result = gw_malloc(len + 1);
  2207.     for (i = 0; i < len; i++)
  2208.         result[i] = toupper(orig[i]);
  2209.     result[i] = 0;
  2210.     return result;
  2211. }
  2212. static int http_something_accepted(List *headers, char *header_name,
  2213.                                    char *what)
  2214. {
  2215.     int found;
  2216.     long i;
  2217.     List *accepts;
  2218.     char *iwhat;
  2219.     gwlib_assert_init();
  2220.     gw_assert(headers != NULL);
  2221.     gw_assert(what != NULL);
  2222.     iwhat = istrdup(what);
  2223.     accepts = http_header_find_all(headers, header_name);
  2224.     found = 0;
  2225.     for (i = 0; !found && i < list_len(accepts); ++i) {
  2226.         char *header_value = istrdup(octstr_get_cstr(list_get(accepts, i)));
  2227.         if (strstr(header_value, iwhat) != NULL)
  2228.             found = 1;
  2229.         gw_free(header_value);
  2230.     }
  2231.     gw_free(iwhat);
  2232.     http_destroy_headers(accepts);
  2233.     return found;
  2234. }
  2235. int http_type_accepted(List *headers, char *type)
  2236. {
  2237.     return http_something_accepted(headers, "Accept", type);
  2238. }
  2239. int http_charset_accepted(List *headers, char *charset)
  2240. {
  2241.     return http_something_accepted(headers, "Accept-Charset", charset);
  2242. }
  2243. void http_add_basic_auth(List *headers, Octstr *username, Octstr *password)
  2244. {
  2245.     Octstr *os;
  2246.     
  2247.     if (password != NULL)
  2248.       os = octstr_format("%S:%S", username, password);
  2249.     else
  2250.       os = octstr_format("%S", username);
  2251.     octstr_binary_to_base64(os);
  2252.     octstr_strip_blanks(os);
  2253.     octstr_insert(os, octstr_imm("Basic "), 0);
  2254.     http_header_add(headers, "Authorization", octstr_get_cstr(os));
  2255.     octstr_destroy(os);
  2256. }
  2257. /***********************************************************************
  2258.  * Module initialization and shutdown.
  2259.  */
  2260. void http_init(void)
  2261. {
  2262.     gw_assert(run_status == limbo);
  2263. #ifdef HAVE_LIBSSL
  2264.     conn_init_ssl();
  2265. #endif /* HAVE_LIBSSL */
  2266.     proxy_init();
  2267.     client_init();
  2268.     conn_pool_init();
  2269.     server_init();
  2270. #ifdef HAVE_LIBSSL
  2271.     server_ssl_init();
  2272. #endif /* HAVE_LIBSSL */
  2273.     port_init();
  2274.     
  2275.     run_status = running;
  2276. }
  2277. void http_shutdown(void)
  2278. {
  2279.     gwlib_assert_init();
  2280.     gw_assert(run_status == running);
  2281.     run_status = terminating;
  2282.     conn_pool_shutdown();
  2283.     port_shutdown();
  2284.     client_shutdown();
  2285.     server_shutdown();
  2286.     proxy_shutdown();
  2287. #ifdef HAVE_LIBSSL
  2288.     conn_shutdown_ssl();
  2289.     server_shutdown_ssl();
  2290. #endif /* HAVE_LIBSSL */
  2291.     run_status = limbo;
  2292. }
  2293. /*
  2294.  * This function relies on the HTTP_STATUS_* enum values being
  2295.  * chosen to fit this.
  2296.  */
  2297. int http_status_class(int code)
  2298. {
  2299.     int sclass;
  2300.     if (code < 100 || code >= 600)
  2301.         sclass = HTTP_STATUS_UNKNOWN;
  2302.     else
  2303.         sclass = code - (code % 100);
  2304.     return sclass;
  2305. }
  2306. int http_name2method(Octstr *method)
  2307. {
  2308.     gw_assert(method != NULL);
  2309.     if (octstr_str_compare(method, "GET") == 0) {
  2310.         return HTTP_METHOD_GET;
  2311.     } 
  2312.     else if (octstr_str_compare(method, "POST") == 0) {
  2313.         return HTTP_METHOD_POST;
  2314.     } 
  2315.     else if (octstr_str_compare(method, "HEAD") == 0) {
  2316.         return HTTP_METHOD_HEAD;
  2317.     } 
  2318.     return -1;
  2319. }
  2320. char *http_method2name(int method)
  2321. {
  2322.     gw_assert(method > 0 && method <= 3);
  2323.     return http_methods[method-1];
  2324. }