Mon Jun 27 16:51:15 2011

Asterisk developer's documentation


http.h File Reference

Support for Private Asterisk HTTP Servers. More...

#include "asterisk/config.h"
#include "asterisk/tcptls.h"
#include "asterisk/linkedlists.h"

Go to the source code of this file.

Data Structures

struct  ast_http_uri
 Definition of a URI handler. More...

Typedefs

typedef int(*) ast_http_callback (struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
 HTTP Callbacks.

Enumerations

enum  ast_http_method {
  AST_HTTP_UNKNOWN = -1, AST_HTTP_GET = 0, AST_HTTP_POST, AST_HTTP_HEAD,
  AST_HTTP_PUT
}
 HTTP Request methods known by Asterisk. More...

Functions

const char * ast_get_http_method (enum ast_http_method method) attribute_pure
 Return http method name string.
void ast_http_auth (struct ast_tcptls_session_instance *ser, const char *realm, const unsigned long nonce, const unsigned long opaque, int stale, const char *text)
 Send http "401 Unauthorized" response and close socket.
void ast_http_error (struct ast_tcptls_session_instance *ser, int status, const char *title, const char *text)
 Send HTTP error message and close socket.
const char * ast_http_ftype2mtype (const char *ftype) attribute_pure
 Return mime type based on extension.
ast_variableast_http_get_cookies (struct ast_variable *headers)
 Get cookie from Request headers.
ast_variableast_http_get_post_vars (struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
 Get post variables from client Request Entity-Body, if content type is application/x-www-form-urlencoded.
uint32_t ast_http_manid_from_vars (struct ast_variable *headers) attribute_pure
 Return manager id, if exist, from request headers.
void ast_http_prefix (char *buf, int len)
 Return the current prefix.
void ast_http_send (struct ast_tcptls_session_instance *ser, enum ast_http_method method, int status_code, const char *status_title, struct ast_str *http_header, struct ast_str *out, const int fd, unsigned int static_content)
 Generic function for sending http/1.1 response.
int ast_http_uri_link (struct ast_http_uri *urihandler)
 Register a URI handler.
void ast_http_uri_unlink (struct ast_http_uri *urihandler)
 Unregister a URI handler.
void ast_http_uri_unlink_all_with_key (const char *key)
 Unregister all handlers with matching key.


Detailed Description

Support for Private Asterisk HTTP Servers.

Note:
Note: The Asterisk HTTP servers are extremely simple and minimal and only support the "GET" method.
Author:
Mark Spencer <markster@digium.com>
Note:
In order to have TLS/SSL support, we need the openssl libraries. Still we can decide whether or not to use them by commenting in or out the DO_SSL macro. TLS/SSL support is basically implemented by reading from a config file (currently http.conf) the names of the certificate and cipher to use, and then run ssl_setup() to create an appropriate SSL_CTX (ssl_ctx) If we support multiple domains, presumably we need to read multiple certificates. When we are requested to open a TLS socket, we run make_file_from_fd() on the socket, to do the necessary setup. At the moment the context's name is hardwired in the function, but we can certainly make it into an extra parameter to the function. We declare most of ssl support variables unconditionally, because their number is small and this simplifies the code.

: the ssl-support variables (ssl_ctx, do_ssl, certfile, cipher) and their setup should be moved to a more central place, e.g. asterisk.conf and the source files that processes it. Similarly, ssl_setup() should be run earlier in the startup process so modules have it available.

Definition in file http.h.


Typedef Documentation

typedef int(*) ast_http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)

HTTP Callbacks.

Note:
The callback function receives server instance, uri, http method, get method (if present in URI), and http headers as arguments and should use the ast_http_send() function for sending content allocated with ast_str and/or content from an opened file descriptor.
Status and status text should be sent as arguments to the ast_http_send() function to reflect the status of the request (200 or 304, for example). Content length is calculated by ast_http_send() automatically.

Static content may be indicated to the ast_http_send() function, to indicate that it may be cached.

 * The return value may include additional headers at the front and MUST
 * include a blank line with \r\n to provide separation between user headers
 * and content (even if no content is specified)
 * 

For an error response, the ast_http_error() function may be used.

Definition at line 88 of file http.h.


Enumeration Type Documentation

enum ast_http_method

HTTP Request methods known by Asterisk.

Enumerator:
AST_HTTP_UNKNOWN  Unknown response
AST_HTTP_GET 
AST_HTTP_POST 
AST_HTTP_HEAD 
AST_HTTP_PUT  Not supported in Asterisk

Definition at line 56 of file http.h.

00056                      {
00057    AST_HTTP_UNKNOWN = -1,   /*!< Unknown response */
00058    AST_HTTP_GET = 0,
00059    AST_HTTP_POST,
00060    AST_HTTP_HEAD,
00061    AST_HTTP_PUT,            /*!< Not supported in Asterisk */
00062 };


Function Documentation

const char* ast_get_http_method ( enum ast_http_method  method  ) 

Return http method name string.

Since:
1.8

Definition at line 144 of file http.c.

References ast_http_methods_text, and ast_cfhttp_methods_text::text.

00145 {
00146    return ast_http_methods_text[method].text;
00147 }

void ast_http_auth ( struct ast_tcptls_session_instance ser,
const char *  realm,
const unsigned long  nonce,
const unsigned long  opaque,
int  stale,
const char *  text 
)

Send http "401 Unauthorized" response and close socket.

Definition at line 449 of file http.c.

References ast_free, ast_http_send(), AST_HTTP_UNKNOWN, ast_str_create(), and ast_str_set().

00452 {
00453    struct ast_str *http_headers = ast_str_create(128);
00454    struct ast_str *out = ast_str_create(512);
00455 
00456    if (!http_headers || !out) {
00457       ast_free(http_headers);
00458       ast_free(out);
00459       return;
00460    }
00461 
00462    ast_str_set(&http_headers, 0,
00463       "WWW-authenticate: Digest algorithm=MD5, realm=\"%s\", nonce=\"%08lx\", qop=\"auth\", opaque=\"%08lx\"%s\r\n"
00464       "Content-type: text/html",
00465       realm ? realm : "Asterisk",
00466       nonce,
00467       opaque,
00468       stale ? ", stale=true" : "");
00469 
00470    ast_str_set(&out, 0,
00471       "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
00472       "<html><head>\r\n"
00473       "<title>401 Unauthorized</title>\r\n"
00474       "</head><body>\r\n"
00475       "<h1>401 Unauthorized</h1>\r\n"
00476       "<p>%s</p>\r\n"
00477       "<hr />\r\n"
00478       "<address>Asterisk Server</address>\r\n"
00479       "</body></html>\r\n",
00480       text ? text : "");
00481 
00482    ast_http_send(ser, AST_HTTP_UNKNOWN, 401, "Unauthorized", http_headers, out, 0, 0);
00483    return;
00484 }

void ast_http_error ( struct ast_tcptls_session_instance ser,
int  status,
const char *  title,
const char *  text 
)

Send HTTP error message and close socket.

Definition at line 487 of file http.c.

References ast_free, ast_http_send(), AST_HTTP_UNKNOWN, ast_str_create(), and ast_str_set().

Referenced by auth_http_callback(), generic_http_callback(), handle_uri(), http_post_callback(), httpd_helper_thread(), httpstatus_callback(), phoneprov_callback(), and static_callback().

00488 {
00489    struct ast_str *http_headers = ast_str_create(40);
00490    struct ast_str *out = ast_str_create(256);
00491 
00492    if (!http_headers || !out) {
00493       ast_free(http_headers);
00494       ast_free(out);
00495       return;
00496    }
00497 
00498    ast_str_set(&http_headers, 0, "Content-type: text/html");
00499 
00500    ast_str_set(&out, 0,
00501       "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
00502       "<html><head>\r\n"
00503       "<title>%d %s</title>\r\n"
00504       "</head><body>\r\n"
00505       "<h1>%s</h1>\r\n"
00506       "<p>%s</p>\r\n"
00507       "<hr />\r\n"
00508       "<address>Asterisk Server</address>\r\n"
00509       "</body></html>\r\n",
00510          status_code, status_title, status_title, text);
00511 
00512    ast_http_send(ser, AST_HTTP_UNKNOWN, status_code, status_title, http_headers, out, 0, 0);
00513    return;
00514 }

const char* ast_http_ftype2mtype ( const char *  ftype  ) 

Return mime type based on extension.

Parameters:
ftype filename extension
Returns:
String containing associated MIME type
Since:
1.8

Definition at line 149 of file http.c.

References ARRAY_LEN, ext, and mimetypes.

Referenced by static_callback().

00150 {
00151    int x;
00152 
00153    if (ftype) {
00154       for (x = 0; x < ARRAY_LEN(mimetypes); x++) {
00155          if (!strcasecmp(ftype, mimetypes[x].ext)) {
00156             return mimetypes[x].mtype;
00157          }
00158       }
00159    }
00160    return NULL;
00161 }

struct ast_variable* ast_http_get_cookies ( struct ast_variable headers  ) 

Get cookie from Request headers.

Definition at line 823 of file http.c.

References ast_strdupa, ast_variables_destroy(), ast_variable::name, ast_variable::next, parse_cookies(), and ast_variable::value.

Referenced by ast_http_manid_from_vars(), generic_http_callback(), http_post_callback(), and httpstatus_callback().

00824 {
00825    struct ast_variable *v, *cookies=NULL;
00826 
00827    for (v = headers; v; v = v->next) {
00828       if (!strncasecmp(v->name, "Cookie", 6)) {
00829          char *tmp = ast_strdupa(v->value);
00830          if (cookies) {
00831             ast_variables_destroy(cookies);
00832          }
00833 
00834          cookies = parse_cookies(tmp);
00835       }
00836    }
00837    return cookies;
00838 }

struct ast_variable* ast_http_get_post_vars ( struct ast_tcptls_session_instance ser,
struct ast_variable headers 
)

Get post variables from client Request Entity-Body, if content type is application/x-www-form-urlencoded.

Parameters:
ser TCP/TLS session object
headers List of HTTP headers
Returns:
List of variables within the POST body
Note:
Since returned list is malloc'd, list should be free'd by the calling function
Since:
1.8

Definition at line 603 of file http.c.

References ast_variable::name, ast_variable::next, ast_variable::value, and var.

00605 {
00606    int content_length = 0;
00607    struct ast_variable *v, *post_vars=NULL, *prev = NULL;
00608    char *buf, *var, *val;
00609 
00610    for (v = headers; v; v = v->next) {
00611       if (!strcasecmp(v->name, "Content-Type")) {
00612          if (strcasecmp(v->value, "application/x-www-form-urlencoded")) {
00613             return NULL;
00614          }
00615          break;
00616       }
00617    }
00618 
00619    for (v = headers; v; v = v->next) {
00620       if (!strcasecmp(v->name, "Content-Length")) {
00621          content_length = atoi(v->value) + 1;
00622          break;
00623       }
00624    }
00625 
00626    if (!content_length) {
00627       return NULL;
00628    }
00629 
00630    if (!(buf = alloca(content_length))) {
00631       return NULL;
00632    }
00633    if (!fgets(buf, content_length, ser->f)) {
00634       return NULL;
00635    }
00636 
00637    while ((val = strsep(&buf, "&"))) {
00638       var = strsep(&val, "=");
00639       if (val) {
00640          http_decode(val);
00641       } else  {
00642          val = "";
00643       }
00644       http_decode(var);
00645       if ((v = ast_variable_new(var, val, ""))) {
00646          if (post_vars) {
00647             prev->next = v;
00648          } else {
00649             post_vars = v;
00650          }
00651          prev = v;
00652       }
00653    }
00654    return post_vars;
00655 }

uint32_t ast_http_manid_from_vars ( struct ast_variable headers  ) 

Return manager id, if exist, from request headers.

Parameters:
headers List of HTTP headers
Returns:
32-bit associated manager session identifier
Since:
1.8

Definition at line 163 of file http.c.

References ast_http_get_cookies(), ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by http_post_callback(), and static_callback().

00164 {
00165    uint32_t mngid = 0;
00166    struct ast_variable *v, *cookies;
00167 
00168    cookies = ast_http_get_cookies(headers);
00169    for (v = cookies; v; v = v->next) {
00170       if (!strcasecmp(v->name, "mansession_id")) {
00171          sscanf(v->value, "%30x", &mngid);
00172          break;
00173       }
00174    }
00175    if (cookies) {
00176       ast_variables_destroy(cookies);
00177    }
00178    return mngid;
00179 }

void ast_http_prefix ( char *  buf,
int  len 
)

Return the current prefix.

Parameters:
[out] buf destination buffer for previous
[in] len length of prefix to copy
Since:
1.6.1

Definition at line 181 of file http.c.

References ast_copy_string().

00182 {
00183    if (buf) {
00184       ast_copy_string(buf, prefix, len);
00185    }
00186 }

void ast_http_send ( struct ast_tcptls_session_instance ser,
enum ast_http_method  method,
int  status_code,
const char *  status_title,
struct ast_str http_header,
struct ast_str out,
const int  fd,
unsigned int  static_content 
)

Generic function for sending http/1.1 response.

Parameters:
ser TCP/TLS session object
method GET/POST/HEAD
status_code HTTP response code (200/401/403/404/500)
status_title English equivalent to the status_code parameter
http_header An ast_str object containing all headers
out An ast_str object containing the body of the response
fd If out is NULL, a file descriptor where the body of the response is held (otherwise -1)
static_content Zero if the content is dynamically generated and should not be cached; nonzero otherwise
Note:
Function determines the HTTP response header from status_code, status_header, and http_header.
Extra HTTP headers MUST be present only in the http_header argument. The argument "out" should contain only content of the response (no headers!).

HTTP content can be constructed from the argument "out", if it is not NULL; otherwise, the function will read content from FD.

This function calculates the content-length http header itself.

Both the http_header and out arguments will be freed by this function; however, if FD is open, it will remain open.

Since:
1.8

Definition at line 376 of file http.c.

References ast_free, ast_get_version(), AST_HTTP_HEAD, ast_localtime(), ast_log(), ast_str_buffer(), ast_strftime(), ast_tvnow(), errno, ast_tcptls_session_instance::f, fwrite, len(), and LOG_WARNING.

Referenced by ast_http_auth(), ast_http_error(), handle_uri(), httpstatus_callback(), and phoneprov_callback().

00380 {
00381    struct timeval now = ast_tvnow();
00382    struct ast_tm tm;
00383    char timebuf[80];
00384    int content_length = 0;
00385 
00386    if (!ser || 0 == ser->f) {
00387       return;
00388    }
00389 
00390    ast_strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", ast_localtime(&now, &tm, "GMT"));
00391 
00392    /* calc conetnt length */
00393    if (out) {
00394       content_length += strlen(ast_str_buffer(out));
00395    }
00396 
00397    if (fd) {
00398       content_length += lseek(fd, 0, SEEK_END);
00399       lseek(fd, 0, SEEK_SET);
00400    }
00401 
00402    /* send http header */
00403    fprintf(ser->f, "HTTP/1.1 %d %s\r\n"
00404       "Server: Asterisk/%s\r\n"
00405       "Date: %s\r\n"
00406       "Connection: close\r\n"
00407       "%s"
00408       "Content-Length: %d\r\n"
00409       "%s\r\n\r\n",
00410       status_code, status_title ? status_title : "OK",
00411       ast_get_version(),
00412       timebuf,
00413       static_content ? "" : "Cache-Control: no-cache, no-store\r\n",
00414       content_length,
00415       http_header ? ast_str_buffer(http_header) : ""
00416       );
00417 
00418    /* send content */
00419    if (method != AST_HTTP_HEAD || status_code >= 400) {
00420       if (out) {
00421          fprintf(ser->f, "%s", ast_str_buffer(out));
00422       }
00423 
00424       if (fd) {
00425          char buf[256];
00426          int len;
00427          while ((len = read(fd, buf, sizeof(buf))) > 0) {
00428             if (fwrite(buf, len, 1, ser->f) != 1) {
00429                ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
00430                break;
00431             }
00432          }
00433       }
00434    }
00435 
00436    if (http_header) {
00437       ast_free(http_header);
00438    }
00439    if (out) {
00440       ast_free(out);
00441    }
00442 
00443    fclose(ser->f);
00444    ser->f = 0;
00445    return;
00446 }

int ast_http_uri_link ( struct ast_http_uri urih  ) 

Register a URI handler.

They are sorted by length of the string, not alphabetically. Duplicate entries are not replaced, but the insertion order (using <= and not just <) makes sure that more recent insertions hide older ones. On a lookup, we just scan the list and stop at the first matching entry.

Definition at line 525 of file http.c.

References AST_RWLIST_EMPTY, AST_RWLIST_FIRST, AST_RWLIST_INSERT_AFTER, AST_RWLIST_INSERT_HEAD, AST_RWLIST_INSERT_TAIL, AST_RWLIST_NEXT, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_http_uri::entry, len(), and ast_http_uri::uri.

Referenced by __ast_http_post_load(), ast_http_init(), and load_module().

00526 {
00527    struct ast_http_uri *uri;
00528    int len = strlen(urih->uri);
00529 
00530    AST_RWLIST_WRLOCK(&uris);
00531 
00532    if ( AST_RWLIST_EMPTY(&uris) || strlen(AST_RWLIST_FIRST(&uris)->uri) <= len ) {
00533       AST_RWLIST_INSERT_HEAD(&uris, urih, entry);
00534       AST_RWLIST_UNLOCK(&uris);
00535       return 0;
00536    }
00537 
00538    AST_RWLIST_TRAVERSE(&uris, uri, entry) {
00539       if (AST_RWLIST_NEXT(uri, entry) &&
00540          strlen(AST_RWLIST_NEXT(uri, entry)->uri) <= len) {
00541          AST_RWLIST_INSERT_AFTER(&uris, uri, urih, entry);
00542          AST_RWLIST_UNLOCK(&uris);
00543 
00544          return 0;
00545       }
00546    }
00547 
00548    AST_RWLIST_INSERT_TAIL(&uris, urih, entry);
00549 
00550    AST_RWLIST_UNLOCK(&uris);
00551 
00552    return 0;
00553 }

void ast_http_uri_unlink ( struct ast_http_uri urihandler  ) 

Unregister a URI handler.

Definition at line 555 of file http.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_http_uri::entry.

Referenced by unload_module().

00556 {
00557    AST_RWLIST_WRLOCK(&uris);
00558    AST_RWLIST_REMOVE(&uris, urih, entry);
00559    AST_RWLIST_UNLOCK(&uris);
00560 }

void ast_http_uri_unlink_all_with_key ( const char *  key  ) 

Unregister all handlers with matching key.

Definition at line 562 of file http.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_http_uri::data, ast_http_uri::dmallocd, ast_http_uri::entry, ast_http_uri::key, and ast_http_uri::mallocd.

Referenced by __ast_http_post_load(), and unload_module().

00563 {
00564    struct ast_http_uri *urih;
00565    AST_RWLIST_WRLOCK(&uris);
00566    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&uris, urih, entry) {
00567       if (!strcmp(urih->key, key)) {
00568          AST_RWLIST_REMOVE_CURRENT(entry);
00569       }
00570       if (urih->dmallocd) {
00571          ast_free(urih->data);
00572       }
00573       if (urih->mallocd) {
00574          ast_free(urih);
00575       }
00576    }
00577    AST_RWLIST_TRAVERSE_SAFE_END;
00578    AST_RWLIST_UNLOCK(&uris);
00579 }


Generated on Mon Jun 27 16:51:15 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7