Wed Jan 8 2020 09:50:13

Asterisk developer's documentation


http.c File Reference

http server for AMI access More...

#include "asterisk.h"
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <fcntl.h>
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include "asterisk/cli.h"
#include "asterisk/tcptls.h"
#include "asterisk/http.h"
#include "asterisk/utils.h"
#include "asterisk/strings.h"
#include "asterisk/config.h"
#include "asterisk/stringfields.h"
#include "asterisk/ast_version.h"
#include "asterisk/manager.h"
#include "asterisk/_private.h"
#include "asterisk/astobj2.h"

Go to the source code of this file.

Data Structures

struct  ast_cfhttp_methods_text
 
struct  http_uri_redirect
 
struct  uri_redirects
 
struct  uris
 

Macros

#define DEFAULT_HTTP_PORT   8088
 
#define DEFAULT_HTTPS_PORT   8089
 
#define DEFAULT_SESSION_INACTIVITY   30000 /* (ms) Idle time waiting for data. */
 
#define DEFAULT_SESSION_LIMIT   100
 
#define DO_SSL   /* comment in/out if you want to support ssl */
 
#define HOOK_T   ssize_t
 
#define LEN_T   size_t
 
#define MAX_HTTP_REQUEST_HEADERS   100
 
#define MAX_POST_CONTENT   1025
 
#define MAX_PREFIX   80
 

Functions

static int __ast_http_load (int reload)
 
static void add_redirect (const char *value)
 Add a new URI redirect The entries in the redirect list are sorted by length, just like the list of URI handlers. More...
 
const char * ast_get_http_method (enum ast_http_method method)
 Return http method name string. More...
 
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. More...
 
void ast_http_error (struct ast_tcptls_session_instance *ser, int status_code, const char *status_title, const char *text)
 Send HTTP error message and close socket. More...
 
const char * ast_http_ftype2mtype (const char *ftype)
 Return mime type based on extension. More...
 
struct ast_variableast_http_get_cookies (struct ast_variable *headers)
 Get cookie from Request headers. More...
 
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. More...
 
int ast_http_init (void)
 
uint32_t ast_http_manid_from_vars (struct ast_variable *headers)
 Return manager id, if exist, from request headers. More...
 
void ast_http_prefix (char *buf, int len)
 Return the current prefix. More...
 
int ast_http_reload (void)
 
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. More...
 
int ast_http_uri_link (struct ast_http_uri *urih)
 Link the new uri into the list. More...
 
void ast_http_uri_unlink (struct ast_http_uri *urih)
 Unregister a URI handler. More...
 
void ast_http_uri_unlink_all_with_key (const char *key)
 Unregister all handlers with matching key. More...
 
static char * handle_show_http (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int handle_uri (struct ast_tcptls_session_instance *ser, char *uri, enum ast_http_method method, struct ast_variable *headers)
 
static void http_decode (char *s)
 
static void http_shutdown (void)
 
static void * httpd_helper_thread (void *arg)
 
static int httpstatus_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_vars, struct ast_variable *headers)
 
static struct ast_variableparse_cookies (const char *cookies)
 
static int static_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_vars, struct ast_variable *headers)
 

Variables

static struct
ast_cfhttp_methods_text 
ast_http_methods_text []
 
static struct ast_cli_entry cli_http []
 
static int enablestatic
 
static struct
ast_tcptls_session_args 
http_desc
 
static struct ast_tls_config http_tls_cfg
 
static struct
ast_tcptls_session_args 
https_desc
 
struct {
   const char *   ext
 
