Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

http.c File Reference

#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "gwlib.h"
#include "gwlib/regex.h"

Include dependency graph for http.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  HTTPEntity
struct  HTTPServer
struct  HTTPClient
struct  port
struct  server

Defines

#define DUMP_RESPONSE   1
#define HTTP_SERVER_TIMEOUT   60
#define HTTP_MAX_FOLLOW   5
#define MAX_SERVERS   32
#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

int read_some_headers (Connection *conn, List *headers)
int parse_http_version (Octstr *version)
void proxy_add_authentication (List *headers)
void proxy_init (void)
void proxy_shutdown (void)
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)
void deduce_body_state (HTTPEntity *ent)
HTTPEntityentity_create (enum body_expectation exp)
void entity_destroy (HTTPEntity *ent)
void read_chunked_body_len (HTTPEntity *ent, Connection *conn)
void read_chunked_body_data (HTTPEntity *ent, Connection *conn)
void read_chunked_body_crlf (HTTPEntity *ent, Connection *conn)
void read_chunked_body_trailer (HTTPEntity *ent, Connection *conn)
void read_body_until_eof (HTTPEntity *ent, Connection *conn)
void read_body_with_length (HTTPEntity *ent, Connection *conn)
int entity_read (HTTPEntity *ent, Connection *conn)
int send_request (HTTPServer *trans)
Octstrbuild_response (List *headers, Octstr *body)
HTTPServerserver_create (HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow_remaining, Octstr *certkeyfile)
void server_destroy (void *p)
void conn_pool_item_destroy (void *item)
void conn_pool_init (void)
void conn_pool_shutdown (void)
Octstrconn_pool_key (Octstr *host, int port, int ssl, Octstr *certfile, Octstr *our_host)
Connectionconn_pool_get (Octstr *host, int port, int ssl, Octstr *certkeyfile, Octstr *our_host)
void check_pool_conn (Connection *conn, void *data)
void conn_pool_put (Connection *conn, Octstr *host, int port, int ssl, Octstr *certfile, Octstr *our_host)
HTTPCallerhttp_caller_create (void)
void http_caller_destroy (HTTPCaller *caller)
void http_caller_signal_shutdown (HTTPCaller *caller)
Octstrget_redirection_location (HTTPServer *trans)
int client_read_status (HTTPServer *trans)
int response_expectation (int method, int status)
void handle_transaction (Connection *conn, void *data)
Octstrbuild_request (char *method_name, Octstr *path_or_url, Octstr *host, long port, List *headers, Octstr *request_body)
HTTPURLParsehttp_urlparse_create (void)
void http_urlparse_destroy (HTTPURLParse *p)
void parse_dump (HTTPURLParse *p)
HTTPURLParseparse_url (Octstr *url)
void parse2trans (HTTPURLParse *p, HTTPServer *t)
Connectionget_connection (HTTPServer *trans)
void write_request_thread (void *arg)
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)
void client_init (void)
void client_shutdown (void)
HTTPClientclient_create (int port, Connection *conn, Octstr *ip)
void client_destroy (void *client)
void client_reset (HTTPClient *p)
int client_is_persistent (List *headers, int use_version_1_0)
int port_match (void *client, void *port)
void port_init (void)
void port_shutdown (void)
Octstrport_key (int port)
void port_add (int port)
void port_remove (int port)
void port_put_request (HTTPClient *client)
HTTPClientport_get_request (int port)
int parse_request_line (int *method, Octstr **url, int *use_version_1_0, Octstr *line)
void receive_request (Connection *conn, void *data)
void server_thread (void *dummy)
void start_server_thread (void)
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)
Listparse_cgivars (Octstr *url)
HTTPClienthttp_accept_request (int port, Octstr **client_ip, Octstr **url, List **headers, Octstr **body, List **cgivars)
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)
void server_init (void)
void destroy_struct_server (void *p)
void destroy_int_pointer (void *p)
void server_shutdown (void)
void http_destroy_cgiargs (List *args)
Octstrhttp_cgi_variable (List *list, char *name)
int header_is_called (Octstr *header, 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)
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)
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

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


Define Documentation

#define DUMP_RESPONSE   1
 

Definition at line 88 of file http.c.

#define HTTP_MAX_FOLLOW   5
 

Definition at line 651 of file http.c.

#define HTTP_SERVER_TIMEOUT   60
 

Definition at line 94 of file http.c.

Referenced by start_server_thread().

#define MAX_HEADER_LENGTH   256
 

Definition at line 2819 of file http.c.

#define MAX_SERVERS   32
 

Definition at line 2052 of file http.c.

Referenced by server_thread().


Enumeration Type Documentation

anonymous enum
 

Enumeration values:
HTTP_PORT 
HTTPS_PORT 

Definition at line 104 of file http.c.

00104      { HTTP_PORT = 80,
00105        HTTPS_PORT = 443 };

anonymous enum
 

Enumeration values:
limbo 
running 
terminating 

Definition at line 111 of file http.c.

00111             { 
00112     limbo, 
00113     running, 
00114     terminating 
00115 } run_status = limbo;

enum body_expectation
 

Enumeration values:
expect_no_body 
expect_body_if_indicated 
expect_body 

Definition at line 329 of file http.c.

00329                       {
00330    /*
00331     * Message must not have a body, even if the headers indicate one.
00332     * (i.e. response to HEAD method).
00333     */
00334    expect_no_body,
00335    /*
00336     * Message will have a body if Content-Length or Transfer-Encoding
00337     * headers are present (i.e. most request methods).
00338     */
00339    expect_body_if_indicated,
00340    /*
00341     * Message will have a body, possibly zero-length.
00342     * (i.e. 200 OK responses to a GET method.)
00343     */
00344    expect_body
00345 };

enum entity_state
 

Enumeration values:
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 347 of file http.c.

Referenced by entity_read().

00347                   {
00348     reading_headers,
00349     reading_chunked_body_len,
00350     reading_chunked_body_data,
00351     reading_chunked_body_crlf,
00352     reading_chunked_body_trailer,
00353     reading_body_until_eof,
00354     reading_body_with_length,
00355     body_error,
00356     entity_done
00357 };


Function Documentation

Octstr* build_request char *  method_name,
Octstr path_or_url,
Octstr host,
long  port,
List headers,
Octstr request_body
[static]
 

Definition at line 1170 of file http.c.

References gwlist_get(), gwlist_len(), octstr_append(), octstr_format(), octstr_format_append(), octstr_imm(), and port.

Referenced by send_request().

01173 {
01174     /* XXX headers missing */
01175     Octstr *request;
01176     int i;
01177 
01178     request = octstr_format("%s %S HTTP/1.1\r\n",
01179                             method_name, path_or_url);
01180 
01181     octstr_format_append(request, "Host: %S", host);
01182     if (port != HTTP_PORT)
01183         octstr_format_append(request, ":%ld", port);
01184     octstr_append(request, octstr_imm("\r\n"));
01185 #ifdef USE_KEEPALIVE 
01186     octstr_append(request, octstr_imm("Connection: keep-alive\r\n"));
01187 #endif
01188 
01189     for (i = 0; headers != NULL && i < gwlist_len(headers); ++i) {
01190         octstr_append(request, gwlist_get(headers, i));
01191         octstr_append(request, octstr_imm("\r\n"));
01192     }
01193     octstr_append(request, octstr_imm("\r\n"));
01194 
01195     if (request_body != NULL)
01196         octstr_append(request, request_body);
01197 
01198     return request;
01199 }

Here is the call graph for this function:

Octstr * build_response List headers,
Octstr body
[static]
 

Definition at line 1206 of file http.c.

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

Referenced by handle_transaction().

01207 {
01208     Octstr *response;
01209     int i;
01210 
01211     response = octstr_create("");
01212 
01213     for (i = 0; headers != NULL && i < gwlist_len(headers); ++i) {
01214         octstr_append(response, gwlist_get(headers, i));
01215         octstr_append(response, octstr_imm("\r\n"));
01216     }
01217     octstr_append(response, octstr_imm("\r\n"));
01218 
01219     if (body != NULL)
01220         octstr_append(response, body);
01221 
01222     return response;
01223 }

Here is the call graph for this function:

void check_pool_conn Connection conn,
void *  data
[static]
 

Definition at line 840 of file http.c.

References conn_destroy(), conn_eof(), conn_error(), conn_get_id(), conn_pool, conn_pool_lock, conn_unregister(), debug(), dict_get(), gwlist_delete_equal(), mutex_lock, mutex_unlock, octstr_get_cstr, and run_status.

Referenced by conn_pool_put().

00841 {
00842     Octstr *key = data;
00843     
00844     if (run_status != running) {
00845         conn_unregister(conn);
00846         return;
00847     }
00848     /* check if connection still ok */
00849     if (conn_error(conn) || conn_eof(conn)) {
00850         List *list;
00851         mutex_lock(conn_pool_lock);
00852         list = dict_get(conn_pool, key);
00853         if (gwlist_delete_equal(list, conn) > 0) {
00854             /*
00855              * ok, connection was still within pool. So it's
00856              * safe to destroy this connection.
00857              */
00858             debug("gwlib.http", 0, "HTTP: Server closed connection, destroying it <%s><%p><fd:%d>.",
00859                   octstr_get_cstr(key), conn, conn_get_id(conn));
00860             conn_unregister(conn);
00861             conn_destroy(conn);
00862         }
00863         /*
00864          * it's perfectly valid if connection was not found in connection pool because
00865          * in 'conn_pool_get' we first removed connection from pool with conn_pool_lock locked
00866          * and then check connection for errors with conn_pool_lock unlocked. In the meantime
00867          * fdset's poller may call us. So just ignore such "dummy" call.
00868         */
00869         mutex_unlock(conn_pool_lock);
00870     }
00871 }

Here is the call graph for this function:

HTTPClient* client_create int  port,
Connection conn,
Octstr ip
[static]
 

Definition at line 1799 of file http.c.

References active_connections, HTTPClient::conn, conn_get_ssl(), debug(), gwlist_produce(), octstr_get_cstr, and HTTPClient::port.

Referenced by server_thread().

01800 {
01801     HTTPClient *p;
01802     
01803 #ifdef HAVE_LIBSSL
01804     if (conn_get_ssl(conn)) 
01805         debug("gwlib.http", 0, "HTTP: Creating SSL-enabled HTTPClient for `%s', using cipher '%s'.",
01806               octstr_get_cstr(ip), SSL_get_cipher_version(conn_get_ssl(conn)));
01807     else
01808 #endif    
01809         debug("gwlib.http", 0, "HTTP: Creating HTTPClient for `%s'.", octstr_get_cstr(ip));
01810     p = gw_malloc(sizeof(*p));
01811     p->port = port;
01812     p->conn = conn;
01813     p->ip = ip;
01814     p->state = reading_request_line;
01815     p->url = NULL;
01816     p->use_version_1_0 = 0;
01817     p->persistent_conn = 1;
01818     p->conn_time = time(NULL);
01819     p->request = NULL;
01820     debug("gwlib.http", 0, "HTTP: Created HTTPClient area %p.", p);
01821     
01822     /* add this client to active_connections */
01823     gwlist_produce(active_connections, p);
01824     
01825     return p;
01826 }

