Support for Private Asterisk HTTP Servers. More...


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_variable * | ast_http_get_cookies (struct ast_variable *headers) |
| Get cookie from Request headers. | |
| 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. | |
| 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. | |
Support for Private Asterisk HTTP Servers.
Definition in file http.h.
| 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.
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.
| enum ast_http_method |
HTTP Request methods known by Asterisk.
| 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 */
};
| const char* ast_get_http_method | ( | enum ast_http_method | method | ) |
Return http method name string.
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.
| ftype | filename extension |
Definition at line 161 of file http.c.
References ARRAY_LEN, ext, and mimetypes.
Referenced by build_profile(), and static_callback().
| 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.
| ser | TCP/TLS session object |
| headers | List of HTTP headers |
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.
| headers | List of HTTP headers |
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.
| [out] | buf | destination buffer for previous |
| [in] | len | length of prefix to copy |
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.
| 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 |
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.
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().
{
AST_RWLIST_WRLOCK(&uris);
AST_RWLIST_REMOVE(&uris, urih, entry);
AST_RWLIST_UNLOCK(&uris);
}
| void ast_http_uri_unlink_all_with_key | ( | const char * | key | ) |
Unregister all handlers with matching key.
Definition at line 575 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, http_uri_redirect::entry, ast_http_uri::key, and ast_http_uri::mallocd.
Referenced by __ast_http_post_load(), and unload_module().
{
struct ast_http_uri *urih;
AST_RWLIST_WRLOCK(&uris);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&uris, urih, entry) {
if (!strcmp(urih->key, key)) {
AST_RWLIST_REMOVE_CURRENT(entry);
}
if (urih->dmallocd) {
ast_free(urih->data);
}
if (urih->mallocd) {
ast_free(urih);
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&uris);
}