Kannel: Open Source WAP and SMS gateway  svn-r5335
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/gw-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)
 
void parse_cgivars (List *cgivars, Octstr *pairs)
 
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 = 30
 
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

◆ DUMP_RESPONSE

#define DUMP_RESPONSE   1

Definition at line 88 of file http.c.

◆ HTTP_MAX_FOLLOW

#define HTTP_MAX_FOLLOW   5

Definition at line 653 of file http.c.

Referenced by http_start_request().

◆ HTTP_SERVER_MAX_ACTIVE_CONNECTIONS

#define HTTP_SERVER_MAX_ACTIVE_CONNECTIONS   500

Definition at line 96 of file http.c.

Referenced by client_destroy(), and server_thread().

◆ HTTP_SERVER_TIMEOUT

#define HTTP_SERVER_TIMEOUT   60

Definition at line 94 of file http.c.

Referenced by port_add().

◆ MAX_HEADER_LENGTH

#define MAX_HEADER_LENGTH   256

Definition at line 2987 of file http.c.

Referenced by http_header_pack().

Enumeration Type Documentation

◆ anonymous enum

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

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

◆ body_expectation

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 };

◆ entity_state

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

◆ build_request()

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 1244 of file http.c.

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

Referenced by send_request().

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

◆ build_response()

static Octstr * build_response ( List headers,
Octstr body 
)
static

Definition at line 1293 of file http.c.

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

Referenced by handle_transaction().

