Mon Mar 12 2012 21:40:09

Asterisk developer's documentation


http.h File Reference

Support for Private Asterisk HTTP Servers. More...

Include dependency graph for http.h:
This graph shows which files directly or indirectly include this file:

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.
struct ast_variableast_http_get_cookies (struct ast_variable *headers)
 Get cookie from Request headers.
struct 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

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.

                     {
   AST_HTTP_UNKNOWN = -1,   /*!< Unknown response */
   AST_HTTP_GET = 0,
   AST_HTTP_POST,
   AST_HTTP_HEAD,
   AST_HTTP_PUT,            /*!< Not supported in Asterisk */
};

Function Documentation

const char* ast_get_http_method ( enum ast_http_method  method)

Return http method name string.

Since:
1.8

Definition at line 148 of file http.c.

References ARRAY_LEN, ast_http_methods_text, and ast_cfhttp_methods_text::text.

Referenced by auth_http_callback().

{
   int x;

   for (x = 0; x < ARRAY_LEN(ast_http_methods_text); x++) {
      if (ast_http_methods_text[x].method == method) {
         return ast_http_methods_text[x].text;
      }
   }

   return NULL;
}
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 462 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().

{
   struct ast_str *http_headers = ast_str_create(128);
   struct ast_str *out = ast_str_create(512);

   if (!http_headers || !out) {
      ast_free(http_headers);
      ast_free(out);
      return;
   }

   ast_str_set(&http_headers, 0,
      "WWW-authenticate: Digest algorithm=MD5, realm=\"%s\", nonce=\"%08lx\", qop=\"auth\", opaque=\"%08lx\"%s\r\n"
      "Content-type: text/html\r\n",
      realm ? realm : "Asterisk",
      nonce,
      opaque,
      stale ? ", stale=true" : "");

   ast_str_set(&out, 0,
      "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
      "<html><head>\r\n"
      "<title>401 Unauthorized</title>\r\n"
      "</head><body>\r\n"
      "<h1>401 Unauthorized</h1>\r\n"
      "<p>%s</p>\r\n"
      "<hr />\r\n"
      "<address>Asterisk Server</address>\r\n"
      "</body></html>\r\n",
      text ? text : "");

   ast_http_send(ser, AST_HTTP_UNKNOWN, 401, "Unauthorized", http_headers, out, 0, 0);
   return;
}
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 500 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().

{
   struct ast_str *http_headers = ast_str_create(40);
   struct ast_str *out = ast_str_create(256);

   if (!http_headers || !out) {
      ast_free(http_headers);
      ast_free(out);
      return;
   }

   ast_str_set(&http_headers, 0, "Content-type: text/html\r\n");

   ast_str_set(&out, 0,
      "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
      "<html><head>\r\n"
      "<title>%d %s</title>\r\n"
      "</head><body>\r\n"
      "<h1>%s</h1>\r\n"
      "<p>%s</p>\r\n"
      "<hr />\r\n"
      "<address>Asterisk Server</address>\r\n"
      "</body></html>\r\n",
         status_code, status_title, status_title, text);

   ast_http_send(ser, AST_HTTP_UNKNOWN, status_code, status_title, http_headers, out, 0, 0);
   return;
}
const char* ast_http_ftype2mtype ( const char *  ftype)

Return mime type based on extension.

Parameters:
ftypefilename extension
Returns:
String containing associated MIME type
Since:
1.8

Definition at line 161 of file http.c.

References ARRAY_LEN, ext, and mimetypes.

Referenced by build_profile(), and static_callback().

{
   int x;

   if (ftype) {
      for (x = 0; x < ARRAY_LEN(mimetypes); x++) {
         if (!strcasecmp(ftype, mimetypes[x].ext)) {
            return mimetypes[x].mtype;
         }
      }
   }
   return NULL;
}
struct ast_variable* ast_http_get_cookies ( struct ast_variable headers) [read]

Get cookie from Request headers.

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

{
   struct ast_variable *v, *cookies=NULL;

   for (v = headers; v; v = v->next) {
      if (!strncasecmp(v->name, "Cookie", 6)) {
         char *tmp = ast_strdupa(v->value);
         if (cookies) {
            ast_variables_destroy(cookies);
         }

         cookies = parse_cookies(tmp);
      }
   }
   return cookies;
}
struct ast_variable* ast_http_get_post_vars ( struct ast_tcptls_session_instance ser,
struct ast_variable headers 
) [read]

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

Parameters:
serTCP/TLS session object
headersList 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 616 of file http.c.

References ast_variable_new(), ast_tcptls_session_instance::f, http_decode(), ast_variable::name, ast_variable::next, strsep(), ast_variable::value, and var.

Referenced by auth_http_callback(), and generic_http_callback().