   const char *   mtype
 
mimetypes []
 Limit the kinds of files we're willing to serve up. More...
 
static char prefix [MAX_PREFIX]
 
static int session_count = 0
 
static int session_inactivity = DEFAULT_SESSION_INACTIVITY
 
static int session_limit = DEFAULT_SESSION_LIMIT
 
static struct ast_http_uri staticuri
 
static struct ast_http_uri statusuri
 
static struct uri_redirects uri_redirects = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct uris uris = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 

Detailed Description

http server for AMI access

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

This program implements a tiny http server and was inspired by micro-httpd by Jef Poskanzer

ExtRef:
GMime http://spruce.sourceforge.net/gmime/

AMI over HTTP support - AMI over the http protocol

Definition in file http.c.

Macro Definition Documentation

#define DEFAULT_HTTP_PORT   8088

Definition at line 65 of file http.c.

Referenced by __ast_http_load().

#define DEFAULT_HTTPS_PORT   8089

Definition at line 66 of file http.c.

Referenced by __ast_http_load().

#define DEFAULT_SESSION_INACTIVITY   30000 /* (ms) Idle time waiting for data. */

Definition at line 63 of file http.c.

Referenced by __ast_http_load().

#define DEFAULT_SESSION_LIMIT   100

Definition at line 62 of file http.c.

Referenced by __ast_http_load().

#define DO_SSL   /* comment in/out if you want to support ssl */

Definition at line 70 of file http.c.

#define HOOK_T   ssize_t

Definition at line 788 of file http.c.

#define LEN_T   size_t

Definition at line 789 of file http.c.

#define MAX_HTTP_REQUEST_HEADERS   100

Limit the number of request headers in case the sender is being ridiculous.

Definition at line 876 of file http.c.

Referenced by httpd_helper_thread().

#define MAX_POST_CONTENT   1025

Definition at line 618 of file http.c.

Referenced by ast_http_get_post_vars().

#define MAX_PREFIX   80

Definition at line 61 of file http.c.

Referenced by __ast_http_load().

Function Documentation

static int __ast_http_load ( int  reload)
static

Definition at line 1084 of file http.c.

References add_redirect(), AST_CERTFILE, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_free, ast_gethostbyname(), ast_log(), ast_parse_arg(), AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sockaddr_from_sin, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_to_sin, ast_ssl_setup(), ast_strdup, ast_strlen_zero(), ast_tcptls_server_start(), ast_tcptls_server_stop(), ast_tls_read_conf(), ast_true(), ast_variable_browse(), ast_tls_config::certfile, ast_tls_config::cipher, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT, DEFAULT_SESSION_INACTIVITY, DEFAULT_SESSION_LIMIT, ast_tls_config::enabled, enabled, http_uri_redirect::entry, hp, http_tls_cfg, ast_variable::lineno, ast_tcptls_session_args::local_address, LOG_WARNING, MAX_PREFIX, ast_variable::name, ast_variable::next, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_INT32, ast_tls_config::pvtfile, ast_tcptls_session_args::tls_cfg, and ast_variable::value.

Referenced by ast_http_init(), and ast_http_reload().

1085 {
1086  struct ast_config *cfg;
1087  struct ast_variable *v;
1088  int enabled=0;
1089  int newenablestatic=0;
1090  struct hostent *hp;
1091  struct ast_hostent ahp;
1092  char newprefix[MAX_PREFIX] = "";
1093  struct http_uri_redirect *redirect;
1094  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1095  struct sockaddr_in tmp = {0,};
1096  struct sockaddr_in tmp2 = {0,};
1097  int http_tls_was_enabled = 0;
1098 
1099  cfg = ast_config_load2("http.conf", "http", config_flags);
1101  return 0;
1102  }
1103 
1104  http_tls_was_enabled = (reload && http_tls_cfg.enabled);
1105 
1106  tmp.sin_family = AF_INET;
1107  tmp.sin_port = htons(DEFAULT_HTTP_PORT);
1109 
1110  http_tls_cfg.enabled = 0;
1111  if (http_tls_cfg.certfile) {
1113  }
1115 
1116  if (http_tls_cfg.pvtfile) {
1118  }
1120 
1121  if (http_tls_cfg.cipher) {
1123  }
1125 
1127  while ((redirect = AST_RWLIST_REMOVE_HEAD(&uri_redirects, entry))) {
1128  ast_free(redirect);
1129  }
1131 
1133 
1136 
1137  if (cfg) {
1138  v = ast_variable_browse(cfg, "general");
1139  for (; v; v = v->next) {
1140 
1141  /* read tls config options while preventing unsupported options from being set */
1142  if (strcasecmp(v->name, "tlscafile")
1143  && strcasecmp(v->name, "tlscapath")
1144  && strcasecmp(v->name, "tlscadir")
1145  && strcasecmp(v->name, "tlsverifyclient")
1146  && strcasecmp(v->name, "tlsdontverifyserver")
1147  && strcasecmp(v->name, "tlsclientmethod")
1148  && strcasecmp(v->name, "sslclientmethod")
1149  && strcasecmp(v->name, "tlscipher")
1150  && strcasecmp(v->name, "sslcipher")
1152  continue;
1153  }
1154 
1155  if (!strcasecmp(v->name, "enabled")) {
1156  enabled = ast_true(v->value);
1157  } else if (!strcasecmp(v->name, "enablestatic")) {
1158  newenablestatic = ast_true(v->value);
1159  } else if (!strcasecmp(v->name, "bindport")) {
1161  atoi(v->value));
1162  } else if (!strcasecmp(v->name, "bindaddr")) {
1163  if ((hp = ast_gethostbyname(v->value, &ahp))) {
1165  &tmp);
1166  memcpy(&tmp.sin_addr, hp->h_addr, sizeof(tmp.sin_addr));
1168  &tmp);
1169  } else {
1170  ast_log(LOG_WARNING, "Invalid bind address '%s'\n", v->value);
1171  }
1172  } else if (!strcasecmp(v->name, "prefix")) {
1173  if (!ast_strlen_zero(v->value)) {
1174  newprefix[0] = '/';
1175  ast_copy_string(newprefix + 1, v->value, sizeof(newprefix) - 1);
1176  } else {
1177  newprefix[0] = '\0';
1178  }
1179  } else if (!strcasecmp(v->name, "redirect")) {
1180  add_redirect(v->value);
1181  } else if (!strcasecmp(v->name, "sessionlimit")) {
1183  &session_limit, DEFAULT_SESSION_LIMIT, 1, INT_MAX)) {
1184  ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
1185  v->name, v->value, v->lineno);
1186  }
1187  } else if (!strcasecmp(v->name, "session_inactivity")) {
1190  ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
1191  v->name, v->value, v->lineno);
1192  }
1193  } else {
1194  ast_log(LOG_WARNING, "Ignoring unknown option '%s' in http.conf\n", v->name);
1195  }
1196  }
1197 
1198  ast_config_destroy(cfg);
1199  }
1200  /* if the https address has not been set, default is the same as non secure http */
1203  if (!tmp2.sin_addr.s_addr) {
1204  tmp2.sin_addr = tmp.sin_addr;
1205  }
1206  if (!tmp2.sin_port) {
1207  tmp2.sin_port = htons(DEFAULT_HTTPS_PORT);
1208  }
1210  if (!enabled) {
1213  }
1214  if (strcmp(prefix, newprefix)) {
1215  ast_copy_string(prefix, newprefix, sizeof(prefix));
1216  }
1217  enablestatic = newenablestatic;
1219  /* If https was enabled previously but now is not, then stop the service */
1220  if (http_tls_was_enabled && !http_tls_cfg.enabled) {
1222  } else if (ast_ssl_setup(https_desc.tls_cfg)) {
1224  }
1225 
1226  return 0;
1227 }
#define DEFAULT_HTTP_PORT
Definition: http.c:65
char * pvtfile
Definition: tcptls.h:88
#define AST_CERTFILE
Definition: tcptls.h:68
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a ...
Definition: tcptls.c:964
#define ast_strdup(a)
Definition: astmm.h:109
int ast_ssl_setup(struct ast_tls_config *cfg)
Set up an SSL server.
Definition: tcptls.c:850
#define DEFAULT_HTTPS_PORT
Definition: http.c:66
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
int lineno
Definition: config.h:87
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define DEFAULT_SESSION_LIMIT
Definition: http.c:62
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define MAX_PREFIX
Definition: http.c:61
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:106
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
const char * value
Definition: config.h:79
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *result,...)
The argument parsing routine.
Definition: config.c:2805
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
static int enablestatic
Definition: http.c:108
unsigned int enabled
Definition: devicestate.c:205
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_tls_config http_tls_cfg
Definition: http.c:77
const char * name
Definition: config.h:77
static struct ast_tcptls_session_args http_desc
Definition: http.c:84
static struct ast_hostent ahp
Definition: chan_skinny.c:1047
static int reload(void)
Definition: app_amd.c:497
static void add_redirect(const char *value)
Add a new URI redirect The entries in the redirect list are sorted by length, just like the list of U...
Definition: http.c:1031
static int session_limit
Definition: http.c:73
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
static int session_inactivity
Definition: http.c:74
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:829
#define DEFAULT_SESSION_INACTIVITY
Definition: http.c:63
Structure used to handle boolean flags.
Definition: utils.h:200
char * certfile
Definition: tcptls.h:87
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
Definition: utils.c:195
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
Used to parse conf files containing tls/ssl options.
Definition: tcptls.c:1072
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
struct ast_variable * next
Definition: config.h:82
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition: tcptls.c:1058
struct ast_tls_config * tls_cfg
Definition: tcptls.h:128
struct ast_sockaddr local_address
Definition: tcptls.h:124
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static struct hostent * hp
Definition: chan_skinny.c:1048
static struct ast_tcptls_session_args https_desc
Definition: http.c:94
char * cipher
Definition: tcptls.h:89
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static char prefix[MAX_PREFIX]
Definition: http.c:107
int enabled
Definition: tcptls.h:86
static void add_redirect ( const char *  value)
static

Add a new URI redirect The entries in the redirect list are sorted by length, just like the list of URI handlers.

Definition at line 1031 of file http.c.

References ast_calloc, ast_log(), 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_skip_blanks(), ast_strdupa, http_uri_redirect::dest, http_uri_redirect::entry, LOG_WARNING, strsep(), and http_uri_redirect::target.

Referenced by __ast_http_load().

