![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
http.h
Go to the documentation of this file.
00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 1999 - 2006, Digium, Inc. 00005 * 00006 * Mark Spencer <markster@digium.com> 00007 * 00008 * See http://www.asterisk.org for more information about 00009 * the Asterisk project. Please do not directly contact 00010 * any of the maintainers of this project for assistance; 00011 * the project provides a web site, mailing lists and IRC 00012 * channels for your use. 00013 * 00014 * This program is free software, distributed under the terms of 00015 * the GNU General Public License Version 2. See the LICENSE file 00016 * at the top of the source tree. 00017 */ 00018 00019 #ifndef _ASTERISK_HTTP_H 00020 #define _ASTERISK_HTTP_H 00021 00022 #include "asterisk/config.h" 00023 00024 /*! 00025 * \file http.h 00026 * \brief Support for Private Asterisk HTTP Servers. 00027 * \note Note: The Asterisk HTTP servers are extremely simple and minimal and 00028 * only support the "GET" method. 00029 * 00030 * \author Mark Spencer <markster@digium.com> 00031 * 00032 * \note In order to have TLS/SSL support, we need the openssl libraries. 00033 * Still we can decide whether or not to use them by commenting 00034 * in or out the DO_SSL macro. 00035 * TLS/SSL support is basically implemented by reading from a config file 00036 * (currently http.conf) the names of the certificate and cipher to use, 00037 * and then run ssl_setup() to create an appropriate SSL_CTX (ssl_ctx) 00038 * If we support multiple domains, presumably we need to read multiple 00039 * certificates. 00040 * When we are requested to open a TLS socket, we run make_file_from_fd() 00041 * on the socket, to do the necessary setup. At the moment the context's name 00042 * is hardwired in the function, but we can certainly make it into an extra 00043 * parameter to the function. 00044 * We declare most of ssl support variables unconditionally, 00045 * because their number is small and this simplifies the code. 00046 * 00047 * \note: the ssl-support variables (ssl_ctx, do_ssl, certfile, cipher) 00048 * and their setup should be moved to a more central place, e.g. asterisk.conf 00049 * and the source files that processes it. Similarly, ssl_setup() should 00050 * be run earlier in the startup process so modules have it available. 00051 */ 00052 00053 #if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE)) 00054 #define DO_SSL /* comment in/out if you want to support ssl */ 00055 #endif 00056 00057 #ifdef DO_SSL 00058 #include <openssl/ssl.h> 00059 #include <openssl/err.h> 00060 #else 00061 /* declare dummy types so we can define a pointer to them */ 00062 typedef struct {} SSL; 00063 typedef struct {} SSL_CTX; 00064 #endif /* DO_SSL */ 00065 00066 /*! SSL support */ 00067 #define AST_CERTFILE "asterisk.pem" 00068 00069 struct tls_config { 00070 int enabled; 00071 char *certfile; 00072 char *cipher; 00073 SSL_CTX *ssl_ctx; 00074 }; 00075 00076 /*! 00077 * The following code implements a generic mechanism for starting 00078 * services on a TCP or TLS socket. 00079 * The service is configured in the struct server_args, and 00080 * then started by calling server_start(desc) on the descriptor. 00081 * server_start() first verifies if an instance of the service is active, 00082 * and in case shuts it down. Then, if the service must be started, creates 00083 * a socket and a thread in charge of doing the accept(). 00084 * 00085 * The body of the thread is desc->accept_fn(desc), which the user can define 00086 * freely. We supply a sample implementation, server_root(), structured as an 00087 * infinite loop. At the beginning of each iteration it runs periodic_fn() 00088 * if defined (e.g. to perform some cleanup etc.) then issues a poll() 00089 * or equivalent with a timeout of 'poll_timeout' milliseconds, and if the 00090 * following accept() is successful it creates a thread in charge of 00091 * running the session, whose body is desc->worker_fn(). The argument of 00092 * worker_fn() is a struct server_instance, which contains the address 00093 * of the other party, a pointer to desc, the file descriptors (fd) on which 00094 * we can do a select/poll (but NOT IO/, and a FILE * on which we can do I/O. 00095 * We have both because we want to support plain and SSL sockets, and 00096 * going through a FILE * lets us provide the encryption/decryption 00097 * on the stream without using an auxiliary thread. 00098 * 00099 * NOTE: in order to let other parts of asterisk use these services, 00100 * we need to do the following: 00101 * + move struct server_instance and struct server_args to 00102 * a common header file, together with prototypes for 00103 * server_start() and server_root(). 00104 * + 00105 */ 00106 00107 /*! 00108 * describes a server instance 00109 */ 00110 struct server_instance { 00111 FILE *f; /* fopen/funopen result */ 00112 int fd; /* the socket returned by accept() */ 00113 SSL *ssl; /* ssl state */ 00114 struct sockaddr_in requestor; 00115 struct server_args *parent; 00116 }; 00117 00118 /*! 00119 * arguments for the accepting thread 00120 */ 00121 struct server_args { 00122 struct sockaddr_in sin; 00123 struct sockaddr_in oldsin; 00124 struct tls_config *tls_cfg; /* points to the SSL configuration if any */ 00125 int accept_fd; 00126 int poll_timeout; 00127 pthread_t master; 00128 void *(*accept_fn)(void *); /* the function in charge of doing the accept */ 00129 void (*periodic_fn)(void *); /* something we may want to run before after select on the accept socket */ 00130 void *(*worker_fn)(void *); /* the function in charge of doing the actual work */ 00131 const char *name; 00132 }; 00133 00134 void *server_root(void *); 00135 void server_start(struct server_args *desc); 00136 int ssl_setup(struct tls_config *cfg); 00137 00138 /*! \brief HTTP Callbacks take the socket 00139 00140 \note The method and the path as arguments and should 00141 return the content, allocated with malloc(). Status should be changed to reflect 00142 the status of the request if it isn't 200 and title may be set to a malloc()'d string 00143 to an appropriate title for non-200 responses. Content length may also be specified. 00144 The return value may include additional headers at the front and MUST include a blank 00145 line with \r\n to provide separation between user headers and content (even if no 00146 content is specified) 00147 */ 00148 typedef struct ast_str *(*ast_http_callback)(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength); 00149 00150 struct ast_http_uri { 00151 AST_LIST_ENTRY(ast_http_uri) entry; 00152 const char *description; 00153 const char *uri; 00154 int has_subtree; 00155 ast_http_callback callback; 00156 }; 00157 00158 /*! \brief Link into the Asterisk HTTP server */ 00159 int ast_http_uri_link(struct ast_http_uri *urihandler); 00160 00161 /*! \brief Return an ast_str malloc()'d string containing an HTTP error message */ 00162 struct ast_str *ast_http_error(int status, const char *title, const char *extra_header, const char *text); 00163 00164 /*! \brief Destroy an HTTP server */ 00165 void ast_http_uri_unlink(struct ast_http_uri *urihandler); 00166 00167 int ast_http_init(void); 00168 int ast_http_reload(void); 00169 00170 #endif /* _ASTERISK_SRV_H */