{
   int content_length = 0;
   struct ast_variable *v, *post_vars=NULL, *prev = NULL;
   char *buf, *var, *val;

   for (v = headers; v; v = v->next) {
      if (!strcasecmp(v->name, "Content-Type")) {
         if (strcasecmp(v->value, "application/x-www-form-urlencoded")) {
            return NULL;
         }
         break;
      }
   }

   for (v = headers; v; v = v->next) {
      if (!strcasecmp(v->name, "Content-Length")) {
         content_length = atoi(v->value) + 1;
         break;
      }
   }

   if (!content_length) {
      return NULL;
   }

   if (!(buf = alloca(content_length))) {
      return NULL;
   }
   if (!fgets(buf, content_length, ser->f)) {
      return NULL;
   }

   while ((val = strsep(&buf, "&"))) {
      var = strsep(&val, "=");
      if (val) {
         http_decode(val);
      } else  {
         val = "";
      }
      http_decode(var);
      if ((v = ast_variable_new(var, val, ""))) {
         if (post_vars) {
            prev->next = v;
         } else {
            post_vars = v;
         }
         prev = v;
      }
   }
   return post_vars;
}
uint32_t ast_http_manid_from_vars ( struct ast_variable headers)

Return manager id, if exist, from request headers.

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

Definition at line 175 of file http.c.

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

Referenced by http_post_callback(), and static_callback().

{
   uint32_t mngid = 0;
   struct ast_variable *v, *cookies;

   cookies = ast_http_get_cookies(headers);
   for (v = cookies; v; v = v->next) {
      if (!strcasecmp(v->name, "mansession_id")) {
         sscanf(v->value, "%30x", &mngid);
         break;
      }
   }
   if (cookies) {
      ast_variables_destroy(cookies);
   }
   return mngid;
}
void ast_http_prefix ( char *  buf,
int  len 
)

Return the current prefix.

Parameters:
[out]bufdestination buffer for previous
[in]lenlength of prefix to copy
Since:
1.6.1

Definition at line 193 of file http.c.

References ast_copy_string().

{
   if (buf) {
      ast_copy_string(buf, prefix, len);
   }
}
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:
serTCP/TLS session object
methodGET/POST/HEAD
status_codeHTTP response code (200/401/403/404/500)
status_titleEnglish equivalent to the status_code parameter
http_headerAn ast_str object containing all headers
outAn ast_str object containing the body of the response
fdIf out is NULL, a file descriptor where the body of the response is held (otherwise -1)
static_contentZero 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 388 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, len(), and LOG_WARNING.

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

{
   struct timeval now = ast_tvnow();
   struct ast_tm tm;
   char timebuf[80];
   int content_length = 0;

   if (!ser || 0 == ser->f) {
      return;
   }

   ast_strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", ast_localtime(&now, &tm, "GMT"));

   /* calc content length */
   if (out) {
      content_length += strlen(ast_str_buffer(out));
   }

   if (fd) {
      content_length += lseek(fd, 0, SEEK_END);
      lseek(fd, 0, SEEK_SET);
   }

   /* send http header */
   fprintf(ser->f, "HTTP/1.1 %d %s\r\n"
      "Server: Asterisk/%s\r\n"
      "Date: %s\r\n"
      "Connection: close\r\n"
      "%s"
      "Content-Length: %d\r\n"
      "%s"
      "\r\n",
      status_code, status_title ? status_title : "OK",
      ast_get_version(),
      timebuf,
      static_content ? "" : "Cache-Control: no-cache, no-store\r\n",
      content_length,
      http_header ? ast_str_buffer(http_header) : ""
      );

   /* send content */
   if (method != AST_HTTP_HEAD || status_code >= 400) {
      if (out) {
         fprintf(ser->f, "%s", ast_str_buffer(out));
      }

      if (fd) {
         char buf[256];
         int len;
         while ((len = read(fd, buf, sizeof(buf))) > 0) {
            if (fwrite(buf, len, 1, ser->f) != 1) {
               ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
               break;
            }
         }
      }
   }

   if (http_header) {
      ast_free(http_header);
   }
   if (out) {
      ast_free(out);
   }

   fclose(ser->f);
   ser->f = 0;
   return;
}
int ast_http_uri_link ( struct ast_http_uri urih)

Register a URI handler.

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 538 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, http_uri_redirect::entry, len(), and ast_http_uri::uri.

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

{
   struct ast_http_uri *uri;
   int len = strlen(urih->uri);

   AST_RWLIST_WRLOCK(&uris);

   if ( AST_RWLIST_EMPTY(&uris) || strlen(AST_RWLIST_FIRST(&uris)->uri) <= len ) {
      AST_RWLIST_INSERT_HEAD(&uris, urih, entry);
      AST_RWLIST_UNLOCK(&uris);
      return 0;
   }

   AST_RWLIST_TRAVERSE(&uris, uri, entry) {
      if (AST_RWLIST_NEXT(uri, entry) &&
         strlen(AST_RWLIST_NEXT(uri, entry)->uri) <= len) {
         AST_RWLIST_INSERT_AFTER(&uris, uri, urih, entry);
         AST_RWLIST_UNLOCK(&uris);

         return 0;
      }
   }

   AST_RWLIST_INSERT_TAIL(&uris, urih, entry);

   AST_RWLIST_UNLOCK(&uris);

   return 0;
}
void ast_http_uri_unlink ( struct ast_http_uri urihandler)

Unregister a URI handler.

Definition at line 568 of file http.c.

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

Referenced by __init_manager(), and unload_module().

void ast_http_uri_unlink_all_with_key ( const char *  key)