Here is the call graph for this function:

void client_destroy void *  client  )  [static]
 

Definition at line 1829 of file http.c.

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

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

01830 {
01831     HTTPClient *p;
01832     
01833     if (client == NULL)
01834         return;
01835 
01836     p = client;
01837     
01838     /* drop this client from active_connections list */
01839     gwlist_lock(active_connections);
01840     if (gwlist_delete_equal(active_connections, p) != 1)
01841         panic(0, "HTTP: Race condition in client_destroy(%p) detected!", client);
01842     gwlist_unlock(active_connections);
01843     
01844     debug("gwlib.http", 0, "HTTP: Destroying HTTPClient area %p.", p);
01845     gw_assert_allocated(p, __FILE__, __LINE__, __func__);
01846     debug("gwlib.http", 0, "HTTP: Destroying HTTPClient for `%s'.",
01847           octstr_get_cstr(p->ip));
01848     
01849     conn_destroy(p->conn);
01850     octstr_destroy(p->ip);
01851     octstr_destroy(p->url);
01852     entity_destroy(p->request);
01853     gw_free(p);
01854 }

Here is the call graph for this function:

void client_init void   )  [static]
 

Definition at line 1746 of file http.c.

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

Referenced by http_init().

01747 {
01748     pending_requests = gwlist_create();
01749     gwlist_add_producer(pending_requests);
01750     client_thread_lock = mutex_create();
01751 }

Here is the call graph for this function:

int client_is_persistent List headers,
int  use_version_1_0
[static]
 

Definition at line 1872 of file http.c.

References http_header_find_first, octstr_case_compare(), octstr_destroy(), and octstr_imm().

Referenced by http_accept_request().

01873 {
01874     Octstr *h = http_header_find_first(headers, "Connection");
01875 
01876     if (h == NULL) {
01877         return !use_version_1_0;
01878     } else {
01879         if (!use_version_1_0) {
01880             if (octstr_case_compare(h, octstr_imm("keep-alive")) == 0) {
01881                 octstr_destroy(h);
01882                 return 1;
01883             } else {
01884                 octstr_destroy(h);
01885                 return 0;
01886             }
01887         } else if (octstr_case_compare(h, octstr_imm("close")) == 0) {
01888             octstr_destroy(h);
01889             return 0;
01890         }
01891         octstr_destroy(h);
01892     }
01893 
01894     return 1;
01895 }

Here is the call graph for this function:

int client_read_status HTTPServer trans  )  [static]
 

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

00937 {
00938     Octstr *line, *version;
00939     long space;
00940     int ret;
00941 
00942     line = conn_read_line(trans->conn);
00943     if (line == NULL) {
00944     if (conn_eof(trans->conn) || conn_error(trans->conn))
00945         return -1;
00946         return 1;
00947     }
00948 
00949     debug("gwlib.http", 0, "HTTP: Status line: <%s>", octstr_get_cstr(line));
00950 
00951     space = octstr_search_char(line, ' ', 0);
00952     if (space == -1)
00953         goto error;
00954     
00955     version = octstr_copy(line, 0, space);
00956     ret = parse_http_version(version);
00957     octstr_destroy(version);
00958     if (ret == -1)
00959         goto error;
00960     trans->persistent = ret;
00961 
00962     octstr_delete(line, 0, space + 1);
00963     space = octstr_search_char(line, ' ', 0);
00964     if (space == -1)
00965         goto error;
00966     octstr_truncate(line, space);
00967     
00968     if (octstr_parse_long(&trans->status, line, 0, 10) == -1)
00969         goto error;
00970 
00971     octstr_destroy(line);
00972     return 0;
00973 
00974 error:
00975     error(0, "HTTP: Malformed status line from HTTP server: <%s>",
00976       octstr_get_cstr(line));
00977     octstr_destroy(line);
00978     return -1;
00979 }

Here is the call graph for this function:

void client_reset HTTPClient p  )  [static]
 

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

01858 {
01859     debug("gwlib.http", 0, "HTTP: Resetting HTTPClient for `%s'.",
01860           octstr_get_cstr(p->ip));
01861     p->state = reading_request_line;
01862     p->conn_time = time(NULL);
01863     gw_assert(p->request == NULL);
01864 }

Here is the call graph for this function:

void client_shutdown void   )  [static]
 

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

01755 {
01756     gwlist_remove_producer(pending_requests);
01757     gwthread_join_every(write_request_thread);
01758     client_threads_are_running = 0;
01759     gwlist_destroy(pending_requests, server_destroy);
01760     mutex_destroy(client_thread_lock);
01761     fdset_destroy(client_fdset);
01762     client_fdset = NULL;
01763     octstr_destroy(http_interface);
01764     http_interface = NULL;
01765 }

Here is the call graph for this function:

Connection* conn_pool_get Octstr host,
int  port,
int  ssl,
Octstr certkeyfile,
Octstr our_host
[static]
 

Definition at line 780 of file http.c.

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

Referenced by get_connection().

00782 {
00783     Octstr *key;
00784     List *list = NULL;
00785     Connection *conn = NULL;
00786     int retry;
00787 
00788     do {
00789         retry = 0;
00790         key = conn_pool_key(host, port, ssl, certkeyfile, our_host);
00791         mutex_lock(conn_pool_lock);
00792         list = dict_get(conn_pool, key);
00793         if (list != NULL)
00794             conn = gwlist_extract_first(list);
00795         mutex_unlock(conn_pool_lock);
00796         /*
00797          * Note: we don't hold conn_pool_lock when we check/destroy/unregister
00798          *       connection because otherwise we can deadlock! And it's even better
00799          *       not to delay other threads while we check connection.
00800          */
00801         if (conn != NULL) {
00802 #ifdef USE_KEEPALIVE
00803             /* unregister our server disconnect callback */
00804             conn_unregister(conn);
00805 #endif 
00806             /*
00807              * Check whether the server has closed the connection while
00808              * it has been in the pool.
00809              */
00810             conn_wait(conn, 0);
00811             if (conn_eof(conn) || conn_error(conn)) {
00812                 debug("gwlib.http", 0, "HTTP:conn_pool_get: Server closed connection, destroying it <%s><%p><fd:%d>.",
00813                       octstr_get_cstr(key), conn, conn_get_id(conn));
00814                 conn_destroy(conn);
00815                 retry = 1;
00816                 conn = NULL;
00817             }
00818         }
00819         octstr_destroy(key);
00820     } while(retry == 1);
00821     
00822     if (conn == NULL) {
00823 #ifdef HAVE_LIBSSL
00824         if (ssl) 
00825             conn = conn_open_ssl_nb(host, port, certkeyfile, our_host);
00826         else
00827 #endif /* HAVE_LIBSSL */
00828             conn = conn_open_tcp_nb(host, port, our_host);
00829         debug("gwlib.http", 0, "HTTP: Opening connection to `%s:%d' (fd=%d).",
00830               octstr_get_cstr(host), port, conn_get_id(conn));
00831     } else {
00832         debug("gwlib.http", 0, "HTTP: Reusing connection to `%s:%d' (fd=%d).",
00833               octstr_get_cstr(host), port, conn_get_id(conn)); 
00834     }
00835     
00836     return conn;
00837 }

Here is the call graph for this function:

void conn_pool_init void   )  [static]
 

Definition at line 759 of file http.c.

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

Referenced by http_init().

00760 {
00761     conn_pool = dict_create(1024, conn_pool_item_destroy);
00762     conn_pool_lock = mutex_create();
00763 }

Here is the call graph for this function:

void conn_pool_item_destroy void *  item  )  [static]
 

Definition at line 754 of file http.c.

References conn_destroy(), and gwlist_destroy().

Referenced by conn_pool_init().

00755 {
00756     gwlist_destroy(item, (void(*)(void*))conn_destroy);
00757 }

Here is the call graph for this function:

Octstr* conn_pool_key Octstr host,
int  port,
int  ssl,
Octstr certfile,
Octstr our_host
[inline, static]
 

Definition at line 773 of file http.c.

References octstr_format(), port, and ssl.

Referenced by conn_pool_get(), and conn_pool_put().

00774 {
00775     return octstr_format("%S:%d:%d:%S:%S", host, port, ssl?1:0, certfile?certfile:octstr_imm(""),
00776                          our_host?our_host:octstr_imm(""));
00777 }

Here is the call graph for this function:

void conn_pool_put Connection conn,
Octstr host,
int  port,
int  ssl,
Octstr certfile,
Octstr our_host
[static]
 

Definition at line 874 of file http.c.

References check_pool_conn(), client_fdset, conn_pool, conn_pool_key(), conn_pool_lock, conn_register_real(), dict_get(), dict_put(), gwlist_append(), gwlist_create, mutex_lock, mutex_unlock, octstr_destroy_item(), port, and ssl.

Referenced by handle_transaction().

00875 {
00876     Octstr *key;
00877     List *list;
00878 
00879     key = conn_pool_key(host, port, ssl, certfile, our_host);
00880     mutex_lock(conn_pool_lock);
00881     list = dict_get(conn_pool, key);
00882     if (list == NULL) {
00883         list = gwlist_create();
00884         dict_put(conn_pool, key, list);
00885     }
00886     gwlist_append(list, conn);
00887     /* register connection to get server disconnect */
00888     conn_register_real(conn, client_fdset, check_pool_conn, key, octstr_destroy_item);
00889     mutex_unlock(conn_pool_lock);
00890 }

Here is the call graph for this function:

void conn_pool_shutdown void   )  [static]
 

Definition at line 766 of file http.c.

References conn_pool, conn_pool_lock, dict_destroy(), and mutex_destroy().

Referenced by http_shutdown().

00767 {
00768     dict_destroy(conn_pool);
00769     mutex_destroy(conn_pool_lock);
00770 }

Here is the call graph for this function:

void deduce_body_state HTTPEntity ent  )  [static]
 

Definition at line 373 of file http.c.

References error(), HTTPEntity::expected_body_len, HTTPEntity::headers, http_header_find_first, octstr_destroy(), octstr_get_cstr, octstr_parse_long(), octstr_str_compare(), and octstr_strip_blanks().

Referenced by entity_read().