1032 {
1033  char *target, *dest;
1034  struct http_uri_redirect *redirect, *cur;
1035  unsigned int target_len;
1036  unsigned int total_len;
1037 
1038  dest = ast_strdupa(value);
1039  dest = ast_skip_blanks(dest);
1040  target = strsep(&dest, " ");
1041  target = ast_skip_blanks(target);
1042  target = strsep(&target, " "); /* trim trailing whitespace */
1043 
1044  if (!dest) {
1045  ast_log(LOG_WARNING, "Invalid redirect '%s'\n", value);
1046  return;
1047  }
1048 
1049  target_len = strlen(target) + 1;
1050  total_len = sizeof(*redirect) + target_len + strlen(dest) + 1;
1051 
1052  if (!(redirect = ast_calloc(1, total_len))) {
1053  return;
1054  }
1055  redirect->dest = redirect->target + target_len;
1056  strcpy(redirect->target, target);
1057  strcpy(redirect->dest, dest);
1058 
1060 
1061  target_len--; /* So we can compare directly with strlen() */
1063  || strlen(AST_RWLIST_FIRST(&uri_redirects)->target) <= target_len ) {
1066 
1067  return;
1068  }
1069 
1071  if (AST_RWLIST_NEXT(cur, entry)
1072  && strlen(AST_RWLIST_NEXT(cur, entry)->target) <= target_len ) {
1073  AST_RWLIST_INSERT_AFTER(&uri_redirects, cur, redirect, entry);
1075  return;
1076  }
1077  }
1078 
1080 
1082 }
struct http_uri_redirect::@275 entry
#define AST_RWLIST_NEXT
Definition: linkedlists.h:440
char * strsep(char **str, const char *delims)
#define AST_RWLIST_INSERT_AFTER
Definition: linkedlists.h:687
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
char * dest
Definition: http.c:136
int value
Definition: syslog.c:39
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:703
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:97
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char target[0]
Definition: http.c:137
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define ast_calloc(a, b)
Definition: astmm.h:82
#define AST_RWLIST_FIRST
Definition: linkedlists.h:422
const char* ast_get_http_method ( enum ast_http_method  method)

Return http method name string.

Since
1.8

Definition at line 153 of file http.c.

References ARRAY_LEN, ast_http_methods_text, and ast_cfhttp_methods_text::text.

Referenced by auth_http_callback().