1294 {
1295  Octstr *response;
1296  int i;
1297 
1298  response = octstr_create("");
1299 
1300  for (i = 0; headers != NULL && i < gwlist_len(headers); ++i) {
1301  octstr_append(response, gwlist_get(headers, i));
1302  octstr_append(response, octstr_imm("\r\n"));
1303  }
1304  octstr_append(response, octstr_imm("\r\n"));
1305 
1306  if (body != NULL)
1307  octstr_append(response, body);
1308 
1309  return response;
1310 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
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:283
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
static int response(List *push_headers, Octstr **username, Octstr **password)

◆ client_create()

static HTTPClient* client_create ( int  port,
Connection conn,
Octstr ip 
)
static

Definition at line 1902 of file http.c.

References active_connections, 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().

1903 {
1904  HTTPClient *p;
1905 
1906 #ifdef HAVE_LIBSSL
1907  if (conn_get_ssl(conn))
1908  debug("gwlib.http", 0, "HTTP: Creating SSL-enabled HTTPClient for `%s', using cipher '%s'.",
1909  octstr_get_cstr(ip), SSL_get_cipher_version(conn_get_ssl(conn)));
1910  else
1911 #endif
1912  debug("gwlib.http", 0, "HTTP: Creating HTTPClient for `%s'.", octstr_get_cstr(ip));
1913  p = gw_malloc(sizeof(*p));
1914  p->port = port;
1915  p->conn = conn;
1916  p->ip = ip;
1917  p->state = reading_request_line;
1918  p->url = NULL;
1919  p->use_version_1_0 = 0;
1920  p->persistent_conn = 1;
1921  p->conn_time = time(NULL);
1922  p->request = NULL;
1923  debug("gwlib.http", 0, "HTTP: Created HTTPClient area %p.", p);
1924 
1925  /* add this client to active_connections */
1927 
1928  return p;
1929 }
static List * active_connections
Definition: http.c:1899
void gwlist_produce(List *list, void *item)
Definition: list.c:411
Connection * conn
Definition: http.c:1872
int use_version_1_0
Definition: http.c:1882
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * ip
Definition: http.c:1873
static int port
Definition: fakesmsc.c:121
Octstr * url
Definition: http.c:1881
int persistent_conn
Definition: http.c:1883
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int port
Definition: http.c:1871
enum HTTPClient::@61 state
unsigned long conn_time
Definition: http.c:1884
HTTPEntity * request
Definition: http.c:1885

◆ client_destroy()

static void client_destroy ( void *  client)
static

Definition at line 1932 of file http.c.

References active_connections, 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, server_thread_id, and HTTPClient::url.

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

1933 {
1934  HTTPClient *p;
1935  long a_len;
1936 
1937  if (client == NULL)
1938  return;
1939 
1940  p = client;
1941 
1942  /* drop this client from active_connections list */
1945  panic(0, "HTTP: Race condition in client_destroy(%p) detected!", client);
1946 
1947  /* signal server thread that client slot is free */
1948  a_len = gwlist_len(active_connections);
1950 
1951  if (a_len >= HTTP_SERVER_MAX_ACTIVE_CONNECTIONS - 1)
1953 
1954  debug("gwlib.http", 0, "HTTP: Destroying HTTPClient area %p.", p);
1955  gw_assert_allocated(p, __FILE__, __LINE__, __func__);
1956  debug("gwlib.http", 0, "HTTP: Destroying HTTPClient for `%s'.",
1957  octstr_get_cstr(p->ip));
1958 
1959  conn_destroy(p->conn);
1960  octstr_destroy(p->ip);
1961  octstr_destroy(p->url);
1962  entity_destroy(p->request);
1963  gw_free(p);
1964 }
static List * active_connections
Definition: http.c:1899
static long server_thread_id
Definition: http.c:1894
long gwlist_len(List *list)
Definition: list.c:166
Connection * conn
Definition: http.c:1872
static void client(int port)
Definition: test_udp.c:77
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * ip
Definition: http.c:1873
void gwlist_unlock(List *list)
Definition: list.c:354
void conn_destroy(Connection *conn)
Definition: conn.c:627
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
Octstr * url
Definition: http.c:1881
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#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:726
#define panic
Definition: log.h:87
void gwthread_wakeup(long thread)
HTTPEntity * request
Definition: http.c:1885

◆ client_init()

static void client_init ( void  )
static

Definition at line 1840 of file http.c.

References client_thread_lock, gwlist_add_producer(), gwlist_create, mutex_create, and pending_requests.

Referenced by http_init().

1841 {
1845 }
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

◆ client_is_persistent()

static int client_is_persistent ( List headers,
int  use_version_1_0 
)
static

Definition at line 1982 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().

1983 {
1984  Octstr *h = http_header_find_first(headers, "Connection");
1985 
1986  if (h == NULL) {
1987  /* assumes persistent for HTTP/1.1, not for HTTP/1.0 */
1988  return !use_version_1_0;
1989  } else {
1990  List *values = octstr_split(h, octstr_imm(","));
1991  int ret;
1992  octstr_destroy(h);
1993  if (gwlist_search(values, octstr_imm("keep-alive"), octstr_item_case_match) != NULL) {
1994  /* Keep-Alive was requested */
1995  ret = 1;
1996  } else if (gwlist_search(values, octstr_imm("close"), octstr_item_case_match) != NULL) {
1997  /* Close was requested */
1998  ret = 0;
1999  } else {
2000  /* Nothing was requested, so based on HTTP version */
2001  ret = (!use_version_1_0);
2002  }
2004  return ret;
2005  }
2006 
2007  return 1;
2008 }
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
#define http_header_find_first(headers, name)
Definition: http.h:603
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void octstr_destroy_item(void *os)
Definition: octstr.c:336
int octstr_item_case_match(void *item, void *pattern)
Definition: octstr.c:1667
Definition: octstr.c:118
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1640
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ client_read_status()

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:1134
void error(int err, const char *fmt,...)
Definition: log.c:648
long status
Definition: http.c:682
Connection * conn
Definition: http.c:685
int conn_eof(Connection *conn)
Definition: conn.c:705
#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:1012
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
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:726
int persistent
Definition: http.c:683
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:749
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1327
int conn_error(Connection *conn)
Definition: conn.c:716

◆ client_reset()

static void client_reset ( HTTPClient p)
static

Definition at line 1967 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().

1968 {
1969  debug("gwlib.http", 0, "HTTP: Resetting HTTPClient for `%s'.",
1970  octstr_get_cstr(p->ip));
1971  p->state = reading_request_line;
1972  p->conn_time = time(NULL);
1973  gw_assert(p->request == NULL);
1974 }
gw_assert(wtls_machine->packet_to_send !=NULL)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * ip
Definition: http.c:1873
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
enum HTTPClient::@61 state
unsigned long conn_time
Definition: http.c:1884
HTTPEntity * request
Definition: http.c:1885

◆ client_shutdown()

static void client_shutdown ( void  )
static

Definition at line 1848 of file http.c.

References client_fdset, client_thread_lock, client_threads_are_running, fdset_destroy(), gwlist_destroy(), gwlist_remove_producer(), gwthread_join_every(), http_interface, mutex_destroy(), octstr_destroy(), pending_requests, server_destroy(), and write_request_thread().

Referenced by http_shutdown().

1849 {
1856  client_fdset = NULL;
1858  http_interface = NULL;
1859 }
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:324
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:1681
static FDSet * client_fdset
Definition: http.c:647
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ conn_pool_get()

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, conn_pool_key(), conn_pool_lock, conn_unregister(), conn_wait(), debug(), dict_get(), gwlist_extract_first(), host, mutex_lock, mutex_unlock, octstr_destroy(), octstr_get_cstr, our_host, and ssl.

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 */
832  debug("gwlib.http", 0, "HTTP: Opening connection to `%s:%d' (fd=%d).",
834  } else {
835  debug("gwlib.http", 0, "HTTP: Reusing connection to `%s:%d' (fd=%d).",
837  }
838 
839  return conn;
840 }
Definition: http.c:2014
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:501
static Octstr * host
Definition: fakesmsc.c:122
int conn_eof(Connection *conn)
Definition: conn.c:705
static Dict * conn_pool
Definition: http.c:753
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * our_host
Definition: radius_acct.c:86
void * gwlist_extract_first(List *list)
Definition: list.c:305
int conn_get_id(Connection *conn)
Definition: conn.c:1552
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void conn_destroy(Connection *conn)
Definition: conn.c:627
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void conn_unregister(Connection *conn)
Definition: conn.c:858
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:904
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
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:716
#define mutex_lock(m)
Definition: thread.h:130
static Mutex * conn_pool_lock
Definition: http.c:754
Definition: list.c:102

◆ conn_pool_init()

static void conn_pool_init ( void  )
static

Definition at line 762 of file http.c.

References conn_pool, conn_pool_item_destroy(), conn_pool_lock, 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

◆ conn_pool_item_destroy()

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:627
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ conn_pool_key()

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 host, octstr_format(), octstr_imm(), our_host, and ssl.

Referenced by conn_pool_get().

777 {
778  return octstr_format("%S:%d:%d:%S:%S", host, port, ssl?1:0, certfile?certfile:octstr_imm(""),
780 }
Definition: http.c:2014
int ssl
static Octstr * host
Definition: fakesmsc.c:122
static Octstr * our_host
Definition: radius_acct.c:86
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464

◆ conn_pool_shutdown()

static void conn_pool_shutdown ( void  )
static

Definition at line 769 of file http.c.

References conn_pool, conn_pool_lock, 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

◆ deduce_body_state()

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:648
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#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:603
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:973
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:749
enum entity_state state
Definition: http.c:365

◆ destroy_int_pointer()

static void destroy_int_pointer ( void *  p)
static

Definition at line 2792 of file http.c.

Referenced by server_shutdown().

2793 {
2794  (void) close(*(int *) p);
2795  gw_free(p);
2796 }

◆ destroy_struct_server()

static void destroy_struct_server ( void *  p)
static

Definition at line 2782 of file http.c.

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

Referenced by server_shutdown().

2783 {
2784  struct port *pp;
2785 
2786  pp = p;
2787  (void) close(pp->fd);
2788  port_remove(pp->port);
2789 }
Definition: http.c:2014
int port
Definition: http.c:2016
int fd
Definition: http.c:2015
static void port_remove(int port)
Definition: http.c:2081

◆ entity_create()

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:2872
#define octstr_create(cstr)
Definition: octstr.h:125
enum entity_state state
Definition: http.c:365

◆ entity_destroy()

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:2879
Octstr * body
Definition: http.c:363
List * headers
Definition: http.c:362
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324

◆ entity_read()

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

◆ get_connection()

static Connection* get_connection ( HTTPServer trans)
static

Definition at line 1567 of file http.c.

References HTTPServer::certkeyfile, conn_destroy(), conn_pool_get(), error(), host, HTTPServer::host, http_interface, 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().

1568 {
1569  Connection *conn = NULL;
1570  Octstr *host;
1571  HTTPURLParse *p;
1572  int port, ssl;
1573 
1574  /* if the parsing has not yet been done, then do it now */
1575  if (!trans->host && trans->port == 0 && trans->url != NULL) {
1576  if ((p = parse_url(trans->url)) != NULL) {
1577  parse2trans(p, trans);
1579  } else {
1580  goto error;
1581  }
1582  }
1583 
1584  if (proxy_used_for_host(trans->host, trans->url)) {
1585  host = proxy_hostname;
1586  port = proxy_port;
1587  ssl = proxy_ssl;
1588  } else {
1589  host = trans->host;
1590  port = trans->port;
1591  ssl = trans->ssl;
1592  }
1593 
1594  conn = conn_pool_get(host, port, ssl, trans->certkeyfile,
1595  http_interface);
1596  if (conn == NULL)
1597  goto error;
1598 
1599  return conn;
1600 
1601 error:
1602  conn_destroy(conn);
1603  error(0, "Couldn't send request to <%s>", octstr_get_cstr(trans->url));
1604  return NULL;
1605 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static void parse2trans(HTTPURLParse *p, HTTPServer *t)
Definition: http.c:1543
Definition: http.c:2014
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:122
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:121
void http_urlparse_destroy(HTTPURLParse *p)
Definition: http.c:1332
Octstr * url
Definition: http.c:671
void conn_destroy(Connection *conn)
Definition: conn.c:627
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:1377
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

◆ get_redirection_location()

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:603
HTTPEntity * response
Definition: http.c:684

◆ handle_transaction()

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(), gw_assert(), gwlist_insert(), gwlist_produce(), HTTPEntity::headers, HTTPServer::host, http_header_find_first, http_interface, 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, pending_requests, HTTPServer::persistent, HTTPServer::port, proxy_hostname, 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  gw_assert(trans->conn == conn);
1048 
1049  if (run_status != running) {
1050  conn_unregister(trans->conn);
1051  return;
1052  }
1053 
1054  while (trans->state != transaction_done) {
1055  switch (trans->state) {
1056  case connecting:
1057  debug("gwlib.http", 0, "Get info about connecting socket");
1058  if (conn_get_connect_result(trans->conn) != 0) {
1059  debug("gwlib.http", 0, "Socket not connected");
1060  goto error;
1061  }
1062 
1063  if ((rc = send_request(trans)) == 0) {
1064  trans->state = reading_status;
1065  } else {
1066  debug("gwlib.http", 0, "Failed while sending request");
1067  goto error;
1068  }
1069  break;
1070 
1071  case reading_status:
1072  ret = client_read_status(trans);
1073  if (ret < 0) {
1074  /*
1075  * Couldn't read the status from the socket. This may mean
1076  * that the socket had been closed by the server after an
1077  * idle timeout.
1078  */
1079  debug("gwlib.http",0,"Failed while reading status");
1080  goto error;
1081  } else if (ret == 0) {
1082  /* Got the status, go read headers and body next. */
1083  trans->state = reading_entity;
1084  trans->response = entity_create(response_expectation(trans->method, trans->status));
1085  } else {
1086  return;
1087  }
1088  break;
1089 
1090  case reading_entity:
1091  ret = entity_read(trans->response, trans->conn);
1092  if (ret < 0) {
1093  debug("gwlib.http",0,"Failed reading entity");
1094  goto error;
1095  } else if (ret == 0 &&
1097  /* This was a provisional reply; get the real one now. */
1098  trans->state = reading_status;
1099  entity_destroy(trans->response);
1100  trans->response = NULL;
1101  } else if (ret == 0) {
1102  trans->state = transaction_done;
1103 #ifdef DUMP_RESPONSE
1104  /* Dump the response */
1105  debug("gwlib.http", 0, "HTTP: Received response:");
1106  h = build_response(trans->response->headers, trans->response->body);
1107  octstr_dump(h, 0);
1108  octstr_destroy(h);
1109 #endif
1110  } else {
1111  return;
1112  }
1113  break;
1114 
1115  default:
1116  panic(0, "Internal error: Invalid HTTPServer state.");
1117  }
1118  }
1119 
1120  /*
1121  * Connection may have been destroyed within send_request,
1122  * so be more carefull here not to panic.
1123  */
1124  if (trans->conn)
1125  conn_unregister(trans->conn);
1126 
1127  /*
1128  * Take care of persistent connection handling.
1129  * At this point we have only obeyed if server responds in HTTP/1.0 or 1.1
1130  * and have assigned trans->persistent accordingly. This can be keept
1131  * for default usage, but if we have [Proxy-]Connection: keep-alive, then
1132  * we're still forcing persistancy of the connection.
1133  */
1134  h = http_header_find_first(trans->response->headers, "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  if (proxy_used_for_host(trans->host, trans->url)) {
1141  h = http_header_find_first(trans->response->headers, "Proxy-Connection");
1142  if (h != NULL && octstr_case_compare(h, octstr_imm("close")) == 0)
1143  trans->persistent = 0;
1144  if (h != NULL && octstr_case_compare(h, octstr_imm("keep-alive")) == 0)
1145  trans->persistent = 1;
1146  octstr_destroy(h);
1147  }
1148 
1149 #ifdef USE_KEEPALIVE
1150  if (trans->persistent) {
1151  if (proxy_used_for_host(trans->host, trans->url))
1152  conn_pool_put(trans->conn, proxy_hostname, proxy_port, trans->ssl, trans->certkeyfile, http_interface);
1153  else
1154  conn_pool_put(trans->conn, trans->host, trans->port, trans->ssl, trans->certkeyfile, http_interface);
1155  } else
1156 #endif
1157  conn_destroy(trans->conn);
1158 
1159  trans->conn = NULL;
1160 
1161  /*
1162  * Check if the HTTP server told us to look somewhere else,
1163  * hence if we got one of the following response codes:
1164  * HTTP_MOVED_PERMANENTLY (301)
1165  * HTTP_FOUND (302)
1166  * HTTP_SEE_OTHER (303)
1167  * HTTP_TEMPORARY_REDIRECT (307)
1168  */
1169  if ((h = get_redirection_location(trans)) != NULL) {
1170 
1171  /*
1172  * This is a redirected response, we have to follow.
1173  *
1174  * According to HTTP/1.1 (RFC 2616), section 14.30 any Location
1175  * header value should be 'absoluteURI', which is defined in
1176  * RFC 2616, section 3.2.1 General Syntax, and specifically in
1177  * RFC 2396, section 3 URI Syntactic Components as
1178  *
1179  * absoluteURI = scheme ":" ( hier_part | opaque_part )
1180  *
1181  * Some HTTP servers 'interpret' a leading UDI / as that kind
1182  * of absoluteURI, which is not correct, following the protocol in
1183  * detail. But we'll try to recover from that misleaded
1184  * interpreation and try to convert the partly absoluteURI to a
1185  * fully qualified absoluteURI.
1186  *
1187  * http_URL = "http:" "//" [ userid : password "@"] host
1188  * [ ":" port ] [ abs_path [ "?" query ]]
1189  *
1190  */
1192  recover_absolute_uri(trans, h);
1193 
1194  /*
1195  * Clean up all trans stuff for the next request we do.
1196  */
1197  octstr_destroy(trans->url);
1198  octstr_destroy(trans->host);
1199  trans->port = 0;
1200  octstr_destroy(trans->uri);
1201  octstr_destroy(trans->username);
1202  octstr_destroy(trans->password);
1203  trans->host = NULL;
1204  trans->port = 0;
1205  trans->uri = NULL;
1206  trans->username = NULL;
1207  trans->password = NULL;
1208  trans->ssl = 0;
1209  trans->url = h; /* apply new absolute URL to next request */
1210  trans->state = request_not_sent;
1211  trans->status = -1;
1212  entity_destroy(trans->response);
1213  trans->response = NULL;
1214  --trans->follow_remaining;
1215  conn_destroy(trans->conn);
1216  trans->conn = NULL;
1217 
1218  /* re-inject request to the front of the queue */
1219  gwlist_insert(pending_requests, 0, trans);
1220 
1221  } else {
1222  /* handle this response as usual */
1223  gwlist_produce(trans->caller, trans);
1224  }
1225  return;
1226 
1227 error:
1228  if (trans->conn != NULL) {
1229  conn_unregister(trans->conn);
1230  conn_destroy(trans->conn);
1231  trans->conn = NULL;
1232  }
1233  error(0, "Couldn't fetch <%s>", octstr_get_cstr(trans->url));
1234  trans->status = -1;
1235  gwlist_produce(trans->caller, trans);
1236 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static List * pending_requests
Definition: http.c:633
long status
Definition: http.c:682
gw_assert(wtls_machine->packet_to_send !=NULL)
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:1346
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:1293
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:283
int conn_get_connect_result(Connection *conn)
Definition: conn.c:530
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:627
static int send_request(HTTPServer *trans)
Definition: http.c:1611
#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:3642
#define http_header_find_first(headers, name)
Definition: http.h:603
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:903
static void recover_absolute_uri(HTTPServer *trans, Octstr *loc)
Definition: http.c:941
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
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:858
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:726
#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

◆ header_is_called()

static int header_is_called ( Octstr header,
char *  name 
)
static

Definition at line 2859 of file http.c.

References colon, name, 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().

2860 {
2861  long colon;
2862 
2863  colon = octstr_search_char(header, ':', 0);
2864  if (colon == -1)
2865  return 0;
2866  if ((long) strlen(name) != colon)
2867  return 0;
2868  return strncasecmp(octstr_get_cstr(header), name, colon) == 0;
2869 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
char * name
Definition: smsc_cimd2.c:212
static Octstr * colon
Definition: smsc_smasi.c:218

◆ http_accept_request()

HTTPClient* http_accept_request ( int  port,
Octstr **  client_ip,
Octstr **  url,
List **  headers,
Octstr **  body,
List **  cgivars 
)

Definition at line 2571 of file http.c.

References charset, client(), client_destroy(), client_is_persistent(), conn_eof(), conn_error(), conn_wait(), content_type, debug(), entity_destroy(), gwlist_create, http_header_get_content_type(), http_method2name(), HTTP_METHOD_POST, HTTP_METHOD_PUT, octstr_copy, octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_len(), octstr_search_char(), octstr_str_compare(), octstr_truncate(), parse_cgivars(), port_get_request(), and url.

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

2574 {
2575  HTTPClient *client;
2576  Octstr *query, *content_type, *charset;
2577  int question_mark;
2578 
2579  do {
2581  if (client == NULL) {
2582  debug("gwlib.http", 0, "HTTP: No clients with requests, quitting.");
2583  return NULL;
2584  }
2585  /* check whether client connection still ok */
2586  conn_wait(client->conn, 0);
2587  if (conn_error(client->conn) || conn_eof(client->conn)) {
2589  client = NULL;
2590  }
2591  } while(client == NULL);
2592 
2593  debug("gwlib.http", 0, "HTTP: Got %s request with url='%s' and body='%s'",
2594  http_method2name(client->method), octstr_get_cstr(client->url), octstr_get_cstr(client->request->body));
2595 
2596  *client_ip = octstr_duplicate(client->ip);
2597  *url = client->url;
2598  *headers = client->request->headers;
2599  *body = client->request->body;
2600  *cgivars = gwlist_create();
2601 
2602  /* is there a query string in the url? */
2603  question_mark = octstr_search_char(*url, '?', 0);
2604  if (question_mark >= 0) {
2605  /* parse the query string */
2606  query = octstr_copy(*url, question_mark + 1, octstr_len(*url));
2607  parse_cgivars(*cgivars, query);
2608  octstr_destroy(query);
2609 
2610  /* remove query string from url */
2611  octstr_truncate(*url, question_mark);
2612  }
2613 
2614  if (client->method == HTTP_METHOD_POST || client->method == HTTP_METHOD_PUT) {
2615  if (octstr_len(*body) > 0) {
2617  if (octstr_str_compare(content_type, "application/x-www-form-urlencoded") == 0) {
2618  /* parse the body */
2619  parse_cgivars(*cgivars, *body);
2620  }
2623  }
2624  } else {
2625  octstr_destroy(*body);
2626  *body = NULL;
2627  }
2628 
2629  client->persistent_conn = client_is_persistent(client->request->headers,
2630  client->use_version_1_0);
2631 
2632  client->url = NULL;
2633  client->request->headers = NULL;
2634  client->request->body = NULL;
2635  entity_destroy(client->request);
2636  client->request = NULL;
2637 
2638  return client;
2639 }
void parse_cgivars(List *cgivars, Octstr *pairs)
Definition: http.c:2542
char * http_method2name(int method)
Definition: http.c:3681
Definition: http.c:2014
static HTTPClient * port_get_request(int port)
Definition: http.c:2149
static void client(int port)
Definition: test_udp.c:77
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
Definition: http.c:3225
static int client_is_persistent(List *headers, int use_version_1_0)
Definition: http.c:1982
int conn_eof(Connection *conn)
Definition: conn.c:705
#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:1012
Octstr * charset
Definition: test_ota.c:68
static void client_destroy(void *client)
Definition: http.c:1932
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
const char * content_type
Definition: fakewap.c:249
static void entity_destroy(HTTPEntity *ent)
Definition: http.c:445
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:904
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:973
#define gwlist_create()
Definition: list.h:136
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1327
int conn_error(Connection *conn)
Definition: conn.c:716
static Octstr * url
Definition: test_xmlrpc.c:84

◆ http_add_basic_auth()

void http_add_basic_auth ( List headers,
Octstr username,
Octstr password 
)

Definition at line 3515 of file http.c.

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

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

3516 {
3517  Octstr *os;
3518 
3519  if (password != NULL)
3520  os = octstr_format("%S:%S", username, password);
3521  else
3522  os = octstr_format("%S", username);
3524  octstr_strip_blanks(os);
3525  octstr_insert(os, octstr_imm("Basic "), 0);
3526  http_header_add(headers, "Authorization", octstr_get_cstr(os));
3527  octstr_destroy(os);
3528 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2886
void octstr_binary_to_base64(Octstr *ostr)
Definition: octstr.c:542
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned char * username
Definition: test_cimd2.c:99
unsigned char * password
Definition: test_cimd2.c:100
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118

◆ http_append_headers()

void http_append_headers ( List to,
List from 
)

Definition at line 3052 of file http.c.

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

Referenced by http_header_combine(), and pap_request_thread().

3053 {
3054  Octstr *header;
3055  long i;
3056 
3058  gw_assert(to != NULL);
3059  gw_assert(from != NULL);
3060 
3061  for (i = 0; i < gwlist_len(from); ++i) {
3062  header = gwlist_get(from, i);
3063  gwlist_append(to, octstr_duplicate(header));
3064  }
3065 }
gw_assert(wtls_machine->packet_to_send !=NULL)
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 Octstr * from
Definition: mtbatch.c:95
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72

◆ http_caller_create()

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();
903  return caller;
904 }
static HTTPCaller * caller
Definition: smsbox.c:442
#define gwlist_create()
Definition: list.h:136
void gwlist_add_producer(List *list)
Definition: list.c:383
Definition: list.c:102

◆ http_caller_destroy()

void http_caller_destroy ( HTTPCaller caller)

Definition at line 907 of file http.c.

References caller, 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
static HTTPCaller * caller
Definition: smsbox.c:442
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ http_caller_signal_shutdown()

void http_caller_signal_shutdown ( HTTPCaller caller)

Definition at line 913 of file http.c.

References caller, and gwlist_remove_producer().

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

914 {
916 }
static HTTPCaller * caller
Definition: smsbox.c:442
void gwlist_remove_producer(List *list)
Definition: list.c:401

◆ http_cgi_variable()

Octstr* http_cgi_variable ( List list,
char *  name 
)

Definition at line 2836 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_get(), gwlist_len(), name, 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().

2837 {
2838  int i;
2839  HTTPCGIVar *v;
2840 
2842  gw_assert(list != NULL);
2843  gw_assert(name != NULL);
2844 
2845  for (i = 0; i < gwlist_len(list); ++i) {
2846  v = gwlist_get(list, i);
2847  if (octstr_str_compare(v->name, name) == 0)
2848  return v->value;
2849  }
2850  return NULL;
2851 }
Octstr * value
Definition: http.h:216
gw_assert(wtls_machine->packet_to_send !=NULL)
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:215
char * name
Definition: smsc_cimd2.c:212
void() gwlib_assert_init(void)
Definition: gwlib.c:72
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:973

◆ http_cgivar_dump()

void http_cgivar_dump ( List cgiargs)

Definition at line 3440 of file http.c.

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

3441 {
3442  HTTPCGIVar *v;
3443  long i, len;
3444 
3446 
3447  len = gwlist_len(cgiargs);
3448 
3449  debug("gwlib.http", 0, "Dumping %ld cgi variables:", len);
3450  for (i = 0; i < len; i++) {
3451  v = gwlist_get(cgiargs, i);
3452  octstr_dump(v->name, 0);
3453  octstr_dump(v->value, 0);
3454  }
3455  debug("gwlib.http", 0, "End of dump.");
3456 }
Octstr * value
Definition: http.h:216
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:215
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void() gwlib_assert_init(void)
Definition: gwlib.c:72

◆ http_cgivar_dump_into()

void http_cgivar_dump_into ( List cgiargs,
Octstr os 
)

Definition at line 3459 of file http.c.

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

Referenced by httpsmsc_receiver().

3460 {
3461  HTTPCGIVar *v;
3462  long i;
3463 
3464  if (os == NULL)
3465  return;
3466 
3468 
3469  for (i = 0; i < gwlist_len(cgiargs); i++) {
3470  v = gwlist_get(cgiargs, i);
3471  octstr_format_append(os, "&%E=%E", v->name, v->value);
3472  }
3473 }
Octstr * value
Definition: http.h:216
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:215
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2507

◆ http_charset_accepted()

int http_charset_accepted ( List headers,
char *  charset 
)

Definition at line 3509 of file http.c.

References charset, and http_something_accepted().

Referenced by add_charset_headers(), and normalize_charset().

3510 {
3511  return http_something_accepted(headers, "Accept-Charset", charset);
3512 }
Octstr * charset
Definition: test_ota.c:68
static int http_something_accepted(List *headers, char *header_name, char *what)
Definition: http.c:3476

◆ http_close_all_ports()

void http_close_all_ports ( void  )

Definition at line 2526 of file http.c.

References gwthread_join_every(), gwthread_wakeup(), keep_servers_open, server_thread(), server_thread_id, and server_thread_is_running.

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

2527 {
2528  if (server_thread_id != -1) {
2529  keep_servers_open = 0;
2533  }
2534 }
static long server_thread_id
Definition: http.c:1894
void gwthread_join_every(gwthread_func_t *func)
static int keep_servers_open
Definition: http.c:1897
void gwthread_wakeup(long thread)
static void server_thread(void *dummy)
Definition: http.c:2344
static volatile sig_atomic_t server_thread_is_running
Definition: http.c:1893

◆ http_close_client()

void http_close_client ( HTTPClient client)

Definition at line 2758 of file http.c.

References client(), and client_destroy().

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

2759 {
2761 }
static void client(int port)
Definition: test_udp.c:77
static void client_destroy(void *client)
Definition: http.c:1932

◆ http_close_port()

void http_close_port ( int  port)

Definition at line 2515 of file http.c.

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

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

2516 {
2517  int *p;
2518 
2519  p = gw_malloc(sizeof(*p));
2520  *p = port;
2523 }
static long server_thread_id
Definition: http.c:1894
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static int port
Definition: fakesmsc.c:121
static List * closed_server_sockets
Definition: http.c:1896
void gwthread_wakeup(long thread)

◆ http_close_proxy()

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, proxy_exceptions_regex, proxy_hostname, proxy_mutex, proxy_password, proxy_port, proxy_username, 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 }
gw_assert(wtls_machine->packet_to_send !=NULL)
#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:324
static Octstr * proxy_username
Definition: http.c:203
void octstr_destroy_item(void *os)
Definition: octstr.c:336
static Mutex * proxy_mutex
Definition: http.c:199
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

◆ http_create_empty_headers()

◆ http_destroy_cgiargs()

void http_destroy_cgiargs ( List args)

Definition at line 2818 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().

2819 {
2820  HTTPCGIVar *v;
2821 
2823 
2824  if (args == NULL)
2825  return ;
2826 
2827  while ((v = gwlist_extract_first(args)) != NULL) {
2828  octstr_destroy(v->name);
2829  octstr_destroy(v->value);
2830  gw_free(v);
2831  }
2832  gwlist_destroy(args, NULL);
2833 }
Octstr * value
Definition: http.h:216
Octstr * name
Definition: http.h:215
void * gwlist_extract_first(List *list)
Definition: list.c:305
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ http_destroy_headers()

void http_destroy_headers ( List headers)

Definition at line 2879 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(), xidris_receive_sms(), and xidris_send_sms().

2880 {
2883 }
void octstr_destroy_item(void *os)
Definition: octstr.c:336
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ http_get_header_parameter()

Octstr* http_get_header_parameter ( Octstr value,
Octstr parameter 
)

Definition at line 3531 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().

3532 {
3533  long pos, len, end;
3534  int c, found = 0;
3535  Octstr *result = NULL;
3536 
3537  len = octstr_len(value);
3538  /* Find the start of the first parameter. */
3539  for (pos = 0; pos < len; pos++) {
3540  c = octstr_get_char(value, pos);
3541  if (c == ';')
3542  break;
3543  else if (c == '"')
3544  pos += http_header_quoted_string_len(value, pos) - 1;
3545  }
3546 
3547  if (pos >= len)
3548  return NULL; /* no parameters */
3549 
3550  for (pos++; pos > 0 && pos < len && found == 0; pos++) {
3551  Octstr *key = NULL;
3552  Octstr *val = NULL;
3553 
3554  end = octstr_search_char(value, '=', pos);
3555  if (end < 0)
3556  end = octstr_search_char(value, ';', pos);
3557  if (end < 0)
3558  end = octstr_len(value);
3559  key = octstr_copy(value, pos, end - pos);
3560  octstr_strip_blanks(key);
3561  pos = end;
3562 
3563  if (octstr_get_char(value, pos) == '=') {
3564  pos++;
3565  while (isspace(octstr_get_char(value, pos)))
3566  pos++;
3567  if (octstr_get_char(value, pos) == '"')
3568  end = pos + http_header_quoted_string_len(value, pos);
3569  else
3570  end = octstr_search_char(value, ';', pos);
3571  if (end < 0)
3572  end = octstr_len(value);
3573  val = octstr_copy(value, pos, end - pos);
3574  octstr_strip_blanks(val);
3575  pos = end;
3576  pos = octstr_search_char(value, ';', pos);
3577  }
3578 
3579  /* is this the pair we look for? bail out then*/
3580  if (octstr_case_compare(key, parameter) == 0) {
3581  found++;
3582  result = octstr_duplicate(val);
3583  }
3584 
3585  octstr_destroy(key);
3586  octstr_destroy(val);
3587  }
3588 
3589  return result;
3590 }
long http_header_quoted_string_len(Octstr *header, long start)
Definition: http.c:3293
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
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:903
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ http_get_real()

int http_get_real ( int  method,
Octstr url,
List request_headers,
Octstr **  final_url,
List **  reply_headers,
Octstr **  reply_body 
)

Definition at line 1821 of file http.c.

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

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

1823 {
1824  HTTPCaller *caller;
1825  int status;
1826  void *ret;
1827 
1829  http_start_request(caller, method, url, request_headers,
1830  NULL, 1, http_get_real, NULL);
1831  ret = http_receive_result(caller, &status, final_url,
1832  reply_headers, reply_body);
1834  if (ret == NULL)
1835  return -1;
1836  return status;
1837 }
static HTTPCaller * caller
Definition: smsbox.c:442
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1760
static int method
Definition: test_http.c:76
#define http_receive_result(caller, status, final_url, headers, body)
Definition: http.h:394
int http_get_real(int method, Octstr *url, List *request_headers, Octstr **final_url, List **reply_headers, Octstr **reply_body)
Definition: http.c:1821
HTTPCaller * http_caller_create(void)
Definition: http.c:897
void http_caller_destroy(HTTPCaller *caller)
Definition: http.c:907
static Octstr * url
Definition: test_xmlrpc.c:84
Definition: list.c:102

◆ http_header_add()

void http_header_add ( List headers,
char *  name,
char *  contents 
)

Definition at line 2886 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_append(), name, 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(), generic_send_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().

2887 {
2889  gw_assert(headers != NULL);
2890  gw_assert(name != NULL);
2891  gw_assert(contents != NULL);
2892 
2893  gwlist_append(headers, octstr_format("%s: %s", name, contents));
2894 }
gw_assert(wtls_machine->packet_to_send !=NULL)
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:2464
void() gwlib_assert_init(void)
Definition: gwlib.c:72

◆ http_header_add_element()

static void http_header_add_element ( List list,
Octstr value,
long  start,
long  end 
)
static

Definition at line 3279 of file http.c.

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

Referenced by http_header_split_value().

3281 {
3282  Octstr *element;
3283 
3284  element = octstr_copy(value, start, end - start);
3286  if (octstr_len(element) == 0)
3288  else
3289  gwlist_append(list, element);
3290 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
static int start

◆ http_header_combine()

void http_header_combine ( List old_headers,
List new_headers 
)

Definition at line 3068 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().

3069 {
3070  long i;
3071  Octstr *name;
3072  Octstr *value;
3073 
3074  /*
3075  * Avoid doing this scan if old_headers is empty anyway.
3076  */
3077  if (gwlist_len(old_headers) > 0) {
3078  for (i = 0; i < gwlist_len(new_headers); i++) {
3079  http_header_get(new_headers, i, &name, &value);
3082  octstr_destroy(value);
3083  }
3084  }
3085 
3086  http_append_headers(old_headers, new_headers);
3087 }
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2902
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:3052
char * name
Definition: smsc_cimd2.c:212
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3135

◆ http_header_dump()

void http_header_dump ( List headers)

Definition at line 3427 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().

3428 {
3429  long i;
3430 
3432 
3433  debug("gwlib.http", 0, "Dumping HTTP headers:");
3434  for (i = 0; headers != NULL && i < gwlist_len(headers); ++i)
3435  octstr_dump(gwlist_get(headers, i), 1);
3436  debug("gwlib.http", 0, "End of dump.");
3437 }
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:726
void() gwlib_assert_init(void)
Definition: gwlib.c:72

◆ http_header_duplicate()

List* http_header_duplicate ( List headers)

Definition at line 2969 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().

2970 {
2971  List *new;
2972  long i, len;
2973 
2975 
2976  if (headers == NULL)
2977  return NULL;
2978 
2979  new = http_create_empty_headers();
2980  len = gwlist_len(headers);
2981  for (i = 0; i < len; ++i)
2982  gwlist_append(new, octstr_duplicate(gwlist_get(headers, i)));
2983  return new;
2984 }
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:2872
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void() gwlib_assert_init(void)
Definition: gwlib.c:72
Definition: list.c:102

◆ http_header_find_all()

List* http_header_find_all ( List headers,
char *  name 
)

Definition at line 3115 of file http.c.

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

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

3116 {
3117  List *list;
3118  long i;
3119  Octstr *h;
3120 
3122  gw_assert(headers != NULL);
3123  gw_assert(name != NULL);
3124 
3125  list = gwlist_create();
3126  for (i = 0; i < gwlist_len(headers); ++i) {
3127  h = gwlist_get(headers, i);
3128  if (header_is_called(h, name))
3129  gwlist_append(list, octstr_duplicate(h));
3130  }
3131  return list;
3132 }
gw_assert(wtls_machine->packet_to_send !=NULL)
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
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:2859
Definition: list.c:102

◆ http_header_find_first_real()

Octstr* http_header_find_first_real ( List headers,
char *  name,
const char *  file,
long  line,
const char *  func 
)

Definition at line 3090 of file http.c.

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

3092 {
3093  long i, name_len;
3094  Octstr *h, *value;
3095 
3097  gw_assert(headers != NULL);
3098  gw_assert(name != NULL);
3099 
3100  name_len = strlen(name);
3101 
3102  for (i = 0; i < gwlist_len(headers); ++i) {
3103  h = gwlist_get(headers, i);
3104  if (header_is_called(h, name)) {
3105  value = octstr_copy_real(h, name_len + 1, octstr_len(h),
3106  file, line, func);
3107  octstr_strip_blanks(value);
3108  return value;
3109  }
3110  }
3111  return NULL;
3112 }
size_t name_len
Definition: wslexer.c:158
gw_assert(wtls_machine->packet_to_send !=NULL)
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:351
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
FILE * file
Definition: log.c:169
char * name
Definition: smsc_cimd2.c:212
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
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:2859

◆ http_header_get()

void http_header_get ( List headers,
long  i,
Octstr **  name,
Octstr **  value 
)

Definition at line 2902 of file http.c.

References colon, error(), gw_assert(), gwlib_assert_init(), gwlist_get(), name, 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().

2903 {
2904  Octstr *os;
2905  long colon;
2906 
2908  gw_assert(i >= 0);
2909  gw_assert(name != NULL);
2910  gw_assert(value != NULL);
2911 
2912  os = gwlist_get(headers, i);
2913  if (os == NULL)
2914  colon = -1;
2915  else
2916  colon = octstr_search_char(os, ':', 0);
2917  if (colon == -1) {
2918  error(0, "HTTP: Header does not contain a colon. BAD.");
2919  *name = octstr_create("X-Unknown");
2920  *value = octstr_duplicate(os);
2921  } else {
2922  *name = octstr_copy(os, 0, colon);
2923  *value = octstr_copy(os, colon + 1, octstr_len(os) - colon - 1);
2924  octstr_strip_blanks(*value);
2925  }
2926 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
#define octstr_duplicate(ostr)
Definition: octstr.h:187
char * name
Definition: smsc_cimd2.c:212
#define octstr_create(cstr)
Definition: octstr.h:125
static Octstr * colon
Definition: smsc_smasi.c:218
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72

◆ http_header_get_content_type()

void http_header_get_content_type ( List headers,
Octstr **  type,
Octstr **  charset 
)

Definition at line 3225 of file http.c.

References charset, 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(), octstr_truncate(), and type.

Referenced by generic_receive_sms(), http_accept_request(), 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().

3227 {
3228  Octstr *h;
3229  long semicolon, equals, len;
3230 
3232  gw_assert(headers != NULL);
3233  gw_assert(type != NULL);
3234  gw_assert(charset != NULL);
3235 
3236  h = http_header_find_first(headers, "Content-Type");
3237  if (h == NULL) {
3238  *type = octstr_create("application/octet-stream");
3239  *charset = octstr_create("");
3240  } else {
3242  semicolon = octstr_search_char(h, ';', 0);
3243  if (semicolon == -1) {
3244  *type = h;
3245  *charset = octstr_create("");
3246  } else {
3247  *charset = octstr_duplicate(h);
3248  octstr_delete(*charset, 0, semicolon + 1);
3250  equals = octstr_search_char(*charset, '=', 0);
3251  if (equals == -1)
3252  octstr_truncate(*charset, 0);
3253  else {
3254  octstr_delete(*charset, 0, equals + 1);
3255  if (octstr_get_char(*charset, 0) == '"')
3256  octstr_delete(*charset, 0, 1);
3257  len = octstr_len(*charset);
3258  if (octstr_get_char(*charset, len - 1) == '"')
3259  octstr_truncate(*charset, len - 1);
3260  }
3261 
3262  octstr_truncate(h, semicolon);
3264  *type = h;
3265  }
3266 
3267  /*
3268  * According to HTTP/1.1 (RFC 2616, section 3.7.1) we have to ensure
3269  * to return charset 'iso-8859-1' in case of no given encoding and
3270  * content-type is a 'text' subtype.
3271  */
3272  if (octstr_len(*charset) == 0 &&
3273  octstr_ncompare(*type, octstr_imm("text"), 4) == 0)
3274  octstr_append_cstr(*charset, "ISO-8859-1");
3275  }
3276 }
gw_assert(wtls_machine->packet_to_send !=NULL)
int type
Definition: smsc_cimd2.c:215
void octstr_append_cstr(Octstr *ostr, const char *cstr)
Definition: octstr.c:1511
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
Octstr * charset
Definition: test_ota.c:68
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
int octstr_ncompare(const Octstr *ostr1, const Octstr *ostr2, long n)
Definition: octstr.c:952
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define http_header_find_first(headers, name)
Definition: http.h:603
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1327
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ http_header_mark_transformation()

void http_header_mark_transformation ( List headers,
Octstr new_body,
Octstr new_type 
)

Definition at line 3203 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().

3205 {
3206  Octstr *new_length = NULL;
3207 
3208  /* Remove all headers that no longer apply to the new body. */
3209  http_header_remove_all(headers, "Content-Length");
3210  http_header_remove_all(headers, "Content-MD5");
3211  http_header_remove_all(headers, "Content-Type");
3212 
3213  /* Add headers that we need to describe the new body. */
3214  new_length = octstr_format("%ld", octstr_len(new_body));
3215  http_header_add(headers, "Content-Length", octstr_get_cstr(new_length));
3216  if(octstr_len(new_type))
3217  http_header_add(headers, "Content-Type", octstr_get_cstr(new_type));
3218 
3219  /* Perhaps we should add Warning: 214 "Transformation applied" too? */
3220 
3221  octstr_destroy(new_length);
3222 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2886
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3135

◆ http_header_pack()

void http_header_pack ( List headers)

Definition at line 2992 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().

2993 {
2994  Octstr *name, *value;
2995  Octstr *name2, *value2;
2996  long i, j;
2997 
2999  gw_assert(headers != NULL);
3000 
3001  /*
3002  * For each header, search forward headers for similar ones and if possible,
3003  * add it to current header and delete it
3004  */
3005  for(i = 0; i < gwlist_len(headers); i++) {
3006  http_header_get(headers, i, &name, &value);
3007  /* debug("http_header_pack", 0, "HTTP_HEADER_PACK: Processing header %d. [%s: %s]",
3008  i, octstr_get_cstr(name), octstr_get_cstr(value)); */
3009 
3010  for(j=i+1; j < gwlist_len(headers); j++) {
3011  http_header_get(headers, j, &name2, &value2);
3012 
3013  if(octstr_case_compare(name, name2) == 0) {
3014  if(octstr_len(value) + 2 + octstr_len(value2) > MAX_HEADER_LENGTH) {
3015  octstr_destroy(name2);
3016  octstr_destroy(value2);
3017  break;
3018  } else {
3019  Octstr *header;
3020 
3021  /* Delete old header */
3022  header = gwlist_get(headers, i);
3023  octstr_destroy(header);
3024  gwlist_delete(headers, i, 1);
3025 
3026  /* Adds comma and new value to old header value */
3027  octstr_append(value, octstr_imm(", "));
3028  octstr_append(value, value2);
3029  /* Creates a new header */
3030  header = octstr_create("");
3031  octstr_append(header, name);
3032  octstr_append(header, octstr_imm(": "));
3033  octstr_append(header, value);
3034  gwlist_insert(headers, i, header);
3035 
3036  /* Delete this header */
3037  header = gwlist_get(headers, j);
3038  octstr_destroy(header);
3039  gwlist_delete(headers, j, 1);
3040  j--;
3041  }
3042  }
3043  octstr_destroy(name2);
3044  octstr_destroy(value2);
3045  }
3047  octstr_destroy(value);
3048  }
3049 }
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2902
gw_assert(wtls_machine->packet_to_send !=NULL)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
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:283
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
#define MAX_HEADER_LENGTH
Definition: http.c:2987
char * name
Definition: smsc_cimd2.c:212
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:903
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
void gwlist_insert(List *list, long pos, void *item)
Definition: list.c:214
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72

◆ http_header_quoted_string_len()

long http_header_quoted_string_len ( Octstr header,
long  start 
)

Definition at line 3293 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().

3294 {
3295  long len;
3296  long pos;
3297  int c;
3298 
3299  if (octstr_get_char(header, start) != '"')
3300  return -1;
3301 
3302  len = octstr_len(header);
3303  for (pos = start + 1; pos < len; pos++) {
3304  c = octstr_get_char(header, pos);
3305  if (c == '\\') /* quoted-pair */
3306  pos++;
3307  else if (c == '"')
3308  return pos - start + 1;
3309  }
3310 
3311  warning(0, "Header contains unterminated quoted-string:");
3312  warning(0, "%s", octstr_get_cstr(header));
3313  return len - start;
3314 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void warning(int err, const char *fmt,...)
Definition: log.c:660
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static int start

◆ http_header_remove_all()

long http_header_remove_all ( List headers,
char *  name 
)

Definition at line 3135 of file http.c.

References gw_assert(), gwlib_assert_init(), gwlist_delete(), gwlist_get(), gwlist_len(), header_is_called(), name, 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().

3136 {
3137  long i;
3138  Octstr *h;
3139  long count;
3140 
3142  gw_assert(headers != NULL);
3143  gw_assert(name != NULL);
3144 
3145  i = 0;
3146  count = 0;
3147  while (i < gwlist_len(headers)) {
3148  h = gwlist_get(headers, i);
3149  if (header_is_called(h, name)) {
3150  gwlist_delete(headers, i, 1);
3151  octstr_destroy(h);
3152  count++;
3153  } else
3154  i++;
3155  }
3156 
3157  return count;
3158 }
gw_assert(wtls_machine->packet_to_send !=NULL)
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:324
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:2859

◆ http_header_split_auth_value()

List* http_header_split_auth_value ( Octstr value)

Definition at line 3351 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().

3352 {
3353  List *result;
3354  Octstr *auth_scheme;
3355  Octstr *element;
3356  long i;
3357 
3358  /*
3359  * According to RFC2617, both "challenge" and "credentials"
3360  * consist of an auth-scheme followed by a list of auth-param.
3361  * Since we have to parse a list of challenges or credentials,
3362  * we have to look for auth-scheme to signal the start of
3363  * a new element. (We can't just split on commas because
3364  * they are also used to separate the auth-params.)
3365  *
3366  * An auth-scheme is a single token, while an auth-param is
3367  * always a key=value pair. So we can recognize an auth-scheme
3368  * as a token that is not followed by a '=' sign.
3369  *
3370  * Simple approach: First split at all commas, then recombine
3371  * the elements that belong to the same challenge or credential.
3372  * This is somewhat expensive but saves programmer thinking time.
3373  *
3374  * Richard Braakman
3375  */
3376 
3377  result = http_header_split_value(value);
3378  if (gwlist_len(result) == 0)
3379  return result;
3380 
3381  auth_scheme = gwlist_get(result, 0);
3382  i = 1;
3383  while (i < gwlist_len(result)) {
3384  int c;
3385  long pos;
3386 
3387  element = gwlist_get(result, i);
3388 
3389  /*
3390  * If the element starts with: token '='
3391  * then it's just an auth_param; append it to the current
3392  * auth_scheme. If it starts with: token token '='
3393  * then it's the start of a new auth scheme.
3394  *
3395  * To make the scan easier, we consider anything other
3396  * than whitespace or '=' to be part of a token.
3397  */
3398 
3399  /* Skip first token */
3400  for (pos = 0; pos < octstr_len(element); pos++) {
3401  c = octstr_get_char(element, pos);
3402  if (isspace(c) || c == '=')
3403  break;
3404  }
3405 
3406  /* Skip whitespace, if any */
3407  while (isspace(octstr_get_char(element, pos)))
3408  pos++;
3409 
3410  if (octstr_get_char(element, pos) == '=') {
3411  octstr_append_char(auth_scheme, ';');
3412  octstr_append(auth_scheme, element);
3413  gwlist_delete(result, i, 1);
3415  } else {
3416  char semicolon = ';';
3417  octstr_insert_data(element, pos, &semicolon, 1);
3418  auth_scheme = element;
3419  i++;
3420  }
3421  }
3422 
3423  return result;
3424 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
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:1517
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
Definition: octstr.c:1461
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
List * http_header_split_value(Octstr *value)
Definition: http.c:3317
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
Definition: list.c:102

◆ http_header_split_value()

List* http_header_split_value ( Octstr value)

Definition at line 3317 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().

3318 {
3319  long start; /* start of current element */
3320  long pos;
3321  long len;
3322  List *result;
3323  int c;
3324 
3325  /*
3326  * According to RFC2616 section 4.2, a field-value is either *TEXT
3327  * (the caller is responsible for not feeding us one of those) or
3328  * combinations of token, separators, and quoted-string. We're
3329  * looking for commas which are separators, and have to skip
3330  * commas in quoted-strings.
3331  */
3332 
3333  result = gwlist_create();
3334  len = octstr_len(value);
3335  start = 0;
3336  for (pos = 0; pos < len; pos++) {
3337  c = octstr_get_char(value, pos);
3338  if (c == ',') {
3339  http_header_add_element(result, value, start, pos);
3340  start = pos + 1;
3341  } else if (c == '"') {
3342  pos += http_header_quoted_string_len(value, pos);
3343  pos--; /* compensate for the loop's pos++ */
3344  }
3345  }
3346  http_header_add_element(result, value, start, len);
3347  return result;
3348 }
long http_header_quoted_string_len(Octstr *header, long start)
Definition: http.c:3293
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define gwlist_create()
Definition: list.h:136
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static void http_header_add_element(List *list, Octstr *value, long start, long end)
Definition: http.c:3279
Definition: list.c:102
static int start

◆ http_header_value()

Octstr* http_header_value ( List headers,
Octstr name 
)

Definition at line 2932 of file http.c.

References colon, gw_assert(), gwlib_assert_init(), gwlist_get(), gwlist_len(), name, 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().

2933 {
2934  Octstr *value;
2935  long i;
2936  Octstr *os;
2937  long colon;
2938  Octstr *current_name;
2939 
2941  gw_assert(name);
2942 
2943  value = NULL;
2944  i = 0;
2945  while (i < gwlist_len(headers)) {
2946  os = gwlist_get(headers, i);
2947  if (os == NULL)
2948  colon = -1;
2949  else
2950  colon = octstr_search_char(os, ':', 0);
2951  if (colon == -1) {
2952  return NULL;
2953  } else {
2954  current_name = octstr_copy(os, 0, colon);
2955  }
2956  if (octstr_case_compare(current_name, name) == 0) {
2957  value = octstr_copy(os, colon + 1, octstr_len(os) - colon - 1);
2958  octstr_strip_blanks(value);
2959  octstr_destroy(current_name);
2960  return value;
2961  }
2962  octstr_destroy(current_name);
2963  ++i;
2964  }
2965 
2966  return NULL;
2967 }
gw_assert(wtls_machine->packet_to_send !=NULL)
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:1346
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
char * name
Definition: smsc_cimd2.c:212
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:903
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static Octstr * colon
Definition: smsc_smasi.c:218
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72

◆ http_init()

void http_init ( void  )

Definition at line 3598 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().

3599 {
3601 
3602 #ifdef HAVE_LIBSSL
3603  conn_init_ssl();
3604 #endif /* HAVE_LIBSSL */
3605  proxy_init();
3606  client_init();
3607  conn_pool_init();
3608  port_init();
3609  server_init();
3610 #ifdef HAVE_LIBSSL
3611  server_ssl_init();
3612 #endif /* HAVE_LIBSSL */
3613 
3614  run_status = running;
3615 }
static void proxy_init(void)
Definition: http.c:225
gw_assert(wtls_machine->packet_to_send !=NULL)
static void server_init(void)
Definition: http.c:2773
static void client_init(void)
Definition: http.c:1840
Definition: http.c:115
static void conn_pool_init(void)
Definition: http.c:762
static void port_init(void)
Definition: http.c:2034
static enum @59 run_status
Definition: http.c:114

◆ http_method()

int http_method ( HTTPClient client)

Definition at line 2763 of file http.c.

References client().

2764 {
2765  return client->method;
2766 }
static void client(int port)
Definition: test_udp.c:77

◆ http_method2name()

char* http_method2name ( int  method)

Definition at line 3681 of file http.c.

References gw_assert(), HTTP_METHOD_GET, HTTP_METHOD_PATCH, http_methods, and method.

Referenced by http_accept_request(), and send_request().

3682 {
3684 
3685  return http_methods[method-1];
3686 }
gw_assert(wtls_machine->packet_to_send !=NULL)
static int method
Definition: test_http.c:76
static char * http_methods[]
Definition: http.c:660

◆ http_name2method()

int http_name2method ( Octstr method)

Definition at line 3654 of file http.c.

References gw_assert(), HTTP_METHOD_DELETE, HTTP_METHOD_GET, HTTP_METHOD_HEAD, HTTP_METHOD_PATCH, HTTP_METHOD_POST, HTTP_METHOD_PUT, method, and octstr_str_compare().

Referenced by main(), parse_request_line(), and start_fetch().

3655 {
3656  gw_assert(method != NULL);
3657 
3658  if (octstr_str_compare(method, "GET") == 0) {
3659  return HTTP_METHOD_GET;
3660  }
3661  else if (octstr_str_compare(method, "POST") == 0) {
3662  return HTTP_METHOD_POST;
3663  }
3664  else if (octstr_str_compare(method, "HEAD") == 0) {
3665  return HTTP_METHOD_HEAD;
3666  }
3667  else if (octstr_str_compare(method, "PUT") == 0) {
3668  return HTTP_METHOD_PUT;
3669  }
3670  else if (octstr_str_compare(method, "DELETE") == 0) {
3671  return HTTP_METHOD_DELETE;
3672  }
3673  else if (octstr_str_compare(method, "PATCH") == 0) {
3674  return HTTP_METHOD_PATCH;
3675  }
3676 
3677  return -1;
3678 }
gw_assert(wtls_machine->packet_to_send !=NULL)
static int method
Definition: test_http.c:76
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:973

◆ http_open_port()

int http_open_port ( int  port,
int  ssl 
)

Definition at line 2509 of file http.c.

References http_open_port_if(), and ssl.

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

2510 {
2511  return http_open_port_if(port, ssl, NULL);
2512 }
Definition: http.c:2014
int ssl
int http_open_port_if(int port, int ssl, Octstr *interface)
Definition: http.c:2483

◆ http_open_port_if()

int http_open_port_if ( int  port,
int  ssl,
Octstr interface 
)

Definition at line 2483 of file http.c.

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

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

2484 {
2485  struct port *p;
2486 
2487  if (ssl)
2488  info(0, "HTTP: Opening SSL server at port %d.", port);
2489  else
2490  info(0, "HTTP: Opening server at port %d.", port);
2491  p = port_add(port);
2492  p->port = port;
2493  p->ssl = ssl;
2494  p->fd = make_server_socket(port, (interface ? octstr_get_cstr(interface) : NULL));
2495  if (p->fd == -1) {
2496  port_remove(port);
2497  return -1;
2498  }
2499 
2501  keep_servers_open = 1;
2504 
2505  return 0;
2506 }
void info(int err, const char *fmt,...)
Definition: log.c:672
Definition: http.c:2014
static long server_thread_id
Definition: http.c:1894
int ssl
void gwlist_produce(List *list, void *item)
Definition: list.c:411
int port
Definition: http.c:2016
int ssl
Definition: http.c:2017
int fd
Definition: http.c:2015
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static List * new_server_sockets
Definition: http.c:1895
static void port_remove(int port)
Definition: http.c:2081
static int port
Definition: fakesmsc.c:121
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
static int keep_servers_open
Definition: http.c:1897
void gwthread_wakeup(long thread)
static void start_server_thread(void)
Definition: http.c:2458
static struct port * port_add(int port)
Definition: http.c:2057

◆ http_reason_phrase()

static const char* http_reason_phrase ( int  status)
static

Definition at line 2645 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().

2646 {
2647  switch (status) {
2648  case HTTP_OK:
2649  return "OK"; /* 200 */
2650  case HTTP_CREATED:
2651  return "Created"; /* 201 */
2652  case HTTP_ACCEPTED:
2653  return "Accepted"; /* 202 */
2654  case HTTP_NO_CONTENT:
2655  return "No Content"; /* 204 */
2656  case HTTP_RESET_CONTENT:
2657  return "Reset Content"; /* 205 */
2659  return "Moved Permanently"; /* 301 */
2660  case HTTP_FOUND:
2661  return "Found"; /* 302 */
2662  case HTTP_SEE_OTHER:
2663  return "See Other"; /* 303 */
2664  case HTTP_NOT_MODIFIED:
2665  return "Not Modified"; /* 304 */
2667  return "Temporary Redirect"; /* 307 */
2668  case HTTP_BAD_REQUEST:
2669  return "Bad Request"; /* 400 */
2670  case HTTP_UNAUTHORIZED:
2671  return "Unauthorized"; /* 401 */
2672  case HTTP_FORBIDDEN:
2673  return "Forbidden"; /* 403 */
2674  case HTTP_NOT_FOUND:
2675  return "Not Found"; /* 404 */
2676  case HTTP_BAD_METHOD:
2677  return "Method Not Allowed"; /* 405 */
2678  case HTTP_NOT_ACCEPTABLE:
2679  return "Not Acceptable"; /* 406 */
2681  return "Request Entity Too Large"; /* 413 */
2683  return "Unsupported Media Type"; /* 415 */
2685  return "Internal Server Error"; /* 500 */
2686  case HTTP_NOT_IMPLEMENTED:
2687  return "Not Implemented"; /* 501 */
2688  case HTTP_BAD_GATEWAY:
2689  return "Bad Gateway"; /* 502 */
2690  }
2691  return "Foo";
2692 }
Definition: http.h:142

◆ http_receive_result_real()

void* http_receive_result_real ( HTTPCaller caller,
int *  status,
Octstr **  final_url,
List **  headers,
Octstr **  body,
int  blocking 
)

Definition at line 1786 of file http.c.

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

1788 {
1789  HTTPServer *trans;
1790  void *request_id;
1791 
1792  if (blocking == 0)
1793  trans = gwlist_extract_first(caller);
1794  else
1795  trans = gwlist_consume(caller);
1796  if (trans == NULL)
1797  return NULL;
1798 
1799  request_id = trans->request_id;
1800  *status = trans->status;
1801 
1802  if (trans->status >= 0) {
1803  *final_url = trans->url;
1804  *headers = trans->response->headers;
1805  *body = trans->response->body;
1806 
1807  trans->url = NULL;
1808  trans->response->headers = NULL;
1809  trans->response->body = NULL;
1810  } else {
1811  *final_url = NULL;
1812  *headers = NULL;
1813  *body = NULL;
1814  }
1815 
1816  server_destroy(trans);
1817  return request_id;
1818 }
static void server_destroy(void *p)
Definition: http.c:730
void * request_id
Definition: http.c:669
long status
Definition: http.c:682
static HTTPCaller * caller
Definition: smsbox.c:442
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

◆ http_remove_hop_headers()

void http_remove_hop_headers ( List headers)

Definition at line 3161 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().

3162 {
3163  Octstr *h;
3164  List *connection_headers;
3165 
3167  gw_assert(headers != NULL);
3168 
3169  /*
3170  * The hop-by-hop headers are a standard list, plus those named
3171  * in the Connection header(s).
3172  */
3173 
3174  connection_headers = http_header_find_all(headers, "Connection");
3175  while ((h = gwlist_consume(connection_headers))) {
3176  List *hop_headers;
3177  Octstr *e;
3178 
3179  octstr_delete(h, 0, strlen("Connection:"));
3180  hop_headers = http_header_split_value(h);
3181  octstr_destroy(h);
3182 
3183  while ((e = gwlist_consume(hop_headers))) {
3185  octstr_destroy(e);
3186  }
3187 
3188  gwlist_destroy(hop_headers, NULL);
3189  }
3190  gwlist_destroy(connection_headers, NULL);
3191 
3192  http_header_remove_all(headers, "Connection");
3193  http_header_remove_all(headers, "Keep-Alive");
3194  http_header_remove_all(headers, "Proxy-Authenticate");
3195  http_header_remove_all(headers, "Proxy-Authorization");
3196  http_header_remove_all(headers, "TE");
3197  http_header_remove_all(headers, "Trailers");
3198  http_header_remove_all(headers, "Transfer-Encoding");
3199  http_header_remove_all(headers, "Upgrade");
3200 }
List * http_header_find_all(List *headers, char *name)
Definition: http.c:3115
gw_assert(wtls_machine->packet_to_send !=NULL)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
List * http_header_split_value(Octstr *value)
Definition: http.c:3317
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
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:3135
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ http_request_url()

Octstr* http_request_url ( HTTPClient client)

Definition at line 2768 of file http.c.

References client().

2769 {
2770  return client->url;
2771 }
static void client(int port)
Definition: test_udp.c:77

◆ http_send_reply()

void http_send_reply ( HTTPClient client,
int  status,
List headers,
Octstr body 
)

Definition at line 2695 of file http.c.

References client(), client_destroy(), client_reset(), conn_register, conn_write(), date(), date_format_http(), gwlist_get(), gwlist_len(), HTTP_METHOD_DELETE, HTTP_METHOD_HEAD, http_reason_phrase(), octstr_append(), octstr_destroy(), octstr_format(), octstr_format_append(), octstr_get_cstr, octstr_len(), port_get_fdset(), receive_request(), and response().

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().

2697 {
2698  Octstr *response;
2699  Octstr *date;
2700  long i;
2701  int ret;
2702 
2703  if (client->use_version_1_0)
2704  response = octstr_format("HTTP/1.0 %d %s\r\n", status, http_reason_phrase(status));
2705  else
2706  response = octstr_format("HTTP/1.1 %d %s\r\n", status, http_reason_phrase(status));
2707 
2708  /* identify ourselfs */
2709  octstr_format_append(response, "Server: " GW_NAME "/%s\r\n", GW_VERSION);
2710 
2711  /* let's inform the client of our time */
2712  date = date_format_http(time(NULL));
2715 
2716  octstr_format_append(response, "Content-Length: %ld\r\n", octstr_len(body));
2717 
2718  /* Indicate if we're keeping the connection or closing. */
2719  if (client->persistent_conn)
2720  octstr_format_append(response, "Connection: Keep-Alive\r\n");
2721  else
2722  octstr_format_append(response, "Connection: Close\r\n");
2723 
2724  for (i = 0; i < gwlist_len(headers); ++i)
2725  octstr_format_append(response, "%S\r\n", gwlist_get(headers, i));
2726  octstr_format_append(response, "\r\n");
2727 
2728  if (body != NULL && client->method != HTTP_METHOD_HEAD && client->method != HTTP_METHOD_DELETE)
2729  octstr_append(response, body);
2730 
2731  ret = conn_write(client->conn, response);
2733 
2734  /* obey return code of conn_write() */
2735  /* sending response was successful */
2736  if (ret == 0) {
2737  /* HTTP/1.0 or 1.1, hence keep-alive or keep-alive */
2738  if (!client->persistent_conn) {
2740  } else {
2741  /* XXX mark this HTTPClient in the keep-alive cleaner thread */
2744  }
2745  }
2746  /* queued for sending, we don't want to block */
2747  else if (ret == 1) {
2748  client->state = sending_reply;
2750  }
2751  /* error while sending response */
2752  else {
2754  }
2755 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
long gwlist_len(List *list)
Definition: list.c:166
static void client(int port)
Definition: test_udp.c:77
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static void client_destroy(void *client)
Definition: http.c:1932
static const char * http_reason_phrase(int status)
Definition: http.c:2645
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
static FDSet * port_get_fdset(int port)
Definition: http.c:2190
static void client_reset(HTTPClient *p)
Definition: http.c:1967
#define conn_register(conn, fdset, callback, data)
Definition: conn.h:215
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
static void receive_request(Connection *conn, void *data)
Definition: http.c:2251
Definition: octstr.c:118
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2507
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)

◆ http_set_client_timeout()

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 1751 of file http.c.

References client_fdset, fdset_set_timeout(), and http_client_timeout.

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

1752 {
1753  http_client_timeout = timeout;
1754  if (client_fdset != NULL) {
1755  /* we are already initialized set timeout in fdset */
1757  }
1758 }
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

◆ http_set_interface()

void http_set_interface ( const Octstr our_host)

Definition at line 1746 of file http.c.

References http_interface, octstr_duplicate, and our_host.

Referenced by config_reload().

1747 {
1749 }
static Octstr * http_interface
Definition: http.c:123
static Octstr * our_host
Definition: radius_acct.c:86
#define octstr_duplicate(ostr)
Definition: octstr.h:187

◆ http_set_server_timeout()

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 2477 of file http.c.

References port_set_timeout().

2478 {
2479  port_set_timeout(port, timeout);
2480 }
static void port_set_timeout(int port, long timeout)
Definition: http.c:2173
Definition: http.c:2014

◆ http_shutdown()

void http_shutdown ( void  )

Definition at line 3618 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().

3619 {
3622 
3624 
3626  client_shutdown();
3627  server_shutdown();
3628  port_shutdown();
3629  proxy_shutdown();
3630 #ifdef HAVE_LIBSSL
3631  conn_shutdown_ssl();
3632  server_shutdown_ssl();
3633 #endif /* HAVE_LIBSSL */
3634  run_status = limbo;
3635 }
gw_assert(wtls_machine->packet_to_send !=NULL)
Definition: http.c:115
static void server_shutdown(void)
Definition: http.c:2799
static enum @59 run_status
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:2042
static void proxy_shutdown(void)
Definition: http.c:232
static void client_shutdown(void)
Definition: http.c:1848

◆ http_something_accepted()

static int http_something_accepted ( List headers,
char *  header_name,
char *  what 
)
static

Definition at line 3476 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().

3478 {
3479  int found;
3480  long i;
3481  List *accepts;
3482  Octstr *needle = octstr_create(what);
3483 
3485  gw_assert(headers != NULL);
3486  gw_assert(what != NULL);
3487 
3488  /* return all headers with this name */
3489  accepts = http_header_find_all(headers, header_name);
3490 
3491  found = 0;
3492  for (i = 0; !found && i < gwlist_len(accepts); ++i) {
3493  Octstr *header_value = gwlist_get(accepts, i);
3494  if (octstr_case_search(header_value, needle, 0) != -1)
3495  found = 1;
3496  }
3497  octstr_destroy(needle);
3498  http_destroy_headers(accepts);
3499  return found;
3500 }
List * http_header_find_all(List *headers, char *name)
Definition: http.c:3115
gw_assert(wtls_machine->packet_to_send !=NULL)
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:2879
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1102
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
void() gwlib_assert_init(void)
Definition: gwlib.c:72
Definition: list.c:102

◆ http_start_request()

void http_start_request ( HTTPCaller caller,
int  method,
Octstr url,
List headers,
Octstr body,
int  follow,
void *  id,
Octstr certkeyfile 
)

Definition at line 1760 of file http.c.

References caller, gwlist_produce(), HTTP_MAX_FOLLOW, http_start_request(), method, pending_requests, HTTPServer::request_id, server_create(), start_client_threads(), and url.

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(), xidris_send_sms(), and xmlrpc_doc_send().

1762 {
1763  HTTPServer *trans;
1764  int follow_remaining;
1765 
1766  if (follow)
1767  follow_remaining = HTTP_MAX_FOLLOW;
1768  else
1769  follow_remaining = 0;
1770 
1771  trans = server_create(caller, method, url, headers, body, follow_remaining,
1772  certkeyfile);
1773 
1774  if (id == NULL)
1775  /* We don't leave this NULL so http_receive_result can use NULL
1776  * to signal no more requests */
1777  trans->request_id = http_start_request;
1778  else
1779  trans->request_id = id;
1780 
1783 }
#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
static HTTPCaller * caller
Definition: smsbox.c:442
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1760
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 Octstr * url
Definition: test_xmlrpc.c:84
static void start_client_threads(void)
Definition: http.c:1723

◆ http_status_class()

int http_status_class ( int  code)

Definition at line 3642 of file http.c.

References code, and HTTP_STATUS_UNKNOWN.

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

3643 {
3644  int sclass;
3645 
3646  if (code < 100 || code >= 600)
3647  sclass = HTTP_STATUS_UNKNOWN;
3648  else
3649  sclass = code - (code % 100);
3650  return sclass;
3651 }
int code
Definition: smsc_cimd2.c:346

◆ http_type_accepted()

int http_type_accepted ( List headers,
char *  type 
)

Definition at line 3503 of file http.c.

References http_something_accepted(), and type.

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

3504 {
3505  return http_something_accepted(headers, "Accept", type);
3506 }
int type
Definition: smsc_cimd2.c:215
static int http_something_accepted(List *headers, char *header_name, char *what)
Definition: http.c:3476

◆ http_urlparse_create()

HTTPURLParse* http_urlparse_create ( void  )

Definition at line 1313 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().

1314 {
1315  HTTPURLParse *p;
1316 
1317  p = gw_malloc(sizeof(HTTPURLParse));
1318  p->url = NULL;
1319  p->scheme = NULL;
1320  p->host = NULL;
1321  p->port = 0;
1322  p->user = NULL;
1323  p->pass = NULL;
1324  p->path = NULL;
1325  p->query = NULL;
1326  p->fragment = NULL;
1327 
1328  return p;
1329 }
Octstr * pass
Definition: http.h:247
Octstr * fragment
Definition: http.h:250
Octstr * query
Definition: http.h:249
unsigned long port
Definition: http.h:245
Octstr * host
Definition: http.h:244
Octstr * url
Definition: http.h:242
Octstr * path
Definition: http.h:248
Octstr * user
Definition: http.h:246
Octstr * scheme
Definition: http.h:243

◆ http_urlparse_destroy()

void http_urlparse_destroy ( HTTPURLParse p)

Definition at line 1332 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 generic_send_sms(), get_connection(), and parse_url().

1333 {
1334  gw_assert(p != NULL);
1335 
1336  octstr_destroy(p->url);
1337  octstr_destroy(p->scheme);
1338  octstr_destroy(p->host);
1339  octstr_destroy(p->user);
1340  octstr_destroy(p->pass);
1341  octstr_destroy(p->path);
1342  octstr_destroy(p->query);
1344  gw_free(p);
1345 }
Octstr * pass
Definition: http.h:247
gw_assert(wtls_machine->packet_to_send !=NULL)
Octstr * fragment
Definition: http.h:250
Octstr * query
Definition: http.h:249
Octstr * host
Definition: http.h:244
Octstr * url
Definition: http.h:242
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Octstr * path
Definition: http.h:248
Octstr * user
Definition: http.h:246
Octstr * scheme
Definition: http.h:243

◆ http_use_proxy()

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(), hostname, http_close_proxy(), mutex_lock, mutex_unlock, octstr_duplicate, octstr_get_cstr, octstr_len(), panic, password, port, proxy_exceptions, proxy_exceptions_regex, proxy_hostname, proxy_mutex, proxy_password, proxy_port, proxy_ssl, proxy_username, run_status, running, ssl, and username.

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

270 {
271  Octstr *e;
272  int i;
273 
275  gw_assert(hostname != NULL);
277  gw_assert(port > 0);
278 
281 
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));
296  debug("gwlib.http", 0, "Using proxy <%s:%d> with %s scheme",
298  (proxy_ssl ? "HTTPS" : "HTTP"));
299 
301 }
Definition: http.c:2014
gw_assert(wtls_machine->packet_to_send !=NULL)
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
unsigned char * username
Definition: test_cimd2.c:99
Definition: http.c:115
static regex_t * proxy_exceptions_regex
Definition: http.c:206
static int port
Definition: fakesmsc.c:121
unsigned char * password
Definition: test_cimd2.c:100
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
Octstr * hostname
Definition: fakewap.c:232
static Octstr * proxy_username
Definition: http.c:203
static Mutex * proxy_mutex
Definition: http.c:199
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:342
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#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

◆ parse2trans()

static void parse2trans ( HTTPURLParse p,
HTTPServer t 
)
static

Definition at line 1543 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().

1544 {
1545  if (p == NULL || t == NULL)
1546  return;
1547 
1548  if (p->user && !t->username)
1549  t->username = octstr_duplicate(p->user);
1550  if (p->pass && !t->password)
1551  t->password = octstr_duplicate(p->pass);
1552  if (p->host && !t->host)
1553  t->host = octstr_duplicate(p->host);
1554  if (p->port && !t->port)
1555  t->port = p->port;
1556  if (p->path && !t->uri) {
1557  t->uri = octstr_duplicate(p->path);
1558  if (p->query) { /* add the query too */
1559  octstr_append_char(t->uri, '?');
1560  octstr_append(t->uri, p->query);
1561  }
1562  }
1563  t->ssl = (p->scheme && (octstr_compare(p->scheme, octstr_imm("https://")) == 0)
1564  && !t->ssl) ? 1 : 0;
1565 }
Octstr * pass
Definition: http.h:247
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
Octstr * query
Definition: http.h:249
Octstr * uri
Definition: http.c:672
unsigned long port
Definition: http.h:245
Octstr * host
Definition: http.h:244
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Octstr * username
Definition: http.c:691
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Octstr * path
Definition: http.h:248
Octstr * user
Definition: http.h:246
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:243
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ parse_cgivars()

void parse_cgivars ( List cgivars,
Octstr pairs 
)

Definition at line 2542 of file http.c.

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

Referenced by generic_receive_sms(), and http_accept_request().

2543 {
2544  HTTPCGIVar *v;
2545  Octstr *pair;
2546  long ampersand, equal, start;
2547  long pairs_len = octstr_len(pairs);
2548 
2549  for (start = 0; start < pairs_len; start = ampersand + 1) {
2550  ampersand = octstr_search_char(pairs, '&', start);
2551  if (ampersand == -1)
2552  ampersand = pairs_len;
2553  pair = octstr_copy(pairs, start, ampersand - start);
2554 
2555  equal = octstr_search_char(pair, '=', 0);
2556  if (equal == -1)
2557  equal = octstr_len(pair);
2558 
2559  v = gw_malloc(sizeof(HTTPCGIVar));
2560  v->name = octstr_copy(pair, 0, equal);
2561  v->value = octstr_copy(pair, equal + 1, octstr_len(pair));
2562  octstr_url_decode(v->name);
2564  gwlist_append(cgivars, v);
2565 
2566  octstr_destroy(pair);
2567  }
2568 }
Octstr * value
Definition: http.h:216
void gwlist_append(List *list, void *item)
Definition: list.c:179
int octstr_url_decode(Octstr *ostr)
Definition: octstr.c:1746
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
Octstr * name
Definition: http.h:215
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
static int start

◆ parse_dump()

void parse_dump ( HTTPURLParse p)

Definition at line 1348 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().

1349 {
1350  if (p == NULL)
1351  return;
1352  debug("http.parse_url",0,"Parsing URL `%s':", octstr_get_cstr(p->url));
1353  debug("http.parse_url",0," Scheme: %s", octstr_get_cstr(p->scheme));
1354  debug("http.parse_url",0," Host: %s", octstr_get_cstr(p->host));
1355  debug("http.parse_url",0," Port: %ld", p->port);
1356  debug("http.parse_url",0," Username: %s", octstr_get_cstr(p->user));
1357  debug("http.parse_url",0," Password: %s", octstr_get_cstr(p->pass));
1358  debug("http.parse_url",0," Path: %s", octstr_get_cstr(p->path));
1359  debug("http.parse_url",0," Query: %s", octstr_get_cstr(p->query));
1360  debug("http.parse_url",0," Fragment: %s", octstr_get_cstr(p->fragment));
1361 }
Octstr * pass
Definition: http.h:247
Octstr * fragment
Definition: http.h:250
Octstr * query
Definition: http.h:249
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long port
Definition: http.h:245
Octstr * host
Definition: http.h:244
Octstr * url
Definition: http.h:242
Octstr * path
Definition: http.h:248
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Octstr * user
Definition: http.h:246
Octstr * scheme
Definition: http.h:243

◆ parse_http_version()

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:283
int octstr_ncompare(const Octstr *ostr1, const Octstr *ostr2, long n)
Definition: octstr.c:952
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ parse_request_line()

static int parse_request_line ( int *  method,
Octstr **  url,
int *  use_version_1_0,
Octstr line 
)
static

Definition at line 2210 of file http.c.

References error(), gwlist_destroy(), gwlist_get(), gwlist_len(), http_name2method(), method, octstr_destroy(), octstr_destroy_item(), octstr_split_words(), parse_http_version(), and url.

Referenced by receive_request().

2212 {
2213  List *words;
2214  Octstr *version;
2215  Octstr *method_str;
2216  int ret;
2217 
2218  words = octstr_split_words(line);
2219  if (gwlist_len(words) != 3) {
2221  return -1;
2222  }
2223 
2224  method_str = gwlist_get(words, 0);
2225  *url = gwlist_get(words, 1);
2226  version = gwlist_get(words, 2);
2227  gwlist_destroy(words, NULL);
2228 
2229  *method = http_name2method(method_str);
2230  if (*method == -1)
2231  goto error;
2232 
2233  ret = parse_http_version(version);
2234  if (ret < 0)
2235  goto error;
2236  *use_version_1_0 = !ret;
2237 
2238  octstr_destroy(method_str);
2239  octstr_destroy(version);
2240  return 0;
2241 
2242 error:
2243  octstr_destroy(method_str);
2244  octstr_destroy(*url);
2245  octstr_destroy(version);
2246  *url = NULL;
2247  return -1;
2248 }
void error(int err, const char *fmt,...)
Definition: log.c:648
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int http_name2method(Octstr *method)
Definition: http.c:3654
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1602
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
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:336
Definition: octstr.c:118
static Octstr * url
Definition: test_xmlrpc.c:84
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ parse_url()

HTTPURLParse* parse_url ( Octstr url)

Definition at line 1377 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(), octstr_url_decode(), parse_dump(), HTTPURLParse::pass, HTTPURLParse::path, HTTPURLParse::port, HTTPURLParse::query, HTTPURLParse::scheme, url, HTTPURLParse::url, and HTTPURLParse::user.

Referenced by generic_send_sms(), and get_connection().

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

◆ port_add()

static struct port* port_add ( int  port)
static

Definition at line 2057 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_collection, port_key(), port_mutex, port::server_fdset, and warning().

Referenced by http_open_port_if().

2058 {
2059  Octstr *key;
2060  struct port *p;
2061 
2062  key = port_key(port);
2064  if ((p = dict_get(port_collection, key)) == NULL) {
2065  p = gw_malloc(sizeof(*p));
2070  dict_put(port_collection, key, p);
2071  } else {
2072  warning(0, "HTTP: port_add called for existing port (%d)", port);
2073  }
2075  octstr_destroy(key);
2076 
2077  return p;
2078 }
Definition: http.c:2014
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:2024
static Octstr * port_key(int port)
Definition: http.c:2051
FDSet * server_fdset
Definition: http.c:2020
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:2019
void warning(int err, const char *fmt,...)
Definition: log.c:660
List * clients_with_requests
Definition: http.c:2018
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
#define HTTP_SERVER_TIMEOUT
Definition: http.c:94
static Dict * port_collection
Definition: http.c:2025
#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

◆ port_get_fdset()

static FDSet* port_get_fdset ( int  port)
static

Definition at line 2190 of file http.c.

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

Referenced by http_send_reply().

2191 {
2192  Octstr *key;
2193  struct port *p;
2194  FDSet *ret = NULL;
2195 
2197  key = port_key(port);
2198  p = dict_get(port_collection, key);
2199  octstr_destroy(key);
2200 
2201  if (p != NULL)
2202  ret = p->server_fdset;
2203 
2205 
2206  return ret;
2207 }
Definition: http.c:2014
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * port_mutex
Definition: http.c:2024
static Octstr * port_key(int port)
Definition: http.c:2051
FDSet * server_fdset
Definition: http.c:2020
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
static Dict * port_collection
Definition: http.c:2025
Definition: fdset.c:70
#define mutex_lock(m)
Definition: thread.h:130

◆ port_get_request()

static HTTPClient* port_get_request ( int  port)
static

Definition at line 2149 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(), port_collection, port_key(), and port_mutex.

Referenced by http_accept_request().

2150 {
2151  Octstr *key;
2152  struct port *p;
2153  HTTPClient *client;
2154 
2156  key = port_key(port);
2157  p = dict_get(port_collection, key);
2158  octstr_destroy(key);
2159 
2160  if (p == NULL) {
2161  client = NULL;
2163  } else {
2165  mutex_unlock(port_mutex); /* Placement of this unlock is tricky. */
2168  }
2169  return client;
2170 }
Definition: http.c:2014
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * port_mutex
Definition: http.c:2024
static void client(int port)
Definition: test_udp.c:77
static Octstr * port_key(int port)
Definition: http.c:2051
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:2019
List * clients_with_requests
Definition: http.c:2018
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427
static Dict * port_collection
Definition: http.c:2025
#define mutex_lock(m)
Definition: thread.h:130

◆ port_init()

static void port_init ( void  )
static

Definition at line 2034 of file http.c.

References active_connections, dict_create(), gwlist_create, mutex_create, port_collection, and port_mutex.

Referenced by http_init().

2035 {
2037  port_collection = dict_create(1024, NULL);
2038  /* create list with all active_connections */
2040 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static List * active_connections
Definition: http.c:1899
static Mutex * port_mutex
Definition: http.c:2024
#define mutex_create()
Definition: thread.h:96
static Dict * port_collection
Definition: http.c:2025
#define gwlist_create()
Definition: list.h:136

◆ port_key()

static Octstr* port_key ( int  port)
static

Definition at line 2051 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().

2052 {
2053  return octstr_format("%d", port);
2054 }
Definition: http.c:2014
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464

◆ port_match()

static int port_match ( void *  client,
void *  port 
)
static

Definition at line 2028 of file http.c.

References client().

Referenced by port_remove().

2029 {
2030  return ((HTTPClient*)client)->port == *((int*)port);
2031 }
Definition: http.c:2014
static void client(int port)
Definition: test_udp.c:77

◆ port_put_request()

static void port_put_request ( HTTPClient client)
static

Definition at line 2129 of file http.c.

References client(), client_destroy(), port::clients_with_requests, dict_get(), gwlist_produce(), mutex_lock, mutex_unlock, octstr_destroy(), port_collection, port_key(), and port_mutex.

Referenced by receive_request().

2130 {
2131  Octstr *key;
2132  struct port *p;
2133 
2135  key = port_key(client->port);
2136  p = dict_get(port_collection, key);
2137  octstr_destroy(key);
2138  if (p == NULL) {
2139  /* client was too slow and we closed port already */
2142  return;
2143  }
2146 }
Definition: http.c:2014
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * port_mutex
Definition: http.c:2024
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static void client(int port)
Definition: test_udp.c:77
static Octstr * port_key(int port)
Definition: http.c:2051
static void client_destroy(void *client)
Definition: http.c:1932
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
List * clients_with_requests
Definition: http.c:2018
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
static Dict * port_collection
Definition: http.c:2025
#define mutex_lock(m)
Definition: thread.h:130

◆ port_remove()

static void port_remove ( int  port)
static

Definition at line 2081 of file http.c.

References active_connections, port::active_consumers, client(), client_destroy(), port::clients_with_requests, conn_unregister(), counter_destroy(), counter_value(), dict_remove(), error(), fdset_destroy(), gwlist_destroy(), gwlist_extract_first(), gwlist_lock(), gwlist_remove_producer(), gwlist_search(), gwlist_search_all(), gwlist_unlock(), gwthread_sleep(), mutex_lock, mutex_unlock, octstr_destroy(), port_collection, port_key(), port_match(), port_mutex, and port::server_fdset.

Referenced by destroy_struct_server(), http_open_port_if(), and server_thread().

2082 {
2083  Octstr *key;
2084  struct port *p;
2085  List *l;
2086  HTTPClient *client;
2087 
2088  key = port_key(port);
2090  p = dict_remove(port_collection, key);
2092  octstr_destroy(key);
2093 
2094  if (p == NULL) {
2095  error(0, "HTTP: Could not find port (%d) in port_collection.", port);
2096  return;
2097  }
2098 
2100  while (counter_value(p->active_consumers) > 0)
2101  gwthread_sleep(0.1); /* Reasonable use of busy waiting. */
2102 
2105 
2106  /*
2107  * In order to avoid race conditions with FDSet thread, we
2108  * destroy Clients for this port in two steps:
2109  * 1) unregister from fdset with gwlist_lock held, so client_destroy
2110  * cannot destroy our client that we currently use
2111  * 2) without gwlist_lock held destroy every client, we can do this
2112  * because we only one thread that can use this client struct
2113  */
2116  while(l != NULL && (client = gwlist_extract_first(l)) != NULL)
2117  conn_unregister(client->conn);
2119  gwlist_destroy(l, NULL);
2120  while((client = gwlist_search(active_connections, &port, port_match)) != NULL)
2122 
2123  /* now destroy fdset */
2125  gw_free(p);
2126 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static List * active_connections
Definition: http.c:1899
Definition: http.c:2014
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
void counter_destroy(Counter *counter)
Definition: counter.c:110
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * port_mutex
Definition: http.c:2024
static void client(int port)
Definition: test_udp.c:77
static Octstr * port_key(int port)
Definition: http.c:2051
FDSet * server_fdset
Definition: http.c:2020
static void client_destroy(void *client)
Definition: http.c:1932
List * gwlist_search_all(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:508
void gwlist_unlock(List *list)
Definition: list.c:354
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
void * gwlist_extract_first(List *list)
Definition: list.c:305
void gwlist_remove_producer(List *list)
Definition: list.c:401
Counter * active_consumers
Definition: http.c:2019
List * clients_with_requests
Definition: http.c:2018
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
void gwthread_sleep(double seconds)
void fdset_destroy(FDSet *set)
Definition: fdset.c:398
void gwlist_lock(List *list)
Definition: list.c:347
void conn_unregister(Connection *conn)
Definition: conn.c:858
Definition: octstr.c:118
static Dict * port_collection
Definition: http.c:2025
#define mutex_lock(m)
Definition: thread.h:130
Definition: list.c:102
static int port_match(void *client, void *port)
Definition: http.c:2028
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ port_set_timeout()

static void port_set_timeout ( int  port,
long  timeout 
)
static

Definition at line 2173 of file http.c.

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

Referenced by http_set_server_timeout().

2174 {
2175  Octstr *key;
2176  struct port *p;
2177 
2179  key = port_key(port);
2180  p = dict_get(port_collection, key);
2181  octstr_destroy(key);
2182 
2183  if (p != NULL)
2184  fdset_set_timeout(p->server_fdset, timeout);
2185 
2187 }
Definition: http.c:2014
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * port_mutex
Definition: http.c:2024
static Octstr * port_key(int port)
Definition: http.c:2051
FDSet * server_fdset
Definition: http.c:2020
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
static Dict * port_collection
Definition: http.c:2025
void fdset_set_timeout(FDSet *set, long timeout)
Definition: fdset.c:547
#define mutex_lock(m)
Definition: thread.h:130

◆ port_shutdown()

static void port_shutdown ( void  )
static

Definition at line 2042 of file http.c.

References active_connections, client_destroy(), dict_destroy(), gwlist_destroy(), mutex_destroy(), port_collection, and port_mutex.

Referenced by http_shutdown().

2043 {
2046  /* destroy active_connections list */
2048 }
static List * active_connections
Definition: http.c:1899
static Mutex * port_mutex
Definition: http.c:2024
static void client_destroy(void *client)
Definition: http.c:1932
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
void dict_destroy(Dict *dict)
Definition: dict.c:215
static Dict * port_collection
Definition: http.c:2025
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ proxy_add_authentication()

static void proxy_add_authentication ( List headers)
static

Definition at line 209 of file http.c.

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

Referenced by send_request().

210 {
211  Octstr *os;
212 
213  if (proxy_username == NULL || proxy_password == NULL)
214  return;
215 
219  octstr_insert(os, octstr_imm("Basic "), 0);
220  http_header_add(headers, "Proxy-Authorization", octstr_get_cstr(os));
221  octstr_destroy(os);
222 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2886
void octstr_binary_to_base64(Octstr *ostr)
Definition: octstr.c:542
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static Octstr * proxy_username
Definition: http.c:203
Definition: octstr.c:118
static Octstr * proxy_password
Definition: http.c:204

◆ proxy_init()

static void proxy_init ( void  )
static

Definition at line 225 of file http.c.

References gwlist_create, mutex_create, proxy_exceptions, and proxy_mutex.

Referenced by http_init().

226 {
229 }
#define mutex_create()
Definition: thread.h:96
static Mutex * proxy_mutex
Definition: http.c:199
static List * proxy_exceptions
Definition: http.c:205
#define gwlist_create()
Definition: list.h:136

◆ proxy_shutdown()

static void proxy_shutdown ( void  )
static

Definition at line 232 of file http.c.

References http_close_proxy(), mutex_destroy(), and proxy_mutex.

Referenced by http_shutdown().

233 {
236  proxy_mutex = NULL;
237 }
void http_close_proxy(void)
Definition: http.c:304
static Mutex * proxy_mutex
Definition: http.c:199
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97

◆ proxy_used_for_host()

static int proxy_used_for_host ( Octstr host,
Octstr url 
)
static

Definition at line 240 of file http.c.

References gwlist_get(), gwlist_len(), host, mutex_lock, mutex_unlock, octstr_compare(), proxy_exceptions, proxy_exceptions_regex, proxy_hostname, proxy_mutex, and url.

Referenced by get_connection(), handle_transaction(), and send_request().

241 {
242  int i;
243 
245 
246  if (proxy_hostname == NULL) {
248  return 0;
249  }
250 
251  for (i = 0; i < gwlist_len(proxy_exceptions); ++i) {
254  return 0;
255  }
256  }
257 
258  if (proxy_exceptions_regex != NULL && gw_regex_match_pre(proxy_exceptions_regex, url)) {
260  return 0;
261  }
262 
264  return 1;
265 }
#define mutex_unlock(m)
Definition: thread.h:136
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static Octstr * host
Definition: fakesmsc.c:122
static regex_t * proxy_exceptions_regex
Definition: http.c:206
static Mutex * proxy_mutex
Definition: http.c:199
static Octstr * proxy_hostname
Definition: http.c:200
static List * proxy_exceptions
Definition: http.c:205
static Octstr * url
Definition: test_xmlrpc.c:84
#define mutex_lock(m)
Definition: thread.h:130
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ read_body_until_eof()

static void read_body_until_eof ( HTTPEntity ent,
Connection conn 
)
static

Definition at line 525 of file http.c.

References HTTPEntity::body, body_error, conn_eof(), conn_error(), conn_read_everything(), entity_done, octstr_append(), octstr_destroy(), and HTTPEntity::state.

Referenced by entity_read().

526 {
527  Octstr *os;
528 
529  while ((os = conn_read_everything(conn)) != NULL) {
530  octstr_append(ent->body, os);
531  octstr_destroy(os);
532  }
533  if (conn_error(conn))
534  ent->state = body_error;
535  if (conn_eof(conn))
536  ent->state = entity_done;
537 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
int conn_eof(Connection *conn)
Definition: conn.c:705
Octstr * body
Definition: http.c:363
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
int conn_error(Connection *conn)
Definition: conn.c:716
enum entity_state state
Definition: http.c:365
Octstr * conn_read_everything(Connection *conn)
Definition: conn.c:1090

◆ read_body_with_length()

static void read_body_with_length ( HTTPEntity ent,
Connection conn 
)
static

Definition at line 540 of file http.c.

References HTTPEntity::body, body_error, conn_eof(), conn_error(), conn_read_fixed(), entity_done, HTTPEntity::expected_body_len, octstr_destroy(), and HTTPEntity::state.

Referenced by entity_read().

541 {
542  Octstr *os;
543 
544  os = conn_read_fixed(conn, ent->expected_body_len);
545  if (os == NULL) {
546  if (conn_error(conn) || conn_eof(conn))
547  ent->state = body_error;
548  return;
549  }
550  octstr_destroy(ent->body);
551  ent->body = os;
552  ent->state = entity_done;
553 }
int conn_eof(Connection *conn)
Definition: conn.c:705
Octstr * body
Definition: http.c:363
long expected_body_len
Definition: http.c:367
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
Octstr * conn_read_fixed(Connection *conn, long length)
Definition: conn.c:1110
int conn_error(Connection *conn)
Definition: conn.c:716
enum entity_state state
Definition: http.c:365

◆ read_chunked_body_crlf()

static void read_chunked_body_crlf ( HTTPEntity ent,
Connection conn 
)
static

Definition at line 498 of file http.c.

References body_error, conn_eof(), conn_error(), conn_read_line(), octstr_destroy(), reading_chunked_body_len, and HTTPEntity::state.

Referenced by entity_read().

499 {
500  Octstr *os;
501 
502  os = conn_read_line(conn);
503  if (os == NULL) {
504  if (conn_error(conn) || conn_eof(conn))
505  ent->state = body_error;
506  } else {
507  octstr_destroy(os);
509  }
510 }
Octstr * conn_read_line(Connection *conn)
Definition: conn.c:1134
int conn_eof(Connection *conn)
Definition: conn.c:705
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
int conn_error(Connection *conn)
Definition: conn.c:716
enum entity_state state
Definition: http.c:365

◆ read_chunked_body_data()

static void read_chunked_body_data ( HTTPEntity ent,
Connection conn 
)
static

Definition at line 482 of file http.c.

References HTTPEntity::body, body_error, HTTPEntity::chunked_body_chunk_len, conn_eof(), conn_error(), conn_read_fixed(), octstr_append(), octstr_destroy(), reading_chunked_body_crlf, and HTTPEntity::state.

Referenced by entity_read().

483 {
484  Octstr *os;
485 
486  os = conn_read_fixed(conn, ent->chunked_body_chunk_len);
487  if (os == NULL) {
488  if (conn_error(conn) || conn_eof(conn))
489  ent->state = body_error;
490  } else {
491  octstr_append(ent->body, os);
492  octstr_destroy(os);
494  }
495 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
long chunked_body_chunk_len
Definition: http.c:366
int conn_eof(Connection *conn)
Definition: conn.c:705
Octstr * body
Definition: http.c:363
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
Octstr * conn_read_fixed(Connection *conn, long length)
Definition: conn.c:1110
int conn_error(Connection *conn)
Definition: conn.c:716
enum entity_state state
Definition: http.c:365

◆ read_chunked_body_len()

static void read_chunked_body_len ( HTTPEntity ent,
Connection conn 
)
static

Definition at line 456 of file http.c.

References body_error, HTTPEntity::chunked_body_chunk_len, conn_eof(), conn_error(), conn_read_line(), octstr_destroy(), octstr_parse_long(), reading_chunked_body_data, reading_chunked_body_trailer, and HTTPEntity::state.

Referenced by entity_read().

457 {
458  Octstr *os;
459  long len;
460 
461  os = conn_read_line(conn);
462  if (os == NULL) {
463  if (conn_error(conn) || conn_eof(conn))
464  ent->state = body_error;
465  return;
466  }
467  if (octstr_parse_long(&len, os, 0, 16) == -1) {
468  octstr_destroy(os);
469  ent->state = body_error;
470  return;
471  }
472  octstr_destroy(os);
473  if (len == 0)
475  else {
477  ent->chunked_body_chunk_len = len;
478  }
479 }
Octstr * conn_read_line(Connection *conn)
Definition: conn.c:1134
long chunked_body_chunk_len
Definition: http.c:366
int conn_eof(Connection *conn)
Definition: conn.c:705
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:749
int conn_error(Connection *conn)
Definition: conn.c:716
enum entity_state state
Definition: http.c:365

◆ read_chunked_body_trailer()

static void read_chunked_body_trailer ( HTTPEntity ent,
Connection conn 
)
static

Definition at line 513 of file http.c.

References body_error, entity_done, HTTPEntity::headers, read_some_headers(), and HTTPEntity::state.

Referenced by entity_read().

514 {
515  int ret;
516 
517  ret = read_some_headers(conn, ent->headers);
518  if (ret == -1)
519  ent->state = body_error;
520  if (ret == 0)
521  ent->state = entity_done;
522 }
List * headers
Definition: http.c:362
static int read_some_headers(Connection *conn, List *headers)
Definition: http.c:131
enum entity_state state
Definition: http.c:365

◆ read_some_headers()

static int read_some_headers ( Connection conn,
List headers 
)
static

Definition at line 131 of file http.c.

References conn_eof(), conn_error(), conn_read_line(), gwlist_append(), gwlist_get(), gwlist_len(), octstr_append(), octstr_destroy(), octstr_get_char(), and octstr_len().

Referenced by entity_read(), and read_chunked_body_trailer().

132 {
133  Octstr *line, *prev;
134 
135  if (gwlist_len(headers) == 0)
136  prev = NULL;
137  else
138  prev = gwlist_get(headers, gwlist_len(headers) - 1);
139 
140  for (;;) {
141  line = conn_read_line(conn);
142  if (line == NULL) {
143  if (conn_eof(conn) || conn_error(conn))
144  return -1;
145  return 1;
146  }
147  if (octstr_len(line) == 0) {
148  octstr_destroy(line);
149  break;
150  }
151  if (isspace(octstr_get_char(line, 0)) && prev != NULL) {
152  octstr_append(prev, line);
153  octstr_destroy(line);
154  } else {
155  gwlist_append(headers, line);
156  prev = line;
157  }
158  }
159 
160  return 0;
161 }
Octstr * conn_read_line(Connection *conn)
Definition: conn.c:1134
void gwlist_append(List *list, void *item)
Definition: list.c:179
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int conn_eof(Connection *conn)
Definition: conn.c:705
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int conn_error(Connection *conn)
Definition: conn.c:716
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ receive_request()

static void receive_request ( Connection conn,
void *  data 
)
static

Definition at line 2251 of file http.c.

References client(), client_destroy(), client_reset(), conn_eof(), conn_error(), conn_outbuf_len(), conn_read_line(), conn_unregister(), entity_create(), entity_read(), error(), expect_body_if_indicated, HTTP_BAD_REQUEST, http_send_reply(), octstr_destroy(), panic, parse_request_line(), port_put_request(), run_status, and running.

Referenced by http_send_reply(), and server_thread().

2252 {
2253  HTTPClient *client;
2254  Octstr *line;
2255  int ret;
2256 
2257  if (run_status != running) {
2258  conn_unregister(conn);
2259  return;
2260  }
2261 
2262  client = data;
2263 
2264  for (;;) {
2265  switch (client->state) {
2266  case reading_request_line:
2267  line = conn_read_line(conn);
2268  if (line == NULL) {
2269  if (conn_eof(conn) || conn_error(conn))
2270  goto error;
2271  return;
2272  }
2273  ret = parse_request_line(&client->method, &client->url,
2274  &client->use_version_1_0, line);
2275  octstr_destroy(line);
2276  /* client sent bad request? */
2277  if (ret == -1) {
2278  /*
2279  * mark client as not persistent in order to destroy connection
2280  * afterwards
2281  */
2282  client->persistent_conn = 0;
2283  /* unregister connection, http_send_reply handle this */
2284  conn_unregister(conn);
2285  http_send_reply(client, HTTP_BAD_REQUEST, NULL, NULL);
2286  return;
2287  }
2288  /*
2289  * RFC2616 (4.3) says we should read a message body if there
2290  * is one, even on GET requests.
2291  */
2293  client->state = reading_request;
2294  break;
2295 
2296  case reading_request:
2297  ret = entity_read(client->request, conn);
2298  if (ret < 0)
2299  goto error;
2300  if (ret == 0) {
2301  client->state = request_is_being_handled;
2302  conn_unregister(conn);
2304  }
2305  return;
2306 
2307  case sending_reply:
2308  /* Implicit conn_unregister() and _destroy */
2309  if (conn_error(conn))
2310  goto error;
2311  if (conn_outbuf_len(conn) > 0)
2312  return;
2313  /* Reply has been sent completely */
2314  if (!client->persistent_conn) {
2315  /*
2316  * in order to avoid race conditions while conn will be destroyed but
2317  * conn is still in use, we call conn_unregister explicit here because
2318  * conn_unregister call uses locks
2319  */
2320  conn_unregister(conn);
2322  return;
2323  }
2324  /* Start reading another request */
2326  break;
2327 
2328  default:
2329  panic(0, "Internal error: HTTPClient state is wrong.");
2330  }
2331  }
2332 
2333 error:
2334  /*
2335  * in order to avoid race conditions while conn will be destroyed but
2336  * conn is still in use, we call conn_unregister explicit here because
2337  * conn_unregister call uses locks
2338  */
2339  conn_unregister(conn);
2341 }
Octstr * conn_read_line(Connection *conn)
Definition: conn.c:1134
void error(int err, const char *fmt,...)
Definition: log.c:648
static void client(int port)
Definition: test_udp.c:77
int conn_eof(Connection *conn)
Definition: conn.c:705
static void client_destroy(void *client)
Definition: http.c:1932
static int parse_request_line(int *method, Octstr **url, int *use_version_1_0, Octstr *line)
Definition: http.c:2210
Definition: http.c:115
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
Definition: http.c:2695
static void client_reset(HTTPClient *p)
Definition: http.c:1967
static enum @59 run_status
static int entity_read(HTTPEntity *ent, Connection *conn)
Definition: http.c:560
long conn_outbuf_len(Connection *conn)
Definition: conn.c:683
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static void port_put_request(HTTPClient *client)
Definition: http.c:2129
void conn_unregister(Connection *conn)
Definition: conn.c:858
Definition: octstr.c:118
#define panic
Definition: log.h:87
static HTTPEntity * entity_create(enum body_expectation exp)
Definition: http.c:429
int conn_error(Connection *conn)
Definition: conn.c:716

◆ recover_absolute_uri()

static void recover_absolute_uri ( HTTPServer trans,
Octstr loc 
)
static

Definition at line 941 of file http.c.

References gw_assert(), HTTPServer::host, octstr_append(), octstr_append_char(), octstr_create, octstr_destroy(), octstr_format_append(), octstr_get_char(), octstr_insert(), HTTPServer::password, HTTPServer::port, HTTPServer::ssl, and HTTPServer::username.

Referenced by handle_transaction().

942 {
943  Octstr *os;
944 
945  gw_assert(loc != NULL && trans != NULL);
946 
947  /* we'll only accept locations with a leading / */
948  if (octstr_get_char(loc, 0) == '/') {
949 
950  /* scheme */
951  os = trans->ssl ? octstr_create("https://") :
952  octstr_create("http://");
953 
954  /* credentials, if any */
955  if (trans->username && trans->password) {
956  octstr_append(os, trans->username);
957  octstr_append_char(os, ':');
958  octstr_append(os, trans->password);
959  octstr_append_char(os, '@');
960  }
961 
962  /* host */
963  octstr_append(os, trans->host);
964 
965  /* port, only added if literally not default. */
966  if (trans->port != 80 || trans->ssl) {
967  octstr_format_append(os, ":%ld", trans->port);
968  }
969 
970  /* prepend the created octstr to the loc, and destroy then. */
971  octstr_insert(loc, os, 0);
972  octstr_destroy(os);
973  }
974 }
gw_assert(wtls_machine->packet_to_send !=NULL)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
Octstr * username
Definition: http.c:691
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2507
long port
Definition: http.c:687
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
int ssl
Definition: http.c:690
Octstr * host
Definition: http.c:686
Octstr * password
Definition: http.c:692

◆ response_expectation()

static int response_expectation ( int  method,
int  status 
)
static

Definition at line 1027 of file http.c.

References expect_body, expect_no_body, HTTP_METHOD_DELETE, HTTP_METHOD_HEAD, HTTP_NO_CONTENT, HTTP_NOT_MODIFIED, http_status_class(), HTTP_STATUS_PROVISIONAL, and method.

Referenced by handle_transaction().

1028 {
1029  if (status == HTTP_NO_CONTENT ||
1033  return expect_no_body;
1034  else
1035  return expect_body;
1036 }
int http_status_class(int code)
Definition: http.c:3642
static int method
Definition: test_http.c:76

◆ send_request()

static int send_request ( HTTPServer trans)
static

Definition at line 1611 of file http.c.

References build_request(), HTTPServer::conn, conn_destroy(), conn_write(), debug(), error(), HTTPServer::host, http_add_basic_auth(), http_header_add(), http_header_remove_all(), http_method2name(), HTTP_METHOD_PATCH, HTTP_METHOD_POST, HTTP_METHOD_PUT, HTTPServer::method, octstr_destroy(), octstr_dump, octstr_get_cstr, octstr_len(), HTTPServer::password, HTTPServer::port, proxy_add_authentication(), proxy_used_for_host(), HTTPServer::request_body, HTTPServer::request_headers, HTTPServer::ssl, HTTPServer::uri, HTTPServer::url, HTTPServer::username, and warning().

Referenced by handle_transaction(), and write_request_thread().

1612 {
1613  char buf[128];
1614  Octstr *request = NULL;
1615 
1616  if (trans->method == HTTP_METHOD_POST || trans->method == HTTP_METHOD_PATCH || trans->method == HTTP_METHOD_PUT) {
1617  /*
1618  * Add a Content-Length header. Override an existing one, if
1619  * necessary. We must have an accurate one in order to use the
1620  * connection for more than a single request.
1621  */
1622  http_header_remove_all(trans->request_headers, "Content-Length");
1623  snprintf(buf, sizeof(buf), "%ld", octstr_len(trans->request_body));
1624  http_header_add(trans->request_headers, "Content-Length", buf);
1625  }
1626  /*
1627  * ok, this has to be an GET or HEAD request method then,
1628  * if it contains a body, then this is not HTTP conform, so at
1629  * least warn the user
1630  */
1631  else if (trans->request_body != NULL) {
1632  warning(0, "HTTP: GET or HEAD method request contains body:");
1633  octstr_dump(trans->request_body, 0);
1634  }
1635 
1636  /*
1637  * we have to assume all values in trans are already set
1638  * by parse_url() before calling this.
1639  */
1640 
1641  if (trans->username != NULL)
1643  trans->password);
1644 
1645  if (proxy_used_for_host(trans->host, trans->url)) {
1647  request = build_request(http_method2name(trans->method), trans->url,
1648  trans->host, trans->port, trans->ssl,
1649  trans->request_headers,
1650  trans->request_body);
1651  } else {
1652  request = build_request(http_method2name(trans->method), trans->uri,
1653  trans->host, trans->port, trans->ssl,
1654  trans->request_headers,
1655  trans->request_body);
1656  }
1657 
1658  debug("gwlib.http", 0, "HTTP: Sending request:");
1659  octstr_dump(request, 0);
1660  if (conn_write(trans->conn, request) == -1)
1661  goto error;
1662 
1663  octstr_destroy(request);
1664 
1665  return 0;
1666 
1667 error:
1668  conn_destroy(trans->conn);
1669  trans->conn = NULL;
1670  octstr_destroy(request);
1671  error(0, "Couldn't send request to <%s>", octstr_get_cstr(trans->url));
1672  return -1;
1673 }
char * http_method2name(int method)
Definition: http.c:3681
void error(int err, const char *fmt,...)
Definition: log.c:648
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2886
int method
Definition: http.c:670
void http_add_basic_auth(List *headers, Octstr *username, Octstr *password)
Definition: http.c:3515
Octstr * uri
Definition: http.c:672
Connection * conn
Definition: http.c:685
List * request_headers
Definition: http.c:673
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
Octstr * url
Definition: http.c:671
Octstr * username
Definition: http.c:691
void conn_destroy(Connection *conn)
Definition: conn.c:627
Octstr * request_body
Definition: http.c:674
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static void proxy_add_authentication(List *headers)
Definition: http.c:209
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3135
long port
Definition: http.c:687
int ssl
Definition: http.c:690
static Octstr * build_request(char *method_name, Octstr *path_or_url, Octstr *host, long port, int ssl, List *headers, Octstr *request_body)
Definition: http.c:1244
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

◆ server_create()

static HTTPServer* server_create ( HTTPCaller caller,
int  method,
Octstr url,
List headers,
Octstr body,
int  follow_remaining,
Octstr certkeyfile 
)
static

Definition at line 700 of file http.c.

References caller, HTTPServer::caller, HTTPServer::certkeyfile, HTTPServer::conn, HTTPServer::follow_remaining, HTTPServer::host, http_header_duplicate(), method, HTTPServer::method, octstr_duplicate, HTTPServer::password, HTTPServer::persistent, HTTPServer::port, HTTPServer::request_body, HTTPServer::request_headers, HTTPServer::request_id, HTTPServer::response, HTTPServer::ssl, HTTPServer::state, HTTPServer::status, HTTPServer::uri, url, HTTPServer::url, and HTTPServer::username.

Referenced by http_start_request().

703 {
704  HTTPServer *trans;
705 
706  trans = gw_malloc(sizeof(*trans));
707  trans->caller = caller;
708  trans->request_id = NULL;
709  trans->method = method;
710  trans->url = octstr_duplicate(url);
711  trans->uri = NULL;
712  trans->request_headers = http_header_duplicate(headers);
713  trans->request_body = octstr_duplicate(body);
714  trans->state = request_not_sent;
715  trans->status = -1;
716  trans->persistent = 0;
717  trans->response = NULL;
718  trans->conn = NULL;
719  trans->host = NULL;
720  trans->port = 0;
721  trans->username = NULL;
722  trans->password = NULL;
723  trans->follow_remaining = follow_remaining;
724  trans->certkeyfile = octstr_duplicate(certkeyfile);
725  trans->ssl = 0;
726  return trans;
727 }
void * request_id
Definition: http.c:669
long status
Definition: http.c:682
static HTTPCaller * caller
Definition: smsbox.c:442
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
List * request_headers
Definition: http.c:673
Octstr * certkeyfile
Definition: http.c:689
Octstr * url
Definition: http.c:671
Octstr * username
Definition: http.c:691
Octstr * request_body
Definition: http.c:674
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static int method
Definition: test_http.c:76
enum HTTPServer::@60 state
HTTPEntity * response
Definition: http.c:684
int persistent
Definition: http.c:683
List * http_header_duplicate(List *headers)
Definition: http.c:2969
long port
Definition: http.c:687
static Octstr * url
Definition: test_xmlrpc.c:84
int ssl
Definition: http.c:690
HTTPCaller * caller
Definition: http.c:668
Octstr * host
Definition: http.c:686
Octstr * password
Definition: http.c:692

◆ server_destroy()

static void server_destroy ( void *  p)
static

Definition at line 730 of file http.c.

References HTTPServer::certkeyfile, entity_destroy(), HTTPServer::host, http_destroy_headers(), octstr_destroy(), HTTPServer::password, HTTPServer::request_body, HTTPServer::request_headers, HTTPServer::response, HTTPServer::uri, HTTPServer::url, and HTTPServer::username.

Referenced by client_shutdown(), http_caller_destroy(), and http_receive_result_real().

731 {
732  HTTPServer *trans;
733 
734  trans = p;
735  octstr_destroy(trans->url);
736  octstr_destroy(trans->uri);
738  trans->request_headers = NULL;
740  entity_destroy(trans->response);
741  octstr_destroy(trans->host);
742  octstr_destroy(trans->certkeyfile);
743  octstr_destroy(trans->username);
744  octstr_destroy(trans->password);
745  gw_free(trans);
746 }
Octstr * uri
Definition: http.c:672
List * request_headers
Definition: http.c:673
Octstr * certkeyfile
Definition: http.c:689
void http_destroy_headers(List *headers)
Definition: http.c:2879
Octstr * url
Definition: http.c:671
Octstr * username
Definition: http.c:691
Octstr * request_body
Definition: http.c:674
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static void entity_destroy(HTTPEntity *ent)
Definition: http.c:445
HTTPEntity * response
Definition: http.c:684
Octstr * host
Definition: http.c:686
Octstr * password
Definition: http.c:692

◆ server_init()

static void server_init ( void  )
static

Definition at line 2773 of file http.c.

References closed_server_sockets, gwlist_add_producer(), gwlist_create, mutex_create, new_server_sockets, and server_thread_lock.

Referenced by http_init().

2774 {
2779 }
#define mutex_create()
Definition: thread.h:96
static List * new_server_sockets
Definition: http.c:1895
static List * closed_server_sockets
Definition: http.c:1896
#define gwlist_create()
Definition: list.h:136
static Mutex * server_thread_lock
Definition: http.c:1892
void gwlist_add_producer(List *list)
Definition: list.c:383

◆ server_shutdown()

static void server_shutdown ( void  )
static

Definition at line 2799 of file http.c.

References closed_server_sockets, destroy_int_pointer(), destroy_struct_server(), gwlist_destroy(), gwlist_remove_producer(), gwthread_join_every(), gwthread_wakeup(), mutex_destroy(), new_server_sockets, server_thread(), server_thread_id, server_thread_is_running, and server_thread_lock.

Referenced by http_shutdown().

2800 {
2802  if (server_thread_id != -1) {
2806  }
2810 }
static long server_thread_id
Definition: http.c:1894
void gwthread_join_every(gwthread_func_t *func)
static List * new_server_sockets
Definition: http.c:1895
void gwlist_remove_producer(List *list)
Definition: list.c:401
static List * closed_server_sockets
Definition: http.c:1896
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
static void destroy_int_pointer(void *p)
Definition: http.c:2792
static void destroy_struct_server(void *p)
Definition: http.c:2782
void gwthread_wakeup(long thread)
static void server_thread(void *dummy)
Definition: http.c:2344
static Mutex * server_thread_lock
Definition: http.c:1892
static volatile sig_atomic_t server_thread_is_running
Definition: http.c:1893
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ server_thread()

static void server_thread ( void *  dummy)
static

Definition at line 2344 of file http.c.

References active_connections, client(), client_create(), closed_server_sockets, conn_register, conn_wrap_fd(), debug(), error(), pollfd::events, pollfd::fd, port::fd, gwlist_consume(), gwlist_extract_first(), gwlist_len(), gwthread_poll(), gwthread_sleep(), host_ip(), HTTP_SERVER_MAX_ACTIVE_CONNECTIONS, keep_servers_open, new_server_sockets, octstr_destroy(), octstr_get_cstr, POLLIN, port::port, port_remove(), receive_request(), run_status, running, port::server_fdset, server_thread_id, ssl, and warning().

Referenced by http_close_all_ports(), server_shutdown(), and start_server_thread().

2345 {
2346  struct pollfd *tab = NULL;
2347  struct port **ports = NULL;
2348  int tab_size = 0, n, i, fd, ret, max_clients_reached;
2349  struct sockaddr_in addr;
2350  socklen_t addrlen;
2351  HTTPClient *client;
2352  Connection *conn;
2353  int *portno;
2354 
2355  n = max_clients_reached = 0;
2356  while (run_status == running && keep_servers_open) {
2357  while (n == 0 || gwlist_len(new_server_sockets) > 0) {
2358  struct port *p = gwlist_consume(new_server_sockets);
2359  if (p == NULL) {
2360  debug("gwlib.http", 0, "HTTP: No new servers. Quitting.");
2361  break;
2362  } else {
2363  debug ("gwlib.http", 0, "HTTP: Including port %d, fd %d for polling in server thread", p->port, p->fd);
2364  }
2365  if (tab_size <= n) {
2366  tab_size++;
2367  tab = gw_realloc(tab, tab_size * sizeof(*tab));
2368  ports = gw_realloc(ports, tab_size * sizeof(*ports));
2369  if (tab == NULL || ports == NULL) {
2370  tab_size--;
2371  port_remove(p->port);
2372  continue;
2373  }
2374  }
2375  tab[n].fd = p->fd;
2376  tab[n].events = POLLIN;
2377  ports[n] = p;
2378  n++;
2379  }
2380 
2381  if (max_clients_reached && gwlist_len(active_connections) >= HTTP_SERVER_MAX_ACTIVE_CONNECTIONS) {
2382  /* TODO start cleanup of stale connections */
2383  /* wait for slots to become free */
2384  gwthread_sleep(1.0);
2385  } else if (!max_clients_reached && (ret = gwthread_poll(tab, n, -1.0)) == -1) {
2386  if (errno != EINTR) /* a signal was caught during poll() function */
2387  warning(errno, "HTTP: gwthread_poll failed.");
2388  continue;
2389  }
2390 
2391  for (i = 0; i < n; ++i) {
2392  if (tab[i].revents & POLLIN) {
2393  /* check our limit */
2395  max_clients_reached = 1;
2396  break;
2397  } else {
2398  max_clients_reached = 0;
2399  }
2400 
2401  addrlen = sizeof(addr);
2402  fd = accept(tab[i].fd, (struct sockaddr *) &addr, &addrlen);
2403  if (fd == -1) {
2404  error(errno, "HTTP: Error accepting a client.");
2405  } else {
2406  Octstr *client_ip = host_ip(addr);
2407  /*
2408  * Be aware that conn_wrap_fd() will return NULL if SSL
2409  * handshake has failed, so we only client_create() if
2410  * there is an conn.
2411  */
2412  if ((conn = conn_wrap_fd(fd, ports[i]->ssl))) {
2413  client = client_create(ports[i]->port, conn, client_ip);
2414  conn_register(conn, ports[i]->server_fdset, receive_request, client);
2415  } else {
2416  error(0, "HTTP: unsuccessful SSL handshake for client `%s'",
2417  octstr_get_cstr(client_ip));
2418  octstr_destroy(client_ip);
2419  }
2420  }
2421  }
2422  }
2423 
2424  while ((portno = gwlist_extract_first(closed_server_sockets)) != NULL) {
2425  for (i = 0; i < n; ++i) {
2426  if (ports[i]->port == *portno) {
2427  (void) close(tab[i].fd);
2428  tab[i].fd = -1;
2429  tab[i].events = 0;
2430  port_remove(ports[i]->port);
2431  ports[i] = NULL;
2432  n--;
2433 
2434  /* now put the last entry on this place */
2435  tab[i].fd = tab[n].fd;
2436  tab[i].events = tab[n].events;
2437  tab[n].fd = -1;
2438  tab[n].events = 0;
2439  ports[i] = ports[n];
2440  }
2441  }
2442  gw_free(portno);
2443  }
2444  }
2445 
2446  /* make sure we close all ports */
2447  for (i = 0; i < n; ++i) {
2448  (void) close(tab[i].fd);
2449  port_remove(ports[i]->port);
2450  }
2451  gw_free(tab);
2452  gw_free(ports);
2453 
2454  server_thread_id = -1;
2455 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static List * active_connections
Definition: http.c:1899
Definition: http.c:2014
static long server_thread_id
Definition: http.c:1894
int ssl
long gwlist_len(List *list)
Definition: list.c:166
static void client(int port)
Definition: test_udp.c:77
int port
Definition: http.c:2016
FDSet * server_fdset
Definition: http.c:2020
int fd
Definition: http.c:2015
int gwthread_poll(struct pollfd *fds, long numfds, double timeout)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
short events
Definition: gwpoll.h:86
static List * new_server_sockets
Definition: http.c:1895
Definition: http.c:115
static void port_remove(int port)
Definition: http.c:2081
#define POLLIN
Definition: gwpoll.h:91
void * gwlist_extract_first(List *list)
Definition: list.c:305
static HTTPClient * client_create(int port, Connection *conn, Octstr *ip)
Definition: http.c:1902
static enum @59 run_status
#define conn_register(conn, fdset, callback, data)
Definition: conn.h:215
void warning(int err, const char *fmt,...)
Definition: log.c:660
static List * closed_server_sockets
Definition: http.c:1896
Definition: gwpoll.h:84
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void gwthread_sleep(double seconds)
#define HTTP_SERVER_MAX_ACTIVE_CONNECTIONS
Definition: http.c:96
static int keep_servers_open
Definition: http.c:1897
static void receive_request(Connection *conn, void *data)
Definition: http.c:2251
Definition: octstr.c:118
int fd
Definition: gwpoll.h:85
void * gwlist_consume(List *list)
Definition: list.c:427
Octstr * host_ip(struct sockaddr_in addr)
Definition: socket.c:615
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int socklen_t
Definition: socket.h:73
Connection * conn_wrap_fd(int fd, int ssl)
Definition: conn.c:566

◆ start_client_threads()

static void start_client_threads ( void  )
static

Definition at line 1723 of file http.c.

References client_fdset, client_thread_lock, client_threads_are_running, error(), fdset_create_real(), fdset_destroy(), gwthread_create, http_client_timeout, mutex_lock, mutex_unlock, and write_request_thread().

Referenced by http_start_request().

1724 {
1726  /*
1727  * To be really certain, we must repeat the test, but use the
1728  * lock first. If the test failed, however, we _know_ we've
1729  * already initialized. This strategy of double testing avoids
1730  * using the lock more than a few times at startup.
1731  */
1735  if (gwthread_create(write_request_thread, NULL) == -1) {
1736  error(0, "HTTP: Could not start client write_request thread.");
1739  } else
1741  }
1743  }
1744 }
void error(int err, const char *fmt,...)
Definition: log.c:648
#define mutex_unlock(m)
Definition: thread.h:136
static volatile sig_atomic_t client_threads_are_running
Definition: http.c:640
static Mutex * client_thread_lock
Definition: http.c:639
#define gwthread_create(func, arg)
Definition: gwthread.h:90
void fdset_destroy(FDSet *set)
Definition: fdset.c:398
static int http_client_timeout
Definition: http.c:91
static void write_request_thread(void *arg)
Definition: http.c:1681
static FDSet * client_fdset
Definition: http.c:647
#define mutex_lock(m)
Definition: thread.h:130
FDSet * fdset_create_real(long timeout)
Definition: fdset.c:368

◆ start_server_thread()

static void start_server_thread ( void  )
static

Definition at line 2458 of file http.c.

References gwthread_create, mutex_lock, mutex_unlock, server_thread(), server_thread_id, server_thread_is_running, and server_thread_lock.

Referenced by http_open_port_if().

2459 {
2460  if (!server_thread_is_running) {
2461  /*
2462  * To be really certain, we must repeat the test, but use the
2463  * lock first. If the test failed, however, we _know_ we've
2464  * already initialized. This strategy of double testing avoids
2465  * using the lock more than a few times at startup.
2466  */
2468  if (!server_thread_is_running) {
2471  }
2473  }
2474 }
static long server_thread_id
Definition: http.c:1894
#define mutex_unlock(m)
Definition: thread.h:136
#define gwthread_create(func, arg)
Definition: gwthread.h:90
static void server_thread(void *dummy)
Definition: http.c:2344
static Mutex * server_thread_lock
Definition: http.c:1892
#define mutex_lock(m)
Definition: thread.h:130
static volatile sig_atomic_t server_thread_is_running
Definition: http.c:1893

◆ write_request_thread()

static void write_request_thread ( void *  arg)
static

Definition at line 1681 of file http.c.

References HTTPServer::caller, client_fdset, HTTPServer::conn, conn_is_connected(), conn_register, debug(), get_connection(), gw_assert(), gwlist_consume(), gwlist_len(), gwlist_produce(), handle_transaction(), pending_requests, run_status, running, send_request(), and HTTPServer::state.

Referenced by client_shutdown(), and start_client_threads().

1682 {
1683  HTTPServer *trans;
1684  int rc;
1685 
1686  while (run_status == running) {
1688  if (trans == NULL)
1689  break;
1690 
1691  gw_assert(trans->state == request_not_sent);
1692 
1693  debug("gwlib.http", 0, "Queue contains %ld pending requests.", gwlist_len(pending_requests));
1694 
1695  /*
1696  * get the connection to use
1697  * also calls parse_url() to populate the trans values
1698  */
1699  trans->conn = get_connection(trans);
1700 
1701  if (trans->conn == NULL)
1702  gwlist_produce(trans->caller, trans);
1703  else if (conn_is_connected(trans->conn) == 0) {
1704  debug("gwlib.http", 0, "Socket connected at once");
1705 
1706  if ((rc = send_request(trans)) == 0) {
1707  trans->state = reading_status;
1709  trans);
1710  } else {
1711  gwlist_produce(trans->caller, trans);
1712  }
1713 
1714  } else { /* Socket not connected, wait for connection */
1715  debug("gwlib.http", 0, "Socket connecting");
1716  trans->state = connecting;
1718  }
1719  }
1720 }
static Connection * get_connection(HTTPServer *trans)
Definition: http.c:1567
static List * pending_requests
Definition: http.c:633
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_produce(List *list, void *item)
Definition: list.c:411
long gwlist_len(List *list)
Definition: list.c:166
int conn_is_connected(Connection *conn)
Definition: conn.c:525
Connection * conn
Definition: http.c:685
Definition: http.c:115
static void handle_transaction(Connection *conn, void *data)
Definition: http.c:1038
static enum @59 run_status
#define conn_register(conn, fdset, callback, data)
Definition: conn.h:215
static int send_request(HTTPServer *trans)
Definition: http.c:1611
enum HTTPServer::@60 state
void * gwlist_consume(List *list)
Definition: list.c:427
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static FDSet * client_fdset
Definition: http.c:647
HTTPCaller * caller
Definition: http.c:668

Variable Documentation

◆ active_connections

List* active_connections
static

◆ client_fdset

FDSet* client_fdset = NULL
static

◆ client_thread_lock

Mutex* client_thread_lock = NULL
static

Definition at line 639 of file http.c.

Referenced by client_init(), client_shutdown(), and start_client_threads().

◆ client_threads_are_running

volatile sig_atomic_t client_threads_are_running = 0
static

Definition at line 640 of file http.c.

Referenced by client_shutdown(), and start_client_threads().

◆ closed_server_sockets

List* closed_server_sockets = NULL
static

Definition at line 1896 of file http.c.

Referenced by http_close_port(), server_init(), server_shutdown(), and server_thread().

◆ conn_pool

Dict* conn_pool
static

Definition at line 753 of file http.c.

Referenced by conn_pool_get(), conn_pool_init(), and conn_pool_shutdown().

◆ conn_pool_lock

Mutex* conn_pool_lock
static

Definition at line 754 of file http.c.

Referenced by conn_pool_get(), conn_pool_init(), and conn_pool_shutdown().

◆ http_client_timeout

int http_client_timeout = 30
static

Definition at line 91 of file http.c.

Referenced by http_set_client_timeout(), and start_client_threads().

◆ http_interface

Octstr* http_interface = NULL
static

Definition at line 123 of file http.c.

Referenced by client_shutdown(), get_connection(), handle_transaction(), and http_set_interface().

◆ http_methods

char* http_methods[]
static
Initial value:
= {
"GET", "POST", "HEAD", "PUT", "DELETE", "PATCH"
}

Definition at line 660 of file http.c.

Referenced by http_method2name().

◆ keep_servers_open

int keep_servers_open = 0
static

Definition at line 1897 of file http.c.

Referenced by http_close_all_ports(), http_open_port_if(), and server_thread().

◆ new_server_sockets

List* new_server_sockets = NULL
static

Definition at line 1895 of file http.c.

Referenced by http_open_port_if(), server_init(), server_shutdown(), and server_thread().

◆ pending_requests

List* pending_requests = NULL
static

◆ port_collection

Dict* port_collection = NULL
static

◆ port_mutex

Mutex* port_mutex = NULL
static

◆ proxy_exceptions

List* proxy_exceptions = NULL
static

Definition at line 205 of file http.c.

Referenced by http_close_proxy(), http_use_proxy(), proxy_init(), and proxy_used_for_host().

◆ proxy_exceptions_regex

regex_t* proxy_exceptions_regex = NULL
static

Definition at line 206 of file http.c.

Referenced by http_close_proxy(), http_use_proxy(), and proxy_used_for_host().

◆ proxy_hostname

Octstr* proxy_hostname = NULL
static

◆ proxy_mutex

Mutex* proxy_mutex = NULL
static

◆ proxy_password

Octstr* proxy_password = NULL
static

Definition at line 204 of file http.c.

Referenced by http_close_proxy(), http_use_proxy(), main(), and proxy_add_authentication().

◆ proxy_port

int proxy_port = 0
static

Definition at line 201 of file http.c.

Referenced by get_connection(), handle_transaction(), http_close_proxy(), http_use_proxy(), and main().

◆ proxy_ssl

int proxy_ssl = 0
static

Definition at line 202 of file http.c.

Referenced by get_connection(), http_use_proxy(), and main().

◆ proxy_username

Octstr* proxy_username = NULL
static

Definition at line 203 of file http.c.

Referenced by http_close_proxy(), http_use_proxy(), main(), and proxy_add_authentication().

◆ run_status

◆ server_thread_id

long server_thread_id = -1
static

◆ server_thread_is_running

volatile sig_atomic_t server_thread_is_running = 0
static

Definition at line 1893 of file http.c.

Referenced by http_close_all_ports(), server_shutdown(), and start_server_thread().

◆ server_thread_lock

Mutex* server_thread_lock = NULL
static

Definition at line 1892 of file http.c.

Referenced by server_init(), server_shutdown(), and start_server_thread().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.