00374 {
00375     Octstr *h = NULL;
00376 
00377     if (ent->expect_state == expect_no_body) {
00378         ent->state = entity_done;
00379         return;
00380     }
00381 
00382     ent->state = body_error;  /* safety net */
00383 
00384     h = http_header_find_first(ent->headers, "Transfer-Encoding");
00385     if (h != NULL) {
00386         octstr_strip_blanks(h);
00387         if (octstr_str_compare(h, "chunked") != 0) {
00388             error(0, "HTTP: Unknown Transfer-Encoding <%s>",
00389                   octstr_get_cstr(h));
00390             ent->state = body_error;
00391         } else {
00392             ent->state = reading_chunked_body_len;
00393         }
00394         octstr_destroy(h);
00395         return;
00396     }
00397 
00398     h = http_header_find_first(ent->headers, "Content-Length");
00399     if (h != NULL) {
00400         if (octstr_parse_long(&ent->expected_body_len, h, 0, 10) == -1 ||
00401             ent->expected_body_len < 0) {
00402             error(0, "HTTP: Content-Length header wrong: <%s>",
00403                   octstr_get_cstr(h));
00404             ent->state = body_error;
00405         } else if (ent->expected_body_len == 0) {
00406             ent->state = entity_done;
00407         } else {
00408             ent->state = reading_body_with_length;
00409         }
00410         octstr_destroy(h);
00411         return;
00412     }
00413 
00414     if (ent->expect_state == expect_body)
00415         ent->state = reading_body_until_eof;
00416     else
00417         ent->state = entity_done;
00418 }

Here is the call graph for this function:

void destroy_int_pointer void *  p  )  [static]
 

Definition at line 2622 of file http.c.

Referenced by server_shutdown().

02623 {
02624     (void) close(*(int *) p);
02625     gw_free(p);
02626 }

void destroy_struct_server void *  p  )  [static]
 

Definition at line 2612 of file http.c.

References server::fd.

Referenced by server_shutdown().

02613 {
02614     struct server *pp;
02615     
02616     pp = p;
02617     (void) close(pp->fd);
02618     gw_free(pp);
02619 }

HTTPEntity* entity_create enum body_expectation  exp  )  [static]
 

Definition at line 427 of file http.c.

References HTTPEntity::headers, http_create_empty_headers(), and octstr_create.

Referenced by handle_transaction(), and receive_request().

00428 {
00429     HTTPEntity *ent;
00430 
00431     ent = gw_malloc(sizeof(*ent));
00432     ent->headers = http_create_empty_headers();
00433     ent->body = octstr_create("");
00434     ent->chunked_body_chunk_len = -1;
00435     ent->expected_body_len = -1;
00436     ent->state = reading_headers;
00437     ent->expect_state = exp;
00438 
00439     return ent;
00440 }

Here is the call graph for this function:

void entity_destroy HTTPEntity ent  )  [static]
 

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

00444 {
00445     if (ent == NULL)
00446         return;
00447 
00448     http_destroy_headers(ent->headers);
00449     octstr_destroy(ent->body);
00450     gw_free(ent);
00451 }

Here is the call graph for this function:

int entity_read HTTPEntity ent,
Connection conn
[static]
 

Definition at line 558 of file http.c.

References body_error, deduce_body_state(), entity_done, entity_state, 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, and reading_headers.

Referenced by handle_transaction(), and receive_request().

00559 {
00560     int ret;
00561     enum entity_state old_state;
00562 
00563     /*
00564      * In this loop, each state will process as much input as it needs
00565      * and then switch to the next state, unless it's a final state in
00566      * which case it returns directly, or unless it needs more input.
00567      * So keep looping as long as the state changes.
00568      */
00569     do {
00570     old_state = ent->state;
00571     switch (ent->state) {
00572     case reading_headers:
00573         ret = read_some_headers(conn, ent->headers);
00574             if (ret == 0)
00575             deduce_body_state(ent);
00576         if (ret < 0)
00577         return -1;
00578         break;
00579 
00580     case reading_chunked_body_len:
00581         read_chunked_body_len(ent, conn);
00582         break;
00583         
00584     case reading_chunked_body_data:
00585         read_chunked_body_data(ent, conn);
00586         break;
00587 
00588     case reading_chunked_body_crlf:
00589         read_chunked_body_crlf(ent, conn);
00590         break;
00591 
00592     case reading_chunked_body_trailer:
00593         read_chunked_body_trailer(ent, conn);
00594         break;
00595 
00596     case reading_body_until_eof:
00597         read_body_until_eof(ent, conn);
00598         break;
00599 
00600     case reading_body_with_length:
00601         read_body_with_length(ent, conn);
00602         break;
00603 
00604     case body_error:
00605         return -1;
00606 
00607     case entity_done:
00608         return 0;
00609 
00610     default:
00611         panic(0, "Internal error: Invalid HTTPEntity state.");
00612     }
00613     } while (ent->state != old_state);
00614 
00615     /*
00616      * If we got here, then the loop ended because a non-final state
00617      * needed more input.
00618      */
00619     return 1;
00620 }

Here is the call graph for this function:

Connection* get_connection HTTPServer trans  )  [static]
 

Definition at line 1473 of file http.c.

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

Referenced by write_request_thread().

01474 {
01475     Connection *conn = NULL;
01476     Octstr *host;
01477     HTTPURLParse *p;
01478     int port, ssl;
01479     
01480     /* if the parsing has not yet been done, then do it now */
01481     if (!trans->host && trans->port == 0 && trans->url != NULL) {
01482         if ((p = parse_url(trans->url)) != NULL) {
01483             parse2trans(p, trans);
01484             http_urlparse_destroy(p);
01485         } else {
01486             goto error;
01487         }
01488     }
01489 
01490     if (proxy_used_for_host(trans->host, trans->url)) {
01491         host = proxy_hostname;
01492         port = proxy_port;
01493         ssl = proxy_ssl;
01494     } else {
01495         host = trans->host;
01496         port = trans->port;
01497         ssl = trans->ssl;
01498     }
01499 
01500     conn = conn_pool_get(host, port, ssl, trans->certkeyfile,
01501                          http_interface);
01502     if (conn == NULL)
01503         goto error;
01504 
01505     return conn;
01506 
01507 error:
01508     conn_destroy(conn);
01509     error(0, "Couldn't send request to <%s>", octstr_get_cstr(trans->url));
01510     return NULL;
01511 }

Here is the call graph for this function:

Octstr* get_redirection_location HTTPServer trans  )  [static]
 

Definition at line 916 of file http.c.

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

Referenced by handle_transaction().

00917 {
00918     if (trans->status < 0 || trans->follow_remaining <= 0)
00919         return NULL;
00920     /* check for the redirection response codes */
00921     if (trans->status != HTTP_MOVED_PERMANENTLY &&
00922         trans->status != HTTP_FOUND && trans->status != HTTP_SEE_OTHER &&
00923         trans->status != HTTP_TEMPORARY_REDIRECT)
00924     return NULL;
00925     if (trans->response == NULL)
00926         return NULL;
00927     return http_header_find_first(trans->response->headers, "Location");
00928 }

void handle_transaction Connection conn,
void *  data
[static]
 

Definition at line 992 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_pool_put(), conn_unregister(), debug(), entity_create(), entity_destroy(), entity_read(), error(), HTTPServer::follow_remaining, get_redirection_location(), gwlist_create, gwlist_insert(), gwlist_produce(), HTTPEntity::headers, HTTPServer::host, http_destroy_headers(), http_header_find_first, http_interface, http_status_class(), HTTPServer::method, octstr_case_compare(), octstr_create, 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(), HTTPServer::response, response_expectation(), run_status, send_request(), HTTPServer::ssl, HTTPServer::state, HTTPServer::status, HTTPServer::uri, HTTPServer::url, and HTTPServer::username.

Referenced by write_request_thread().

00993 {
00994     HTTPServer *trans;
00995     int ret;
00996     Octstr *h;
00997     int rc;
00998     
00999     trans = data;
01000 
01001     if (run_status != running) {
01002         conn_unregister(conn);
01003         return;
01004     }
01005 
01006     while (trans->state != transaction_done) {
01007         switch (trans->state) {
01008         case connecting:
01009             debug("gwlib.http", 0, "Get info about connecting socket");
01010             if (conn_get_connect_result(trans->conn) != 0) {
01011                 debug("gwlib.http", 0, "Socket not connected");
01012                 goto error;
01013             }
01014 
01015             if ((rc = send_request(trans)) == 0) {
01016                 trans->state = reading_status;
01017             } else {
01018                 debug("gwlib.http", 0, "Failed while sending request");
01019                 goto error;
01020             }
01021             break;
01022 
01023     case reading_status:
01024         ret = client_read_status(trans);
01025         if (ret < 0) {
01026         /*
01027          * Couldn't read the status from the socket. This may mean 
01028          * that the socket had been closed by the server after an 
01029          * idle timeout.
01030          */
01031                 debug("gwlib.http",0,"Failed while reading status");
01032                 goto error;
01033         } else if (ret == 0) {
01034         /* Got the status, go read headers and body next. */
01035         trans->state = reading_entity;
01036         trans->response =
01037             entity_create(response_expectation(trans->method, trans->status));
01038         } else
01039         return;
01040         break;
01041         
01042     case reading_entity:
01043         ret = entity_read(trans->response, conn);
01044         if (ret < 0) {
01045             debug("gwlib.http",0,"Failed reading entity");
01046             goto error;
01047         } else if (ret == 0 && 
01048                     http_status_class(trans->status) == HTTP_STATUS_PROVISIONAL) {
01049                 /* This was a provisional reply; get the real one now. */
01050                 trans->state = reading_status;
01051                 entity_destroy(trans->response);
01052                 trans->response = NULL;
01053             } else if (ret == 0) {
01054                 trans->state = transaction_done;
01055 #ifdef DUMP_RESPONSE
01056                 /* Dump the response */
01057                 debug("gwlib.http", 0, "HTTP: Received response:");
01058                 h = build_response(trans->response->headers, trans->response->body);
01059                 octstr_dump(h, 0);
01060                 octstr_destroy(h);
01061 #endif
01062         } else {
01063                 return;
01064             }
01065             break;
01066 
01067         default:
01068             panic(0, "Internal error: Invalid HTTPServer state.");
01069         }
01070     }
01071 
01072     conn_unregister(trans->conn);
01073 
01074     /* 
01075      * Take care of persistent connection handling. 
01076      * At this point we have only obeyed if server responds in HTTP/1.0 or 1.1
01077      * and have assigned trans->persistent accordingly. This can be keept
01078      * for default usage, but if we have [Proxy-]Connection: keep-alive, then
01079      * we're still forcing persistancy of the connection.
01080      */
01081     h = http_header_find_first(trans->response->headers, "Connection");
01082     if (h != NULL && octstr_case_compare(h, octstr_imm("close")) == 0)
01083         trans->persistent = 0;
01084     if (h != NULL && octstr_case_compare(h, octstr_imm("keep-alive")) == 0)
01085         trans->persistent = 1;
01086     octstr_destroy(h);
01087     if (proxy_used_for_host(trans->host, trans->url)) {
01088         h = http_header_find_first(trans->response->headers, "Proxy-Connection");
01089         if (h != NULL && octstr_case_compare(h, octstr_imm("close")) == 0)
01090             trans->persistent = 0;
01091         if (h != NULL && octstr_case_compare(h, octstr_imm("keep-alive")) == 0)
01092             trans->persistent = 1;
01093         octstr_destroy(h);
01094     }
01095 
01096 #ifdef USE_KEEPALIVE 
01097     if (trans->persistent) {
01098         if (proxy_used_for_host(trans->host, trans->url))
01099             conn_pool_put(trans->conn, proxy_hostname, proxy_port, trans->ssl, trans->certkeyfile, http_interface);
01100         else 
01101             conn_pool_put(trans->conn, trans->host, trans->port, trans->ssl, trans->certkeyfile, http_interface);
01102     } else
01103 #endif
01104         conn_destroy(trans->conn);
01105 
01106     trans->conn = NULL;
01107 
01108     /* 
01109      * Check if the HTTP server told us to look somewhere else,
01110      * hence if we got one of the following response codes:
01111      *   HTTP_MOVED_PERMANENTLY (301)
01112      *   HTTP_FOUND (302)
01113      *   HTTP_SEE_OTHER (303)
01114      *   HTTP_TEMPORARY_REDIRECT (307)
01115      */
01116     if ((h = get_redirection_location(trans)) != NULL) {
01117 
01118         /* 
01119          * This is a redirected response, we have to follow.
01120          * Clean up all trans stuff for the next request we do.
01121          */
01122         octstr_strip_blanks(h);
01123         octstr_destroy(trans->url);
01124         octstr_destroy(trans->host);
01125         trans->port = 0;
01126         octstr_destroy(trans->uri);
01127         octstr_destroy(trans->username);
01128         octstr_destroy(trans->password);
01129         trans->host = NULL;
01130         trans->port = 0;
01131         trans->uri = NULL;
01132         trans->username = NULL;
01133         trans->password = NULL;
01134         trans->ssl = 0;
01135         trans->url = h; /* apply new absolute URL to next request */
01136         trans->state = request_not_sent;
01137         trans->status = -1;
01138         http_destroy_headers(trans->response->headers);
01139         trans->response->headers = gwlist_create();
01140         octstr_destroy(trans->response->body);
01141         trans->response->body = octstr_create("");
01142         --trans->follow_remaining;
01143         conn_destroy(trans->conn);
01144         trans->conn = NULL;
01145 
01146         /* re-inject request to the front of the queue */
01147         gwlist_insert(pending_requests, 0, trans);
01148 
01149     } else {
01150         /* handle this response as usual */
01151         gwlist_produce(trans->caller, trans);
01152     }
01153     return;
01154 
01155 error:
01156     conn_unregister(trans->conn);
01157     conn_destroy(trans->conn);
01158     trans->conn = NULL;
01159     error(0, "Couldn't fetch <%s>", octstr_get_cstr(trans->url));
01160     trans->status = -1;
01161     gwlist_produce(trans->caller, trans);
01162 }