154 {
155  int x;
156 
157  for (x = 0; x < ARRAY_LEN(ast_http_methods_text); x++) {
158  if (ast_http_methods_text[x].method == method) {
159  return ast_http_methods_text[x].text;
160  }
161  }
162 
163  return NULL;
164 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_cfhttp_methods_text ast_http_methods_text[]
const char * text
Definition: http.c:144
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 468 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().

471 {
472  struct ast_str *http_headers = ast_str_create(128);
473  struct ast_str *out = ast_str_create(512);
474 
475  if (!http_headers || !out) {
476  ast_free(http_headers);
477  ast_free(out);
478  return;
479  }
480 
481  ast_str_set(&http_headers, 0,
482  "WWW-authenticate: Digest algorithm=MD5, realm=\"%s\", nonce=\"%08lx\", qop=\"auth\", opaque=\"%08lx\"%s\r\n"
483  "Content-type: text/html\r\n",
484  realm ? realm : "Asterisk",
485  nonce,
486  opaque,
487  stale ? ", stale=true" : "");
488 
489  ast_str_set(&out, 0,
490  "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
491  "<html><head>\r\n"
492  "<title>401 Unauthorized</title>\r\n"
493  "</head><body>\r\n"
494  "<h1>401 Unauthorized</h1>\r\n"
495  "<p>%s</p>\r\n"
496  "<hr />\r\n"
497  "<address>Asterisk Server</address>\r\n"
498  "</body></html>\r\n",
499  text ? text : "");
500 
501  ast_http_send(ser, AST_HTTP_UNKNOWN, 401, "Unauthorized", http_headers, out, 0, 0);
502  return;
503 }
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
char * text
Definition: app_queue.c:1091
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.
Definition: http.c:393
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define ast_free(a)
Definition: astmm.h:97
void ast_http_error ( struct ast_tcptls_session_instance ser,
int  status_code,
const char *  status_title,
const char *  text 
)

Send HTTP error message and close socket.

Definition at line 506 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(), and static_callback().

507 {
508  struct ast_str *http_headers = ast_str_create(40);
509  struct ast_str *out = ast_str_create(256);
510 
511  if (!http_headers || !out) {
512  ast_free(http_headers);
513  ast_free(out);
514  return;
515  }
516 
517  ast_str_set(&http_headers, 0, "Content-type: text/html\r\n");
518 
519  ast_str_set(&out, 0,
520  "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
521  "<html><head>\r\n"
522  "<title>%d %s</title>\r\n"
523  "</head><body>\r\n"
524  "<h1>%s</h1>\r\n"
525  "<p>%s</p>\r\n"
526  "<hr />\r\n"
527  "<address>Asterisk Server</address>\r\n"
528  "</body></html>\r\n",
529  status_code, status_title, status_title, text);
530 
531  ast_http_send(ser, AST_HTTP_UNKNOWN, status_code, status_title, http_headers, out, 0, 0);
532  return;
533 }
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
char * text
Definition: app_queue.c:1091
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.
Definition: http.c:393
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define ast_free(a)
Definition: astmm.h:97
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 166 of file http.c.

References ARRAY_LEN, ext, and mimetypes.

Referenced by static_callback().

167 {
168  int x;
169 
170  if (ftype) {
171  for (x = 0; x < ARRAY_LEN(mimetypes); x++) {
172  if (!strcasecmp(ftype, mimetypes[x].ext)) {
173  return mimetypes[x].mtype;
174  }
175  }
176  }
177  return NULL;
178 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
const char * ext
Definition: http.c:112
static struct @274 mimetypes[]
Limit the kinds of files we&#39;re willing to serve up.
struct ast_variable* ast_http_get_cookies ( struct ast_variable headers)

Get cookie from Request headers.

Definition at line 862 of file http.c.

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

863 {
864  struct ast_variable *v, *cookies = NULL;
865 
866  for (v = headers; v; v = v->next) {
867  if (!strcasecmp(v->name, "Cookie")) {
868  ast_variables_destroy(cookies);
869  cookies = parse_cookies(v->value);
870  }
871  }
872  return cookies;
873 }
static struct ast_variable * parse_cookies(const char *cookies)
Definition: http.c:828
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
const char * value
Definition: config.h:79
const char * name
Definition: config.h:77
struct ast_variable * next
Definition: config.h:82
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
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 624 of file http.c.

References ast_free, AST_HTTP_POST, ast_http_send(), ast_log(), ast_malloc, ast_variable_new(), ast_tcptls_session_instance::f, http_decode(), LOG_WARNING, MAX_POST_CONTENT, ast_variable::name, ast_variable::next, strsep(), ast_variable::value, and var.

Referenced by auth_http_callback(), and generic_http_callback().

626 {
627  int content_length = 0;
628  struct ast_variable *v, *post_vars=NULL, *prev = NULL;
629  char *buf, *var, *val;
630  int res;
631 
632  for (v = headers; v; v = v->next) {
633  if (!strcasecmp(v->name, "Content-Type")) {
634  if (strcasecmp(v->value, "application/x-www-form-urlencoded")) {
635  return NULL;
636  }
637  break;
638  }
639  }
640 
641  for (v = headers; v; v = v->next) {
642  if (!strcasecmp(v->name, "Content-Length")) {
643  content_length = atoi(v->value);
644  break;
645  }
646  }
647 
648  if (content_length <= 0) {
649  return NULL;
650  }
651 
652  if (content_length > MAX_POST_CONTENT - 1) {
653  ast_log(LOG_WARNING, "Excessively long HTTP content. %d is greater than our max of %d\n",
654  content_length, MAX_POST_CONTENT);
655  ast_http_send(ser, AST_HTTP_POST, 413, "Request Entity Too Large", NULL, NULL, 0, 0);
656  return NULL;
657  }
658 
659  buf = ast_malloc(content_length + 1);
660  if (!buf) {
661  return NULL;
662  }
663 
664  res = fread(buf, 1, content_length, ser->f);
665  if (res < content_length) {
666  /* Error, distinguishable by ferror() or feof(), but neither
667  * is good. */
668  goto done;
669  }
670  buf[content_length] = '\0';
671 
672  while ((val = strsep(&buf, "&"))) {
673  var = strsep(&val, "=");
674  if (val) {
675  http_decode(val);
676  } else {
677  val = "";
678  }
679  http_decode(var);
680  if ((v = ast_variable_new(var, val, ""))) {
681  if (post_vars) {
682  prev->next = v;
683  } else {
684  post_vars = v;
685  }
686  prev = v;
687  }
688  }
689 
690 done:
691  ast_free(buf);
692  return post_vars;
693 }
char * strsep(char **str, const char *delims)
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:144
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
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.
Definition: http.c:393
const char * value
Definition: config.h:79
const char * name
Definition: config.h:77
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
#define MAX_POST_CONTENT
Definition: http.c:618
static void http_decode(char *s)
Definition: http.c:605
struct ast_variable * next
Definition: config.h:82
#define ast_malloc(a)
Definition: astmm.h:91
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
int ast_http_init ( void  )

Provided by http.c

Definition at line 1319 of file http.c.

References __ast_http_load(), ARRAY_LEN, ast_cli_register_multiple(), ast_http_uri_link(), ast_register_atexit(), cli_http, http_shutdown(), staticuri, and statusuri.

Referenced by main().

1320 {
1325 
1326  return __ast_http_load(0);
1327 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_cli_entry cli_http[]
Definition: http.c:1292
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Definition: http.c:544
static struct ast_http_uri staticuri
Definition: http.c:381
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static int __ast_http_load(int reload)
Definition: http.c:1084
static void http_shutdown(void)
Definition: http.c:1296
static struct ast_http_uri statusuri
Definition: http.c:372
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
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 180 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().

181 {
182  uint32_t mngid = 0;
183  struct ast_variable *v, *cookies;
184 
185  cookies = ast_http_get_cookies(headers);
186  for (v = cookies; v; v = v->next) {
187  if (!strcasecmp(v->name, "mansession_id")) {
188  sscanf(v->value, "%30x", &mngid);
189  break;
190  }
191  }
192  ast_variables_destroy(cookies);
193  return mngid;
194 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
const char * value
Definition: config.h:79
const char * name
Definition: config.h:77
struct ast_variable * next
Definition: config.h:82
struct ast_variable * ast_http_get_cookies(struct ast_variable *headers)
Get cookie from Request headers.
Definition: http.c:862
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 196 of file http.c.

References ast_copy_string().

197 {
198  if (buf) {
199  ast_copy_string(buf, prefix, len);
200  }
201 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char prefix[MAX_PREFIX]
Definition: http.c:107
int ast_http_reload ( void  )

Provided by http.c

Definition at line 1287 of file http.c.

References __ast_http_load().

1288 {
1289  return __ast_http_load(1);
1290 }
static int __ast_http_load(int reload)
Definition: http.c:1084
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 393 of file http.c.

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

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

397 {
398  struct timeval now = ast_tvnow();
399  struct ast_tm tm;
400  char timebuf[80];
401  int content_length = 0;
402 
403  if (!ser || 0 == ser->f) {
404  return;
405  }
406 
407  ast_strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", ast_localtime(&now, &tm, "GMT"));
408 
409  /* calc content length */
410  if (out) {
411  content_length += ast_str_strlen(out);
412  }
413 
414  if (fd) {
415  content_length += lseek(fd, 0, SEEK_END);
416  lseek(fd, 0, SEEK_SET);
417  }
418 
419  /* send http header */
420  fprintf(ser->f, "HTTP/1.1 %d %s\r\n"
421  "Server: Asterisk/%s\r\n"
422  "Date: %s\r\n"
423  "Connection: close\r\n"
424  "%s"
425  "Content-Length: %d\r\n"
426  "%s"
427  "\r\n",
428  status_code, status_title ? status_title : "OK",
429  ast_get_version(),
430  timebuf,
431  static_content ? "" : "Cache-Control: no-cache, no-store\r\n",
432  content_length,
433  http_header ? ast_str_buffer(http_header) : ""
434  );
435 
436  /* send content */
437  if (method != AST_HTTP_HEAD || status_code >= 400) {
438  if (out && ast_str_strlen(out)) {
439  if (fwrite(ast_str_buffer(out), ast_str_strlen(out), 1, ser->f) != 1) {
440  ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
441  }
442  }
443 
444  if (fd) {
445  char buf[256];
446  int len;
447  while ((len = read(fd, buf, sizeof(buf))) > 0) {
448  if (fwrite(buf, len, 1, ser->f) != 1) {
449  ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
450  break;
451  }
452  }
453  }
454  }
455 
456  if (http_header) {
457  ast_free(http_header);
458  }
459  if (out) {
460  ast_free(out);
461  }
462 
464  return;
465 }
const char * ast_get_version(void)
Retrieve the Asterisk version string.
Definition: version.c:14
#define LOG_WARNING
Definition: logger.h:144
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define LOG_ERROR
Definition: logger.h:155
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
#define ast_free(a)
Definition: astmm.h:97
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
Closes a tcptls session instance&#39;s file and/or file descriptor. The tcptls_session will be set to NUL...
Definition: tcptls.c:1033
int ast_http_uri_link ( struct ast_http_uri urih)

Link the new uri into the list.

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 544 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(), and ast_http_init().

545 {
546  struct ast_http_uri *uri;
547  int len = strlen(urih->uri);
548 
550 
551  if ( AST_RWLIST_EMPTY(&uris) || strlen(AST_RWLIST_FIRST(&uris)->uri) <= len ) {
554  return 0;
555  }
556 
557  AST_RWLIST_TRAVERSE(&uris, uri, entry) {
558  if (AST_RWLIST_NEXT(uri, entry) &&
559  strlen(AST_RWLIST_NEXT(uri, entry)->uri) <= len) {
560  AST_RWLIST_INSERT_AFTER(&uris, uri, urih, entry);
562 
563  return 0;
564  }
565  }
566 
568 
570 
571  return 0;
572 }
#define AST_RWLIST_NEXT
Definition: linkedlists.h:440
#define AST_RWLIST_INSERT_AFTER
Definition: linkedlists.h:687
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct ast_http_uri::@175 entry
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:703
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
Definition of a URI handler.
Definition: http.h:91
Definition: http.c:104
const char * uri
Definition: http.h:94
#define AST_RWLIST_FIRST
Definition: linkedlists.h:422
void ast_http_uri_unlink ( struct ast_http_uri urih)

Unregister a URI handler.

Definition at line 574 of file http.c.

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

Referenced by __init_manager(), and http_shutdown().

575 {
577  AST_RWLIST_REMOVE(&uris, urih, entry);
579 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct ast_http_uri::@175 entry
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
Definition: http.c:104
void ast_http_uri_unlink_all_with_key ( const char *  key)

Unregister all handlers with matching key.

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

582 {
583  struct ast_http_uri *urih;
586  if (!strcmp(urih->key, key)) {
588  if (urih->dmallocd) {
589  ast_free(urih->data);
590  }
591  if (urih->mallocd) {
592  ast_free(urih);
593  }
594  }
595  }
598 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * key
Definition: http.h:104
struct ast_http_uri::@175 entry
unsigned int mallocd
Definition: http.h:98
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
#define ast_free(a)
Definition: astmm.h:97
Definition of a URI handler.
Definition: http.h:91
unsigned int dmallocd
Definition: http.h:100
Definition: http.c:104
void * data
Definition: http.h:102
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
static char* handle_show_http ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1229 of file http.c.

References ast_cli_args::argc, ast_cli(), ast_inet_ntoa(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_sockaddr_to_sin, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_http_uri::description, http_uri_redirect::dest, ast_tls_config::enabled, http_uri_redirect::entry, ast_cli_args::fd, ast_http_uri::has_subtree, http_tls_cfg, ast_tcptls_session_args::old_address, http_uri_redirect::target, ast_http_uri::uri, and ast_cli_entry::usage.

1230 {
1231  struct ast_http_uri *urih;
1232  struct http_uri_redirect *redirect;
1233  struct sockaddr_in tmp;
1234 
1235  switch (cmd) {
1236  case CLI_INIT:
1237  e->command = "http show status";
1238  e->usage =
1239  "Usage: http show status\n"
1240  " Lists status of internal HTTP engine\n";
1241  return NULL;
1242  case CLI_GENERATE:
1243  return NULL;
1244  }
1245 
1246  if (a->argc != 3) {
1247  return CLI_SHOWUSAGE;
1248  }
1249  ast_cli(a->fd, "HTTP Server Status:\n");
1250  ast_cli(a->fd, "Prefix: %s\n", prefix);
1252  if (!tmp.sin_family) {
1253  ast_cli(a->fd, "Server Disabled\n\n");
1254  } else {
1255  ast_cli(a->fd, "Server Enabled and Bound to %s:%d\n\n",
1256  ast_inet_ntoa(tmp.sin_addr), ntohs(tmp.sin_port));
1257  if (http_tls_cfg.enabled) {
1259  ast_cli(a->fd, "HTTPS Server Enabled and Bound to %s:%d\n\n",
1260  ast_inet_ntoa(tmp.sin_addr),
1261  ntohs(tmp.sin_port));
1262  }
1263  }
1264 
1265  ast_cli(a->fd, "Enabled URI's:\n");
1267  if (AST_RWLIST_EMPTY(&uris)) {
1268  ast_cli(a->fd, "None.\n");
1269  } else {
1270  AST_RWLIST_TRAVERSE(&uris, urih, entry)
1271  ast_cli(a->fd, "%s/%s%s => %s\n", prefix, urih->uri, (urih->has_subtree ? "/..." : "" ), urih->description);
1272  }
1274 
1275  ast_cli(a->fd, "\nEnabled Redirects:\n");
1277  AST_RWLIST_TRAVERSE(&uri_redirects, redirect, entry)
1278  ast_cli(a->fd, " %s => %s\n", redirect->target, redirect->dest);
1279  if (AST_RWLIST_EMPTY(&uri_redirects)) {
1280  ast_cli(a->fd, " None.\n");
1281  }
1283 
1284  return CLI_SUCCESS;
1285 }
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
static struct ast_tls_config http_tls_cfg
Definition: http.c:77
static struct ast_tcptls_session_args http_desc
Definition: http.c:84
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
#define CLI_SHOWUSAGE
Definition: cli.h:44
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
char * command
Definition: cli.h:180
struct ast_sockaddr old_address
Definition: tcptls.h:125
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
Definition of a URI handler.
Definition: http.h:91
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
Definition: http.c:104
static struct ast_tcptls_session_args https_desc
Definition: http.c:94
static char prefix[MAX_PREFIX]
Definition: http.c:107
int enabled
Definition: tcptls.h:86
static int handle_uri ( struct ast_tcptls_session_instance ser,
char *  uri,
enum ast_http_method  method,
struct ast_variable headers 
)
static

Definition at line 695 of file http.c.

References ast_debug, ast_http_error(), ast_http_send(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_create(), ast_str_set(), ast_variable_new(), ast_variables_destroy(), ast_http_uri::callback, cleanup(), http_uri_redirect::dest, http_uri_redirect::entry, ast_http_uri::has_subtree, http_decode(), strsep(), http_uri_redirect::target, ast_http_uri::uri, and var.

Referenced by httpd_helper_thread().

697 {
698  char *c;
699  int res = -1;
700  char *params = uri;
701  struct ast_http_uri *urih = NULL;
702  int l;
703  struct ast_variable *get_vars = NULL, *v, *prev = NULL;
704  struct http_uri_redirect *redirect;
705 
706  ast_debug(2, "HTTP Request URI is %s \n", uri);
707 
708  strsep(&params, "?");
709  /* Extract arguments from the request and store them in variables. */
710  if (params) {
711  char *var, *val;
712 
713  while ((val = strsep(&params, "&"))) {
714  var = strsep(&val, "=");
715  if (val) {
716  http_decode(val);
717  } else {
718  val = "";
719  }
720  http_decode(var);
721  if ((v = ast_variable_new(var, val, ""))) {
722  if (get_vars) {
723  prev->next = v;
724  } else {
725  get_vars = v;
726  }
727  prev = v;
728  }
729  }
730  }
731  http_decode(uri);
732 
735  if (!strcasecmp(uri, redirect->target)) {
736  struct ast_str *http_header = ast_str_create(128);
737  ast_str_set(&http_header, 0, "Location: %s\r\n", redirect->dest);
738  ast_http_send(ser, method, 302, "Moved Temporarily", http_header, NULL, 0, 0);
739 
740  break;
741  }
742  }
744  if (redirect) {
745  goto cleanup;
746  }
747 
748  /* We want requests to start with the (optional) prefix and '/' */
749  l = strlen(prefix);
750  if (!strncasecmp(uri, prefix, l) && uri[l] == '/') {
751  uri += l + 1;
752  /* scan registered uris to see if we match one. */
754  AST_RWLIST_TRAVERSE(&uris, urih, entry) {
755  ast_debug(2, "match request [%s] with handler [%s] len %d\n", uri, urih->uri, l);
756  l = strlen(urih->uri);
757  c = uri + l; /* candidate */
758  if (strncasecmp(urih->uri, uri, l) /* no match */
759  || (*c && *c != '/')) { /* substring */
760  continue;
761  }
762  if (*c == '/') {
763  c++;
764  }
765  if (!*c || urih->has_subtree) {
766  uri = c;
767  break;
768  }
769  }
771  }
772  if (urih) {
773  res = urih->callback(ser, urih, uri, method, get_vars, headers);
774  } else {
775  ast_http_error(ser, 404, "Not Found", "The requested URL was not found on this server.");
776  }
777 
778 cleanup:
779  ast_variables_destroy(get_vars);
780  return res;
781 }
struct http_uri_redirect::@275 entry
char * strsep(char **str, const char *delims)
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: http.c:506
ast_http_callback callback
Definition: http.h:95
Definition: ast_expr2.c:325
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
char * dest
Definition: http.c:136
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
unsigned int has_subtree
Definition: http.h:96
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
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.
Definition: http.c:393
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
char target[0]
Definition: http.c:137
static void * cleanup(void *unused)
Definition: pbx_realtime.c:125
Definition of a URI handler.
Definition: http.h:91
static void http_decode(char *s)
Definition: http.c:605
Definition: http.c:104
const char * uri
Definition: http.h:94
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static char prefix[MAX_PREFIX]
Definition: http.c:107
static void http_decode ( char *  s)
static

Definition at line 605 of file http.c.

References ast_uri_decode().

Referenced by ast_http_get_post_vars(), and handle_uri().

606 {
607  char *t;
608 
609  for (t = s; *t; t++) {
610  if (*t == '+') {
611  *t = ' ';
612  }
613  }
614 
615  ast_uri_decode(s);
616 }
void ast_uri_decode(char *s)
Decode URI, URN, URL (overwrite string)
Definition: utils.c:484
static void http_shutdown ( void  )
static

Definition at line 1296 of file http.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_free, ast_http_uri_unlink(), AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tcptls_server_stop(), ast_tls_config::certfile, ast_tls_config::cipher, cli_http, ast_tls_config::enabled, http_uri_redirect::entry, http_tls_cfg, ast_tls_config::pvtfile, staticuri, and statusuri.

Referenced by ast_http_init().

1297 {
1298  struct http_uri_redirect *redirect;
1300 
1302  if (http_tls_cfg.enabled) {
1304  }
1308 
1311 
1313  while ((redirect = AST_RWLIST_REMOVE_HEAD(&uri_redirects, entry))) {
1314  ast_free(redirect);
1315  }
1317 }
struct http_uri_redirect::@275 entry
char * pvtfile
Definition: tcptls.h:88
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
static struct ast_cli_entry cli_http[]
Definition: http.c:1292
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static struct ast_http_uri staticuri
Definition: http.c:381
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Definition: http.c:574
static struct ast_tls_config http_tls_cfg
Definition: http.c:77
static struct ast_tcptls_session_args http_desc
Definition: http.c:84
#define ast_free(a)
Definition: astmm.h:97
static struct ast_http_uri statusuri
Definition: http.c:372
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:829
char * certfile
Definition: tcptls.h:87
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition: tcptls.c:1058
static struct ast_tcptls_session_args https_desc
Definition: http.c:94
char * cipher
Definition: tcptls.h:89
int enabled
Definition: tcptls.h:86
static void * httpd_helper_thread ( void *  arg)
static

Definition at line 878 of file http.c.

References ao2_ref, ast_atomic_fetchadd_int(), ast_http_error(), AST_HTTP_GET, AST_HTTP_HEAD, AST_HTTP_POST, AST_HTTP_PUT, AST_HTTP_UNKNOWN, ast_log(), ast_skip_blanks(), ast_skip_nonblanks(), ast_strlen_zero(), ast_tcptls_close_session_file(), ast_tcptls_stream_set_exclusive_input(), ast_tcptls_stream_set_timeout_inactivity(), ast_trim_blanks(), ast_variable_new(), ast_variables_destroy(), errno, ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, handle_uri(), LOG_WARNING, MAX_HTTP_REQUEST_HEADERS, name, ast_variable::next, ast_tcptls_session_instance::stream_cookie, strsep(), and value.

879 {
880  char buf[4096];
881  char header_line[4096];
882  struct ast_tcptls_session_instance *ser = data;
883  struct ast_variable *headers = NULL;
884  struct ast_variable *tail = headers;
885  char *uri, *method;
886  enum ast_http_method http_method = AST_HTTP_UNKNOWN;
887  int remaining_headers;
888  int flags;
889  struct protoent *p;
890 
892  goto done;
893  }
894 
895  /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
896  * This is necessary to prevent delays (caused by buffering) as we
897  * write to the socket in bits and pieces. */
898  p = getprotobyname("tcp");
899  if (p) {
900  int arg = 1;
901  if( setsockopt(ser->fd, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
902  ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on HTTP connection: %s\n", strerror(errno));
903  ast_log(LOG_WARNING, "Some HTTP requests may be slow to respond.\n");
904  }
905  } else {
906  ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on HTTP connection, getprotobyname(\"tcp\") failed\n");
907  ast_log(LOG_WARNING, "Some HTTP requests may be slow to respond.\n");
908  }
909 
910  /* make sure socket is non-blocking */
911  flags = fcntl(ser->fd, F_GETFL);
912  flags |= O_NONBLOCK;
913  fcntl(ser->fd, F_SETFL, flags);
914 
915  /* We can let the stream wait for data to arrive. */
917 
919 
920  if (!fgets(buf, sizeof(buf), ser->f) || feof(ser->f)) {
921  goto done;
922  }
923 
924  /* Get method */
925  method = ast_skip_blanks(buf);
926  uri = ast_skip_nonblanks(method);
927  if (*uri) {
928  *uri++ = '\0';
929  }
930 
931  if (!strcasecmp(method,"GET")) {
932  http_method = AST_HTTP_GET;
933  } else if (!strcasecmp(method,"POST")) {
934  http_method = AST_HTTP_POST;
935  } else if (!strcasecmp(method,"HEAD")) {
936  http_method = AST_HTTP_HEAD;
937  } else if (!strcasecmp(method,"PUT")) {
938  http_method = AST_HTTP_PUT;
939  }
940 
941  uri = ast_skip_blanks(uri); /* Skip white space */
942 
943  if (*uri) { /* terminate at the first blank */
944  char *c = ast_skip_nonblanks(uri);
945 
946  if (*c) {
947  *c = '\0';
948  }
949  } else {
950  ast_http_error(ser, 400, "Bad Request", "Invalid Request");
951  goto done;
952  }
953 
954  /* process "Request Headers" lines */
955  remaining_headers = MAX_HTTP_REQUEST_HEADERS;
956  for (;;) {
957  char *name;
958  char *value;
959 
960  if (!fgets(header_line, sizeof(header_line), ser->f) || feof(ser->f)) {
961  ast_http_error(ser, 400, "Bad Request", "Timeout");
962  goto done;
963  }
964 
965  /* Trim trailing characters */
966  ast_trim_blanks(header_line);
967  if (ast_strlen_zero(header_line)) {
968  /* A blank line ends the request header section. */
969  break;
970  }
971 
972  value = header_line;
973  name = strsep(&value, ":");
974  if (!value) {
975  continue;
976  }
977 
978  value = ast_skip_blanks(value);
979  if (ast_strlen_zero(value) || ast_strlen_zero(name)) {
980  continue;
981  }
982 
983  ast_trim_blanks(name);
984 
985  if (!remaining_headers--) {
986  /* Too many headers. */
987  ast_http_error(ser, 413, "Request Entity Too Large", "Too many headers");
988  goto done;
989  }
990  if (!headers) {
991  headers = ast_variable_new(name, value, __FILE__);
992  tail = headers;
993  } else {
994  tail->next = ast_variable_new(name, value, __FILE__);
995  tail = tail->next;
996  }
997  if (!tail) {
998  /*
999  * Variable allocation failure.
1000  * Try to make some room.
1001  */
1002  ast_variables_destroy(headers);
1003  headers = NULL;
1004 
1005  ast_http_error(ser, 500, "Server Error", "Out of memory");
1006  goto done;
1007  }
1008  }
1009 
1010  handle_uri(ser, uri, http_method, headers);
1011 
1012 done:
1014 
1015  /* clean up all the header information */
1016  ast_variables_destroy(headers);
1017 
1018  if (ser->f) {
1020  }
1021  ao2_ref(ser, -1);
1022  ser = NULL;
1023  return NULL;
1024 }
char * strsep(char **str, const char *delims)
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: http.c:506
#define LOG_WARNING
Definition: logger.h:144
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
int value
Definition: syslog.c:39
char * ast_skip_nonblanks(const char *str)
Gets a pointer to first whitespace character in a string.
Definition: strings.h:136
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
void ast_tcptls_stream_set_exclusive_input(struct ast_tcptls_stream *stream, int exclusive_input)
Set the TCP/TLS stream I/O if it can exclusively depend upon the set timeouts.
Definition: tcptls.c:107
struct ast_tcptls_stream * stream_cookie
Definition: tcptls.h:218
static int session_limit
Definition: http.c:73
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:97
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:122
void ast_tcptls_stream_set_timeout_inactivity(struct ast_tcptls_stream *stream, int timeout)
Set the TCP/TLS stream inactivity timeout timer.
Definition: tcptls.c:91
int errno
static const char name[]
static int session_inactivity
Definition: http.c:74
static int session_count
Definition: http.c:75
static int handle_uri(struct ast_tcptls_session_instance *ser, char *uri, enum ast_http_method method, struct ast_variable *headers)
Definition: http.c:695
void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
Closes a tcptls session instance&#39;s file and/or file descriptor. The tcptls_session will be set to NUL...
Definition: tcptls.c:1033
#define MAX_HTTP_REQUEST_HEADERS
Definition: http.c:876
struct ast_variable * next
Definition: config.h:82
ast_http_method
HTTP Request methods known by Asterisk.
Definition: http.h:56
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static int httpstatus_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_vars,
struct ast_variable headers 
)
static

Definition at line 323 of file http.c.

References ast_http_error(), AST_HTTP_GET, ast_http_get_cookies(), AST_HTTP_HEAD, ast_http_send(), ast_sockaddr_stringify_addr(), ast_sockaddr_stringify_port(), ast_str_append(), ast_str_create(), ast_variables_destroy(), ast_tls_config::enabled, http_tls_cfg, ast_variable::name, ast_variable::next, ast_tcptls_session_args::old_address, and ast_variable::value.

327 {
328  struct ast_str *out;
329  struct ast_variable *v, *cookies = NULL;
330 
331  if (method != AST_HTTP_GET && method != AST_HTTP_HEAD) {
332  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
333  return -1;
334  }
335 
336  if ( (out = ast_str_create(512)) == NULL) {
337  return -1;
338  }
339 
340  ast_str_append(&out, 0,
341  "<title>Asterisk HTTP Status</title>\r\n"
342  "<body bgcolor=\"#ffffff\">\r\n"
343  "<table bgcolor=\"#f1f1f1\" align=\"center\"><tr><td bgcolor=\"#e0e0ff\" colspan=\"2\" width=\"500\">\r\n"
344  "<h2>&nbsp;&nbsp;Asterisk&trade; HTTP Status</h2></td></tr>\r\n");
345 
346  ast_str_append(&out, 0, "<tr><td><i>Prefix</i></td><td><b>%s</b></td></tr>\r\n", prefix);
347  ast_str_append(&out, 0, "<tr><td><i>Bind Address</i></td><td><b>%s</b></td></tr>\r\n",
349  ast_str_append(&out, 0, "<tr><td><i>Bind Port</i></td><td><b>%s</b></td></tr>\r\n",
351  if (http_tls_cfg.enabled) {
352  ast_str_append(&out, 0, "<tr><td><i>SSL Bind Port</i></td><td><b>%s</b></td></tr>\r\n",
354  }
355  ast_str_append(&out, 0, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
356  for (v = get_vars; v; v = v->next) {
357  ast_str_append(&out, 0, "<tr><td><i>Submitted GET Variable '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
358  }
359  ast_str_append(&out, 0, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
360 
361  cookies = ast_http_get_cookies(headers);
362  for (v = cookies; v; v = v->next) {
363  ast_str_append(&out, 0, "<tr><td><i>Cookie '%s'</i></td><td>%s</td></tr>\r\n", v->name, v->value);
364  }
365  ast_variables_destroy(cookies);
366 
367  ast_str_append(&out, 0, "</table><center><font size=\"-1\"><i>Asterisk and Digium are registered trademarks of Digium, Inc.</i></font></center></body>\r\n");
368  ast_http_send(ser, method, 200, NULL, NULL, out, 0, 0);
369  return 0;
370 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:240
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: http.c:506
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
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.
Definition: http.c:393
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Definition: netsock2.h:302
const char * value
Definition: config.h:79
static struct ast_tls_config http_tls_cfg
Definition: http.c:77
const char * name
Definition: config.h:77
static struct ast_tcptls_session_args http_desc
Definition: http.c:84
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
struct ast_sockaddr old_address
Definition: tcptls.h:125
struct ast_variable * next
Definition: config.h:82
static struct ast_tcptls_session_args https_desc
Definition: http.c:94
struct ast_variable * ast_http_get_cookies(struct ast_variable *headers)
Get cookie from Request headers.
Definition: http.c:862
static char prefix[MAX_PREFIX]
Definition: http.c:107
int enabled
Definition: tcptls.h:86
static struct ast_variable* parse_cookies ( const char *  cookies)
static

replacement read/write functions for SSL support. We use wrappers rather than SSL_read/SSL_write directly so we can put in some debugging.

Definition at line 828 of file http.c.

References ast_debug, ast_strdupa, ast_strip(), ast_strip_quoted(), ast_strlen_zero(), ast_variable_new(), name, parse(), strsep(), and var.

Referenced by ast_http_get_cookies().

829 {
830  char *parse = ast_strdupa(cookies);
831  char *cur;
832  struct ast_variable *vars = NULL, *var;
833 
834  while ((cur = strsep(&parse, ";"))) {
835  char *name, *val;
836 
837  name = val = cur;
838  strsep(&val, "=");
839 
840  if (ast_strlen_zero(name) || ast_strlen_zero(val)) {
841  continue;
842  }
843 
844  name = ast_strip(name);
845  val = ast_strip_quoted(val, "\"", "\"");
846 
847  if (ast_strlen_zero(name) || ast_strlen_zero(val)) {
848  continue;
849  }
850 
851  ast_debug(1, "HTTP Cookie, Name: '%s' Value: '%s'\n", name, val);
852 
853  var = ast_variable_new(name, val, __FILE__);
854  var->next = vars;
855  vars = var;
856  }
857 
858  return vars;
859 }
char * strsep(char **str, const char *delims)
Definition: ast_expr2.c:325
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: utils.c:1431
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
static const char name[]
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static int static_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_vars,
struct ast_variable headers 
)
static

Definition at line 203 of file http.c.

References ast_alloca, ast_config_AST_DATA_DIR, ast_http_error(), ast_http_ftype2mtype(), AST_HTTP_GET, AST_HTTP_HEAD, ast_http_manid_from_vars(), ast_http_send(), ast_localtime(), ast_str_create(), ast_str_set(), ast_strftime(), ast_strlen_zero(), astman_is_authed(), len(), mtype, ast_variable::name, ast_variable::next, S_OR, and ast_variable::value.

207 {
208  char *path;
209  const char *ftype;
210  const char *mtype;
211  char wkspace[80];
212  struct stat st;
213  int len;
214  int fd;
215  struct ast_str *http_header;
216  struct timeval tv;
217  struct ast_tm tm;
218  char timebuf[80], etag[23];
219  struct ast_variable *v;
220  int not_modified = 0;
221 
222  if (method != AST_HTTP_GET && method != AST_HTTP_HEAD) {
223  ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
224  return -1;
225  }
226 
227  /* Yuck. I'm not really sold on this, but if you don't deliver static content it makes your configuration
228  substantially more challenging, but this seems like a rather irritating feature creep on Asterisk. */
229  if (!enablestatic || ast_strlen_zero(uri)) {
230  goto out403;
231  }
232 
233  /* Disallow any funny filenames at all (checking first character only??) */
234  if ((uri[0] < 33) || strchr("./|~@#$%^&*() \t", uri[0])) {
235  goto out403;
236  }
237 
238  if (strstr(uri, "/..")) {
239  goto out403;
240  }
241 
242  if ((ftype = strrchr(uri, '.'))) {
243  ftype++;
244  }
245 
246  if (!(mtype = ast_http_ftype2mtype(ftype))) {
247  snprintf(wkspace, sizeof(wkspace), "text/%s", S_OR(ftype, "plain"));
248  mtype = wkspace;
249  }
250 
251  /* Cap maximum length */
252  if ((len = strlen(uri) + strlen(ast_config_AST_DATA_DIR) + strlen("/static-http/") + 5) > 1024) {
253  goto out403;
254  }
255 
256  path = ast_alloca(len);
257  sprintf(path, "%s/static-http/%s", ast_config_AST_DATA_DIR, uri);
258  if (stat(path, &st)) {
259  goto out404;
260  }
261 
262  if (S_ISDIR(st.st_mode)) {
263  goto out404;
264  }
265 
266  if (strstr(path, "/private/") && !astman_is_authed(ast_http_manid_from_vars(headers))) {
267  goto out403;
268  }
269 
270  fd = open(path, O_RDONLY);
271  if (fd < 0) {
272  goto out403;
273  }
274 
275  /* make "Etag:" http header value */
276  snprintf(etag, sizeof(etag), "\"%ld\"", (long)st.st_mtime);
277 
278  /* make "Last-Modified:" http header value */
279  tv.tv_sec = st.st_mtime;
280  tv.tv_usec = 0;
281  ast_strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", ast_localtime(&tv, &tm, "GMT"));
282 
283  /* check received "If-None-Match" request header and Etag value for file */
284  for (v = headers; v; v = v->next) {
285  if (!strcasecmp(v->name, "If-None-Match")) {
286  if (!strcasecmp(v->value, etag)) {
287  not_modified = 1;
288  }
289  break;
290  }
291  }
292 
293  if ( (http_header = ast_str_create(255)) == NULL) {
294  close(fd);
295  return -1;
296  }
297 
298  ast_str_set(&http_header, 0, "Content-type: %s\r\n"
299  "ETag: %s\r\n"
300  "Last-Modified: %s\r\n",
301  mtype,
302  etag,
303  timebuf);
304 
305  /* ast_http_send() frees http_header, so we don't need to do it before returning */
306  if (not_modified) {
307  ast_http_send(ser, method, 304, "Not Modified", http_header, NULL, 0, 1);
308  } else {
309  ast_http_send(ser, method, 200, NULL, http_header, NULL, fd, 1); /* static content flag is set */
310  }
311  close(fd);
312  return 0;
313 
314 out404:
315  ast_http_error(ser, 404, "Not Found", "The requested URL was not found on this server.");
316  return -1;
317 
318 out403:
319  ast_http_error(ser, 403, "Access Denied", "You do not have permission to access the requested URL.");
320  return -1;
321 }
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: http.c:506
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
const char * ast_http_ftype2mtype(const char *ftype) attribute_pure
Return mime type based on extension.
Definition: http.c:166
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
uint32_t ast_http_manid_from_vars(struct ast_variable *headers) attribute_pure
Return manager id, if exist, from request headers.
Definition: http.c:180
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.
Definition: http.c:393
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
int astman_is_authed(uint32_t ident)
Determinie if a manager session ident is authenticated.
Definition: manager.c:5617
const char * value
Definition: config.h:79
static int enablestatic
Definition: http.c:108
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const char * name
Definition: config.h:77
const char * ast_config_AST_DATA_DIR
Definition: asterisk.c:262
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
const char * mtype
Definition: http.c:113
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct timeval tv
struct ast_variable * next
Definition: config.h:82

Variable Documentation

struct ast_cfhttp_methods_text ast_http_methods_text[]
static

Referenced by ast_get_http_method().

struct ast_cli_entry cli_http[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_show_http, "Display HTTP server status"),
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * handle_show_http(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: http.c:1229

Definition at line 1292 of file http.c.

Referenced by ast_http_init(), and http_shutdown().

int enablestatic
static

Definition at line 108 of file http.c.

struct ast_tcptls_session_args http_desc
static

we have up to two accepting threads, one for http, one for https

Definition at line 84 of file http.c.

struct ast_tls_config http_tls_cfg
static

Definition at line 77 of file http.c.

Referenced by __ast_http_load(), handle_show_http(), http_shutdown(), and httpstatus_callback().

struct ast_tcptls_session_args https_desc
static

Definition at line 94 of file http.c.

struct { ... } mimetypes[]

Limit the kinds of files we're willing to serve up.

Referenced by ast_http_ftype2mtype().

const char* mtype

Definition at line 113 of file http.c.

Referenced by static_callback().

int session_count = 0
static

Definition at line 75 of file http.c.

Referenced by cli_fax_show_sessions().

int session_inactivity = DEFAULT_SESSION_INACTIVITY
static

Definition at line 74 of file http.c.

int session_limit = DEFAULT_SESSION_LIMIT
static

Definition at line 73 of file http.c.

struct ast_http_uri staticuri
static

Definition at line 381 of file http.c.

Referenced by ast_http_init(), and http_shutdown().

struct ast_http_uri statusuri
static

Definition at line 372 of file http.c.

Referenced by ast_http_init(), and http_shutdown().

struct uri_redirects uri_redirects = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
struct uris uris = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static

list of supported handlers