Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
http.c File Reference
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "gwlib.h"
#include "gwlib/regex.h"

Go to the source code of this file.

Data Structures

struct  HTTPEntity
 
struct  HTTPServer
 
struct  HTTPClient
 
struct  port
 

Macros

#define DUMP_RESPONSE   1
 
#define HTTP_SERVER_TIMEOUT   60
 
#define HTTP_SERVER_MAX_ACTIVE_CONNECTIONS   500
 
#define HTTP_MAX_FOLLOW   5
 
#define MAX_HEADER_LENGTH   256
 

Enumerations

enum  { HTTP_PORT = 80, HTTPS_PORT = 443 }
 
enum  { limbo, running, terminating }
 
enum  body_expectation { expect_no_body, expect_body_if_indicated, expect_body }
 
enum  entity_state {
  reading_headers, reading_chunked_body_len, reading_chunked_body_data, reading_chunked_body_crlf,
  reading_chunked_body_trailer, reading_body_until_eof, reading_body_with_length, body_error,
  entity_done
}
 

Functions

static int read_some_headers (Connection *conn, List *headers)
 
static int parse_http_version (Octstr *version)
 
static void proxy_add_authentication (List *headers)
 
static void proxy_init (void)
 
static void proxy_shutdown (void)
 
static int proxy_used_for_host (Octstr *host, Octstr *url)
 
void http_use_proxy (Octstr *hostname, int port, int ssl, List *exceptions, Octstr *username, Octstr *password, Octstr *exceptions_regex)
 
void http_close_proxy (void)
 
static void deduce_body_state (HTTPEntity *ent)
 
static HTTPEntityentity_create (enum body_expectation exp)
 
static void entity_destroy (HTTPEntity *ent)
 
static void read_chunked_body_len (HTTPEntity *ent, Connection *conn)
 
static void read_chunked_body_data (HTTPEntity *ent, Connection *conn)
 
static void read_chunked_body_crlf (HTTPEntity *ent, Connection *conn)
 
static void read_chunked_body_trailer (HTTPEntity *ent, Connection *conn)
 
static void read_body_until_eof (HTTPEntity *ent, Connection *conn)
 
static void read_body_with_length (HTTPEntity *ent, Connection *conn)
 
static int entity_read (HTTPEntity *ent, Connection *conn)
 
static int send_request (HTTPServer *trans)
 
static Octstrbuild_response (List *headers, Octstr *body)
 
static int header_is_called (Octstr *header, char *name)
 
static HTTPServerserver_create (HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow_remaining, Octstr *certkeyfile)
 
static void server_destroy (void *p)
 
static void conn_pool_item_destroy (void *item)
 
static void conn_pool_init (void)
 
static void conn_pool_shutdown (void)
 
static Octstrconn_pool_key (Octstr *host, int port, int ssl, Octstr *certfile, Octstr *our_host)
 
static Connectionconn_pool_get (Octstr *host, int port, int ssl, Octstr *certkeyfile, Octstr *our_host)
 
HTTPCallerhttp_caller_create (void)
 
void http_caller_destroy (HTTPCaller *caller)
 
void http_caller_signal_shutdown (HTTPCaller *caller)
 
static Octstrget_redirection_location (HTTPServer *trans)
 
static void recover_absolute_uri (HTTPServer *trans, Octstr *loc)
 
static int client_read_status (HTTPServer *trans)
 
static int response_expectation (int method, int status)
 
static void handle_transaction (Connection *conn, void *data)
 
static Octstrbuild_request (char *method_name, Octstr *path_or_url, Octstr *host, long port, int ssl, List *headers, Octstr *request_body)
 
HTTPURLParsehttp_urlparse_create (void)
 
void http_urlparse_destroy (HTTPURLParse *p)
 
void parse_dump (HTTPURLParse *p)
 
HTTPURLParseparse_url (Octstr *url)
 
static void parse2trans (HTTPURLParse *p, HTTPServer *t)
 
static Connectionget_connection (HTTPServer *trans)
 
static void write_request_thread (void *arg)
 
static void start_client_threads (void)
 
void http_set_interface (const Octstr *our_host)
 
void http_set_client_timeout (long timeout)
 