Here is the call graph for this function:

int header_is_called Octstr header,
char *  name
[static]
 

Definition at line 2691 of file http.c.

References name, octstr_get_cstr, and octstr_search_char().

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

02692 {
02693     long colon;
02694 
02695     colon = octstr_search_char(header, ':', 0);
02696     if (colon == -1)
02697         return 0;
02698     if ((long) strlen(name) != colon)
02699         return 0;
02700     return strncasecmp(octstr_get_cstr(header), name, colon) == 0;
02701 }

Here is the call graph for this function:

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

Definition at line 2435 of file http.c.

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

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

02438 {
02439     HTTPClient *client;
02440 
02441     do {
02442         client = port_get_request(port);
02443         if (client == NULL) {
02444             debug("gwlib.http", 0, "HTTP: No clients with requests, quitting.");
02445             return NULL;
02446         }
02447         /* check whether client connection still ok */
02448         conn_wait(client->conn, 0);
02449         if (conn_error(client->conn) || conn_eof(client->conn)) {
02450             client_destroy(client);
02451             client = NULL;
02452         }
02453     } while(client == NULL);
02454 
02455     *client_ip = octstr_duplicate(client->ip);
02456     *url = client->url;
02457     *headers = client->request->headers;
02458     *body = client->request->body;
02459     *cgivars = parse_cgivars(client->url);
02460 
02461     if (client->method != HTTP_METHOD_POST) {
02462     octstr_destroy(*body);
02463     *body = NULL;
02464     }
02465 
02466     client->persistent_conn = client_is_persistent(client->request->headers,
02467                            client->use_version_1_0);
02468     
02469     client->url = NULL;
02470     client->request->headers = NULL;
02471     client->request->body = NULL;
02472     entity_destroy(client->request);
02473     client->request = NULL;
02474 
02475     return client;
02476 }

Here is the call graph for this function:

void http_add_basic_auth List headers,
Octstr username,
Octstr password
 

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

03345 {
03346     Octstr *os;
03347     
03348     if (password != NULL)
03349       os = octstr_format("%S:%S", username, password);
03350     else
03351       os = octstr_format("%S", username);
03352     octstr_binary_to_base64(os);
03353     octstr_strip_blanks(os);
03354     octstr_insert(os, octstr_imm("Basic "), 0);
03355     http_header_add(headers, "Authorization", octstr_get_cstr(os));
03356     octstr_destroy(os);
03357 }

Here is the call graph for this function:

void http_append_headers List to,
List from
 

Definition at line 2884 of file http.c.

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

Referenced by http_header_combine(), and pap_request_thread().

02885 {
02886     Octstr *header;
02887     long i;
02888 
02889     gwlib_assert_init();
02890     gw_assert(to != NULL);
02891     gw_assert(from != NULL);
02892 
02893     for (i = 0; i < gwlist_len(from); ++i) {
02894         header = gwlist_get(from, i);
02895         gwlist_append(to, octstr_duplicate(header));
02896     }
02897 }

Here is the call graph for this function:

HTTPCaller* http_caller_create void   ) 
 

Definition at line 894 of file http.c.

References gwlist_add_producer(), gwlist_create, and HTTPCaller.

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

00895 {
00896     HTTPCaller *caller;
00897     
00898     caller = gwlist_create();
00899     gwlist_add_producer(caller);
00900     return caller;
00901 }

Here is the call graph for this function:

void http_caller_destroy HTTPCaller caller  ) 
 

Definition at line 904 of file http.c.

References gwlist_destroy(), HTTPCaller, and server_destroy().

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

00905 {
00906     gwlist_destroy(caller, server_destroy);
00907 }

Here is the call graph for this function:

void http_caller_signal_shutdown HTTPCaller caller  ) 
 

Definition at line 910 of file http.c.

References gwlist_remove_producer(), and HTTPCaller.

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

00911 {
00912     gwlist_remove_producer(caller);
00913 }

Here is the call graph for this function:

Octstr* http_cgi_variable List list,
char *  name
 

Definition at line 2668 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(), httpd_check_authorization(), httpd_emu(), httpd_loglevel(), 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().

02669 {
02670     int i;
02671     HTTPCGIVar *v;
02672 
02673     gwlib_assert_init();
02674     gw_assert(list != NULL);
02675     gw_assert(name != NULL);
02676 
02677     for (i = 0; i < gwlist_len(list); ++i) {
02678         v = gwlist_get(list, i);
02679         if (octstr_str_compare(v->name, name) == 0)
02680             return v->value;
02681     }
02682     return NULL;
02683 }

Here is the call graph for this function:

void http_cgivar_dump List cgiargs  ) 
 

Definition at line 3272 of file http.c.

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

03273 {
03274     HTTPCGIVar *v;
03275     long i, len;
03276 
03277     gwlib_assert_init();
03278 
03279     len = gwlist_len(cgiargs);
03280 
03281     debug("gwlib.http", 0, "Dumping %ld cgi variables:", len);
03282     for (i = 0; i < len; i++) {
03283         v = gwlist_get(cgiargs, i);
03284         octstr_dump(v->name, 0);
03285         octstr_dump(v->value, 0);
03286     }
03287     debug("gwlib.http", 0, "End of dump.");
03288 }

Here is the call graph for this function:

void http_cgivar_dump_into List cgiargs,
Octstr os
 

Definition at line 3291 of file http.c.

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

03292 {
03293     HTTPCGIVar *v;
03294 
03295     if (os == NULL)
03296         return;
03297 
03298     gwlib_assert_init();
03299 
03300     while ((v = gwlist_extract_first(cgiargs)) != NULL)
03301         octstr_format_append(os, "&%S=%S", v->name, v->value);
03302 }

Here is the call graph for this function:

int http_charset_accepted List headers,
char *  charset
 

Definition at line 3338 of file http.c.

References charset, and http_something_accepted().

Referenced by add_charset_headers(), and normalize_charset().

03339 {
03340     return http_something_accepted(headers, "Accept-Charset", charset);
03341 }

Here is the call graph for this function:

void http_close_all_ports void   ) 
 

Definition at line 2374 of file http.c.

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

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

02375 {
02376     if (server_thread_id != -1) {
02377         keep_servers_open = 0;
02378         gwthread_wakeup(server_thread_id);
02379         gwthread_join_every(server_thread);
02380         server_thread_is_running = 0;
02381         fdset_destroy(server_fdset);
02382         server_fdset = NULL;
02383     }
02384 }

Here is the call graph for this function:

void http_close_client HTTPClient client  ) 
 

Definition at line 2597 of file http.c.

References client_destroy().

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

02598 {
02599     client_destroy(client);
02600 }

Here is the call graph for this function:

void http_close_port int  port  ) 
 

Definition at line 2363 of file http.c.

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

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

02364 {
02365     int *p;
02366     
02367     p = gw_malloc(sizeof(*p));
02368     *p = port;
02369     gwlist_produce(closed_server_sockets, p);
02370     gwthread_wakeup(server_thread_id);
02371 }

Here is the call graph for this function:

void http_close_proxy void   ) 
 

Definition at line 302 of file http.c.

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

00303 {
00304     gw_assert(run_status == running || run_status == terminating);
00305 
00306     mutex_lock(proxy_mutex);
00307     proxy_port = 0;
00308     octstr_destroy(proxy_hostname);
00309     octstr_destroy(proxy_username);
00310     octstr_destroy(proxy_password);
00311     proxy_hostname = NULL;
00312     proxy_username = NULL;
00313     proxy_password = NULL;
00314     gwlist_destroy(proxy_exceptions, octstr_destroy_item);
00315     gw_regex_destroy(proxy_exceptions_regex);
00316     proxy_exceptions = NULL;
00317     proxy_exceptions_regex = NULL;
00318     mutex_unlock(proxy_mutex);
00319 }

Here is the call graph for this function:

List* http_create_empty_headers void   ) 
 

Definition at line 2704 of file http.c.

References gwlib_assert_init(), and gwlist_create.

Referenced by brunet_send_sms(), challenge(), clickatell_send_sms(), entity_create(), http_header_duplicate(), httpd_emu_init(), indicate_push_connection(), indicate_push_resume(), kill_kannel(), main(), make_confirmedpush_pdu(), make_push_pdu(), make_reply_headers(), make_resume_reply_pdu(), mime_entity_create(), obey_request(), pass_data_headers(), push_headers_create(), reply(), return_reply(), send_to_pi(), soap_send(), soap_server(), start_fetch(), test_header_combine(), unpack_new_headers(), and wsp_headers_unpack().

02705 {
02706     gwlib_assert_init();
02707     return gwlist_create();
02708 }

Here is the call graph for this function:

void http_destroy_cgiargs List args  ) 
 

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

02651 {
02652     HTTPCGIVar *v;
02653 
02654     gwlib_assert_init();
02655 
02656     if (args == NULL)
02657         return ;
02658 
02659     while ((v = gwlist_extract_first(args)) != NULL) {
02660         octstr_destroy(v->name);
02661         octstr_destroy(v->value);
02662         gw_free(v);
02663     }
02664     gwlist_destroy(args, NULL);
02665 }

Here is the call graph for this function:

void http_destroy_headers List headers  ) 
 

Definition at line 2711 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_send_sms(), handle_transaction(), http_queue_thread(), http_something_accepted(), http_thread(), httpd_emu(), httpd_emu_shutdown(), httpd_serve(), httpsmsc_receiver(), httpsmsc_send_cb(), indicate_push_connection(), indicate_push_resume(), kannel_receive_sms(), kannel_send_sms(), kill_kannel(), main(), make_confirmedpush_pdu(), make_connectreply_pdu(), make_push_pdu(), make_resume_reply_pdu(), mime_entity_to_octstr(), mime_replace_headers(), mime_something_to_entity(), numhash_create(), obey_request(), pack_sia(), pap_request_thread(), receive_push_reply(), receive_reply(), reply(), return_replies_thread(), return_reply(), send_to_pi(), sendsms_thread(), server_destroy(), soap_read_response(), soap_send(), soap_server(), start_fetch(), start_push(), test_header_combine(), url_result_thread(), wapme_smsproxy_send_sms(), xidris_receive_sms(), and xidris_send_sms().

02712 {
02713     gwlib_assert_init();
02714     gwlist_destroy(headers, octstr_destroy_item);
02715 }

Here is the call graph for this function:

Octstr* http_get_header_parameter Octstr value,
Octstr parameter
 

Definition at line 3360 of file http.c.

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

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

03361 {
03362     long pos, len, end;
03363     int c, found = 0;
03364     Octstr *result = NULL;
03365 
03366     len = octstr_len(value);
03367     /* Find the start of the first parameter. */
03368     for (pos = 0; pos < len; pos++) {
03369         c = octstr_get_char(value, pos);
03370         if (c == ';')
03371             break;
03372         else if (c == '"')
03373             pos += http_header_quoted_string_len(value, pos) - 1;
03374     }
03375 
03376     if (pos >= len)
03377         return NULL;   /* no parameters */
03378 
03379     for (pos++; pos > 0 && pos < len && found == 0; pos++) {
03380         Octstr *key = NULL;
03381         Octstr *val = NULL;
03382 
03383         end = octstr_search_char(value, '=', pos);
03384         if (end < 0)
03385             end = octstr_search_char(value, ';', pos);
03386         if (end < 0)
03387             end = octstr_len(value);
03388         key = octstr_copy(value, pos, end - pos);
03389         octstr_strip_blanks(key);
03390         pos = end;
03391 
03392         if (octstr_get_char(value, pos) == '=') {
03393             pos++;
03394             while (isspace(octstr_get_char(value, pos)))
03395                 pos++;
03396             if (octstr_get_char(value, pos) == '"')
03397                 end = pos + http_header_quoted_string_len(value, pos);
03398             else
03399                 end = octstr_search_char(value, ';', pos);
03400             if (end < 0)
03401                 end = octstr_len(value);
03402             val = octstr_copy(value, pos, end - pos);
03403             octstr_strip_blanks(val);
03404             pos = end;
03405             pos = octstr_search_char(value, ';', pos);
03406         }
03407 
03408         /* is this the pair we look for? bail out then*/
03409         if (octstr_case_compare(key, parameter) == 0) {
03410             found++;        
03411             result = octstr_duplicate(val);
03412         }
03413 
03414         octstr_destroy(key);
03415         octstr_destroy(val);
03416     }
03417 
03418     return result;
03419 }

Here is the call graph for this function:

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

Definition at line 1727 of file http.c.

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

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

01729 {
01730     HTTPCaller *caller;
01731     int status;
01732     void *ret;
01733     
01734     caller = http_caller_create();
01735     http_start_request(caller, method, url, request_headers, 
01736                        NULL, 1, http_get_real, NULL);
01737     ret = http_receive_result(caller, &status, final_url, 
01738                               reply_headers, reply_body);
01739     http_caller_destroy(caller);
01740     if (ret == NULL)
01741         return -1;
01742     return status;
01743 }

Here is the call graph for this function:

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

Definition at line 2718 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_application_id(), 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(), 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().

02719 {
02720     gwlib_assert_init();
02721     gw_assert(headers != NULL);
02722     gw_assert(name != NULL);
02723     gw_assert(contents != NULL);
02724 
02725     gwlist_append(headers, octstr_format("%s: %s", name, contents));
02726 }

Here is the call graph for this function:

void http_header_add_element List list,
Octstr value,
long  start,
long  end
[static]
 

Definition at line 3111 of file http.c.

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

Referenced by http_header_split_value().

03113 {
03114     Octstr *element;
03115 
03116     element = octstr_copy(value, start, end - start);
03117     octstr_strip_blanks(element);
03118     if (octstr_len(element) == 0)
03119     octstr_destroy(element);
03120     else
03121         gwlist_append(list, element);
03122 }

Here is the call graph for this function:

void http_header_combine List old_headers,
List new_headers
 

Definition at line 2900 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 return_reply(), start_fetch(), start_request(), test_header_combine(), and unpack_new_headers().

02901 {
02902     long i;
02903     Octstr *name;
02904     Octstr *value;
02905 
02906     /*
02907      * Avoid doing this scan if old_headers is empty anyway.
02908      */
02909     if (gwlist_len(old_headers) > 0) {
02910         for (i = 0; i < gwlist_len(new_headers); i++) {
02911         http_header_get(new_headers, i, &name, &value);
02912         http_header_remove_all(old_headers, octstr_get_cstr(name));
02913             octstr_destroy(name);
02914             octstr_destroy(value);
02915         }
02916     }
02917 
02918     http_append_headers(old_headers, new_headers);
02919 }

Here is the call graph for this function:

void http_header_dump List headers  ) 
 

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

03260 {
03261     long i;
03262 
03263     gwlib_assert_init();
03264 
03265     debug("gwlib.http", 0, "Dumping HTTP headers:");
03266     for (i = 0; headers != NULL && i < gwlist_len(headers); ++i)
03267         octstr_dump(gwlist_get(headers, i), 1);
03268     debug("gwlib.http", 0, "End of dump.");
03269 }

Here is the call graph for this function:

List* http_header_duplicate List headers  ) 
 

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

02802 {
02803     List *new;
02804     long i, len;
02805 
02806     gwlib_assert_init();
02807 
02808     if (headers == NULL)
02809         return NULL;
02810 
02811     new = http_create_empty_headers();
02812     len = gwlist_len(headers);
02813     for (i = 0; i < len; ++i)
02814         gwlist_append(new, octstr_duplicate(gwlist_get(headers, i)));
02815     return new;
02816 }

Here is the call graph for this function:

List* http_header_find_all List headers,
char *  name
 

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

02948 {
02949     List *list;
02950     long i;
02951     Octstr *h;
02952 
02953     gwlib_assert_init();
02954     gw_assert(headers != NULL);
02955     gw_assert(name != NULL);
02956 
02957     list = gwlist_create();
02958     for (i = 0; i < gwlist_len(headers); ++i) {
02959         h = gwlist_get(headers, i);
02960         if (header_is_called(h, name))
02961             gwlist_append(list, octstr_duplicate(h));
02962     }
02963     return list;
02964 }

Here is the call graph for this function:

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

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

02924 {
02925     long i, name_len;
02926     Octstr *h, *value;
02927 
02928     gwlib_assert_init();
02929     gw_assert(headers != NULL);
02930     gw_assert(name != NULL);
02931 
02932     name_len = strlen(name);
02933 
02934     for (i = 0; i < gwlist_len(headers); ++i) {
02935         h = gwlist_get(headers, i);
02936         if (header_is_called(h, name)) {
02937             value = octstr_copy_real(h, name_len + 1, octstr_len(h),
02938                                      file, line, func);
02939         octstr_strip_blanks(value);
02940         return value;
02941     }
02942     }
02943     return NULL;
02944 }

Here is the call graph for this function:

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

Definition at line 2734 of file http.c.

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

02735 {
02736     Octstr *os;
02737     long colon;
02738 
02739     gwlib_assert_init();
02740     gw_assert(i >= 0);
02741     gw_assert(name != NULL);
02742     gw_assert(value != NULL);
02743 
02744     os = gwlist_get(headers, i);
02745     if (os == NULL)
02746         colon = -1;
02747     else
02748         colon = octstr_search_char(os, ':', 0);
02749     if (colon == -1) {
02750         error(0, "HTTP: Header does not contain a colon. BAD.");
02751         *name = octstr_create("X-Unknown");
02752         *value = octstr_duplicate(os);
02753     } else {
02754         *name = octstr_copy(os, 0, colon);
02755         *value = octstr_copy(os, colon + 1, octstr_len(os));
02756         octstr_strip_blanks(*value);
02757     }
02758 }

Here is the call graph for this function:

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

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