void http_start_request (HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
 
void * http_receive_result_real (HTTPCaller *caller, int *status, Octstr **final_url, List **headers, Octstr **body, int blocking)
 
int http_get_real (int method, Octstr *url, List *request_headers, Octstr **final_url, List **reply_headers, Octstr **reply_body)
 
static void client_init (void)
 
static void client_shutdown (void)
 
static HTTPClientclient_create (int port, Connection *conn, Octstr *ip)
 
static void client_destroy (void *client)
 
static void client_reset (HTTPClient *p)
 
static int client_is_persistent (List *headers, int use_version_1_0)
 
static int port_match (void *client, void *port)
 
static void port_init (void)
 
static void port_shutdown (void)
 
static Octstrport_key (int port)
 
static struct portport_add (int port)
 
static void port_remove (int port)
 
static void port_put_request (HTTPClient *client)
 
static HTTPClientport_get_request (int port)
 
static void port_set_timeout (int port, long timeout)
 
static FDSetport_get_fdset (int port)
 
static int parse_request_line (int *method, Octstr **url, int *use_version_1_0, Octstr *line)
 
static void receive_request (Connection *conn, void *data)
 
static void server_thread (void *dummy)
 
static void start_server_thread (void)
 
void http_set_server_timeout (int port, long timeout)
 
int http_open_port_if (int port, int ssl, Octstr *interface)
 
int http_open_port (int port, int ssl)
 
void http_close_port (int port)
 
void http_close_all_ports (void)
 
static Listparse_cgivars (Octstr *url)
 
HTTPClienthttp_accept_request (int port, Octstr **client_ip, Octstr **url, List **headers, Octstr **body, List **cgivars)
 
static const char * http_reason_phrase (int status)
 
void http_send_reply (HTTPClient *client, int status, List *headers, Octstr *body)
 
void http_close_client (HTTPClient *client)
 
int http_method (HTTPClient *client)
 
Octstrhttp_request_url (HTTPClient *client)
 
static void server_init (void)
 
static void destroy_struct_server (void *p)
 
static void destroy_int_pointer (void *p)
 
static void server_shutdown (void)
 
void http_destroy_cgiargs (List *args)
 
Octstrhttp_cgi_variable (List *list, char *name)
 
Listhttp_create_empty_headers (void)
 
void http_destroy_headers (List *headers)
 
void http_header_add (List *headers, char *name, char *contents)
 
void http_header_get (List *headers, long i, Octstr **name, Octstr **value)
 
Octstrhttp_header_value (List *headers, Octstr *name)
 
Listhttp_header_duplicate (List *headers)
 
void http_header_pack (List *headers)
 
void http_append_headers (List *to, List *from)
 
void http_header_combine (List *old_headers, List *new_headers)
 
Octstrhttp_header_find_first_real (List *headers, char *name, const char *file, long line, const char *func)
 
Listhttp_header_find_all (List *headers, char *name)
 
long http_header_remove_all (List *headers, char *name)
 
void http_remove_hop_headers (List *headers)
 
void http_header_mark_transformation (List *headers, Octstr *new_body, Octstr *new_type)
 
void http_header_get_content_type (List *headers, Octstr **type, Octstr **charset)
 
static void http_header_add_element (List *list, Octstr *value, long start, long end)
 
long http_header_quoted_string_len (Octstr *header, long start)
 
Listhttp_header_split_value (Octstr *value)
 
Listhttp_header_split_auth_value (Octstr *value)
 
void http_header_dump (List *headers)
 
void http_cgivar_dump (List *cgiargs)
 
void http_cgivar_dump_into (List *cgiargs, Octstr *os)
 
static int http_something_accepted (List *headers, char *header_name, char *what)
 
int http_type_accepted (List *headers, char *type)
 
int http_charset_accepted (List *headers, char *charset)
 
void http_add_basic_auth (List *headers, Octstr *username, Octstr *password)
 
Octstrhttp_get_header_parameter (Octstr *value, Octstr *parameter)
 
void http_init (void)
 
void http_shutdown (void)
 
int http_status_class (int code)
 
int http_name2method (Octstr *method)
 
char * http_method2name (int method)
 

Variables

static int http_client_timeout = 240
 
static enum { ... }  run_status = limbo
 
static Octstrhttp_interface = NULL
 
static Mutexproxy_mutex = NULL
 
static Octstrproxy_hostname = NULL
 
static int proxy_port = 0
 
static int proxy_ssl = 0
 
static Octstrproxy_username = NULL
 
static Octstrproxy_password = NULL
 
static Listproxy_exceptions = NULL
 
static regex_t * proxy_exceptions_regex = NULL
 
static Listpending_requests = NULL
 
static Mutexclient_thread_lock = NULL
 
static volatile sig_atomic_t client_threads_are_running = 0
 
static FDSetclient_fdset = NULL
 
static char * http_methods []
 
static Dictconn_pool
 
static Mutexconn_pool_lock
 
static Mutexserver_thread_lock = NULL
 
static volatile sig_atomic_t server_thread_is_running = 0
 
static long server_thread_id = -1
 
static Listnew_server_sockets = NULL
 
static Listclosed_server_sockets = NULL
 
static int keep_servers_open = 0
 
static Listactive_connections
 
static Mutexport_mutex = NULL
 
static Dictport_collection = NULL
 

Macro Definition Documentation

#define DUMP_RESPONSE   1

Definition at line 88 of file http.c.

#define HTTP_MAX_FOLLOW   5

Definition at line 653 of file http.c.

Referenced by http_start_request().

#define HTTP_SERVER_MAX_ACTIVE_CONNECTIONS   500

Definition at line 96 of file http.c.

Referenced by client_destroy(), and server_thread().

#define HTTP_SERVER_TIMEOUT   60

Definition at line 94 of file http.c.

Referenced by port_add().

#define MAX_HEADER_LENGTH   256

Definition at line 2964 of file http.c.

Referenced by http_header_pack().

Enumeration Type Documentation

anonymous enum
Enumerator
HTTP_PORT 
HTTPS_PORT 

Definition at line 106 of file http.c.

106  { HTTP_PORT = 80,
107  HTTPS_PORT = 443 };
anonymous enum
Enumerator
limbo 
running 
terminating 

Definition at line 113 of file http.c.

113  {
114  limbo,
115  running,
116  terminating
117 } run_status = limbo;
Definition: http.c:115
static enum @59 run_status
Definition: http.c:114
Enumerator
expect_no_body 
expect_body_if_indicated 
expect_body 

Definition at line 331 of file http.c.

331  {
332  /*
333  * Message must not have a body, even if the headers indicate one.
334  * (i.e. response to HEAD method).
335  */
337  /*
338  * Message will have a body if Content-Length or Transfer-Encoding
339  * headers are present (i.e. most request methods).
340  */
342  /*
343  * Message will have a body, possibly zero-length.
344  * (i.e. 200 OK responses to a GET method.)
345  */
347 };
Enumerator
reading_headers 
reading_chunked_body_len 
reading_chunked_body_data 
reading_chunked_body_crlf 
reading_chunked_body_trailer 
reading_body_until_eof 
reading_body_with_length 
body_error 
entity_done 

Definition at line 349 of file http.c.

Function Documentation

static Octstr* build_request ( char *  method_name,
Octstr path_or_url,
Octstr host,
long  port,
int  ssl,
List headers,
Octstr request_body 
)
static

Definition at line 1235 of file http.c.

References gwlist_get(), gwlist_len(), header_is_called(), HTTP_PORT, HTTPS_PORT, octstr_append(), octstr_format(), octstr_format_append(), and octstr_imm().

Referenced by send_request().

1238 {
1239  /* XXX headers missing */
1240  Octstr *request;
1241  int i, host_found = 0;
1242 
1243  request = octstr_format("%s %S HTTP/1.1\r\n",
1244  method_name, path_or_url);
1245 
1246 #ifdef USE_KEEPALIVE
1247  octstr_append(request, octstr_imm("Connection: keep-alive\r\n"));
1248 #endif
1249 
1250  for (i = 0; headers != NULL && i < gwlist_len(headers); ++i) {
1251  /* check if Host already set in the headers */
1252  if (header_is_called(gwlist_get(headers, i), "Host"))
1253  host_found = 1;
1254  octstr_append(request, gwlist_get(headers, i));
1255  octstr_append(request, octstr_imm("\r\n"));
1256  }
1257 
1258  if (!host_found) {
1259  octstr_format_append(request, "Host: %S", host);
1260  /*
1261  * In accordance with HTT/1.1 [RFC 2616], section 14.23 "Host"
1262  * we shall ONLY add the port number if it is not one of the
1263  * officially assigned port numbers. This means we need to obey
1264  * port 80 for non-SSL connections and port 443 for SSL-enabled.
1265  */
1266  if ((port != HTTP_PORT && !ssl) || (port != HTTPS_PORT && ssl))
1267  octstr_format_append(request, ":%ld", port);
1268  octstr_append(request, octstr_imm("\r\n"));
1269  }
1270 
1271  octstr_append(request, octstr_imm("\r\n"));
1272 
1273  if (request_body != NULL)
1274  octstr_append(request, request_body);
1275 
1276  return request;
1277 }
Definition: http.c:1998
static Octstr * method_name
Definition: test_http.c:86
int ssl
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
Definition: octstr.c:118
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
static int header_is_called(Octstr *header, char *name)
Definition: http.c:2836
static Octstr * build_response ( List headers,
Octstr body 
)
static

Definition at line 1284 of file http.c.

References gwlist_get(), gwlist_len(), octstr_append(), octstr_create, octstr_imm(), and response().

Referenced by handle_transaction().

1285 {
1286  Octstr *response;
1287  int i;
1288 
1289  response = octstr_create("");
1290 
1291  for (i = 0; headers != NULL && i < gwlist_len(headers); ++i) {
1292  octstr_append(response, gwlist_get(headers, i));
1293  octstr_append(response, octstr_imm("\r\n"));
1294  }
1295  octstr_append(response, octstr_imm("\r\n"));
1296 
1297  if (body != NULL)
1298  octstr_append(response, body);
1299 
1300  return response;
1301 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
static int response(List *push_headers, Octstr **username, Octstr **password)
static HTTPClient* client_create ( int  port,
Connection conn,
Octstr ip 
)
static

Definition at line 1887 of file http.c.

References HTTPClient::conn, HTTPClient::conn_time, debug(), gwlist_produce(), HTTPClient::ip, octstr_get_cstr, HTTPClient::persistent_conn, port, HTTPClient::port, HTTPClient::request, HTTPClient::state, HTTPClient::url, and HTTPClient::use_version_1_0.

Referenced by server_thread().

1888 {
1889  HTTPClient *p;
1890 
1891 #ifdef HAVE_LIBSSL
1892  if (conn_get_ssl(conn))
1893  debug("gwlib.http", 0, "HTTP: Creating SSL-enabled HTTPClient for `%s', using cipher '%s'.",
1894  octstr_get_cstr(ip), SSL_get_cipher_version(conn_get_ssl(conn)));
1895  else
1896 #endif
1897  debug("gwlib.http", 0, "HTTP: Creating HTTPClient for `%s'.", octstr_get_cstr(ip));
1898  p = gw_malloc(sizeof(*p));
1899  p->port = port;
1900  p->conn = conn;
1901  p->ip = ip;
1902  p->state = reading_request_line;
1903  p->url = NULL;
1904  p->use_version_1_0 = 0;
1905  p->persistent_conn = 1;
1906  p->conn_time = time(NULL);
1907  p->request = NULL;
1908  debug("gwlib.http", 0, "HTTP: Created HTTPClient area %p.", p);
1909 
1910  /* add this client to active_connections */
1912 
1913  return p;
1914 }
static List * active_connections
Definition: http.c:1884
void gwlist_produce(List *list, void *item)
Definition: list.c:411
Connection * conn
Definition: http.c:1857
int use_version_1_0
Definition: http.c:1867
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * ip
Definition: http.c:1858
static int port
Definition: fakesmsc.c:120
Octstr * url
Definition: http.c:1866
int persistent_conn
Definition: http.c:1868
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int port
Definition: http.c:1856
enum HTTPClient::@61 state
unsigned long conn_time
Definition: http.c:1869
HTTPEntity * request
Definition: http.c:1870
static void client_destroy ( void *  client)
static

Definition at line 1917 of file http.c.

References client(), HTTPClient::conn, conn_destroy(), debug(), entity_destroy(), gwlist_delete_equal(), gwlist_len(), gwlist_lock(), gwlist_unlock(), gwthread_wakeup(), HTTP_SERVER_MAX_ACTIVE_CONNECTIONS, HTTPClient::ip, octstr_destroy(), octstr_get_cstr, panic, HTTPClient::request, and HTTPClient::url.

Referenced by http_accept_request(), http_close_client(), http_send_reply(), port_put_request(), port_remove(), port_shutdown(), and receive_request().

1918 {
1919  HTTPClient *p;
1920  long a_len;
1921 
1922  if (client == NULL)
1923  return;
1924 
1925  p = client;
1926 
1927  /* drop this client from active_connections list */
1930  panic(0, "HTTP: Race condition in client_destroy(%p) detected!", client);
1931 
1932  /* signal server thread that client slot is free */
1933  a_len = gwlist_len(active_connections);
1935 
1936  if (a_len >= HTTP_SERVER_MAX_ACTIVE_CONNECTIONS - 1)
1938 
1939  debug("gwlib.http", 0, "HTTP: Destroying HTTPClient area %p.", p);
1940  gw_assert_allocated(p, __FILE__, __LINE__, __func__);
1941  debug("gwlib.http", 0, "HTTP: Destroying HTTPClient for `%s'.",
1942  octstr_get_cstr(p->ip));
1943 
1944  conn_destroy(p->conn);
1945  octstr_destroy(p->ip);
1946  octstr_destroy(p->url);
1947  entity_destroy(p->request);
1948  gw_free(p);
1949 }
static List * active_connections
Definition: http.c:1884
static long server_thread_id
Definition: http.c:1879
long gwlist_len(List *list)
Definition: list.c:166
Connection * conn
Definition: http.c:1857
static void client(int port)
Definition: test_udp.c:77
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * ip
Definition: http.c:1858
void gwlist_unlock(List *list)
Definition: list.c:354
void conn_destroy(Connection *conn)
Definition: conn.c:619
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
Octstr * url
Definition: http.c:1866
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define HTTP_SERVER_MAX_ACTIVE_CONNECTIONS
Definition: http.c:96
void gwlist_lock(List *list)
Definition: list.c:347
static void entity_destroy(HTTPEntity *ent)
Definition: http.c:445
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define panic
Definition: log.h:87
void gwthread_wakeup(long thread)
HTTPEntity * request
Definition: http.c:1870
static void client_init ( void  )
static

Definition at line 1825 of file http.c.

References gwlist_add_producer(), gwlist_create, and mutex_create.

Referenced by http_init().

1826 {
1830 }
static List * pending_requests
Definition: http.c:633
#define mutex_create()
Definition: thread.h:96
static Mutex * client_thread_lock
Definition: http.c:639
#define gwlist_create()
Definition: list.h:136
void gwlist_add_producer(List *list)
Definition: list.c:383
static int client_is_persistent ( List headers,
int  use_version_1_0 
)
static

Definition at line 1967 of file http.c.

References gwlist_destroy(), gwlist_search(), http_header_find_first, octstr_destroy(), octstr_destroy_item(), octstr_imm(), octstr_item_case_match(), and octstr_split().

Referenced by http_accept_request().

1968 {
1969  Octstr *h = http_header_find_first(headers, "Connection");
1970 
1971  if (h == NULL) {
1972  return !use_version_1_0;
1973  } else {
1974  List *values = octstr_split(h, octstr_imm(","));
1975  octstr_destroy(h);
1976  if (!use_version_1_0) {
1977  if (gwlist_search(values, octstr_imm("keep-alive"), octstr_item_case_match) != NULL) {
1979  return 1;
1980  } else {
1982  return 0;
1983  }
1984  } else if (gwlist_search(values, octstr_imm("close"), octstr_item_case_match) != NULL) {
1986  return 0;
1987  }
1989  }
1990 
1991  return 1;
1992 }
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
#define http_header_find_first(headers, name)
Definition: http.h:592
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void octstr_destroy_item(void *os)
Definition: octstr.c:334
int octstr_item_case_match(void *item, void *pattern)
Definition: octstr.c:1665
Definition: octstr.c:118
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static int client_read_status ( HTTPServer trans)
static

Definition at line 982 of file http.c.

References HTTPServer::conn, conn_eof(), conn_error(), conn_read_line(), debug(), error(), octstr_copy, octstr_delete(), octstr_destroy(), octstr_get_cstr, octstr_parse_long(), octstr_search_char(), octstr_truncate(), parse_http_version(), HTTPServer::persistent, and HTTPServer::status.

Referenced by handle_transaction().

983 {
984  Octstr *line, *version;
985  long space;
986  int ret;
987 
988  line = conn_read_line(trans->conn);
989  if (line == NULL) {
990  if (conn_eof(trans->conn) || conn_error(trans->conn))
991  return -1;
992  return 1;
993  }
994 
995  debug("gwlib.http", 0, "HTTP: Status line: <%s>", octstr_get_cstr(line));
996 
997  space = octstr_search_char(line, ' ', 0);
998  if (space == -1)
999  goto error;
1000 
1001  version = octstr_copy(line, 0, space);
1002  ret = parse_http_version(version);
1003  octstr_destroy(version);
1004  if (ret == -1)
1005  goto error;
1006  trans->persistent = ret;
1007 
1008  octstr_delete(line, 0, space + 1);
1009  space = octstr_search_char(line, ' ', 0);
1010  if (space == -1)
1011  goto error;
1012  octstr_truncate(line, space);
1013 
1014  if (octstr_parse_long(&trans->status, line, 0, 10) == -1)
1015  goto error;
1016 
1017  octstr_destroy(line);
1018  return 0;
1019 
1020 error:
1021  error(0, "HTTP: Malformed status line from HTTP server: <%s>",
1022  octstr_get_cstr(line));
1023  octstr_destroy(line);
1024  return -1;
1025 }
Octstr * conn_read_line(Connection *conn)
Definition: conn.c:1126
void error(int err, const char *fmt,...)
Definition: log.c:612
long status
Definition: http.c:682
Connection * conn
Definition: http.c:685
int conn_eof(Connection *conn)
Definition: conn.c:697
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static int parse_http_version(Octstr *version)
Definition: http.c:168
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int persistent
Definition: http.c:683
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:747
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1325
int conn_error(Connection *conn)
Definition: conn.c:708
static void client_reset ( HTTPClient p)
static

Definition at line 1952 of file http.c.

References HTTPClient::conn_time, debug(), gw_assert(), HTTPClient::ip, octstr_get_cstr, HTTPClient::request, and HTTPClient::state.

Referenced by http_send_reply(), and receive_request().

1953 {
1954  debug("gwlib.http", 0, "HTTP: Resetting HTTPClient for `%s'.",
1955  octstr_get_cstr(p->ip));
1956  p->state = reading_request_line;
1957  p->conn_time = time(NULL);
1958  gw_assert(p->request == NULL);
1959 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * ip
Definition: http.c:1858
gw_assert(wtls_machine->packet_to_send!=NULL)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
enum HTTPClient::@61 state
unsigned long conn_time
Definition: http.c:1869
HTTPEntity * request
Definition: http.c:1870
static void client_shutdown ( void  )
static

Definition at line 1833 of file http.c.

References client_threads_are_running, fdset_destroy(), gwlist_destroy(), gwlist_remove_producer(), gwthread_join_every(), mutex_destroy(), octstr_destroy(), server_destroy(), and write_request_thread().

Referenced by http_shutdown().

1834 {
1841  client_fdset = NULL;
1843  http_interface = NULL;
1844 }
static List * pending_requests
Definition: http.c:633
static void server_destroy(void *p)
Definition: http.c:730
static Octstr * http_interface
Definition: http.c:123
static volatile sig_atomic_t client_threads_are_running
Definition: http.c:640
void gwthread_join_every(gwthread_func_t *func)
static Mutex * client_thread_lock
Definition: http.c:639
void gwlist_remove_producer(List *list)
Definition: list.c:401
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
void fdset_destroy(FDSet *set)
Definition: fdset.c:398
static void write_request_thread(void *arg)
Definition: http.c:1666
static FDSet * client_fdset
Definition: http.c:647
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static Connection* conn_pool_get ( Octstr host,
int  port,
int  ssl,
Octstr certkeyfile,
Octstr our_host 
)
static

Definition at line 783 of file http.c.

References conn_destroy(), conn_eof(), conn_error(), conn_get_id(), conn_open_tcp_nb(), conn_pool_key(), conn_unregister(), conn_wait(), debug(), dict_get(), gwlist_extract_first(), mutex_lock, mutex_unlock, octstr_destroy(), and octstr_get_cstr.

Referenced by get_connection().

785 {
786  Octstr *key;
787  List *list = NULL;
788  Connection *conn = NULL;
789  int retry;
790 
791  do {
792  retry = 0;
793  key = conn_pool_key(host, port, ssl, certkeyfile, our_host);
795  list = dict_get(conn_pool, key);
796  if (list != NULL)
797  conn = gwlist_extract_first(list);
799  /*
800  * Note: we don't hold conn_pool_lock when we check/destroy/unregister
801  * connection because otherwise we can deadlock! And it's even better
802  * not to delay other threads while we check connection.
803  */
804  if (conn != NULL) {
805 #ifdef USE_KEEPALIVE
806  /* unregister our server disconnect callback */
807  conn_unregister(conn);
808 #endif
809  /*
810  * Check whether the server has closed the connection while
811  * it has been in the pool.
812  */
813  conn_wait(conn, 0);
814  if (conn_eof(conn) || conn_error(conn)) {
815  debug("gwlib.http", 0, "HTTP:conn_pool_get: Server closed connection, destroying it <%s><%p><fd:%d>.",
816  octstr_get_cstr(key), conn, conn_get_id(conn));
817  conn_destroy(conn);
818  retry = 1;
819  conn = NULL;
820  }
821  }
822  octstr_destroy(key);
823  } while(retry == 1);
824 
825  if (conn == NULL) {
826 #ifdef HAVE_LIBSSL
827  if (ssl)
828  conn = conn_open_ssl_nb(host, port, certkeyfile, our_host);
829  else
830 #endif /* HAVE_LIBSSL */
831  conn = conn_open_tcp_nb(host, port, our_host);
832  debug("gwlib.http", 0, "HTTP: Opening connection to `%s:%d' (fd=%d).",
833  octstr_get_cstr(host), port, conn_get_id(conn));
834  } else {
835  debug("gwlib.http", 0, "HTTP: Reusing connection to `%s:%d' (fd=%d).",
836  octstr_get_cstr(host), port, conn_get_id(conn));
837  }
838 
839  return conn;
840 }
Definition: http.c:1998
int ssl
#define mutex_unlock(m)
Definition: thread.h:136
Connection * conn_open_tcp_nb(Octstr *host, int port, Octstr *our_host)
Definition: conn.c:493
int conn_eof(Connection *conn)
Definition: conn.c:697
static Dict * conn_pool
Definition: http.c:753
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void * gwlist_extract_first(List *list)
Definition: list.c:305
int conn_get_id(Connection *conn)
Definition: conn.c:1478
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void conn_destroy(Connection *conn)
Definition: conn.c:619
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void conn_unregister(Connection *conn)
Definition: conn.c:850
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:896
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static Octstr * conn_pool_key(Octstr *host, int port, int ssl, Octstr *certfile, Octstr *our_host)
Definition: http.c:776
int conn_error(Connection *conn)
Definition: conn.c:708
#define mutex_lock(m)
Definition: thread.h:130
static Mutex * conn_pool_lock
Definition: http.c:754
Definition: list.c:102
static void conn_pool_init ( void  )
static

Definition at line 762 of file http.c.

References conn_pool_item_destroy(), dict_create(), and mutex_create.

Referenced by http_init().

763 {
766 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
#define mutex_create()
Definition: thread.h:96
static Dict * conn_pool
Definition: http.c:753
static void conn_pool_item_destroy(void *item)
Definition: http.c:757
static Mutex * conn_pool_lock
Definition: http.c:754
static void conn_pool_item_destroy ( void *  item)
static

Definition at line 757 of file http.c.

References conn_destroy(), and gwlist_destroy().

Referenced by conn_pool_init().

758 {
759  gwlist_destroy(item, (void(*)(void*))conn_destroy);
760 }
void conn_destroy(Connection *conn)
Definition: conn.c:619
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static Octstr* conn_pool_key ( Octstr host,
int  port,
int  ssl,
Octstr certfile,
Octstr our_host 
)
inlinestatic

Definition at line 776 of file http.c.

References octstr_format(), and octstr_imm().

Referenced by conn_pool_get().

777 {
778  return octstr_format("%S:%d:%d:%S:%S", host, port, ssl?1:0, certfile?certfile:octstr_imm(""),
779  our_host?our_host:octstr_imm(""));
780 }
Definition: http.c:1998
int ssl
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
static void conn_pool_shutdown ( void  )
static

Definition at line 769 of file http.c.

References dict_destroy(), and mutex_destroy().

Referenced by http_shutdown().

770 {
773 }
static Dict * conn_pool
Definition: http.c:753
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
void dict_destroy(Dict *dict)
Definition: dict.c:215
static Mutex * conn_pool_lock
Definition: http.c:754
static void deduce_body_state ( HTTPEntity ent)
static

Definition at line 375 of file http.c.

References body_error, entity_done, error(), expect_body, expect_no_body, HTTPEntity::expect_state, HTTPEntity::expected_body_len, HTTPEntity::headers, http_header_find_first, octstr_destroy(), octstr_get_cstr, octstr_parse_long(), octstr_str_compare(), octstr_strip_blanks(), reading_body_until_eof, reading_body_with_length, reading_chunked_body_len, and HTTPEntity::state.

Referenced by entity_read().

376 {
377  Octstr *h = NULL;
378 
379  if (ent->expect_state == expect_no_body) {
380  ent->state = entity_done;
381  return;
382  }
383 
384  ent->state = body_error; /* safety net */
385 
386  h = http_header_find_first(ent->headers, "Transfer-Encoding");
387  if (h != NULL) {
389  if (octstr_str_compare(h, "chunked") != 0) {
390  error(0, "HTTP: Unknown Transfer-Encoding <%s>",
391  octstr_get_cstr(h));
392  ent->state = body_error;
393  } else {
395  }
396  octstr_destroy(h);
397  return;
398  }
399 
400  h = http_header_find_first(ent->headers, "Content-Length");
401  if (h != NULL) {
402  if (octstr_parse_long(&ent->expected_body_len, h, 0, 10) == -1 ||
403  ent->expected_body_len < 0) {
404  error(0, "HTTP: Content-Length header wrong: <%s>",
405  octstr_get_cstr(h));
406  ent->state = body_error;
407  } else if (ent->expected_body_len == 0) {
408  ent->state = entity_done;
409  } else {
411  }
412  octstr_destroy(h);
413  return;
414  }
415 
416  if (ent->expect_state == expect_body)
418  else
419  ent->state = entity_done;
420 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long expected_body_len
Definition: http.c:367
enum body_expectation expect_state
Definition: http.c:364
List * headers
Definition: http.c:362
#define http_header_find_first(headers, name)
Definition: http.h:592
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:747
enum entity_state state
Definition: http.c:365
static void destroy_int_pointer ( void *  p)
static

Definition at line 2769 of file http.c.

Referenced by server_shutdown().

2770 {
2771  (void) close(*(int *) p);
2772  gw_free(p);
2773 }
static void destroy_struct_server ( void *  p)
static

Definition at line 2759 of file http.c.

References port::fd, port::port, and port_remove().

Referenced by server_shutdown().

2760 {
2761  struct port *pp;
2762 
2763  pp = p;
2764  (void) close(pp->fd);
2765  port_remove(pp->port);
2766 }
Definition: http.c:1998
int port
Definition: http.c:2000
int fd
Definition: http.c:1999
static void port_remove(int port)
Definition: http.c:2065
static HTTPEntity* entity_create ( enum body_expectation  exp)
static

Definition at line 429 of file http.c.

References HTTPEntity::body, HTTPEntity::chunked_body_chunk_len, HTTPEntity::expect_state, HTTPEntity::expected_body_len, HTTPEntity::headers, http_create_empty_headers(), octstr_create, reading_headers, and HTTPEntity::state.

Referenced by handle_transaction(), and receive_request().

430 {
431  HTTPEntity *ent;
432 
433  ent = gw_malloc(sizeof(*ent));
435  ent->body = octstr_create("");
436  ent->chunked_body_chunk_len = -1;
437  ent->expected_body_len = -1;
438  ent->state = reading_headers;
439  ent->expect_state = exp;
440 
441  return ent;
442 }
long chunked_body_chunk_len
Definition: http.c:366
Octstr * body
Definition: http.c:363
long expected_body_len
Definition: http.c:367
enum body_expectation expect_state
Definition: http.c:364
List * headers
Definition: http.c:362
List * http_create_empty_headers(void)
Definition: http.c:2849
#define octstr_create(cstr)
Definition: octstr.h:125
enum entity_state state
Definition: http.c:365
static void entity_destroy ( HTTPEntity ent)
static

Definition at line 445 of file http.c.

References HTTPEntity::body, HTTPEntity::headers, http_destroy_headers(), and octstr_destroy().

Referenced by client_destroy(), handle_transaction(), http_accept_request(), and server_destroy().

446 {
447  if (ent == NULL)
448  return;
449 
451  octstr_destroy(ent->body);
452  gw_free(ent);
453 }
void http_destroy_headers(List *headers)
Definition: http.c:2856
Octstr * body
Definition: http.c:363
List * headers
Definition: http.c:362
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static int entity_read ( HTTPEntity ent,
Connection conn 
)
static

Definition at line 560 of file http.c.

References body_error, deduce_body_state(), entity_done, HTTPEntity::headers, panic, read_body_until_eof(), read_body_with_length(), read_chunked_body_crlf(), read_chunked_body_data(), read_chunked_body_len(), read_chunked_body_trailer(), read_some_headers(), reading_body_until_eof, reading_body_with_length, reading_chunked_body_crlf, reading_chunked_body_data, reading_chunked_body_len, reading_chunked_body_trailer, reading_headers, and HTTPEntity::state.

Referenced by handle_transaction(), and receive_request().

561 {
562  int ret;
563  enum entity_state old_state;
564 
565  /*
566  * In this loop, each state will process as much input as it needs
567  * and then switch to the next state, unless it's a final state in
568  * which case it returns directly, or unless it needs more input.
569  * So keep looping as long as the state changes.
570  */
571  do {
572  old_state = ent->state;
573  switch (ent->state) {
574  case reading_headers:
575  ret = read_some_headers(conn, ent->headers);
576  if (ret == 0)
577  deduce_body_state(ent);
578  if (ret < 0)
579  return -1;
580  break;
581 
583  read_chunked_body_len(ent, conn);
584  break;
585 
587  read_chunked_body_data(ent, conn);
588  break;
589 
591  read_chunked_body_crlf(ent, conn);
592  break;
593 
595  read_chunked_body_trailer(ent, conn);
596  break;
597 
599  read_body_until_eof(ent, conn);
600  break;
601 
603  read_body_with_length(ent, conn);
604  break;
605 
606  case body_error:
607  return -1;
608 
609  case entity_done:
610  return 0;
611 
612  default:
613  panic(0, "Internal error: Invalid HTTPEntity state.");
614  }
615  } while (ent->state != old_state);
616 
617  /*
618  * If we got here, then the loop ended because a non-final state
619  * needed more input.
620  */
621  return 1;
622 }
static void read_chunked_body_trailer(HTTPEntity *ent, Connection *conn)
Definition: http.c:513
static void read_chunked_body_len(HTTPEntity *ent, Connection *conn)
Definition: http.c:456
static void read_chunked_body_data(HTTPEntity *ent, Connection *conn)
Definition: http.c:482
static void read_body_until_eof(HTTPEntity *ent, Connection *conn)
Definition: http.c:525
List * headers
Definition: http.c:362
static void deduce_body_state(HTTPEntity *ent)
Definition: http.c:375
#define panic
Definition: log.h:87
static int read_some_headers(Connection *conn, List *headers)
Definition: http.c:131
static void read_chunked_body_crlf(HTTPEntity *ent, Connection *conn)
Definition: http.c:498
static void read_body_with_length(HTTPEntity *ent, Connection *conn)
Definition: http.c:540
enum entity_state state
Definition: http.c:365
entity_state
Definition: http.c:349
static Connection* get_connection ( HTTPServer trans)
static

Definition at line 1552 of file http.c.

References HTTPServer::certkeyfile, conn_destroy(), conn_pool_get(), error(), host, HTTPServer::host, http_urlparse_destroy(), octstr_get_cstr, parse2trans(), parse_url(), port, HTTPServer::port, proxy_hostname, proxy_port, proxy_ssl, proxy_used_for_host(), ssl, HTTPServer::ssl, and HTTPServer::url.

Referenced by write_request_thread().

1553 {
1554  Connection *conn = NULL;
1555  Octstr *host;
1556  HTTPURLParse *p;
1557  int port, ssl;
1558 
1559  /* if the parsing has not yet been done, then do it now */
1560  if (!trans->host && trans->port == 0 && trans->url != NULL) {
1561  if ((p = parse_url(trans->url)) != NULL) {
1562  parse2trans(p, trans);
1564  } else {
1565  goto error;
1566  }
1567  }
1568 
1569  if (proxy_used_for_host(trans->host, trans->url)) {
1570  host = proxy_hostname;
1571  port = proxy_port;
1572  ssl = proxy_ssl;
1573  } else {
1574  host = trans->host;
1575  port = trans->port;
1576  ssl = trans->ssl;
1577  }
1578 
1579  conn = conn_pool_get(host, port, ssl, trans->certkeyfile,
1580  http_interface);
1581  if (conn == NULL)
1582  goto error;
1583 
1584  return conn;
1585 
1586 error:
1587  conn_destroy(conn);
1588  error(0, "Couldn't send request to <%s>", octstr_get_cstr(trans->url));
1589  return NULL;
1590 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static void parse2trans(HTTPURLParse *p, HTTPServer *t)
Definition: http.c:1528
int ssl
static Connection * conn_pool_get(Octstr *host, int port, int ssl, Octstr *certkeyfile, Octstr *our_host)
Definition: http.c:783
static Octstr * host
Definition: fakesmsc.c:121
static Octstr * http_interface
Definition: http.c:123
static int proxy_ssl
Definition: http.c:202
Octstr * certkeyfile
Definition: http.c:689
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static int port
Definition: fakesmsc.c:120
void http_urlparse_destroy(HTTPURLParse *p)
Definition: http.c:1323
Octstr * url
Definition: http.c:671
void conn_destroy(Connection *conn)
Definition: conn.c:619
static int proxy_port
Definition: http.c:201
static Octstr * proxy_hostname
Definition: http.c:200
Definition: octstr.c:118
HTTPURLParse * parse_url(Octstr *url)
Definition: http.c:1368
long port
Definition: http.c:687
int ssl
Definition: http.c:690
Octstr * host
Definition: http.c:686
static int proxy_used_for_host(Octstr *host, Octstr *url)
Definition: http.c:240
static Octstr* get_redirection_location ( HTTPServer trans)
static

Definition at line 919 of file http.c.

References HTTPServer::follow_remaining, HTTPEntity::headers, HTTP_FOUND, http_header_find_first, HTTP_MOVED_PERMANENTLY, HTTP_SEE_OTHER, HTTP_TEMPORARY_REDIRECT, HTTPServer::response, and HTTPServer::status.

Referenced by handle_transaction().

920 {
921  if (trans->status < 0 || trans->follow_remaining <= 0)
922  return NULL;
923  /* check for the redirection response codes */
924  if (trans->status != HTTP_MOVED_PERMANENTLY &&
925  trans->status != HTTP_FOUND && trans->status != HTTP_SEE_OTHER &&
927  return NULL;
928  if (trans->response == NULL)
929  return NULL;
930  return http_header_find_first(trans->response->headers, "Location");
931 }
long status
Definition: http.c:682
int follow_remaining
Definition: http.c:688
List * headers
Definition: http.c:362
#define http_header_find_first(headers, name)
Definition: http.h:592
HTTPEntity * response
Definition: http.c:684
static void handle_transaction ( Connection conn,
void *  data 
)
static

Definition at line 1038 of file http.c.

References HTTPEntity::body, build_response(), HTTPServer::caller, HTTPServer::certkeyfile, client_read_status(), HTTPServer::conn, conn_destroy(), conn_get_connect_result(), conn_unregister(), debug(), entity_create(), entity_destroy(), entity_read(), error(), HTTPServer::follow_remaining, get_redirection_location(), gwlist_insert(), gwlist_produce(), HTTPEntity::headers, HTTPServer::host, http_header_find_first, http_status_class(), HTTP_STATUS_PROVISIONAL, HTTPServer::method, octstr_case_compare(), octstr_destroy(), octstr_dump, octstr_get_cstr, octstr_imm(), octstr_strip_blanks(), panic, HTTPServer::password, HTTPServer::persistent, HTTPServer::port, proxy_port, proxy_used_for_host(), recover_absolute_uri(), HTTPServer::response, response_expectation(), run_status, running, send_request(), HTTPServer::ssl, HTTPServer::state, HTTPServer::status, HTTPServer::uri, HTTPServer::url, and HTTPServer::username.

Referenced by write_request_thread().

1039 {
1040  HTTPServer *trans;
1041  int ret;
1042  Octstr *h;
1043  int rc;
1044 
1045  trans = data;
1046 
1047  if (run_status != running) {
1048  conn_unregister(conn);
1049  return;
1050  }
1051 
1052  while (trans->state != transaction_done) {
1053  switch (trans->state) {
1054  case connecting:
1055  debug("gwlib.http", 0, "Get info about connecting socket");
1056  if (conn_get_connect_result(trans->conn) != 0) {
1057  debug("gwlib.http", 0, "Socket not connected");
1058  goto error;
1059  }
1060 
1061  if ((rc = send_request(trans)) == 0) {
1062  trans->state = reading_status;
1063  } else {
1064  debug("gwlib.http", 0, "Failed while sending request");
1065  goto error;
1066  }
1067  break;
1068 
1069  case reading_status:
1070  ret = client_read_status(trans);
1071  if (ret < 0) {
1072  /*
1073  * Couldn't read the status from the socket. This may mean
1074  * that the socket had been closed by the server after an
1075  * idle timeout.
1076  */
1077  debug("gwlib.http",0,"Failed while reading status");
1078  goto error;
1079  } else if (ret == 0) {
1080  /* Got the status, go read headers and body next. */
1081  trans->state = reading_entity;
1082  trans->response = entity_create(response_expectation(trans->method, trans->status));
1083  } else {
1084  return;
1085  }
1086  break;
1087 
1088  case reading_entity:
1089  ret = entity_read(trans->response, conn);
1090  if (ret < 0) {
1091  debug("gwlib.http",0,"Failed reading entity");
1092  goto error;
1093  } else if (ret == 0 &&
1095  /* This was a provisional reply; get the real one now. */
1096  trans->state = reading_status;
1097  entity_destroy(trans->response);
1098  trans->response = NULL;
1099  } else if (ret == 0) {
1100  trans->state = transaction_done;
1101 #ifdef DUMP_RESPONSE
1102  /* Dump the response */
1103  debug("gwlib.http", 0, "HTTP: Received response:");
1104  h = build_response(trans->response->headers, trans->response->body);
1105  octstr_dump(h, 0);
1106  octstr_destroy(h);
1107 #endif
1108  } else {
1109  return;
1110  }
1111  break;
1112 
1113  default:
1114  panic(0, "Internal error: Invalid HTTPServer state.");
1115  }
1116  }
1117 
1118  conn_unregister(trans->conn);
1119 
1120  /*
1121  * Take care of persistent connection handling.
1122  * At this point we have only obeyed if server responds in HTTP/1.0 or 1.1
1123  * and have assigned trans->persistent accordingly. This can be keept
1124  * for default usage, but if we have [Proxy-]Connection: keep-alive, then
1125  * we're still forcing persistancy of the connection.
1126  */
1127  h = http_header_find_first(trans->response->headers, "Connection");
1128  if (h != NULL && octstr_case_compare(h, octstr_imm("close")) == 0)
1129  trans->persistent = 0;
1130  if (h != NULL && octstr_case_compare(h, octstr_imm("keep-alive")) == 0)
1131  trans->persistent = 1;
1132  octstr_destroy(h);
1133  if (proxy_used_for_host(trans->host, trans->url)) {
1134  h = http_header_find_first(trans->response->headers, "Proxy-Connection");
1135  if (h != NULL && octstr_case_compare(h, octstr_imm("close")) == 0)
1136  trans->persistent = 0;
1137  if (h != NULL && octstr_case_compare(h, octstr_imm("keep-alive")) == 0)
1138  trans->persistent = 1;
1139  octstr_destroy(h);
1140  }
1141 
1142 #ifdef USE_KEEPALIVE
1143  if (trans->persistent) {
1144  if (proxy_used_for_host(trans->host, trans->url))
1145  conn_pool_put(trans->conn, proxy_hostname, proxy_port, trans->ssl, trans->certkeyfile, http_interface);
1146  else
1147  conn_pool_put(trans->conn, trans->host, trans->port, trans->ssl, trans->certkeyfile, http_interface);
1148  } else
1149 #endif
1150  conn_destroy(trans->conn);
1151 
1152  trans->conn = NULL;
1153 
1154  /*
1155  * Check if the HTTP server told us to look somewhere else,
1156  * hence if we got one of the following response codes:
1157  * HTTP_MOVED_PERMANENTLY (301)
1158  * HTTP_FOUND (302)
1159  * HTTP_SEE_OTHER (303)
1160  * HTTP_TEMPORARY_REDIRECT (307)
1161  */
1162  if ((h = get_redirection_location(trans)) != NULL) {
1163 
1164  /*
1165  * This is a redirected response, we have to follow.
1166  *
1167  * According to HTTP/1.1 (RFC 2616), section 14.30 any Location
1168  * header value should be 'absoluteURI', which is defined in
1169  * RFC 2616, section 3.2.1 General Syntax, and specifically in
1170  * RFC 2396, section 3 URI Syntactic Components as
1171  *
1172  * absoluteURI = scheme ":" ( hier_part | opaque_part )
1173  *
1174  * Some HTTP servers 'interpret' a leading UDI / as that kind
1175  * of absoluteURI, which is not correct, following the protocol in
1176  * detail. But we'll try to recover from that misleaded
1177  * interpreation and try to convert the partly absoluteURI to a
1178  * fully qualified absoluteURI.
1179  *
1180  * http_URL = "http:" "//" [ userid : password "@"] host
1181  * [ ":" port ] [ abs_path [ "?" query ]]
1182  *
1183  */
1185  recover_absolute_uri(trans, h);
1186 
1187  /*
1188  * Clean up all trans stuff for the next request we do.
1189  */
1190  octstr_destroy(trans->url);
1191  octstr_destroy(trans->host);
1192  trans->port = 0;
1193  octstr_destroy(trans->uri);
1194  octstr_destroy(trans->username);
1195  octstr_destroy(trans->password);
1196  trans->host = NULL;
1197  trans->port = 0;
1198  trans->uri = NULL;
1199  trans->username = NULL;
1200  trans->password = NULL;
1201  trans->ssl = 0;
1202  trans->url = h; /* apply new absolute URL to next request */
1203  trans->state = request_not_sent;
1204  trans->status = -1;
1205  entity_destroy(trans->response);
1206  trans->response = NULL;
1207  --trans->follow_remaining;
1208  conn_destroy(trans->conn);
1209  trans->conn = NULL;
1210 
1211  /* re-inject request to the front of the queue */
1212  gwlist_insert(pending_requests, 0, trans);
1213 
1214  } else {
1215  /* handle this response as usual */
1216  gwlist_produce(trans->caller, trans);
1217  }
1218  return;
1219 
1220 error:
1221  conn_unregister(trans->conn);
1222  conn_destroy(trans->conn);
1223  trans->conn = NULL;
1224  error(0, "Couldn't fetch <%s>", octstr_get_cstr(trans->url));
1225  trans->status = -1;
1226  gwlist_produce(trans->caller, trans);
1227 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static List * pending_requests
Definition: http.c:633
long status
Definition: http.c:682
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static Octstr * get_redirection_location(HTTPServer *trans)
Definition: http.c:919
int method
Definition: http.c:670
int follow_remaining
Definition: http.c:688
Octstr * uri
Definition: http.c:672
Connection * conn
Definition: http.c:685
static Octstr * http_interface
Definition: http.c:123
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
Octstr * certkeyfile
Definition: http.c:689
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: http.c:115
static Octstr * build_response(List *headers, Octstr *body)
Definition: http.c:1284
static int client_read_status(HTTPServer *trans)
Definition: http.c:982
Octstr * body
Definition: http.c:363
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
int conn_get_connect_result(Connection *conn)
Definition: conn.c:522
static enum @59 run_status
static int entity_read(HTTPEntity *ent, Connection *conn)
Definition: http.c:560
Octstr * url
Definition: http.c:671
List * headers
Definition: http.c:362
Octstr * username
Definition: http.c:691
void conn_destroy(Connection *conn)
Definition: conn.c:619
static int send_request(HTTPServer *trans)
Definition: http.c:1596
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
static int proxy_port
Definition: http.c:201
int http_status_class(int code)
Definition: http.c:3621
#define http_header_find_first(headers, name)
Definition: http.h:592
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
static void recover_absolute_uri(HTTPServer *trans, Octstr *loc)
Definition: http.c:941
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
enum HTTPServer::@60 state
static Octstr * proxy_hostname
Definition: http.c:200
void gwlist_insert(List *list, long pos, void *item)
Definition: list.c:214
static void entity_destroy(HTTPEntity *ent)
Definition: http.c:445
void conn_unregister(Connection *conn)
Definition: conn.c:850
HTTPEntity * response
Definition: http.c:684
Definition: octstr.c:118
static int response_expectation(int method, int status)
Definition: http.c:1027
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define panic
Definition: log.h:87
static HTTPEntity * entity_create(enum body_expectation exp)
Definition: http.c:429
int persistent
Definition: http.c:683
long port
Definition: http.c:687
int ssl
Definition: http.c:690
HTTPCaller * caller
Definition: http.c:668
Octstr * host
Definition: http.c:686
Octstr * password
Definition: http.c:692
static int proxy_used_for_host(Octstr *host, Octstr *url)
Definition: http.c:240
static int header_is_called ( Octstr header,
char *  name 
)
static

Definition at line 2836 of file http.c.

References colon, octstr_get_cstr, and octstr_search_char().

Referenced by build_request(), http_header_find_all(), http_header_find_first_real(), and http_header_remove_all().

2837 {
2838  long colon;
2839 
2840  colon = octstr_search_char(header, ':', 0);
2841  if (colon == -1)
2842  return 0;
2843  if ((long) strlen(name) != colon)
2844  return 0;
2845  return strncasecmp(octstr_get_cstr(header), name, colon) == 0;
2846 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
char * name
Definition: smsc_cimd2.c:212
static Octstr * colon
Definition: smsc_smasi.c:218
HTTPClient* http_accept_request ( int  port,
Octstr **  client_ip,
Octstr **  url,
List **  headers,
Octstr **  body,
List **  cgivars 
)

Definition at line 2574 of file http.c.

References HTTPEntity::body, client(), client_destroy(), client_is_persistent(), HTTPClient::conn, conn_eof(), conn_error(), conn_wait(), debug(), entity_destroy(), HTTPEntity::headers, HTTP_METHOD_POST, HTTPClient::ip, HTTPClient::method, octstr_destroy(), octstr_duplicate, parse_cgivars(), HTTPClient::persistent_conn, port_get_request(), HTTPClient::request, HTTPClient::url, and HTTPClient::use_version_1_0.

Referenced by client_thread(), http_read_thread(), http_thread(), httpadmin_run(), httpd_emu(), httpsmsc_receiver(), sendsms_thread(), and soap_server().

2577 {
2578  HTTPClient *client;
2579 
2580  do {
2581  client = port_get_request(port);
2582  if (client == NULL) {
2583  debug("gwlib.http", 0, "HTTP: No clients with requests, quitting.");
2584  return NULL;
2585  }
2586  /* check whether client connection still ok */
2587  conn_wait(client->conn, 0);
2588  if (conn_error(client->conn) || conn_eof(client->conn)) {
2589  client_destroy(client);
2590  client = NULL;
2591  }
2592  } while(client == NULL);
2593 
2594  *client_ip = octstr_duplicate(client->ip);
2595  *url = client->url;
2596  *headers = client->request->headers;
2597  *body = client->request->body;
2598  *cgivars = parse_cgivars(client->url);
2599 
2600  if (client->method != HTTP_METHOD_POST) {
2601  octstr_destroy(*body);
2602  *body = NULL;
2603  }
2604 
2606  client->use_version_1_0);
2607 
2608  client->url = NULL;
2609  client->request->headers = NULL;
2610  client->request->body = NULL;
2611  entity_destroy(client->request);
2612  client->request = NULL;
2613 
2614  return client;
2615 }
Definition: http.c:1998
static HTTPClient * port_get_request(int port)
Definition: http.c:2133
Connection * conn
Definition: http.c:1857
static void client(int port)
Definition: test_udp.c:77
static int client_is_persistent(List *headers, int use_version_1_0)
Definition: http.c:1967
int conn_eof(Connection *conn)
Definition: conn.c:697
int use_version_1_0
Definition: http.c:1867
Octstr * ip
Definition: http.c:1858
static void client_destroy(void *client)
Definition: http.c:1917
Octstr * body
Definition: http.c:363
int method
Definition: http.c:1865
List * headers
Definition: http.c:362
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static List * parse_cgivars(Octstr *url)
Definition: http.c:2531
Octstr * url
Definition: http.c:1866
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
int persistent_conn
Definition: http.c:1868
static void entity_destroy(HTTPEntity *ent)
Definition: http.c:445
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:896
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int conn_error(Connection *conn)
Definition: conn.c:708
HTTPEntity * request
Definition: http.c:1870
void http_add_basic_auth ( List headers,
Octstr username,
Octstr password 
)

Definition at line 3492 of file http.c.

References http_header_add(), octstr_binary_to_base64(), octstr_destroy(), octstr_format(), octstr_get_cstr, octstr_imm(), octstr_insert(), and octstr_strip_blanks().

Referenced by client_thread(), push_headers_create(), receive_push_reply(), and send_request().

3493 {
3494  Octstr *os;
3495 
3496  if (password != NULL)
3497  os = octstr_format("%S:%S", username, password);
3498  else
3499  os = octstr_format("%S", username);
3501  octstr_strip_blanks(os);
3502  octstr_insert(os, octstr_imm("Basic "), 0);
3503  http_header_add(headers, "Authorization", octstr_get_cstr(os));
3504  octstr_destroy(os);
3505 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
void octstr_binary_to_base64(Octstr *ostr)
Definition: octstr.c:540
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1301
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
void http_append_headers ( List to,
List from 
)

Definition at line 3029 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_append(), gwlist_get(), gwlist_len(), and octstr_duplicate.

Referenced by http_header_combine(), and pap_request_thread().

3030 {
3031  Octstr *header;
3032  long i;
3033 
3035  gw_assert(to != NULL);
3036  gw_assert(from != NULL);
3037 
3038  for (i = 0; i < gwlist_len(from); ++i) {
3039  header = gwlist_get(from, i);
3040  gwlist_append(to, octstr_duplicate(header));
3041  }
3042 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_duplicate(ostr)
Definition: octstr.h:187
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
HTTPCaller* http_caller_create ( void  )

Definition at line 897 of file http.c.

References caller, gwlist_add_producer(), and gwlist_create.

Referenced by http_get_real(), main(), smsc_http_create(), soap_create_client_data(), and wap_appl_init().

898 {
900 
901  caller = gwlist_create();
902  gwlist_add_producer(caller);
903  return caller;
904 }
static HTTPCaller * caller
Definition: smsbox.c:429
#define gwlist_create()
Definition: list.h:136
void gwlist_add_producer(List *list)
Definition: list.c:383
Definition: list.c:102
void http_caller_destroy ( HTTPCaller caller)

Definition at line 907 of file http.c.

References gwlist_destroy(), and server_destroy().

Referenced by client_thread(), conndata_destroy(), http_get_real(), main(), push_thread(), soap_destroy_client_data(), and wap_appl_shutdown().

908 {
910 }
static void server_destroy(void *p)
Definition: http.c:730
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
void http_caller_signal_shutdown ( HTTPCaller caller)

Definition at line 913 of file http.c.

References gwlist_remove_producer().

Referenced by httpsmsc_receiver(), httpsmsc_sender(), main(), soap_destroy_client_data(), and wap_appl_shutdown().

914 {
915  gwlist_remove_producer(caller);
916 }
void gwlist_remove_producer(List *list)
Definition: list.c:401
Octstr* http_cgi_variable ( List list,
char *  name 
)

Definition at line 2813 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_get(), gwlist_len(), HTTPCGIVar::name, octstr_str_compare(), and HTTPCGIVar::value.

Referenced by brunet_receive_sms(), clickatell_receive_sms(), client_thread(), default_authorise_user(), generic_receive_sms(), httpd_add_smsc(), httpd_check_authorization(), httpd_emu(), httpd_loglevel(), httpd_remove_message(), httpd_remove_smsc(), httpd_restart_smsc(), httpd_stop_smsc(), kannel_receive_sms(), parse_cgivars_for_password(), parse_cgivars_for_username(), smsbox_req_sendota(), smsbox_req_sendsms(), and xidris_receive_sms().

2814 {
2815  int i;
2816  HTTPCGIVar *v;
2817 
2819  gw_assert(list != NULL);
2820  gw_assert(name != NULL);
2821 
2822  for (i = 0; i < gwlist_len(list); ++i) {
2823  v = gwlist_get(list, i);
2824  if (octstr_str_compare(v->name, name) == 0)
2825  return v->value;
2826  }
2827  return NULL;
2828 }
Octstr * value
Definition: http.h:213
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * name
Definition: http.h:212
char * name
Definition: smsc_cimd2.c:212
gw_assert(wtls_machine->packet_to_send!=NULL)
void() gwlib_assert_init(void)
Definition: gwlib.c:72
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
void http_cgivar_dump ( List cgiargs)

Definition at line 3417 of file http.c.

References debug(), gwlib_assert_init(), gwlist_get(), gwlist_len(), HTTPCGIVar::name, octstr_dump, and HTTPCGIVar::value.

3418 {
3419  HTTPCGIVar *v;
3420  long i, len;
3421 
3423 
3424  len = gwlist_len(cgiargs);
3425 
3426  debug("gwlib.http", 0, "Dumping %ld cgi variables:", len);
3427  for (i = 0; i < len; i++) {
3428  v = gwlist_get(cgiargs, i);
3429  octstr_dump(v->name, 0);
3430  octstr_dump(v->value, 0);
3431  }
3432  debug("gwlib.http", 0, "End of dump.");
3433 }
Octstr * value
Definition: http.h:213
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * name
Definition: http.h:212
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void http_cgivar_dump_into ( List cgiargs,
Octstr os 
)

Definition at line 3436 of file http.c.

References gwlib_assert_init(), gwlist_get(), gwlist_len(), HTTPCGIVar::name, octstr_format_append(), and HTTPCGIVar::value.

Referenced by httpsmsc_receiver().

3437 {
3438  HTTPCGIVar *v;
3439  long i;
3440 
3441  if (os == NULL)
3442  return;
3443 
3445 
3446  for (i = 0; i < gwlist_len(cgiargs); i++) {
3447  v = gwlist_get(cgiargs, i);
3448  octstr_format_append(os, "&%E=%E", v->name, v->value);
3449  }
3450 }
Octstr * value
Definition: http.h:213
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * name
Definition: http.h:212
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
int http_charset_accepted ( List headers,
char *  charset 
)

Definition at line 3486 of file http.c.

References http_something_accepted().

Referenced by add_charset_headers(), and normalize_charset().

3487 {
3488  return http_something_accepted(headers, "Accept-Charset", charset);
3489 }
Octstr * charset
Definition: test_ota.c:68
static int http_something_accepted(List *headers, char *header_name, char *what)
Definition: http.c:3453
void http_close_all_ports ( void  )

Definition at line 2515 of file http.c.

References gwthread_join_every(), gwthread_wakeup(), and server_thread().

Referenced by client_thread(), httpadmin_stop(), httpd_emu_destroy(), main(), and wap_push_ppg_shutdown().

2516 {
2517  if (server_thread_id != -1) {
2518  keep_servers_open = 0;
2522  }
2523 }
static long server_thread_id
Definition: http.c:1879
void gwthread_join_every(gwthread_func_t *func)
static int keep_servers_open
Definition: http.c:1882
void gwthread_wakeup(long thread)
static void server_thread(void *dummy)
Definition: http.c:2333
static volatile sig_atomic_t server_thread_is_running
Definition: http.c:1878
void http_close_client ( HTTPClient client)

Definition at line 2735 of file http.c.

References client_destroy().

Referenced by httpadmin_run(), httpsmsc_receiver(), and pap_request_thread().

2736 {
2737  client_destroy(client);
2738 }
static void client_destroy(void *client)
Definition: http.c:1917
void http_close_port ( int  port)

Definition at line 2504 of file http.c.

References gwlist_produce(), gwthread_wakeup(), and port.

Referenced by httpsmsc_receiver(), httpsmsc_shutdown(), soap_server_start(), and soap_server_stop().

2505 {
2506  int *p;
2507 
2508  p = gw_malloc(sizeof(*p));
2509  *p = port;
2512 }
static long server_thread_id
Definition: http.c:1879
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static int port
Definition: fakesmsc.c:120
static List * closed_server_sockets
Definition: http.c:1881
void gwthread_wakeup(long thread)
void http_close_proxy ( void  )

Definition at line 304 of file http.c.

References gw_assert(), gwlist_destroy(), mutex_lock, mutex_unlock, octstr_destroy(), octstr_destroy_item(), proxy_exceptions_regex, proxy_port, run_status, running, and terminating.

Referenced by http_use_proxy(), and proxy_shutdown().

305 {
307 
309  proxy_port = 0;
313  proxy_hostname = NULL;
314  proxy_username = NULL;
315  proxy_password = NULL;
317  gw_regex_destroy(proxy_exceptions_regex);
318  proxy_exceptions = NULL;
319  proxy_exceptions_regex = NULL;
321 }
#define mutex_unlock(m)
Definition: thread.h:136
Definition: http.c:115
static regex_t * proxy_exceptions_regex
Definition: http.c:206
static enum @59 run_status
static int proxy_port
Definition: http.c:201
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static Octstr * proxy_username
Definition: http.c:203
void octstr_destroy_item(void *os)
Definition: octstr.c:334
static Mutex * proxy_mutex
Definition: http.c:199
gw_assert(wtls_machine->packet_to_send!=NULL)
static Octstr * proxy_hostname
Definition: http.c:200
static List * proxy_exceptions
Definition: http.c:205
#define mutex_lock(m)
Definition: thread.h:130
static Octstr * proxy_password
Definition: http.c:204
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
void http_destroy_cgiargs ( List args)

Definition at line 2795 of file http.c.

References gwlib_assert_init(), gwlist_destroy(), gwlist_extract_first(), HTTPCGIVar::name, octstr_destroy(), and HTTPCGIVar::value.

Referenced by client_thread(), http_thread(), httpd_emu(), httpd_serve(), httpsmsc_receiver(), pap_request_thread(), and sendsms_thread().

2796 {
2797  HTTPCGIVar *v;
2798 
2800 
2801  if (args == NULL)
2802  return ;
2803 
2804  while ((v = gwlist_extract_first(args)) != NULL) {
2805  octstr_destroy(v->name);
2806  octstr_destroy(v->value);
2807  gw_free(v);
2808  }
2809  gwlist_destroy(args, NULL);
2810 }
Octstr * value
Definition: http.h:213
Octstr * name
Definition: http.h:212
void * gwlist_extract_first(List *list)
Definition: list.c:305
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
void http_destroy_headers ( List headers)

Definition at line 2856 of file http.c.

References gwlib_assert_init(), gwlist_destroy(), and octstr_destroy_item().

Referenced by brunet_receive_sms(), brunet_send_sms(), challenge(), check_application_headers(), clickatell_receive_sms(), clickatell_send_sms(), client_thread(), content_transformable(), decode_bearer_indication(), entity_destroy(), generic_receive_sms(), generic_send_sms(), http_queue_thread(), http_something_accepted(), http_thread(), httpd_emu(), httpd_emu_shutdown(), httpd_serve(), httpsmsc_receiver(), httpsmsc_send_cb(), indicate_push_connection(), indicate_push_resume(), kannel_receive_sms(), kannel_send_sms(), kill_kannel(), main(), make_confirmedpush_pdu(), make_connectreply_pdu(), make_push_pdu(), make_resume_reply_pdu(), mime_entity_to_octstr(), mime_replace_headers(), mime_something_to_entity(), numhash_create(), obey_request(), pack_sia(), pap_request_thread(), receive_push_reply(), receive_reply(), reply(), return_replies_thread(), return_reply(), send_to_pi(), sendsms_thread(), server_destroy(), soap_read_response(), soap_send(), soap_server(), start_fetch(), start_push(), test_header_combine(), url_result_thread(), wapme_smsproxy_send_sms(), xidris_receive_sms(), and xidris_send_sms().

2857 {
2860 }
void octstr_destroy_item(void *os)
Definition: octstr.c:334
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
Octstr* http_get_header_parameter ( Octstr value,
Octstr parameter 
)

Definition at line 3508 of file http.c.

References found, http_header_quoted_string_len(), octstr_case_compare(), octstr_copy, octstr_destroy(), octstr_duplicate, octstr_get_char(), octstr_len(), octstr_search_char(), and octstr_strip_blanks().

Referenced by fix_boundary_element(), get_start_param(), and mime_something_to_entity().

3509 {
3510  long pos, len, end;
3511  int c, found = 0;
3512  Octstr *result = NULL;
3513 
3514  len = octstr_len(value);
3515  /* Find the start of the first parameter. */
3516  for (pos = 0; pos < len; pos++) {
3517  c = octstr_get_char(value, pos);
3518  if (c == ';')
3519  break;
3520  else if (c == '"')
3521  pos += http_header_quoted_string_len(value, pos) - 1;
3522  }
3523 
3524  if (pos >= len)
3525  return NULL; /* no parameters */
3526 
3527  for (pos++; pos > 0 && pos < len && found == 0; pos++) {
3528  Octstr *key = NULL;
3529  Octstr *val = NULL;
3530 
3531  end = octstr_search_char(value, '=', pos);
3532  if (end < 0)
3533  end = octstr_search_char(value, ';', pos);
3534  if (end < 0)
3535  end = octstr_len(value);
3536  key = octstr_copy(value, pos, end - pos);
3537  octstr_strip_blanks(key);
3538  pos = end;
3539 
3540  if (octstr_get_char(value, pos) == '=') {
3541  pos++;
3542  while (isspace(octstr_get_char(value, pos)))
3543  pos++;
3544  if (octstr_get_char(value, pos) == '"')
3545  end = pos + http_header_quoted_string_len(value, pos);
3546  else
3547  end = octstr_search_char(value, ';', pos);
3548  if (end < 0)
3549  end = octstr_len(value);
3550  val = octstr_copy(value, pos, end - pos);
3551  octstr_strip_blanks(val);
3552  pos = end;
3553  pos = octstr_search_char(value, ';', pos);
3554  }
3555 
3556  /* is this the pair we look for? bail out then*/
3557  if (octstr_case_compare(key, parameter) == 0) {
3558  found++;
3559  result = octstr_duplicate(val);
3560  }
3561 
3562  octstr_destroy(key);
3563  octstr_destroy(val);
3564  }
3565 
3566  return result;
3567 }
long http_header_quoted_string_len(Octstr *header, long start)
Definition: http.c:3270
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
static struct pid_list * found
#define octstr_duplicate(ostr)
Definition: octstr.h:187
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
int http_get_real ( int  method,
Octstr url,
List request_headers,
Octstr **  final_url,
List **  reply_headers,
Octstr **  reply_body 
)

Definition at line 1806 of file http.c.

References caller, http_caller_create(), http_caller_destroy(), http_get_real(), http_receive_result, and http_start_request().

Referenced by http_get_real(), kill_kannel(), and numhash_create().

1808 {
1809  HTTPCaller *caller;
1810  int status;
1811  void *ret;
1812 
1813  caller = http_caller_create();
1814  http_start_request(caller, method, url, request_headers,
1815  NULL, 1, http_get_real, NULL);
1816  ret = http_receive_result(caller, &status, final_url,
1817  reply_headers, reply_body);
1818  http_caller_destroy(caller);
1819  if (ret == NULL)
1820  return -1;
1821  return status;
1822 }
static HTTPCaller * caller
Definition: smsbox.c:429
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1745
static int method
Definition: test_http.c:76
#define http_receive_result(caller, status, final_url, headers, body)
Definition: http.h:383
int http_get_real(int method, Octstr *url, List *request_headers, Octstr **final_url, List **reply_headers, Octstr **reply_body)
Definition: http.c:1806
HTTPCaller * http_caller_create(void)
Definition: http.c:897
void http_caller_destroy(HTTPCaller *caller)
Definition: http.c:907
Definition: list.c:102
void http_header_add ( List headers,
char *  name,
char *  contents 
)

Definition at line 2863 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_append(), and octstr_format().

Referenced by add_accept_headers(), add_charset_headers(), add_client_sdu_size(), add_connection_header(), add_dlr_mask(), add_dlr_url(), add_kannel_version(), add_msisdn(), add_network_info(), add_push_flag(), add_session_id(), add_via(), add_x_wap_tod(), brunet_receive_sms(), challenge(), change_header_value(), check_application_headers(), check_session_request_headers(), check_x_wap_application_id_header(), clickatell_receive_sms(), client_thread(), decode_bearer_indication(), fix_boundary_element(), generic_receive_sms(), http_add_basic_auth(), http_header_mark_transformation(), httpd_emu_init(), httpd_serve(), kannel_receive_sms(), kill_kannel(), main(), make_reply_headers(), obey_request(), pack_into_push_datagram(), pack_into_result_datagram(), pass_extension_headers(), pass_optional_header(), proxy_add_authentication(), push_headers_create(), send_request(), send_to_pi(), soap_send(), soap_server(), start_fetch(), test_header_combine(), wsp_unpack_app_header(), wsp_unpack_well_known_field(), and xmlrpc_doc_send().

2864 {
2866  gw_assert(headers != NULL);
2867  gw_assert(name != NULL);
2868  gw_assert(contents != NULL);
2869 
2870  gwlist_append(headers, octstr_format("%s: %s", name, contents));
2871 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
char * name
Definition: smsc_cimd2.c:212
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
gw_assert(wtls_machine->packet_to_send!=NULL)
void() gwlib_assert_init(void)
Definition: gwlib.c:72
static void http_header_add_element ( List list,
Octstr value,
long  start,
long  end 
)
static

Definition at line 3256 of file http.c.

References gwlist_append(), octstr_copy, octstr_destroy(), octstr_len(), and octstr_strip_blanks().

Referenced by http_header_split_value().

3258 {
3259  Octstr *element;
3260 
3261  element = octstr_copy(value, start, end - start);
3262  octstr_strip_blanks(element);
3263  if (octstr_len(element) == 0)
3264  octstr_destroy(element);
3265  else
3266  gwlist_append(list, element);
3267 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static int start
void http_header_combine ( List old_headers,
List new_headers 
)

Definition at line 3045 of file http.c.

References gwlist_len(), http_append_headers(), http_header_get(), http_header_remove_all(), name, octstr_destroy(), and octstr_get_cstr.

Referenced by client_thread(), return_reply(), start_fetch(), start_request(), test_header_combine(), and unpack_new_headers().

3046 {
3047  long i;
3048  Octstr *name;
3049  Octstr *value;
3050 
3051  /*
3052  * Avoid doing this scan if old_headers is empty anyway.
3053  */
3054  if (gwlist_len(old_headers) > 0) {
3055  for (i = 0; i < gwlist_len(new_headers); i++) {
3056  http_header_get(new_headers, i, &name, &value);
3057  http_header_remove_all(old_headers, octstr_get_cstr(name));
3058  octstr_destroy(name);
3059  octstr_destroy(value);
3060  }
3061  }
3062 
3063  http_append_headers(old_headers, new_headers);
3064 }
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2879
long gwlist_len(List *list)
Definition: list.c:166
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_append_headers(List *to, List *from)
Definition: http.c:3029
char * name
Definition: smsc_cimd2.c:212
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
void http_header_dump ( List headers)

Definition at line 3404 of file http.c.

References debug(), gwlib_assert_init(), gwlist_get(), gwlist_len(), and octstr_dump.

Referenced by check_application_headers(), client_thread(), decode_bearer_indication(), main(), and start_push().

3405 {
3406  long i;
3407 
3409 
3410  debug("gwlib.http", 0, "Dumping HTTP headers:");
3411  for (i = 0; headers != NULL && i < gwlist_len(headers); ++i)
3412  octstr_dump(gwlist_get(headers, i), 1);
3413  debug("gwlib.http", 0, "End of dump.");
3414 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void() gwlib_assert_init(void)
Definition: gwlib.c:72
List* http_header_duplicate ( List headers)

Definition at line 2946 of file http.c.

References gwlib_assert_init(), gwlist_append(), gwlist_get(), gwlist_len(), http_create_empty_headers(), and octstr_duplicate.

Referenced by add_push_flag(), create_session(), indicate_confirmedpush(), indicate_push_connection(), indicate_push_resume(), indicate_resume(), make_session_request(), mime_entity_headers(), mime_entity_to_octstr(), mime_replace_headers(), mime_something_to_entity(), pap_request_thread(), push_machine_create(), remember_receiver(), request_confirmed_push(), request_push(), request_unit_push(), and server_create().

2947 {
2948  List *new;
2949  long i, len;
2950 
2952 
2953  if (headers == NULL)
2954  return NULL;
2955 
2956  new = http_create_empty_headers();
2957  len = gwlist_len(headers);
2958  for (i = 0; i < len; ++i)
2959  gwlist_append(new, octstr_duplicate(gwlist_get(headers, i)));
2960  return new;
2961 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
List * http_create_empty_headers(void)
Definition: http.c:2849
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void() gwlib_assert_init(void)
Definition: gwlib.c:72
Definition: list.c:102
List* http_header_find_all ( List headers,
char *  name 
)

Definition at line 3092 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_append(), gwlist_create, gwlist_get(), gwlist_len(), header_is_called(), and octstr_duplicate.

Referenced by content_transformable(), http_remove_hop_headers(), http_something_accepted(), make_session_request(), and split_header_list().

3093 {
3094  List *list;
3095  long i;
3096  Octstr *h;
3097 
3099  gw_assert(headers != NULL);
3100  gw_assert(name != NULL);
3101 
3102  list = gwlist_create();
3103  for (i = 0; i < gwlist_len(headers); ++i) {
3104  h = gwlist_get(headers, i);
3105  if (header_is_called(h, name))
3106  gwlist_append(list, octstr_duplicate(h));
3107  }
3108  return list;
3109 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_duplicate(ostr)
Definition: octstr.h:187
char * name
Definition: smsc_cimd2.c:212
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
#define gwlist_create()
Definition: list.h:136
static int header_is_called(Octstr *header, char *name)
Definition: http.c:2836
Definition: list.c:102
Octstr* http_header_find_first_real ( List headers,
char *  name,
const char *  file,
long  line,
const char *  func 
)

Definition at line 3067 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_get(), gwlist_len(), header_is_called(), name_len, octstr_copy_real(), octstr_len(), and octstr_strip_blanks().

3069 {
3070  long i, name_len;
3071  Octstr *h, *value;
3072 
3074  gw_assert(headers != NULL);
3075  gw_assert(name != NULL);
3076 
3077  name_len = strlen(name);
3078 
3079  for (i = 0; i < gwlist_len(headers); ++i) {
3080  h = gwlist_get(headers, i);
3081  if (header_is_called(h, name)) {
3082  value = octstr_copy_real(h, name_len + 1, octstr_len(h),
3083  file, line, func);
3084  octstr_strip_blanks(value);
3085  return value;
3086  }
3087  }
3088  return NULL;
3089 }
size_t name_len
Definition: wslexer.c:156
long gwlist_len(List *list)
Definition: list.c:166
Octstr * octstr_copy_real(const Octstr *ostr, long from, long len, const char *file, long line, const char *func)
Definition: octstr.c:349
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
FILE * file
Definition: log.c:133
char * name
Definition: smsc_cimd2.c:212
gw_assert(wtls_machine->packet_to_send!=NULL)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
static int header_is_called(Octstr *header, char *name)
Definition: http.c:2836
void http_header_get ( List headers,
long  i,
Octstr **  name,
Octstr **  value 
)

Definition at line 2879 of file http.c.

References colon, error(), gw_assert(), gwlib_assert_init(), gwlist_get(), octstr_copy, octstr_create, octstr_duplicate, octstr_len(), octstr_search_char(), and octstr_strip_blanks().

Referenced by check_application_headers(), content_transformable(), decode_bearer_indication(), get_x_kannel_from_headers(), http_header_combine(), http_header_pack(), pack_appid_list(), smsbox_sendota_post(), and wsp_headers_pack().

2880 {
2881  Octstr *os;
2882  long colon;
2883 
2885  gw_assert(i >= 0);
2886  gw_assert(name != NULL);
2887  gw_assert(value != NULL);
2888 
2889  os = gwlist_get(headers, i);
2890  if (os == NULL)
2891  colon = -1;
2892  else
2893  colon = octstr_search_char(os, ':', 0);
2894  if (colon == -1) {
2895  error(0, "HTTP: Header does not contain a colon. BAD.");
2896  *name = octstr_create("X-Unknown");
2897  *value = octstr_duplicate(os);
2898  } else {
2899  *name = octstr_copy(os, 0, colon);
2900  *value = octstr_copy(os, colon + 1, octstr_len(os) - colon - 1);
2901  octstr_strip_blanks(*value);
2902  }
2903 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_create(cstr)
Definition: octstr.h:125
gw_assert(wtls_machine->packet_to_send!=NULL)
static Octstr * colon
Definition: smsc_smasi.c:218
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void http_header_get_content_type ( List headers,
Octstr **  type,
Octstr **  charset 
)

Definition at line 3202 of file http.c.

References gw_assert(), gwlib_assert_init(), http_header_find_first, octstr_append_cstr(), octstr_create, octstr_delete(), octstr_duplicate, octstr_get_char(), octstr_imm(), octstr_len(), octstr_ncompare(), octstr_search_char(), octstr_strip_blanks(), and octstr_truncate().

Referenced by mime_entity_dump_real(), numhash_create(), receive_reply(), return_reply(), smsbox_sendota_post(), smsbox_sendsms_post(), smsbox_xmlrpc_post(), start_fetch(), transform_message(), and url_result_thread().

3204 {
3205  Octstr *h;
3206  long semicolon, equals, len;
3207 
3209  gw_assert(headers != NULL);
3210  gw_assert(type != NULL);
3211  gw_assert(charset != NULL);
3212 
3213  h = http_header_find_first(headers, "Content-Type");
3214  if (h == NULL) {
3215  *type = octstr_create("application/octet-stream");
3216  *charset = octstr_create("");
3217  } else {
3219  semicolon = octstr_search_char(h, ';', 0);
3220  if (semicolon == -1) {
3221  *type = h;
3222  *charset = octstr_create("");
3223  } else {
3224  *charset = octstr_duplicate(h);
3225  octstr_delete(*charset, 0, semicolon + 1);
3226  octstr_strip_blanks(*charset);
3227  equals = octstr_search_char(*charset, '=', 0);
3228  if (equals == -1)
3229  octstr_truncate(*charset, 0);
3230  else {
3231  octstr_delete(*charset, 0, equals + 1);
3232  if (octstr_get_char(*charset, 0) == '"')
3233  octstr_delete(*charset, 0, 1);
3234  len = octstr_len(*charset);
3235  if (octstr_get_char(*charset, len - 1) == '"')
3236  octstr_truncate(*charset, len - 1);
3237  }
3238 
3239  octstr_truncate(h, semicolon);
3241  *type = h;
3242  }
3243 
3244  /*
3245  * According to HTTP/1.1 (RFC 2616, section 3.7.1) we have to ensure
3246  * to return charset 'iso-8859-1' in case of no given encoding and
3247  * content-type is a 'text' subtype.
3248  */
3249  if (octstr_len(*charset) == 0 &&
3250  octstr_ncompare(*type, octstr_imm("text"), 4) == 0)
3251  octstr_append_cstr(*charset, "ISO-8859-1");
3252  }
3253 }
void octstr_append_cstr(Octstr *ostr, const char *cstr)
Definition: octstr.c:1509
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
int octstr_ncompare(const Octstr *ostr1, const Octstr *ostr2, long n)
Definition: octstr.c:950
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define http_header_find_first(headers, name)
Definition: http.h:592
#define octstr_create(cstr)
Definition: octstr.h:125
gw_assert(wtls_machine->packet_to_send!=NULL)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1325
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
void http_header_mark_transformation ( List headers,
Octstr new_body,
Octstr new_type 
)

Definition at line 3180 of file http.c.

References http_header_add(), http_header_remove_all(), octstr_destroy(), octstr_format(), octstr_get_cstr, and octstr_len().

Referenced by handle_push_message(), return_reply(), and start_fetch().

3182 {
3183  Octstr *new_length = NULL;
3184 
3185  /* Remove all headers that no longer apply to the new body. */
3186  http_header_remove_all(headers, "Content-Length");
3187  http_header_remove_all(headers, "Content-MD5");
3188  http_header_remove_all(headers, "Content-Type");
3189 
3190  /* Add headers that we need to describe the new body. */
3191  new_length = octstr_format("%ld", octstr_len(new_body));
3192  http_header_add(headers, "Content-Length", octstr_get_cstr(new_length));
3193  if(octstr_len(new_type))
3194  http_header_add(headers, "Content-Type", octstr_get_cstr(new_type));
3195 
3196  /* Perhaps we should add Warning: 214 "Transformation applied" too? */
3197 
3198  octstr_destroy(new_length);
3199 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
void http_header_pack ( List headers)

Definition at line 2969 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_delete(), gwlist_get(), gwlist_insert(), gwlist_len(), http_header_get(), MAX_HEADER_LENGTH, name, octstr_append(), octstr_case_compare(), octstr_create, octstr_destroy(), octstr_imm(), and octstr_len().

Referenced by start_fetch().

2970 {
2971  Octstr *name, *value;
2972  Octstr *name2, *value2;
2973  long i, j;
2974 
2976  gw_assert(headers != NULL);
2977 
2978  /*
2979  * For each header, search forward headers for similar ones and if possible,
2980  * add it to current header and delete it
2981  */
2982  for(i = 0; i < gwlist_len(headers); i++) {
2983  http_header_get(headers, i, &name, &value);
2984  /* debug("http_header_pack", 0, "HTTP_HEADER_PACK: Processing header %d. [%s: %s]",
2985  i, octstr_get_cstr(name), octstr_get_cstr(value)); */
2986 
2987  for(j=i+1; j < gwlist_len(headers); j++) {
2988  http_header_get(headers, j, &name2, &value2);
2989 
2990  if(octstr_case_compare(name, name2) == 0) {
2991  if(octstr_len(value) + 2 + octstr_len(value2) > MAX_HEADER_LENGTH) {
2992  octstr_destroy(name2);
2993  octstr_destroy(value2);
2994  break;
2995  } else {
2996  Octstr *header;
2997 
2998  /* Delete old header */
2999  header = gwlist_get(headers, i);
3000  octstr_destroy(header);
3001  gwlist_delete(headers, i, 1);
3002 
3003  /* Adds comma and new value to old header value */
3004  octstr_append(value, octstr_imm(", "));
3005  octstr_append(value, value2);
3006  /* Creates a new header */
3007  header = octstr_create("");
3008  octstr_append(header, name);
3009  octstr_append(header, octstr_imm(": "));
3010  octstr_append(header, value);
3011  gwlist_insert(headers, i, header);
3012 
3013  /* Delete this header */
3014  header = gwlist_get(headers, j);
3015  octstr_destroy(header);
3016  gwlist_delete(headers, j, 1);
3017  j--;
3018  }
3019  }
3020  octstr_destroy(name2);
3021  octstr_destroy(value2);
3022  }
3023  octstr_destroy(name);
3024  octstr_destroy(value);
3025  }
3026 }
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2879
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
#define MAX_HEADER_LENGTH
Definition: http.c:2964
char * name
Definition: smsc_cimd2.c:212
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
gw_assert(wtls_machine->packet_to_send!=NULL)
void gwlist_insert(List *list, long pos, void *item)
Definition: list.c:214
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
long http_header_quoted_string_len ( Octstr header,
long  start 
)

Definition at line 3270 of file http.c.

References octstr_get_char(), octstr_get_cstr, octstr_len(), start, and warning().

Referenced by http_get_header_parameter(), http_header_split_value(), pack_warning(), and wsp_strip_parameters().

3271 {
3272  long len;
3273  long pos;
3274  int c;
3275 
3276  if (octstr_get_char(header, start) != '"')
3277  return -1;
3278 
3279  len = octstr_len(header);
3280  for (pos = start + 1; pos < len; pos++) {
3281  c = octstr_get_char(header, pos);
3282  if (c == '\\') /* quoted-pair */
3283  pos++;
3284  else if (c == '"')
3285  return pos - start + 1;
3286  }
3287 
3288  warning(0, "Header contains unterminated quoted-string:");
3289  warning(0, "%s", octstr_get_cstr(header));
3290  return len - start;
3291 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void warning(int err, const char *fmt,...)
Definition: log.c:624
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static int start
long http_header_remove_all ( List headers,
char *  name 
)

Definition at line 3112 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_delete(), gwlist_get(), gwlist_len(), header_is_called(), and octstr_destroy().

Referenced by add_msisdn(), change_header_value(), check_x_wap_application_id_header(), fix_boundary_element(), handle_push_message(), http_header_combine(), http_header_mark_transformation(), http_remove_hop_headers(), pap_request_thread(), remove_link_headers(), remove_mime_headers(), remove_x_kannel_headers(), response(), return_reply(), send_request(), set_addr_tuple(), split_header_list(), start_fetch(), and xmlrpc_doc_send().

3113 {
3114  long i;
3115  Octstr *h;
3116  long count;
3117 
3119  gw_assert(headers != NULL);
3120  gw_assert(name != NULL);
3121 
3122  i = 0;
3123  count = 0;
3124  while (i < gwlist_len(headers)) {
3125  h = gwlist_get(headers, i);
3126  if (header_is_called(h, name)) {
3127  gwlist_delete(headers, i, 1);
3128  octstr_destroy(h);
3129  count++;
3130  } else
3131  i++;
3132  }
3133 
3134  return count;
3135 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
char * name
Definition: smsc_cimd2.c:212
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
static int header_is_called(Octstr *header, char *name)
Definition: http.c:2836
List* http_header_split_auth_value ( Octstr value)

Definition at line 3328 of file http.c.

References gwlist_delete(), gwlist_get(), gwlist_len(), http_header_split_value(), octstr_append(), octstr_append_char(), octstr_destroy(), octstr_get_char(), octstr_insert_data(), and octstr_len().

Referenced by pack_known_header().

3329 {
3330  List *result;
3331  Octstr *auth_scheme;
3332  Octstr *element;
3333  long i;
3334 
3335  /*
3336  * According to RFC2617, both "challenge" and "credentials"
3337  * consist of an auth-scheme followed by a list of auth-param.
3338  * Since we have to parse a list of challenges or credentials,
3339  * we have to look for auth-scheme to signal the start of
3340  * a new element. (We can't just split on commas because
3341  * they are also used to separate the auth-params.)
3342  *
3343  * An auth-scheme is a single token, while an auth-param is
3344  * always a key=value pair. So we can recognize an auth-scheme
3345  * as a token that is not followed by a '=' sign.
3346  *
3347  * Simple approach: First split at all commas, then recombine
3348  * the elements that belong to the same challenge or credential.
3349  * This is somewhat expensive but saves programmer thinking time.
3350  *
3351  * Richard Braakman
3352  */
3353 
3354  result = http_header_split_value(value);
3355  if (gwlist_len(result) == 0)
3356  return result;
3357 
3358  auth_scheme = gwlist_get(result, 0);
3359  i = 1;
3360  while (i < gwlist_len(result)) {
3361  int c;
3362  long pos;
3363 
3364  element = gwlist_get(result, i);
3365 
3366  /*
3367  * If the element starts with: token '='
3368  * then it's just an auth_param; append it to the current
3369  * auth_scheme. If it starts with: token token '='
3370  * then it's the start of a new auth scheme.
3371  *
3372  * To make the scan easier, we consider anything other
3373  * than whitespace or '=' to be part of a token.
3374  */
3375 
3376  /* Skip first token */
3377  for (pos = 0; pos < octstr_len(element); pos++) {
3378  c = octstr_get_char(element, pos);
3379  if (isspace(c) || c == '=')
3380  break;
3381  }
3382 
3383  /* Skip whitespace, if any */
3384  while (isspace(octstr_get_char(element, pos)))
3385  pos++;
3386 
3387  if (octstr_get_char(element, pos) == '=') {
3388  octstr_append_char(auth_scheme, ';');
3389  octstr_append(auth_scheme, element);
3390  gwlist_delete(result, i, 1);
3391  octstr_destroy(element);
3392  } else {
3393  char semicolon = ';';
3394  octstr_insert_data(element, pos, &semicolon, 1);
3395  auth_scheme = element;
3396  i++;
3397  }
3398  }
3399 
3400  return result;
3401 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
Definition: octstr.c:1459
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
List * http_header_split_value(Octstr *value)
Definition: http.c:3294
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
Definition: list.c:102
List* http_header_split_value ( Octstr value)

Definition at line 3294 of file http.c.

References gwlist_create, http_header_add_element(), http_header_quoted_string_len(), octstr_get_char(), octstr_len(), and start.

Referenced by http_header_split_auth_value(), http_remove_hop_headers(), pack_cache_control(), and pack_known_header().

3295 {
3296  long start; /* start of current element */
3297  long pos;
3298  long len;
3299  List *result;
3300  int c;
3301 
3302  /*
3303  * According to RFC2616 section 4.2, a field-value is either *TEXT
3304  * (the caller is responsible for not feeding us one of those) or
3305  * combinations of token, separators, and quoted-string. We're
3306  * looking for commas which are separators, and have to skip
3307  * commas in quoted-strings.
3308  */
3309 
3310  result = gwlist_create();
3311  len = octstr_len(value);
3312  start = 0;
3313  for (pos = 0; pos < len; pos++) {
3314  c = octstr_get_char(value, pos);
3315  if (c == ',') {
3316  http_header_add_element(result, value, start, pos);
3317  start = pos + 1;
3318  } else if (c == '"') {
3319  pos += http_header_quoted_string_len(value, pos);
3320  pos--; /* compensate for the loop's pos++ */
3321  }
3322  }
3323  http_header_add_element(result, value, start, len);
3324  return result;
3325 }
long http_header_quoted_string_len(Octstr *header, long start)
Definition: http.c:3270
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define gwlist_create()
Definition: list.h:136
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static void http_header_add_element(List *list, Octstr *value, long start, long end)
Definition: http.c:3256
Definition: list.c:102
static int start
Octstr* http_header_value ( List headers,
Octstr name 
)

Definition at line 2909 of file http.c.

References colon, gw_assert(), gwlib_assert_init(), gwlist_get(), gwlist_len(), octstr_case_compare(), octstr_copy, octstr_destroy(), octstr_len(), octstr_search_char(), and octstr_strip_blanks().

Referenced by add_msisdn(), add_via(), cid_matches(), client_thread(), fix_boundary_element(), mime_entity_dump_real(), mime_multipart_start_elem(), mime_something_to_entity(), return_reply(), set_addr_tuple(), set_dlr_mask(), set_dlr_url(), set_smsbox_id(), and set_smsc_id().

2910 {
2911  Octstr *value;
2912  long i;
2913  Octstr *os;
2914  long colon;
2915  Octstr *current_name;
2916 
2918  gw_assert(name);
2919 
2920  value = NULL;
2921  i = 0;
2922  while (i < gwlist_len(headers)) {
2923  os = gwlist_get(headers, i);
2924  if (os == NULL)
2925  colon = -1;
2926  else
2927  colon = octstr_search_char(os, ':', 0);
2928  if (colon == -1) {
2929  return NULL;
2930  } else {
2931  current_name = octstr_copy(os, 0, colon);
2932  }
2933  if (octstr_case_compare(current_name, name) == 0) {
2934  value = octstr_copy(os, colon + 1, octstr_len(os) - colon - 1);
2935  octstr_strip_blanks(value);
2936  octstr_destroy(current_name);
2937  return value;
2938  }
2939  octstr_destroy(current_name);
2940  ++i;
2941  }
2942 
2943  return NULL;
2944 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
static Octstr * colon
Definition: smsc_smasi.c:218
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void http_init ( void  )

Definition at line 3575 of file http.c.

References client_init(), conn_pool_init(), gw_assert(), limbo, port_init(), proxy_init(), run_status, running, and server_init().

Referenced by gwlib_init().

3576 {
3578 
3579 #ifdef HAVE_LIBSSL
3580  openssl_init_locks();
3581  conn_init_ssl();
3582 #endif /* HAVE_LIBSSL */
3583  proxy_init();
3584  client_init();
3585  conn_pool_init();
3586  port_init();
3587  server_init();
3588 #ifdef HAVE_LIBSSL
3589  server_ssl_init();
3590 #endif /* HAVE_LIBSSL */
3591 
3592  run_status = running;
3593 }
static void proxy_init(void)
Definition: http.c:225
static void server_init(void)
Definition: http.c:2750
static void client_init(void)
Definition: http.c:1825
Definition: http.c:115
static void conn_pool_init(void)
Definition: http.c:762
static void port_init(void)
Definition: http.c:2018
static enum @59 run_status
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: http.c:114
int http_method ( HTTPClient client)

Definition at line 2740 of file http.c.

References HTTPClient::method.

2741 {
2742  return client->method;
2743 }
int method
Definition: http.c:1865
char* http_method2name ( int  method)

Definition at line 3651 of file http.c.

References gw_assert(), and http_methods.

Referenced by send_request().

3652 {
3653  gw_assert(method > 0 && method <= 3);
3654 
3655  return http_methods[method-1];
3656 }
static int method
Definition: test_http.c:76
gw_assert(wtls_machine->packet_to_send!=NULL)
static char * http_methods[]
Definition: http.c:660
int http_name2method ( Octstr method)

Definition at line 3633 of file http.c.

References gw_assert(), HTTP_METHOD_GET, HTTP_METHOD_HEAD, HTTP_METHOD_POST, and octstr_str_compare().

Referenced by main(), and start_fetch().

3634 {
3635  gw_assert(method != NULL);
3636 
3637  if (octstr_str_compare(method, "GET") == 0) {
3638  return HTTP_METHOD_GET;
3639  }
3640  else if (octstr_str_compare(method, "POST") == 0) {
3641  return HTTP_METHOD_POST;
3642  }
3643  else if (octstr_str_compare(method, "HEAD") == 0) {
3644  return HTTP_METHOD_HEAD;
3645  }
3646 
3647  return -1;
3648 }
gw_assert(wtls_machine->packet_to_send!=NULL)
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
int http_open_port ( int  port,
int  ssl 
)

Definition at line 2498 of file http.c.

References http_open_port_if().

Referenced by httpd_emu_create(), main(), smsc_http_create(), soap_server_start(), start_http_thread(), and wap_push_ppg_init().

2499 {
2500  return http_open_port_if(port, ssl, NULL);
2501 }
Definition: http.c:1998
int ssl
int http_open_port_if(int port, int ssl, Octstr *interface)
Definition: http.c:2472
int http_open_port_if ( int  port,
int  ssl,
Octstr interface 
)

Definition at line 2472 of file http.c.

References port::fd, gwlist_produce(), gwthread_wakeup(), info(), make_server_socket(), octstr_get_cstr, port, port::port, port_add(), port_remove(), ssl, port::ssl, and start_server_thread().

Referenced by http_open_port(), httpadmin_start(), and init_smsbox().

2473 {
2474  struct port *p;
2475 
2476  if (ssl)
2477  info(0, "HTTP: Opening SSL server at port %d.", port);
2478  else
2479  info(0, "HTTP: Opening server at port %d.", port);
2480  p = port_add(port);
2481  p->port = port;
2482  p->ssl = ssl;
2483  p->fd = make_server_socket(port, (interface ? octstr_get_cstr(interface) : NULL));
2484  if (p->fd == -1) {
2485  port_remove(port);
2486  return -1;
2487  }
2488 
2490  keep_servers_open = 1;
2493 
2494  return 0;
2495 }
void info(int err, const char *fmt,...)
Definition: log.c:636
Definition: http.c:1998
static long server_thread_id
Definition: http.c:1879
int ssl
void gwlist_produce(List *list, void *item)
Definition: list.c:411
int port
Definition: http.c:2000
int ssl
Definition: http.c:2001
int fd
Definition: http.c:1999
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static List * new_server_sockets
Definition: http.c:1880
static void port_remove(int port)
Definition: http.c:2065
static int port
Definition: fakesmsc.c:120
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
static int keep_servers_open
Definition: http.c:1882
void gwthread_wakeup(long thread)
static void start_server_thread(void)
Definition: http.c:2447
static struct port * port_add(int port)
Definition: http.c:2041
static const char* http_reason_phrase ( int  status)
static

Definition at line 2621 of file http.c.

References HTTP_ACCEPTED, HTTP_BAD_GATEWAY, HTTP_BAD_METHOD, HTTP_BAD_REQUEST, HTTP_CREATED, HTTP_FORBIDDEN, HTTP_FOUND, HTTP_INTERNAL_SERVER_ERROR, HTTP_MOVED_PERMANENTLY, HTTP_NO_CONTENT, HTTP_NOT_ACCEPTABLE, HTTP_NOT_FOUND, HTTP_NOT_IMPLEMENTED, HTTP_NOT_MODIFIED, HTTP_OK, HTTP_REQUEST_ENTITY_TOO_LARGE, HTTP_RESET_CONTENT, HTTP_SEE_OTHER, HTTP_TEMPORARY_REDIRECT, HTTP_UNAUTHORIZED, and HTTP_UNSUPPORTED_MEDIA_TYPE.

Referenced by http_send_reply().

2622 {
2623  switch (status) {
2624  case HTTP_OK:
2625  return "OK"; /* 200 */
2626  case HTTP_CREATED:
2627  return "Created"; /* 201 */
2628  case HTTP_ACCEPTED:
2629  return "Accepted"; /* 202 */
2630  case HTTP_NO_CONTENT:
2631  return "No Content"; /* 204 */
2632  case HTTP_RESET_CONTENT:
2633  return "Reset Content"; /* 205 */
2635  return "Moved Permanently"; /* 301 */
2636  case HTTP_FOUND:
2637  return "Found"; /* 302 */
2638  case HTTP_SEE_OTHER:
2639  return "See Other"; /* 303 */
2640  case HTTP_NOT_MODIFIED:
2641  return "Not Modified"; /* 304 */
2643  return "Temporary Redirect"; /* 307 */
2644  case HTTP_BAD_REQUEST:
2645  return "Bad Request"; /* 400 */
2646  case HTTP_UNAUTHORIZED:
2647  return "Unauthorized"; /* 401 */
2648  case HTTP_FORBIDDEN:
2649  return "Forbidden"; /* 403 */
2650  case HTTP_NOT_FOUND:
2651  return "Not Found"; /* 404 */
2652  case HTTP_BAD_METHOD:
2653  return "Method Not Allowed"; /* 405 */
2654  case HTTP_NOT_ACCEPTABLE:
2655  return "Not Acceptable"; /* 406 */
2657  return "Request Entity Too Large"; /* 413 */
2659  return "Unsupported Media Type"; /* 415 */
2661  return "Internal Server Error"; /* 500 */
2662  case HTTP_NOT_IMPLEMENTED:
2663  return "Not Implemented"; /* 501 */
2664  case HTTP_BAD_GATEWAY:
2665  return "Bad Gateway"; /* 502 */
2666  }
2667  return "Foo";
2668 }
Definition: http.h:142
void* http_receive_result_real ( HTTPCaller caller,
int *  status,
Octstr **  final_url,
List **  headers,
Octstr **  body,
int  blocking 
)

Definition at line 1771 of file http.c.

References HTTPEntity::body, gwlist_consume(), gwlist_extract_first(), HTTPEntity::headers, HTTPServer::request_id, HTTPServer::response, server_destroy(), HTTPServer::status, and HTTPServer::url.

1773 {
1774  HTTPServer *trans;
1775  void *request_id;
1776 
1777  if (blocking == 0)
1778  trans = gwlist_extract_first(caller);
1779  else
1780  trans = gwlist_consume(caller);
1781  if (trans == NULL)
1782  return NULL;
1783 
1784  request_id = trans->request_id;
1785  *status = trans->status;
1786 
1787  if (trans->status >= 0) {
1788  *final_url = trans->url;
1789  *headers = trans->response->headers;
1790  *body = trans->response->body;
1791 
1792  trans->url = NULL;
1793  trans->response->headers = NULL;
1794  trans->response->body = NULL;
1795  } else {
1796  *final_url = NULL;
1797  *headers = NULL;
1798  *body = NULL;
1799  }
1800 
1801  server_destroy(trans);
1802  return request_id;
1803 }
static void server_destroy(void *p)
Definition: http.c:730
void * request_id
Definition: http.c:669
long status
Definition: http.c:682
Octstr * body
Definition: http.c:363
void * gwlist_extract_first(List *list)
Definition: list.c:305
Octstr * url
Definition: http.c:671
List * headers
Definition: http.c:362
HTTPEntity * response
Definition: http.c:684
void * gwlist_consume(List *list)
Definition: list.c:427
void http_remove_hop_headers ( List headers)

Definition at line 3138 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_consume(), gwlist_destroy(), http_header_find_all(), http_header_remove_all(), http_header_split_value(), octstr_delete(), octstr_destroy(), and octstr_get_cstr.

Referenced by pap_request_thread(), return_reply(), and start_fetch().

3139 {
3140  Octstr *h;
3141  List *connection_headers;
3142 
3144  gw_assert(headers != NULL);
3145 
3146  /*
3147  * The hop-by-hop headers are a standard list, plus those named
3148  * in the Connection header(s).
3149  */
3150 
3151  connection_headers = http_header_find_all(headers, "Connection");
3152  while ((h = gwlist_consume(connection_headers))) {
3153  List *hop_headers;
3154  Octstr *e;
3155 
3156  octstr_delete(h, 0, strlen("Connection:"));
3157  hop_headers = http_header_split_value(h);
3158  octstr_destroy(h);
3159 
3160  while ((e = gwlist_consume(hop_headers))) {
3162  octstr_destroy(e);
3163  }
3164 
3165  gwlist_destroy(hop_headers, NULL);
3166  }
3167  gwlist_destroy(connection_headers, NULL);
3168 
3169  http_header_remove_all(headers, "Connection");
3170  http_header_remove_all(headers, "Keep-Alive");
3171  http_header_remove_all(headers, "Proxy-Authenticate");
3172  http_header_remove_all(headers, "Proxy-Authorization");
3173  http_header_remove_all(headers, "TE");
3174  http_header_remove_all(headers, "Trailers");
3175  http_header_remove_all(headers, "Transfer-Encoding");
3176  http_header_remove_all(headers, "Upgrade");
3177 }
List * http_header_find_all(List *headers, char *name)
Definition: http.c:3092
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
List * http_header_split_value(Octstr *value)
Definition: http.c:3294
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427
void() gwlib_assert_init(void)
Definition: gwlib.c:72
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
Octstr* http_request_url ( HTTPClient client)

Definition at line 2745 of file http.c.

References HTTPClient::url.

2746 {
2747  return client->url;
2748 }
Octstr * url
Definition: http.c:1866
void http_send_reply ( HTTPClient client,
int  status,
List headers,
Octstr body 
)

Definition at line 2671 of file http.c.

References client_destroy(), client_reset(), HTTPClient::conn, conn_register, conn_write(), date(), date_format_http(), gwlist_get(), gwlist_len(), HTTP_METHOD_HEAD, http_reason_phrase(), HTTPClient::method, octstr_append(), octstr_destroy(), octstr_format(), octstr_format_append(), octstr_get_cstr, octstr_len(), HTTPClient::persistent_conn, HTTPClient::port, port_get_fdset(), receive_request(), response(), HTTPClient::state, and HTTPClient::use_version_1_0.

Referenced by brunet_receive_sms(), challenge(), clickatell_receive_sms(), client_thread(), delayed_http_reply(), generic_receive_sms(), http_thread(), httpd_emu_reply(), httpd_serve(), kannel_receive_sms(), pap_request_thread(), receive_request(), reply(), send_to_pi(), sendsms_thread(), soap_server(), and xidris_receive_sms().

2673 {
2674  Octstr *response;
2675  Octstr *date;
2676  long i;
2677  int ret;
2678 
2679  if (client->use_version_1_0)
2680  response = octstr_format("HTTP/1.0 %d %s\r\n", status, http_reason_phrase(status));
2681  else
2682  response = octstr_format("HTTP/1.1 %d %s\r\n", status, http_reason_phrase(status));
2683 
2684  /* identify ourselfs */
2685  octstr_format_append(response, "Server: " GW_NAME "/%s\r\n", GW_VERSION);
2686 
2687  /* let's inform the client of our time */
2688  date = date_format_http(time(NULL));
2689  octstr_format_append(response, "Date: %s\r\n", octstr_get_cstr(date));
2690  octstr_destroy(date);
2691 
2692  octstr_format_append(response, "Content-Length: %ld\r\n", octstr_len(body));
2693 
2694  /*
2695  * RFC2616, sec. 8.1.2.1 says that if the server chooses to close the
2696  * connection, it *should* send a coresponding header
2697  */
2698  if (!client->use_version_1_0 && !client->persistent_conn)
2699  octstr_format_append(response, "Connection: close\r\n");
2700 
2701  for (i = 0; i < gwlist_len(headers); ++i)
2702  octstr_format_append(response, "%S\r\n", gwlist_get(headers, i));
2703  octstr_format_append(response, "\r\n");
2704 
2705  if (body != NULL && client->method != HTTP_METHOD_HEAD)
2706  octstr_append(response, body);
2707 
2708  ret = conn_write(client->conn, response);
2709  octstr_destroy(response);
2710 
2711  /* obey return code of conn_write() */
2712  /* sending response was successful */
2713  if (ret == 0) {
2714  /* HTTP/1.0 or 1.1, hence keep-alive or keep-alive */
2715  if (!client->persistent_conn) {
2716  client_destroy(client);
2717  } else {
2718  /* XXX mark this HTTPClient in the keep-alive cleaner thread */
2719  client_reset(client);
2720  conn_register(client->conn, port_get_fdset(client->port), receive_request, client);
2721  }
2722  }
2723  /* queued for sending, we don't want to block */
2724  else if (ret == 1) {
2725  client->state = sending_reply;
2726  conn_register(client->conn, port_get_fdset(client->port), receive_request, client);
2727  }
2728  /* error while sending response */
2729  else {
2730  client_destroy(client);
2731  }
2732 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
long gwlist_len(List *list)
Definition: list.c:166
Connection * conn
Definition: http.c:1857
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int use_version_1_0
Definition: http.c:1867
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static void client_destroy(void *client)
Definition: http.c:1917
static const char * http_reason_phrase(int status)
Definition: http.c:2621
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1043
static FDSet * port_get_fdset(int port)
Definition: http.c:2174
static void client_reset(HTTPClient *p)
Definition: http.c:1952
int method
Definition: http.c:1865
#define conn_register(conn, fdset, callback, data)
Definition: conn.h:215
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
int persistent_conn
Definition: http.c:1868
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static void receive_request(Connection *conn, void *data)
Definition: http.c:2240
Definition: octstr.c:118
int port
Definition: http.c:1856
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
enum HTTPClient::@61 state
Octstr * date_format_http(unsigned long unixtime)
Definition: date.c:89
static int date(int hex)
static int response(List *push_headers, Octstr **username, Octstr **password)
void http_set_client_timeout ( long  timeout)

Define timeout in seconds for which HTTP client will wait for response. Set -1 to disable timeouts.

Definition at line 1736 of file http.c.

References fdset_set_timeout(), and http_client_timeout.

Referenced by init_bearerbox(), init_smsbox(), and init_wapbox().

1737 {
1738  http_client_timeout = timeout;
1739  if (client_fdset != NULL) {
1740  /* we are already initialized set timeout in fdset */
1742  }
1743 }
static int http_client_timeout
Definition: http.c:91
static FDSet * client_fdset
Definition: http.c:647
void fdset_set_timeout(FDSet *set, long timeout)
Definition: fdset.c:547
void http_set_interface ( const Octstr our_host)

Definition at line 1731 of file http.c.

References octstr_duplicate.

Referenced by config_reload().

1732 {
1733  http_interface = octstr_duplicate(our_host);
1734 }
static Octstr * http_interface
Definition: http.c:123
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void http_set_server_timeout ( int  port,
long  timeout 
)

Define timeout in seconds for which HTTP server will wait for request. Set -1 to disable timeouts.

Definition at line 2466 of file http.c.

References port_set_timeout().

2467 {
2468  port_set_timeout(port, timeout);
2469 }
static void port_set_timeout(int port, long timeout)
Definition: http.c:2157
Definition: http.c:1998
void http_shutdown ( void  )

Definition at line 3596 of file http.c.

References client_shutdown(), conn_pool_shutdown(), gw_assert(), gwlib_assert_init(), limbo, port_shutdown(), proxy_shutdown(), run_status, running, server_shutdown(), and terminating.

Referenced by gwlib_shutdown().

3597 {
3600 
3602 
3604  client_shutdown();
3605  server_shutdown();
3606  port_shutdown();
3607  proxy_shutdown();
3608 #ifdef HAVE_LIBSSL
3609  openssl_shutdown_locks();
3610  conn_shutdown_ssl();
3611  server_shutdown_ssl();
3612 #endif /* HAVE_LIBSSL */
3613  run_status = limbo;
3614 }
Definition: http.c:115
static void server_shutdown(void)
Definition: http.c:2776
static enum @59 run_status
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: http.c:114
static void conn_pool_shutdown(void)
Definition: http.c:769
void() gwlib_assert_init(void)
Definition: gwlib.c:72
static void port_shutdown(void)
Definition: http.c:2026
static void proxy_shutdown(void)
Definition: http.c:232
static void client_shutdown(void)
Definition: http.c:1833
static int http_something_accepted ( List headers,
char *  header_name,
char *  what 
)
static

Definition at line 3453 of file http.c.

References found, gw_assert(), gwlib_assert_init(), gwlist_get(), gwlist_len(), http_destroy_headers(), http_header_find_all(), octstr_case_search(), octstr_create, and octstr_destroy().

Referenced by http_charset_accepted(), and http_type_accepted().

3455 {
3456  int found;
3457  long i;
3458  List *accepts;
3459  Octstr *needle = octstr_create(what);
3460 
3462  gw_assert(headers != NULL);
3463  gw_assert(what != NULL);
3464 
3465  /* return all headers with this name */
3466  accepts = http_header_find_all(headers, header_name);
3467 
3468  found = 0;
3469  for (i = 0; !found && i < gwlist_len(accepts); ++i) {
3470  Octstr *header_value = gwlist_get(accepts, i);
3471  if (octstr_case_search(header_value, needle, 0) != -1)
3472  found = 1;
3473  }
3474  octstr_destroy(needle);
3475  http_destroy_headers(accepts);
3476  return found;
3477 }
List * http_header_find_all(List *headers, char *name)
Definition: http.c:3092
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static struct pid_list * found
void http_destroy_headers(List *headers)
Definition: http.c:2856
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1100
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
Definition: list.c:102
void http_start_request ( HTTPCaller caller,
int  method,
Octstr url,
List headers,
Octstr body,
int  follow,
void *  id,
Octstr certkeyfile 
)

Definition at line 1745 of file http.c.

References gwlist_produce(), HTTP_MAX_FOLLOW, http_start_request(), HTTPServer::request_id, server_create(), and start_client_threads().

Referenced by brunet_send_sms(), clickatell_send_sms(), generic_send_sms(), http_get_real(), http_queue_thread(), http_start_request(), kannel_send_sms(), obey_request(), receive_push_reply(), soap_client_init_query(), start_fetch(), start_push(), start_request(), wapme_smsproxy_send_sms(), xidris_send_sms(), and xmlrpc_doc_send().

1747 {
1748  HTTPServer *trans;
1749  int follow_remaining;
1750 
1751  if (follow)
1752  follow_remaining = HTTP_MAX_FOLLOW;
1753  else
1754  follow_remaining = 0;
1755 
1756  trans = server_create(caller, method, url, headers, body, follow_remaining,
1757  certkeyfile);
1758 
1759  if (id == NULL)
1760  /* We don't leave this NULL so http_receive_result can use NULL
1761  * to signal no more requests */
1762  trans->request_id = http_start_request;
1763  else
1764  trans->request_id = id;
1765 
1768 }
#define HTTP_MAX_FOLLOW
Definition: http.c:653
static List * pending_requests
Definition: http.c:633
void * request_id
Definition: http.c:669
void gwlist_produce(List *list, void *item)
Definition: list.c:411
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1745
static int method
Definition: test_http.c:76
static HTTPServer * server_create(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow_remaining, Octstr *certkeyfile)
Definition: http.c:700
static void start_client_threads(void)
Definition: http.c:1708
int http_status_class ( int  code)

Definition at line 3621 of file http.c.

References HTTP_STATUS_UNKNOWN.

Referenced by handle_transaction(), response_expectation(), and return_reply().

3622 {
3623  int sclass;
3624 
3625  if (code < 100 || code >= 600)
3626  sclass = HTTP_STATUS_UNKNOWN;
3627  else
3628  sclass = code - (code % 100);
3629  return sclass;
3630 }
int code
Definition: smsc_cimd2.c:346
int http_type_accepted ( List headers,
char *  type 
)

Definition at line 3480 of file http.c.

References http_something_accepted().

Referenced by add_accept_headers(), check_session_request_headers(), convert_content(), httpd_serve(), and return_reply().

3481 {
3482  return http_something_accepted(headers, "Accept", type);
3483 }
int type
Definition: smsc_cimd2.c:215
static int http_something_accepted(List *headers, char *header_name, char *what)
Definition: http.c:3453
HTTPURLParse* http_urlparse_create ( void  )

Definition at line 1304 of file http.c.

References HTTPURLParse::fragment, HTTPURLParse::host, HTTPURLParse::pass, HTTPURLParse::path, HTTPURLParse::port, HTTPURLParse::query, HTTPURLParse::scheme, HTTPURLParse::url, and HTTPURLParse::user.

Referenced by parse_url().

1305 {
1306  HTTPURLParse *p;
1307 
1308  p = gw_malloc(sizeof(HTTPURLParse));
1309  p->url = NULL;
1310  p->scheme = NULL;
1311  p->host = NULL;
1312  p->port = 0;
1313  p->user = NULL;
1314  p->pass = NULL;
1315  p->path = NULL;
1316  p->query = NULL;
1317  p->fragment = NULL;
1318 
1319  return p;
1320 }
Octstr * pass
Definition: http.h:244
Octstr * fragment
Definition: http.h:247
Octstr * query
Definition: http.h:246
unsigned long port
Definition: http.h:242
Octstr * host
Definition: http.h:241
Octstr * url
Definition: http.h:239
Octstr * path
Definition: http.h:245
Octstr * user
Definition: http.h:243
Octstr * scheme
Definition: http.h:240
void http_urlparse_destroy ( HTTPURLParse p)

Definition at line 1323 of file http.c.

References HTTPURLParse::fragment, gw_assert(), HTTPURLParse::host, octstr_destroy(), HTTPURLParse::pass, HTTPURLParse::path, HTTPURLParse::query, HTTPURLParse::scheme, HTTPURLParse::url, and HTTPURLParse::user.

Referenced by get_connection(), and parse_url().

1324 {
1325  gw_assert(p != NULL);
1326 
1327  octstr_destroy(p->url);
1328  octstr_destroy(p->scheme);
1329  octstr_destroy(p->host);
1330  octstr_destroy(p->user);
1331  octstr_destroy(p->pass);
1332  octstr_destroy(p->path);
1333  octstr_destroy(p->query);
1335  gw_free(p);
1336 }
Octstr * pass
Definition: http.h:244
Octstr * fragment
Definition: http.h:247
Octstr * query
Definition: http.h:246
Octstr * host
Definition: http.h:241
Octstr * url
Definition: http.h:239
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
Octstr * path
Definition: http.h:245
Octstr * user
Definition: http.h:243
Octstr * scheme
Definition: http.h:240
void http_use_proxy ( Octstr hostname,
int  port,
int  ssl,
List exceptions,
Octstr username,
Octstr password,
Octstr exceptions_regex 
)

Definition at line 268 of file http.c.

References debug(), gw_assert(), gwlist_append(), gwlist_create, gwlist_get(), gwlist_len(), http_close_proxy(), mutex_lock, mutex_unlock, octstr_duplicate, octstr_get_cstr, octstr_len(), panic, port, proxy_exceptions_regex, proxy_port, proxy_ssl, run_status, running, and ssl.

Referenced by config_reload(), init_bearerbox(), init_smsbox(), and main().

270 {
271  Octstr *e;
272  int i;
273 
275  gw_assert(hostname != NULL);
276  gw_assert(octstr_len(hostname) > 0);
277  gw_assert(port > 0);
278 
281 
282  proxy_hostname = octstr_duplicate(hostname);
283  proxy_port = port;
284  proxy_ssl = ssl;
286  for (i = 0; i < gwlist_len(exceptions); ++i) {
287  e = gwlist_get(exceptions, i);
288  debug("gwlib.http", 0, "HTTP: Proxy exception `%s'.", octstr_get_cstr(e));
290  }
291  if (exceptions_regex != NULL &&
292  (proxy_exceptions_regex = gw_regex_comp(exceptions_regex, REG_EXTENDED)) == NULL)
293  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(exceptions_regex));
294  proxy_username = octstr_duplicate(username);
295  proxy_password = octstr_duplicate(password);
296  debug("gwlib.http", 0, "Using proxy <%s:%d> with %s scheme",
298  (proxy_ssl ? "HTTPS" : "HTTP"));
299 
301 }
Definition: http.c:1998
int ssl
#define mutex_unlock(m)
Definition: thread.h:136
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static int proxy_ssl
Definition: http.c:202
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: http.c:115
static regex_t * proxy_exceptions_regex
Definition: http.c:206
static int port
Definition: fakesmsc.c:120
void http_close_proxy(void)
Definition: http.c:304
static enum @59 run_status
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static int proxy_port
Definition: http.c:201
static Octstr * proxy_username
Definition: http.c:203
static Mutex * proxy_mutex
Definition: http.c:199
gw_assert(wtls_machine->packet_to_send!=NULL)
static Octstr * proxy_hostname
Definition: http.c:200
static List * proxy_exceptions
Definition: http.c:205
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define panic
Definition: log.h:87
#define gwlist_create()
Definition: list.h:136
#define mutex_lock(m)
Definition: thread.h:130
static Octstr * proxy_password
Definition: http.c:204
static void parse2trans ( HTTPURLParse p,
HTTPServer t 
)
static

Definition at line 1528 of file http.c.

References HTTPURLParse::host, HTTPServer::host, octstr_append(), octstr_append_char(), octstr_compare(), octstr_duplicate, octstr_imm(), HTTPURLParse::pass, HTTPServer::password, HTTPURLParse::path, HTTPURLParse::port, HTTPServer::port, HTTPURLParse::query, HTTPURLParse::scheme, HTTPServer::ssl, HTTPServer::uri, HTTPURLParse::user, and HTTPServer::username.

Referenced by get_connection().

1529 {
1530  if (p == NULL || t == NULL)
1531  return;
1532 
1533  if (p->user && !t->username)
1534  t->username = octstr_duplicate(p->user);
1535  if (p->pass && !t->password)
1536  t->password = octstr_duplicate(p->pass);
1537  if (p->host && !t->host)
1538  t->host = octstr_duplicate(p->host);
1539  if (p->port && !t->port)
1540  t->port = p->port;
1541  if (p->path && !t->uri) {
1542  t->uri = octstr_duplicate(p->path);
1543  if (p->query) { /* add the query too */
1544  octstr_append_char(t->uri, '?');
1545  octstr_append(t->uri, p->query);
1546  }
1547  }
1548  t->ssl = (p->scheme && (octstr_compare(p->scheme, octstr_imm("https://")) == 0)
1549  && !t->ssl) ? 1 : 0;
1550 }
Octstr * pass
Definition: http.h:244
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
Octstr * query
Definition: http.h:246
Octstr * uri
Definition: http.c:672
unsigned long port
Definition: http.h:242
Octstr * host
Definition: http.h:241
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Octstr * username
Definition: http.c:691
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Octstr * path
Definition: http.h:245
Octstr * user
Definition: http.h:243
long port
Definition: http.c:687
int ssl
Definition: http.c:690
Octstr * host
Definition: http.c:686
Octstr * password
Definition: http.c:692
Octstr * scheme
Definition: http.h:240
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static List* parse_cgivars ( Octstr url)
static

Definition at line 2531 of file http.c.

References gwlist_append(), gwlist_create, HTTPCGIVar::name, octstr_copy, octstr_delete(), octstr_destroy(), octstr_len(), octstr_search_char(), octstr_truncate(), octstr_url_decode(), and HTTPCGIVar::value.

Referenced by http_accept_request().

2532 {
2533  HTTPCGIVar *v;
2534  List *list;
2535  int query, et, equals;
2536  Octstr *arg, *args;
2537 
2538  query = octstr_search_char(url, '?', 0);
2539  if (query == -1)
2540  return gwlist_create();
2541 
2542  args = octstr_copy(url, query + 1, octstr_len(url));
2543  octstr_truncate(url, query);
2544 
2545  list = gwlist_create();
2546 
2547  while (octstr_len(args) > 0) {
2548  et = octstr_search_char(args, '&', 0);
2549  if (et == -1)
2550  et = octstr_len(args);
2551  arg = octstr_copy(args, 0, et);
2552  octstr_delete(args, 0, et + 1);
2553 
2554  equals = octstr_search_char(arg, '=', 0);
2555  if (equals == -1)
2556  equals = octstr_len(arg);
2557 
2558  v = gw_malloc(sizeof(HTTPCGIVar));
2559  v->name = octstr_copy(arg, 0, equals);
2560  v->value = octstr_copy(arg, equals + 1, octstr_len(arg));
2561  octstr_url_decode(v->name);
2563 
2564  octstr_destroy(arg);
2565 
2566  gwlist_append(list, v);
2567  }
2568  octstr_destroy(args);
2569 
2570  return list;
2571 }
Octstr * value
Definition: http.h:213
void gwlist_append(List *list, void *item)
Definition: list.c:179
int octstr_url_decode(Octstr *ostr)
Definition: octstr.c:1744
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
Octstr * name
Definition: http.h:212
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
#define gwlist_create()
Definition: list.h:136
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1325
Definition: list.c:102
void parse_dump ( HTTPURLParse p)

Definition at line 1339 of file http.c.

References debug(), HTTPURLParse::fragment, HTTPURLParse::host, octstr_get_cstr, HTTPURLParse::pass, HTTPURLParse::path, HTTPURLParse::port, HTTPURLParse::query, HTTPURLParse::scheme, HTTPURLParse::url, and HTTPURLParse::user.

Referenced by parse_url().

1340 {
1341  if (p == NULL)
1342  return;
1343  debug("http.parse_url",0,"Parsing URL `%s':", octstr_get_cstr(p->url));
1344  debug("http.parse_url",0," Scheme: %s", octstr_get_cstr(p->scheme));
1345  debug("http.parse_url",0," Host: %s", octstr_get_cstr(p->host));
1346  debug("http.parse_url",0," Port: %ld", p->port);
1347  debug("http.parse_url",0," Username: %s", octstr_get_cstr(p->user));
1348  debug("http.parse_url",0," Password: %s", octstr_get_cstr(p->pass));
1349  debug("http.parse_url",0," Path: %s", octstr_get_cstr(p->path));
1350  debug("http.parse_url",0," Query: %s", octstr_get_cstr(p->query));
1351  debug("http.parse_url",0," Fragment: %s", octstr_get_cstr(p->fragment));
1352 }
Octstr * pass
Definition: http.h:244
Octstr * fragment
Definition: http.h:247
Octstr * query
Definition: http.h:246
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long port
Definition: http.h:242
Octstr * host
Definition: http.h:241
Octstr * url
Definition: http.h:239
Octstr * path
Definition: http.h:245
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Octstr * user
Definition: http.h:243
Octstr * scheme
Definition: http.h:240
static int parse_http_version ( Octstr version)
static

Definition at line 168 of file http.c.

References octstr_get_char(), octstr_imm(), octstr_len(), and octstr_ncompare().

Referenced by client_read_status(), and parse_request_line().

169 {
170  Octstr *prefix;
171  long prefix_len;
172  int digit;
173 
174  prefix = octstr_imm("HTTP/1.");
175  prefix_len = octstr_len(prefix);
176 
177  if (octstr_ncompare(version, prefix, prefix_len) != 0)
178  return -1;
179  if (octstr_len(version) != prefix_len + 1)
180  return -1;
181  digit = octstr_get_char(version, prefix_len);
182  if (!isdigit(digit))
183  return -1;
184  if (digit == '0')
185  return 0;
186  return 1;
187 }
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
int octstr_ncompare(const Octstr *ostr1, const Octstr *ostr2, long n)
Definition: octstr.c:950
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static int parse_request_line ( int *  method,
Octstr **  url,
int *  use_version_1_0,
Octstr line 
)
static

Definition at line 2194 of file http.c.

References error(), gwlist_destroy(), gwlist_get(), gwlist_len(), HTTP_METHOD_GET, HTTP_METHOD_HEAD, HTTP_METHOD_POST, octstr_compare(), octstr_destroy(), octstr_destroy_item(), octstr_imm(), octstr_split_words(), and parse_http_version().

Referenced by receive_request().

2196 {
2197  List *words;
2198  Octstr *version;
2199  Octstr *method_str;
2200  int ret;
2201 
2202  words = octstr_split_words(line);
2203  if (gwlist_len(words) != 3) {
2205  return -1;
2206  }
2207 
2208  method_str = gwlist_get(words, 0);
2209  *url = gwlist_get(words, 1);
2210  version = gwlist_get(words, 2);
2211  gwlist_destroy(words, NULL);
2212 
2213  if (octstr_compare(method_str, octstr_imm("GET")) == 0)
2215  else if (octstr_compare(method_str, octstr_imm("POST")) == 0)
2217  else if (octstr_compare(method_str, octstr_imm("HEAD")) == 0)
2219  else
2220  goto error;
2221 
2222  ret = parse_http_version(version);
2223  if (ret < 0)
2224  goto error;
2225  *use_version_1_0 = !ret;
2226 
2227  octstr_destroy(method_str);
2228  octstr_destroy(version);
2229  return 0;
2230 
2231 error:
2232  octstr_destroy(method_str);
2233  octstr_destroy(*url);
2234  octstr_destroy(version);
2235  *url = NULL;
2236  return -1;
2237 }
void error(int err, const char *fmt,...)
Definition: log.c:612
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1600
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static int parse_http_version(Octstr *version)
Definition: http.c:168
static int method
Definition: test_http.c:76
void octstr_destroy_item(void *os)
Definition: octstr.c:334
Definition: octstr.c:118
Definition: list.c:102
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
HTTPURLParse* parse_url ( Octstr url)

Definition at line 1368 of file http.c.

References colon, debug(), error(), HTTPURLParse::host, HTTP_PORT, http_urlparse_create(), http_urlparse_destroy(), HTTPS_PORT, octstr_case_search(), octstr_compare(), octstr_copy, octstr_create, octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_len(), octstr_parse_long(), octstr_search_char(), octstr_set_char(), parse_dump(), HTTPURLParse::pass, HTTPURLParse::path, HTTPURLParse::port, HTTPURLParse::query, HTTPURLParse::scheme, HTTPURLParse::url, and HTTPURLParse::user.

Referenced by get_connection().

1369 {
1370  HTTPURLParse *p;
1371  Octstr *prefix, *prefix_https;
1372  long prefix_len;
1373  int host_len, colon, slash, at, auth_sep, query;
1374  host_len = colon = slash = at = auth_sep = query = 0;
1375 
1376  prefix = octstr_imm("http://");
1377  prefix_https = octstr_imm("https://");
1378  prefix_len = octstr_len(prefix);
1379 
1380  if (octstr_case_search(url, prefix, 0) != 0) {
1381  if (octstr_case_search(url, prefix_https, 0) == 0) {
1382 #ifdef HAVE_LIBSSL
1383  debug("gwlib.http", 0, "HTTPS URL; Using SSL for the connection");
1384  prefix = prefix_https;
1385  prefix_len = octstr_len(prefix_https);
1386 #else
1387  error(0, "Attempt to use HTTPS <%s> but SSL not compiled in",
1388  octstr_get_cstr(url));
1389  return NULL;
1390 #endif
1391  } else {
1392  error(0, "URL <%s> doesn't start with `%s' nor `%s'",
1393  octstr_get_cstr(url), octstr_get_cstr(prefix),
1394  octstr_get_cstr(prefix_https));
1395  return NULL;
1396  }
1397  }
1398 
1399  /* an URL should be more (at least one charset) then the scheme itself */
1400  if (octstr_len(url) == prefix_len) {
1401  error(0, "URL <%s> is malformed.", octstr_get_cstr(url));
1402  return NULL;
1403  }
1404 
1405  /* check if colon and slashes are within scheme */
1406  colon = octstr_search_char(url, ':', prefix_len);
1407  slash = octstr_search_char(url, '/', prefix_len);
1408  if (colon == prefix_len || slash == prefix_len) {
1409  error(0, "URL <%s> is malformed.", octstr_get_cstr(url));
1410  return NULL;
1411  }
1412 
1413  /* create struct and add values succesively while parsing */
1414  p = http_urlparse_create();
1415  p->url = octstr_duplicate(url);
1416  p->scheme = octstr_duplicate(prefix);
1417 
1418  /* try to parse authentication separator */
1419  at = octstr_search_char(url, '@', prefix_len);
1420  if (at != -1) {
1421  if ((slash == -1 || ( slash != -1 && at < slash))) {
1422  auth_sep = octstr_search_char(url, ':', prefix_len);
1423  if (auth_sep != -1 && (auth_sep < at)) {
1424  octstr_set_char(url, auth_sep, '@');
1425  colon = octstr_search_char(url, ':', prefix_len);
1426  }
1427  } else {
1428  at = -1;
1429  }
1430  }
1431 
1432  /*
1433  * We have to watch out here for 4 cases:
1434  * a) hostname, no port or path
1435  * b) hostname, port, no path
1436  * c) hostname, path, no port
1437  * d) hostname, port and path
1438  */
1439 
1440  /* we only have the hostname, no port or path. */
1441  if (slash == -1 && colon == -1) {
1442  host_len = octstr_len(url) - prefix_len;
1443 #ifdef HAVE_LIBSSL
1444  p->port = (octstr_compare(p->scheme, octstr_imm("https://")) == 0) ?
1446 #else
1447  p->port = HTTP_PORT;
1448 #endif /* HAVE_LIBSSL */
1449  }
1450  /* we have a port, but no path. */
1451  else if (slash == -1) {
1452  host_len = colon - prefix_len;
1453  if (octstr_parse_long((long*) &(p->port), url, colon + 1, 10) == -1) {
1454  error(0, "URL <%s> has malformed port number.",
1455  octstr_get_cstr(url));
1457  return NULL;
1458  }
1459  }
1460  /* we have a path, but no port. */
1461  else if (colon == -1 || colon > slash) {
1462  host_len = slash - prefix_len;
1463 #ifdef HAVE_LIBSSL
1464  p->port = (octstr_compare(p->scheme, octstr_imm("https://")) == 0) ?
1466 #else
1467  p->port = HTTP_PORT;
1468 #endif /* HAVE_LIBSSL */
1469  }
1470  /* we have both, path and port. */
1471  else if (colon < slash) {
1472  host_len = colon - prefix_len;
1473  if (octstr_parse_long((long*) &(p->port), url, colon + 1, 10) == -1) {
1474  error(0, "URL <%s> has malformed port number.",
1475  octstr_get_cstr(url));
1477  return NULL;
1478  }
1479  /* none of the above, so there is something wrong here */
1480  } else {
1481  error(0, "Internal error in URL parsing logic.");
1483  return NULL;
1484  }
1485 
1486  /* there was an authenticator separator, so try to parse
1487  * the username and password credentials */
1488  if (at != -1) {
1489  int at2;
1490 
1491  at2 = octstr_search_char(url, '@', prefix_len);
1492  p->user = octstr_copy(url, prefix_len, at2 - prefix_len);
1493  p->pass = (at2 != at) ? octstr_copy(url, at2 + 1, at - at2 - 1) : NULL;
1494 
1495  if (auth_sep != -1)
1496  octstr_set_char(url, auth_sep, ':');
1497 
1498  host_len = host_len - at + prefix_len - 1;
1499  prefix_len = at + 1;
1500  }
1501 
1502  /* query (CGI vars) */
1503  query = octstr_search_char(url, '?', (slash == -1) ? prefix_len : slash);
1504  if (query != -1) {
1505  p->query = octstr_copy(url, query + 1, octstr_len(url));
1506  if (colon == -1)
1507  host_len = slash != -1 ? slash - prefix_len : query - prefix_len;
1508  }
1509 
1510  /* path */
1511  p->path = (slash == -1) ?
1512  octstr_create("/") : ((query != -1) && (query > slash) ?
1513  octstr_copy(url, slash, query - slash) :
1514  octstr_copy(url, slash, octstr_len(url) - slash));
1515 
1516  /* hostname */
1517  p->host = octstr_copy(url, prefix_len, host_len);
1518 
1519  /* XXX add fragment too */
1520 
1521  /* dump components */
1522  parse_dump(p);
1523 
1524  return p;
1525 }
void error(int err, const char *fmt,...)
Definition: log.c:612
Octstr * pass
Definition: http.h:244
Octstr * query
Definition: http.h:246
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
unsigned long port
Definition: http.h:242
Octstr * host
Definition: http.h:241
void http_urlparse_destroy(HTTPURLParse *p)
Definition: http.c:1323
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void parse_dump(HTTPURLParse *p)
Definition: http.c:1339
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Octstr * url
Definition: http.h:239
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1100
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * path
Definition: http.h:245
static Octstr * colon
Definition: smsc_smasi.c:218
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:747
Octstr * user
Definition: http.h:243
HTTPURLParse * http_urlparse_create(void)
Definition: http.c:1304
void octstr_set_char(Octstr *ostr, long pos, int ch)
Definition: octstr.c:413
Octstr * scheme
Definition: http.h:240
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static struct port* port_add ( int  port)
static

Definition at line 2041 of file http.c.

References port::active_consumers, port::clients_with_requests, counter_create(), dict_get(), dict_put(), fdset_create_real(), gwlist_add_producer(), gwlist_create, HTTP_SERVER_TIMEOUT, mutex_lock, mutex_unlock, octstr_destroy(), port_key(), port::server_fdset, and warning().

Referenced by http_open_port_if().

2042 {
2043  Octstr *key;
2044  struct port *p;
2045 
2046  key = port_key(port);
2048  if ((p = dict_get(port_collection, key)) == NULL) {
2049  p = gw_malloc(sizeof(*p));
2054  dict_put(port_collection, key, p);
2055  } else {
2056  warning(0, "HTTP: port_add called for existing port (%d)", port);
2057  }
2059  octstr_destroy(key);
2060 
2061  return p;
2062 }
Definition: http.c:1998
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * port_mutex
Definition: http.c:2008
static Octstr * port_key(int port)
Definition: http.c:2035
FDSet * server_fdset
Definition: http.c:2004
Counter * counter_create(void)
Definition: counter.c:94
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
Counter * active_consumers
Definition: http.c:2003
void warning(int err, const char *fmt,...)
Definition: log.c:624
List * clients_with_requests
Definition: http.c:2002
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
#define HTTP_SERVER_TIMEOUT
Definition: http.c:94
static Dict * port_collection
Definition: http.c:2009
#define gwlist_create()
Definition: list.h:136
void gwlist_add_producer(List *list)
Definition: list.c:383
#define mutex_lock(m)
Definition: thread.h:130
FDSet * fdset_create_real(long timeout)
Definition: fdset.c:368
static FDSet* port_get_fdset ( int  port)
static

Definition at line 2174 of file http.c.

References dict_get(), mutex_lock, mutex_unlock, octstr_destroy(), port_key(), and port::server_fdset.

Referenced by http_send_reply().

2175 {
2176  Octstr *key;
2177  struct port *p;
2178  FDSet *ret = NULL;
2179 
2181  key = port_key(port);
2182  p = dict_get(port_collection, key);
2183  octstr_destroy(key);
2184 
2185  if (p != NULL)
2186  ret = p->server_fdset;
2187 
2189 
2190  return ret;
2191 }
Definition: http.c:1998
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * port_mutex
Definition: http.c:2008
static Octstr * port_key(int port)
Definition: http.c:2035
FDSet * server_fdset
Definition: http.c:2004
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
static Dict * port_collection
Definition: http.c:2009
Definition: fdset.c:70
#define mutex_lock(m)
Definition: thread.h:130
static HTTPClient* port_get_request ( int  port)
static

Definition at line 2133 of file http.c.

References port::active_consumers, client(), port::clients_with_requests, counter_decrease(), counter_increase(), dict_get(), gwlist_consume(), mutex_lock, mutex_unlock, octstr_destroy(), and port_key().

Referenced by http_accept_request().

2134 {
2135  Octstr *key;
2136  struct port *p;
2137  HTTPClient *client;
2138 
2140  key = port_key(port);
2141  p = dict_get(port_collection, key);
2142  octstr_destroy(key);
2143 
2144  if (p == NULL) {
2145  client = NULL;
2147  } else {
2149  mutex_unlock(port_mutex); /* Placement of this unlock is tricky. */
2152  }
2153  return client;
2154 }
Definition: http.c:1998
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * port_mutex
Definition: http.c:2008
static void client(int port)
Definition: test_udp.c:77
static Octstr * port_key(int port)
Definition: http.c:2035
unsigned long counter_decrease(Counter *counter)
Definition: counter.c:155
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
Counter * active_consumers
Definition: http.c:2003
List * clients_with_requests
Definition: http.c:2002
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427
static Dict * port_collection
Definition: http.c:2009
#define mutex_lock(m)
Definition: thread.h:130
static void port_init ( void  )
static

Definition at line 2018 of file http.c.

References dict_create(), gwlist_create, and mutex_create.

Referenced by http_init().

2019 {
2021  port_collection = dict_create(1024, NULL);
2022  /* create list with all active_connections */
2024 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static List * active_connections
Definition: http.c:1884
static Mutex * port_mutex
Definition: http.c:2008
#define mutex_create()
Definition: thread.h:96
static Dict * port_collection
Definition: http.c:2009
#define gwlist_create()
Definition: list.h:136
static Octstr* port_key ( int  port)
static

Definition at line 2035 of file http.c.

References octstr_format().

Referenced by port_add(), port_get_fdset(), port_get_request(), port_put_request(), port_remove(), and port_set_timeout().

2036 {
2037  return octstr_format("%d", port);
2038 }
Definition: http.c:1998
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
static int port_match ( void *  client,
void *  port 
)
static

Definition at line 2012 of file http.c.

Referenced by port_remove().

2013 {
2014  return ((HTTPClient*)client)->port == *((int*)port);
2015 }