03059 {
03060     Octstr *h;
03061     long semicolon, equals, len;
03062 
03063     gwlib_assert_init();
03064     gw_assert(headers != NULL);
03065     gw_assert(type != NULL);
03066     gw_assert(charset != NULL);
03067 
03068     h = http_header_find_first(headers, "Content-Type");
03069     if (h == NULL) {
03070         *type = octstr_create("application/octet-stream");
03071         *charset = octstr_create("");
03072     } else {
03073         octstr_strip_blanks(h);
03074         semicolon = octstr_search_char(h, ';', 0);
03075         if (semicolon == -1) {
03076             *type = h;
03077             *charset = octstr_create("");
03078         } else {
03079             *charset = octstr_duplicate(h);
03080             octstr_delete(*charset, 0, semicolon + 1);
03081             octstr_strip_blanks(*charset);
03082             equals = octstr_search_char(*charset, '=', 0);
03083             if (equals == -1)
03084                 octstr_truncate(*charset, 0);
03085             else {
03086                 octstr_delete(*charset, 0, equals + 1);
03087                 if (octstr_get_char(*charset, 0) == '"')
03088                     octstr_delete(*charset, 0, 1);
03089                 len = octstr_len(*charset);
03090                 if (octstr_get_char(*charset, len - 1) == '"')
03091                     octstr_truncate(*charset, len - 1);
03092             }
03093 
03094             octstr_truncate(h, semicolon);
03095             octstr_strip_blanks(h);
03096             *type = h;
03097         }
03098 
03099         /* 
03100          * According to HTTP/1.1 (RFC 2616, section 3.7.1) we have to ensure
03101          * to return charset 'iso-8859-1' in case of no given encoding and
03102          * content-type is a 'text' subtype. 
03103          */
03104         if (octstr_len(*charset) == 0 && 
03105             octstr_ncompare(*type, octstr_imm("text"), 4) == 0)
03106             octstr_append_cstr(*charset, "ISO-8859-1");
03107     }
03108 }

Here is the call graph for this function:

void http_header_mark_transformation List headers,
Octstr new_body,
Octstr new_type
 

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

03037 {
03038     Octstr *new_length = NULL;
03039 
03040     /* Remove all headers that no longer apply to the new body. */
03041     http_header_remove_all(headers, "Content-Length");
03042     http_header_remove_all(headers, "Content-MD5");
03043     http_header_remove_all(headers, "Content-Type");
03044 
03045     /* Add headers that we need to describe the new body. */
03046     new_length = octstr_format("%ld", octstr_len(new_body));
03047     http_header_add(headers, "Content-Length", octstr_get_cstr(new_length));
03048     if(octstr_len(new_type))
03049     http_header_add(headers, "Content-Type", octstr_get_cstr(new_type));
03050 
03051     /* Perhaps we should add Warning: 214 "Transformation applied" too? */
03052 
03053     octstr_destroy(new_length);
03054 }

Here is the call graph for this function:

void http_header_pack List headers  ) 
 

Definition at line 2824 of file http.c.

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

Referenced by start_fetch().

02825 {
02826     Octstr *name, *value;
02827     Octstr *name2, *value2;
02828     long i, j;
02829 
02830     gwlib_assert_init();
02831     gw_assert(headers != NULL);
02832 
02833     /*
02834      * For each header, search forward headers for similar ones and if possible, 
02835      * add it to current header and delete it
02836      */
02837     for(i = 0; i < gwlist_len(headers); i++) {
02838         http_header_get(headers, i, &name, &value);
02839     /* debug("http_header_pack", 0, "HTTP_HEADER_PACK: Processing header %d. [%s: %s]", 
02840            i, octstr_get_cstr(name), octstr_get_cstr(value)); */
02841 
02842         for(j=i+1; j < gwlist_len(headers); j++) {
02843             http_header_get(headers, j, &name2, &value2);
02844 
02845             if(octstr_case_compare(name, name2) == 0) {
02846                 if(octstr_len(value) + 2 + octstr_len(value2) > MAX_HEADER_LENGTH) {
02847             octstr_destroy(name2);
02848             octstr_destroy(value2);
02849                     break;
02850                 } else {
02851             Octstr *header;
02852 
02853             /* Delete old header */
02854             header = gwlist_get(headers, i);
02855             octstr_destroy(header);
02856                     gwlist_delete(headers, i, 1);
02857 
02858             /* Adds comma and new value to old header value */
02859                     octstr_append(value, octstr_imm(", "));
02860                     octstr_append(value, value2);
02861             /* Creates a new header */
02862             header = octstr_create("");
02863                     octstr_append(header, name);
02864                     octstr_append(header, octstr_imm(": "));
02865                     octstr_append(header, value);
02866                     gwlist_insert(headers, i, header);
02867 
02868             /* Delete this header */
02869             header = gwlist_get(headers, j);
02870             octstr_destroy(header);
02871                     gwlist_delete(headers, j, 1);
02872                     j--;
02873                 }
02874             }
02875         octstr_destroy(name2);
02876         octstr_destroy(value2);
02877         }
02878     octstr_destroy(name);
02879     octstr_destroy(value);
02880     }
02881 }

Here is the call graph for this function:

long http_header_quoted_string_len Octstr header,
long  start
 

Definition at line 3125 of file http.c.

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

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

03126 {
03127     long len;
03128     long pos;
03129     int c;
03130 
03131     if (octstr_get_char(header, start) != '"')
03132     return -1;
03133 
03134     len = octstr_len(header);
03135     for (pos = start + 1; pos < len; pos++) {
03136     c = octstr_get_char(header, pos);
03137     if (c == '\\')    /* quoted-pair */
03138         pos++;
03139     else if (c == '"')
03140         return pos - start + 1;
03141     }
03142 
03143     warning(0, "Header contains unterminated quoted-string:");
03144     warning(0, "%s", octstr_get_cstr(header));
03145     return len - start;
03146 }

Here is the call graph for this function:

long http_header_remove_all List headers,
char *  name
 

Definition at line 2967 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(), return_reply(), send_request(), set_addr_tuple(), split_header_list(), start_fetch(), and xmlrpc_doc_send().

02968 {
02969     long i;
02970     Octstr *h;
02971     long count;
02972 
02973     gwlib_assert_init();
02974     gw_assert(headers != NULL);
02975     gw_assert(name != NULL);
02976 
02977     i = 0;
02978     count = 0;
02979     while (i < gwlist_len(headers)) {
02980     h = gwlist_get(headers, i);
02981     if (header_is_called(h, name)) {
02982         gwlist_delete(headers, i, 1);
02983         octstr_destroy(h);
02984         count++;
02985     } else
02986         i++;
02987     }
02988 
02989     return count;
02990 }

Here is the call graph for this function:

List* http_header_split_auth_value Octstr value  ) 
 

Definition at line 3183 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(), octstr_len(), and result.

Referenced by pack_known_header().

03184 {
03185     List *result;
03186     Octstr *auth_scheme;
03187     Octstr *element;
03188     long i;
03189 
03190     /*
03191      * According to RFC2617, both "challenge" and "credentials"
03192      * consist of an auth-scheme followed by a list of auth-param.
03193      * Since we have to parse a list of challenges or credentials,
03194      * we have to look for auth-scheme to signal the start of
03195      * a new element.  (We can't just split on commas because
03196      * they are also used to separate the auth-params.)
03197      *
03198      * An auth-scheme is a single token, while an auth-param is
03199      * always a key=value pair.  So we can recognize an auth-scheme
03200      * as a token that is not followed by a '=' sign.
03201      *
03202      * Simple approach: First split at all commas, then recombine
03203      * the elements that belong to the same challenge or credential.
03204      * This is somewhat expensive but saves programmer thinking time.
03205      *
03206      * Richard Braakman
03207      */
03208  
03209     result = http_header_split_value(value);
03210     if (gwlist_len(result) == 0)
03211         return result;
03212 
03213     auth_scheme = gwlist_get(result, 0);
03214     i = 1;
03215     while (i < gwlist_len(result)) {
03216         int c;
03217         long pos;
03218 
03219         element = gwlist_get(result, i);
03220 
03221         /*
03222          * If the element starts with: token '='
03223          * then it's just an auth_param; append it to the current
03224          * auth_scheme.  If it starts with: token token '='
03225          * then it's the start of a new auth scheme.
03226          *
03227          * To make the scan easier, we consider anything other
03228          * than whitespace or '=' to be part of a token.
03229          */
03230 
03231         /* Skip first token */
03232         for (pos = 0; pos < octstr_len(element); pos++) {
03233             c = octstr_get_char(element, pos);
03234             if (isspace(c) || c == '=')
03235                 break;
03236         }
03237 
03238         /* Skip whitespace, if any */
03239         while (isspace(octstr_get_char(element, pos)))
03240             pos++;
03241 
03242         if (octstr_get_char(element, pos) == '=') {
03243             octstr_append_char(auth_scheme, ';');
03244             octstr_append(auth_scheme, element);
03245             gwlist_delete(result, i, 1);
03246             octstr_destroy(element);
03247         } else {
03248             char semicolon = ';';
03249             octstr_insert_data(element, pos, &semicolon, 1);
03250             auth_scheme = element;
03251             i++;
03252         }
03253     }
03254 
03255     return result;
03256 }

Here is the call graph for this function:

List* http_header_split_value Octstr value  ) 
 

Definition at line 3149 of file http.c.

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

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

03150 {
03151     long start;  /* start of current element */
03152     long pos;
03153     long len;
03154     List *result;
03155     int c;
03156 
03157     /*
03158      * According to RFC2616 section 4.2, a field-value is either *TEXT
03159      * (the caller is responsible for not feeding us one of those) or
03160      * combinations of token, separators, and quoted-string.  We're
03161      * looking for commas which are separators, and have to skip
03162      * commas in quoted-strings.
03163      */
03164  
03165     result = gwlist_create();
03166     len = octstr_len(value);
03167     start = 0;
03168     for (pos = 0; pos < len; pos++) {
03169     c = octstr_get_char(value, pos);
03170     if (c == ',') {
03171         http_header_add_element(result, value, start, pos);
03172         start = pos + 1;
03173     } else if (c == '"') {
03174             pos += http_header_quoted_string_len(value, pos);
03175         pos--; /* compensate for the loop's pos++ */
03176         }
03177     }
03178     http_header_add_element(result, value, start, len);
03179     return result;
03180 }

Here is the call graph for this function:

Octstr* http_header_value List headers,
Octstr name
 

Definition at line 2764 of file http.c.

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

02765 {
02766     Octstr *value;
02767     long i;
02768     Octstr *os;
02769     long colon;
02770     Octstr *current_name;
02771     
02772     gwlib_assert_init();
02773     gw_assert(name);
02774     
02775     value = NULL;
02776     i = 0;
02777     while (i < gwlist_len(headers)) {
02778         os = gwlist_get(headers, i);
02779         if (os == NULL)
02780             colon = -1;
02781         else
02782             colon = octstr_search_char(os, ':', 0);
02783         if (colon == -1) {
02784             return NULL;      
02785         } else {
02786             current_name = octstr_copy(os, 0, colon);
02787         }
02788         if (octstr_case_compare(current_name, name) == 0) {
02789             value = octstr_copy(os, colon + 1, octstr_len(os));
02790             octstr_strip_blanks(value);
02791             octstr_destroy(current_name);
02792             return value;
02793         }
02794         octstr_destroy(current_name);
02795         ++i;
02796     }
02797     
02798     return NULL;
02799 }

Here is the call graph for this function:

void http_init void   ) 
 

Definition at line 3427 of file http.c.

References client_init(), conn_init_ssl(), conn_pool_init(), gw_assert, limbo, openssl_init_locks(), port_init(), proxy_init(), run_status, server_init(), and server_ssl_init().

Referenced by gwlib_init().

03428 {
03429     gw_assert(run_status == limbo);
03430 
03431 #ifdef HAVE_LIBSSL
03432     openssl_init_locks();
03433     conn_init_ssl();
03434 #endif /* HAVE_LIBSSL */
03435     proxy_init();
03436     client_init();
03437     conn_pool_init();
03438     port_init();
03439     server_init();
03440 #ifdef HAVE_LIBSSL
03441     server_ssl_init();
03442 #endif /* HAVE_LIBSSL */
03443     
03444     run_status = running;
03445 }

Here is the call graph for this function:

char* http_method2name int  method  ) 
 

Definition at line 3503 of file http.c.

References gw_assert, and http_methods.

Referenced by send_request().

03504 {
03505     gw_assert(method > 0 && method <= 3);
03506 
03507     return http_methods[method-1];
03508 }

int http_name2method Octstr method  ) 
 

Definition at line 3485 of file http.c.

References gw_assert, and octstr_str_compare().

Referenced by main(), and start_fetch().

03486 {
03487     gw_assert(method != NULL);
03488 
03489     if (octstr_str_compare(method, "GET") == 0) {
03490         return HTTP_METHOD_GET;
03491     } 
03492     else if (octstr_str_compare(method, "POST") == 0) {
03493         return HTTP_METHOD_POST;
03494     } 
03495     else if (octstr_str_compare(method, "HEAD") == 0) {
03496         return HTTP_METHOD_HEAD;
03497     } 
03498 
03499     return -1;
03500 }

Here is the call graph for this function:

int http_open_port int  port,
int  ssl
 

Definition at line 2357 of file http.c.

References http_open_port_if(), port, and ssl.

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

02358 {
02359     return http_open_port_if(port, ssl, NULL);
02360 }

Here is the call graph for this function:

int http_open_port_if int  port,
int  ssl,
Octstr interface
 

Definition at line 2330 of file http.c.

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

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

02331 {
02332     struct server *p;
02333 
02334     if (ssl) 
02335         info(0, "HTTP: Opening SSL server at port %d.", port);
02336     else 
02337         info(0, "HTTP: Opening server at port %d.", port);
02338     p = gw_malloc(sizeof(*p));
02339     p->port = port;
02340     p->ssl = ssl;
02341     p->fd = make_server_socket(port, (interface ? octstr_get_cstr(interface) : NULL));
02342     if (p->fd == -1) {
02343     gw_free(p);
02344         return -1;
02345     }
02346 
02347     port_add(port);
02348     gwlist_produce(new_server_sockets, p);
02349     keep_servers_open = 1;
02350     start_server_thread();
02351     gwthread_wakeup(server_thread_id);
02352 
02353     return 0;
02354 }

Here is the call graph for this function:

const char* http_reason_phrase int  status  )  [static]
 

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

02483 {
02484     switch (status) {
02485     case HTTP_OK:
02486         return "OK";                        /* 200 */
02487     case HTTP_CREATED:                   
02488         return "Created";                   /* 201 */
02489     case HTTP_ACCEPTED:
02490         return "Accepted";                  /* 202 */
02491     case HTTP_NO_CONTENT:
02492         return "No Content";                /* 204 */
02493     case HTTP_RESET_CONTENT: 
02494         return "Reset Content";             /* 205 */
02495     case HTTP_MOVED_PERMANENTLY:
02496         return "Moved Permanently";         /* 301 */
02497     case HTTP_FOUND:
02498         return "Found";                     /* 302 */
02499     case HTTP_SEE_OTHER:
02500         return "See Other";                 /* 303 */
02501     case HTTP_NOT_MODIFIED:
02502         return "Not Modified";              /* 304 */
02503     case HTTP_TEMPORARY_REDIRECT:
02504         return "Temporary Redirect";        /* 307 */
02505     case HTTP_BAD_REQUEST:
02506         return "Bad Request";               /* 400 */
02507     case HTTP_UNAUTHORIZED:
02508         return "Unauthorized";              /* 401 */
02509     case HTTP_FORBIDDEN:
02510         return "Forbidden";                 /* 403 */
02511     case HTTP_NOT_FOUND:            
02512         return "Not Found";                 /* 404 */
02513     case HTTP_BAD_METHOD:
02514         return "Method Not Allowed";        /* 405 */
02515     case HTTP_NOT_ACCEPTABLE:
02516         return "Not Acceptable";            /* 406 */
02517     case HTTP_REQUEST_ENTITY_TOO_LARGE:
02518         return "Request Entity Too Large";  /* 413 */
02519     case HTTP_UNSUPPORTED_MEDIA_TYPE:
02520         return "Unsupported Media Type";    /* 415 */
02521     case HTTP_INTERNAL_SERVER_ERROR:
02522         return "Internal Server Error";     /* 500 */
02523     case HTTP_NOT_IMPLEMENTED:
02524         return "Not Implemented";           /* 501 */
02525     case HTTP_BAD_GATEWAY:
02526         return "Bad Gateway";               /* 502 */
02527     }
02528     return "Foo";
02529 }

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

Definition at line 1692 of file http.c.

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

01694 {
01695     HTTPServer *trans;
01696     void *request_id;
01697 
01698     if (blocking == 0)
01699         trans = gwlist_extract_first(caller);
01700     else
01701         trans = gwlist_consume(caller);
01702     if (trans == NULL)
01703         return NULL;
01704 
01705     request_id = trans->request_id;
01706     *status = trans->status;
01707     
01708     if (trans->status >= 0) {
01709         *final_url = trans->url;
01710         *headers = trans->response->headers;
01711         *body = trans->response->body;
01712 
01713         trans->url = NULL;
01714         trans->response->headers = NULL;
01715         trans->response->body = NULL;
01716     } else {
01717        *final_url = NULL;
01718        *headers = NULL;
01719        *body = NULL;
01720     }
01721 
01722     server_destroy(trans);
01723     return request_id;
01724 }

Here is the call graph for this function:

void http_remove_hop_headers List headers  ) 
 

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

02994 {
02995     Octstr *h;
02996     List *connection_headers;
02997 
02998     gwlib_assert_init();
02999     gw_assert(headers != NULL);
03000 
03001     /*
03002      * The hop-by-hop headers are a standard list, plus those named
03003      * in the Connection header(s).
03004      */
03005 
03006     connection_headers = http_header_find_all(headers, "Connection");
03007     while ((h = gwlist_consume(connection_headers))) {
03008     List *hop_headers;
03009     Octstr *e;
03010 
03011     octstr_delete(h, 0, strlen("Connection:"));
03012     hop_headers = http_header_split_value(h);
03013     octstr_destroy(h);
03014 
03015     while ((e = gwlist_consume(hop_headers))) {
03016         http_header_remove_all(headers, octstr_get_cstr(e));
03017         octstr_destroy(e);
03018     }
03019 
03020     gwlist_destroy(hop_headers, NULL);
03021     }
03022     gwlist_destroy(connection_headers, NULL);
03023    
03024     http_header_remove_all(headers, "Connection");
03025     http_header_remove_all(headers, "Keep-Alive");
03026     http_header_remove_all(headers, "Proxy-Authenticate");
03027     http_header_remove_all(headers, "Proxy-Authorization");
03028     http_header_remove_all(headers, "TE");
03029     http_header_remove_all(headers, "Trailers");
03030     http_header_remove_all(headers, "Transfer-Encoding");
03031     http_header_remove_all(headers, "Upgrade");
03032 }

Here is the call graph for this function:

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

Definition at line 2532 of file http.c.

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

Referenced by brunet_receive_sms(), challenge(), clickatell_receive_sms(), client_thread(), delayed_http_reply(), 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().

02534 {
02535     Octstr *response;
02536     Octstr *date;
02537     long i;
02538     int ret;
02539 
02540     if (client->use_version_1_0)
02541         response = octstr_format("HTTP/1.0 %d %s\r\n", status, http_reason_phrase(status));
02542     else
02543         response = octstr_format("HTTP/1.1 %d %s\r\n", status, http_reason_phrase(status));
02544 
02545     /* identify ourselfs */
02546     octstr_format_append(response, "Server: " GW_NAME "/%s\r\n", GW_VERSION);
02547     
02548     /* let's inform the client of our time */
02549     date = date_format_http(time(NULL));
02550     octstr_format_append(response, "Date: %s\r\n", octstr_get_cstr(date));
02551     octstr_destroy(date);
02552     
02553     octstr_format_append(response, "Content-Length: %ld\r\n",
02554              octstr_len(body));
02555 
02556     /* 
02557      * RFC2616, sec. 8.1.2.1 says that if the server chooses to close the 
02558      * connection, it *should* send a coresponding header
02559      */
02560     if (!client->use_version_1_0 && !client->persistent_conn)
02561         octstr_format_append(response, "Connection: close\r\n");
02562 
02563     for (i = 0; i < gwlist_len(headers); ++i)
02564         octstr_format_append(response, "%S\r\n", gwlist_get(headers, i));
02565     octstr_format_append(response, "\r\n");
02566     
02567     if (body != NULL && client->method != HTTP_METHOD_HEAD)
02568         octstr_append(response, body);
02569     
02570     ret = conn_write(client->conn, response);
02571     octstr_destroy(response);
02572 
02573     /* obey return code of conn_write() */
02574     /* sending response was successful */
02575     if (ret == 0) { 
02576         /* HTTP/1.0 or 1.1, hence keep-alive or keep-alive */
02577         if (!client->persistent_conn) {
02578             client_destroy(client);     
02579         } else {
02580             /* XXX mark this HTTPClient in the keep-alive cleaner thread */
02581             client_reset(client);
02582             conn_register(client->conn, server_fdset, receive_request, client);
02583         }
02584     }
02585     /* queued for sending, we don't want to block */
02586     else if (ret == 1) {    
02587         client->state = sending_reply;
02588         conn_register(client->conn, server_fdset, receive_request, client);
02589     }
02590     /* error while sending response */
02591     else {     
02592         client_destroy(client);
02593     }
02594 }

Here is the call graph for this function:

void http_set_client_timeout long  timeout  ) 
 

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

Definition at line 1657 of file http.c.

References client_fdset, fdset_set_timeout(), and http_client_timeout.

01658 {
01659     http_client_timeout = timeout;
01660     if (client_fdset != NULL) {
01661         /* we are already initialized set timeout in fdset */
01662         fdset_set_timeout(client_fdset, http_client_timeout);
01663     }
01664 }

Here is the call graph for this function:

void http_set_interface const Octstr our_host  ) 
 

Definition at line 1652 of file http.c.

References http_interface, and octstr_duplicate.

Referenced by config_reload().

01653 {
01654     http_interface = octstr_duplicate(our_host);
01655 }

void http_shutdown void   ) 
 

Definition at line 3448 of file http.c.

References client_shutdown(), conn_pool_shutdown(), conn_shutdown_ssl(), gw_assert, gwlib_assert_init(), openssl_shutdown_locks(), port_shutdown(), proxy_shutdown(), run_status, running, server_shutdown(), and server_shutdown_ssl().

Referenced by gwlib_shutdown().

03449 {
03450     gwlib_assert_init();
03451     gw_assert(run_status == running);
03452 
03453     run_status = terminating;
03454 
03455     conn_pool_shutdown();
03456     client_shutdown();
03457     server_shutdown();
03458     port_shutdown();
03459     proxy_shutdown();
03460 #ifdef HAVE_LIBSSL
03461     openssl_shutdown_locks();
03462     conn_shutdown_ssl();
03463     server_shutdown_ssl();
03464 #endif /* HAVE_LIBSSL */
03465     run_status = limbo;
03466 }

Here is the call graph for this function:

int http_something_accepted List headers,
char *  header_name,
char *  what
[static]
 

Definition at line 3305 of file http.c.

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

03307 {
03308     int found;
03309     long i;
03310     List *accepts;
03311     Octstr *needle = octstr_create(what);
03312 
03313     gwlib_assert_init();
03314     gw_assert(headers != NULL);
03315     gw_assert(what != NULL);
03316 
03317     /* return all headers with this name */
03318     accepts = http_header_find_all(headers, header_name);
03319 
03320     found = 0;
03321     for (i = 0; !found && i < gwlist_len(accepts); ++i) {
03322         Octstr *header_value = gwlist_get(accepts, i);
03323         if (octstr_case_search(header_value, needle, 0) != -1)
03324             found = 1;
03325     }
03326     octstr_destroy(needle);
03327     http_destroy_headers(accepts);
03328     return found;
03329 }

Here is the call graph for this function:

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

Definition at line 1666 of file http.c.

References gwlist_produce(), HTTPCaller, pending_requests, HTTPServer::request_id, server_create(), and start_client_threads().

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

01668 {
01669     HTTPServer *trans;
01670     int follow_remaining;
01671     
01672     if (follow)
01673         follow_remaining = HTTP_MAX_FOLLOW;
01674     else
01675         follow_remaining = 0;
01676 
01677     trans = server_create(caller, method, url, headers, body, follow_remaining, 
01678               certkeyfile);
01679 
01680     if (id == NULL)
01681         /* We don't leave this NULL so http_receive_result can use NULL
01682          * to signal no more requests */
01683         trans->request_id = http_start_request;
01684     else
01685         trans->request_id = id;
01686         
01687     gwlist_produce(pending_requests, trans);
01688     start_client_threads();
01689 }

Here is the call graph for this function:

int http_status_class int  code  ) 
 

Definition at line 3473 of file http.c.

References code.

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

03474 {
03475     int sclass;
03476 
03477     if (code < 100 || code >= 600)
03478         sclass = HTTP_STATUS_UNKNOWN;
03479     else
03480         sclass = code - (code % 100);
03481     return sclass;
03482 }

int http_type_accepted List headers,
char *  type
 

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

03333 {
03334     return http_something_accepted(headers, "Accept", type);
03335 }

Here is the call graph for this function:

HTTPURLParse* http_urlparse_create void   ) 
 

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

01227 {
01228     HTTPURLParse *p;
01229 
01230     p = gw_malloc(sizeof(HTTPURLParse));
01231     p->url = NULL;
01232     p->scheme = NULL;
01233     p->host = NULL;
01234     p->port = 0;
01235     p->user = NULL;
01236     p->pass = NULL;
01237     p->path = NULL;
01238     p->query = NULL;
01239     p->fragment = NULL;
01240     
01241     return p;
01242 }

void http_urlparse_destroy HTTPURLParse p  ) 
 

Definition at line 1245 of file http.c.

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

Referenced by get_connection(), and parse_url().

01246 {
01247     gw_assert(p != NULL);
01248 
01249     octstr_destroy(p->url);
01250     octstr_destroy(p->scheme);
01251     octstr_destroy(p->host);
01252     octstr_destroy(p->user);
01253     octstr_destroy(p->pass);
01254     octstr_destroy(p->path);
01255     octstr_destroy(p->query);
01256     octstr_destroy(p->fragment);
01257     gw_free(p);
01258 }

Here is the call graph for this function:

void http_use_proxy Octstr hostname,
int  port,
int  ssl,
List exceptions,
Octstr username,
Octstr password,
Octstr exceptions_regex
 

Definition at line 266 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, and username.

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

00268 {
00269     Octstr *e;
00270     int i;
00271 
00272     gw_assert(run_status == running);
00273     gw_assert(hostname != NULL);
00274     gw_assert(octstr_len(hostname) > 0);
00275     gw_assert(port > 0);
00276 
00277     http_close_proxy();
00278     mutex_lock(proxy_mutex);
00279 
00280     proxy_hostname = octstr_duplicate(hostname);
00281     proxy_port = port;
00282     proxy_ssl = ssl;
00283     proxy_exceptions = gwlist_create();
00284     for (i = 0; i < gwlist_len(exceptions); ++i) {
00285         e = gwlist_get(exceptions, i);
00286         debug("gwlib.http", 0, "HTTP: Proxy exception `%s'.", octstr_get_cstr(e));
00287         gwlist_append(proxy_exceptions, octstr_duplicate(e));
00288     }
00289     if (exceptions_regex != NULL &&
00290         (proxy_exceptions_regex = gw_regex_comp(exceptions_regex, REG_EXTENDED)) == NULL)
00291             panic(0, "Could not compile pattern '%s'", octstr_get_cstr(exceptions_regex));
00292     proxy_username = octstr_duplicate(username);
00293     proxy_password = octstr_duplicate(password);
00294     debug("gwlib.http", 0, "Using proxy <%s:%d> with %s scheme", 
00295           octstr_get_cstr(proxy_hostname), proxy_port,
00296           (proxy_ssl ? "HTTPS" : "HTTP"));
00297 
00298     mutex_unlock(proxy_mutex);
00299 }

Here is the call graph for this function:

void parse2trans HTTPURLParse p,
HTTPServer t
[static]
 

Definition at line 1449 of file http.c.

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

Referenced by get_connection().

01450 {
01451     if (p == NULL || t == NULL)
01452         return;
01453 
01454     if (p->user && !t->username)
01455         t->username = octstr_duplicate(p->user);
01456     if (p->pass && !t->password)
01457         t->password = octstr_duplicate(p->pass);
01458     if (p->host && !t->host) 
01459         t->host = octstr_duplicate(p->host);
01460     if (p->port && !t->port)
01461         t->port = p->port;
01462     if (p->path && !t->uri) {
01463         t->uri = octstr_duplicate(p->path);
01464         if (p->query) { /* add the query too */
01465             octstr_append_char(t->uri, '?');
01466             octstr_append(t->uri, p->query);
01467         }
01468     }
01469     t->ssl = (p->scheme && (octstr_compare(p->scheme, octstr_imm("https://")) == 0) 
01470               && !t->ssl) ? 1 : 0;
01471 }

Here is the call graph for this function:

List* parse_cgivars Octstr url  )  [static]
 

Definition at line 2392 of file http.c.

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

Referenced by http_accept_request().

02393 {
02394     HTTPCGIVar *v;
02395     List *list;
02396     int query, et, equals;
02397     Octstr *arg, *args;
02398 
02399     query = octstr_search_char(url, '?', 0);
02400     if (query == -1)
02401         return gwlist_create();
02402 
02403     args = octstr_copy(url, query + 1, octstr_len(url));
02404     octstr_truncate(url, query);
02405 
02406     list = gwlist_create();
02407 
02408     while (octstr_len(args) > 0) {
02409         et = octstr_search_char(args, '&', 0);
02410         if (et == -1)
02411             et = octstr_len(args);
02412         arg = octstr_copy(args, 0, et);
02413         octstr_delete(args, 0, et + 1);
02414 
02415         equals = octstr_search_char(arg, '=', 0);
02416         if (equals == -1)
02417             equals = octstr_len(arg);
02418 
02419         v = gw_malloc(sizeof(HTTPCGIVar));
02420         v->name = octstr_copy(arg, 0, equals);
02421         v->value = octstr_copy(arg, equals + 1, octstr_len(arg));
02422         octstr_url_decode(v->name);
02423         octstr_url_decode(v->value);
02424 
02425         octstr_destroy(arg);
02426 
02427         gwlist_append(list, v);
02428     }
02429     octstr_destroy(args);
02430 
02431     return list;
02432 }

Here is the call graph for this function:

void parse_dump HTTPURLParse p  ) 
 

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

01262 {
01263     if (p == NULL)
01264         return;
01265     debug("http.parse_url",0,"Parsing URL `%s':", octstr_get_cstr(p->url));
01266     debug("http.parse_url",0,"  Scheme: %s", octstr_get_cstr(p->scheme));  
01267     debug("http.parse_url",0,"  Host: %s", octstr_get_cstr(p->host));  
01268     debug("http.parse_url",0,"  Port: %ld", p->port);  
01269     debug("http.parse_url",0,"  Username: %s", octstr_get_cstr(p->user));  
01270     debug("http.parse_url",0,"  Password: %s", octstr_get_cstr(p->pass));  
01271     debug("http.parse_url",0,"  Path: %s", octstr_get_cstr(p->path));  
01272     debug("http.parse_url",0,"  Query: %s", octstr_get_cstr(p->query));  
01273     debug("http.parse_url",0,"  Fragment: %s", octstr_get_cstr(p->fragment));  
01274 }

Here is the call graph for this function:

int parse_http_version Octstr version  )  [static]
 

Definition at line 166 of file http.c.

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

Referenced by client_read_status(), and parse_request_line().

00167 {
00168     Octstr *prefix;
00169     long prefix_len;
00170     int digit;
00171     
00172     prefix = octstr_imm("HTTP/1.");
00173     prefix_len = octstr_len(prefix);
00174 
00175     if (octstr_ncompare(version, prefix, prefix_len) != 0)
00176         return -1;
00177     if (octstr_len(version) != prefix_len + 1)
00178         return -1;
00179     digit = octstr_get_char(version, prefix_len);
00180     if (!isdigit(digit))
00181         return -1;
00182     if (digit == '0')
00183         return 0;
00184     return 1;
00185 }

Here is the call graph for this function:

int parse_request_line int *  method,
Octstr **  url,
int *  use_version_1_0,
Octstr line
[static]
 

Definiti