Asterisk - The Open Source Telephony Project GIT-master-5467495
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions | Variables
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 <signal.h>
#include <fcntl.h>
#include "asterisk/paths.h"
#include "asterisk/acl.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/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/netsock2.h"
#include "asterisk/json.h"
Include dependency graph for http.c:

Go to the source code of this file.

Data Structures

struct  ast_cfhttp_methods_text
 
struct  ast_http_server
 
struct  http_restriction
 Per-path ACL restriction. More...
 
struct  http_restriction_list
 
struct  http_uri_redirect
 
struct  http_worker_private_data
 
struct  restrictions
 
struct  uri_redirects
 
struct  uris
 

Macros

#define BASIC_LEN   6
 
#define BASIC_PREFIX   "Basic "
 
#define DEFAULT_PORT   8088
 
#define DEFAULT_RESPONSE_HEADER_LENGTH   512
 
#define DEFAULT_SESSION_INACTIVITY   30000
 
#define DEFAULT_SESSION_KEEP_ALIVE   15000
 
#define DEFAULT_SESSION_LIMIT   100
 
#define DEFAULT_TLS_PORT   8089
 
#define HTTP_SERVER_BUCKETS   5
 Number of HTTP server buckets.
 
#define INITIAL_RESPONSE_BODY_BUFFER   1024
 
#define MAX_CONTENT_LENGTH   40960
 
#define MAX_HTTP_LINE_LENGTH   4096
 
#define MAX_HTTP_REQUEST_HEADERS   100
 
#define MAX_PREFIX   80
 
#define MAX_SERVER_NAME_LENGTH   128
 
#define MIN_INITIAL_REQUEST_TIMEOUT   10000
 

Enumerations

enum  http_private_flags { HTTP_FLAG_HAS_BODY = (1 << 0) , HTTP_FLAG_BODY_READ = (1 << 1) , HTTP_FLAG_CLOSE_ON_COMPLETION = (1 << 2) }
 

Functions

static int __ast_http_load (int reload)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
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.
 
 AO2_STRING_FIELD_CMP_FN (ast_http_server, address)
 
 AO2_STRING_FIELD_HASH_FN (ast_http_server, address)
 
const char * ast_get_http_method (enum ast_http_method method)
 Return http method name string.
 
enum ast_http_method ast_get_http_method_from_string (const char *method)
 Return http method from 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.
 
int ast_http_body_discard (struct ast_tcptls_session_instance *ser)
 Read and discard any unread HTTP request body.
 
void ast_http_body_read_status (struct ast_tcptls_session_instance *ser, int read_success)
 Update the body read success status.
 
struct ast_variableast_http_create_basic_auth_header (const char *userid, const char *password)
 Create an HTTP authorization header.
 
void ast_http_create_response (struct ast_tcptls_session_instance *ser, int status_code, const char *status_title, struct ast_str *http_header_data, const char *text)
 Creates and sends a formatted http response message.
 
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.
 
const char * ast_http_ftype2mtype (const char *ftype)
 Return mime type based on extension.
 
struct ast_http_authast_http_get_auth (struct ast_variable *headers)
 Get HTTP authentication information from headers.
 
static char * ast_http_get_contents (int *return_length, struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
 Returns the contents (body) of the HTTP request.
 
struct ast_variableast_http_get_cookies (struct ast_variable *headers)
 Get cookie from Request headers.
 
struct ast_jsonast_http_get_json (struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
 Get JSON from client Request Entity-Body, if content type is application/json.
 
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.
 
int ast_http_header_match (const char *name, const char *expected_name, const char *value, const char *expected_value)
 Check if the header and value match (case insensitive) their associated expected values.
 
int ast_http_header_match_in (const char *name, const char *expected_name, const char *value, const char *expected_value)
 Check if the header name matches the expected header name. If so, then check to see if the value can be located in the expected value.
 
int ast_http_header_parse (char *buf, char **name, char **value)
 Parse a header into the given name/value strings.
 
uint32_t ast_http_manid_from_vars (struct ast_variable *headers)
 Return manager id, if exist, from request headers.
 
struct ast_variableast_http_parse_post_form (char *buf, int content_length, const char *content_type)
 Get post variables from an application/x-www-form-urlencoded buffer.
 
void ast_http_prefix (char *buf, int len)
 Return the current prefix.
 
void ast_http_request_close_on_completion (struct ast_tcptls_session_instance *ser)
 Request the HTTP connection be closed after this HTTP request.
 
int ast_http_response_status_line (const char *buf, const char *version, int code)
 Parse the http response status line.
 
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, int fd, unsigned int static_content)
 Generic function for sending HTTP/1.1 response.
 
int ast_http_uri_link (struct ast_http_uri *urih)
 Link the new uri into the list.
 
void ast_http_uri_unlink (struct ast_http_uri *urih)
 Unregister a URI handler.
 
void ast_http_uri_unlink_all_with_key (const char *key)
 Unregister all handlers with matching key.
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct ast_http_authauth_create (const char *userid, const char *password)
 
static int check_restriction_acl (struct ast_tcptls_session_instance *ser, const char *uri)
 Check if a URI path is allowed or denied by acl.
 
static int chunked_atoh (const char *s, int len)
 
static int get_content_length (struct ast_variable *headers)
 Returns the value of the Content-Length header.
 
static char * get_content_type (struct ast_variable *headers)
 Retrieves the content type specified in the "Content-Type" header.
 
static const char * get_header (struct ast_variable *headers, const char *field_name)
 Retrieves the header with the given field name.
 
static const char * get_transfer_encoding (struct ast_variable *headers)
 Returns the value of the Transfer-Encoding header.
 
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 int http_body_check_chunk_sync (struct ast_tcptls_session_instance *ser)
 
static int http_body_discard_chunk_trailer_headers (struct ast_tcptls_session_instance *ser)
 
static int http_body_discard_contents (struct ast_tcptls_session_instance *ser, int length, const char *what_getting)
 
static int http_body_get_chunk_length (struct ast_tcptls_session_instance *ser)
 
static int http_body_read_contents (struct ast_tcptls_session_instance *ser, char *buf, int length, const char *what_getting)
 
static int http_check_connection_close (struct ast_variable *headers)
 
static int http_request_headers_get (struct ast_tcptls_session_instance *ser, struct ast_variable **headers)
 
static void http_request_tracking_init (struct http_worker_private_data *request)
 
static int http_request_tracking_setup (struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
 
static struct ast_http_serverhttp_server_create (const char *name, const char *address, const struct ast_sockaddr *addr)
 
static void http_server_destroy (void *obj)
 
static void http_server_discard (struct ast_http_server *server)
 Discard/Drop a HTTP server.
 
static struct ast_http_serverhttp_server_get (const char *name, const char *host, uint32_t port, struct ast_http_server **replace_me)
 Retrieve, or create and start a HTTP server.
 
static struct ast_http_serverhttp_server_get_by_addr (const char *name, const struct ast_sockaddr *addr)
 Retrieve, or create a HTTP server object by sock address.
 
static struct ast_http_serverhttp_server_get_by_host (const char *name, const char *host, uint32_t port)
 Retrieve, or create a HTTP server object by host.
 
static int http_server_start (struct ast_http_server *server)
 
static void * httpd_helper_thread (void *arg)
 
static int httpd_process_request (struct ast_tcptls_session_instance *ser)
 
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 int load_module (void)
 
static struct ast_variableparse_cookies (const char *cookies)
 
static int reload_module (void)
 
static void remove_excess_lws (char *s)
 
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 void str_append_escaped (struct ast_str **str, const char *in)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Built-in HTTP Server" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
 
static const struct ast_cfhttp_methods_text ast_http_methods_text []
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_http []
 
struct ast_http_serverglobal_http_server = NULL
 
static char http_server_name [MAX_SERVER_NAME_LENGTH]
 
struct ao2_containerhttp_servers = NULL
 
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.
 
static char prefix [MAX_PREFIX]
 
static struct restrictions restrictions = AST_RWLIST_HEAD_INIT_VALUE
 
static int session_count = 0
 
static int session_inactivity = DEFAULT_SESSION_INACTIVITY
 
static int session_keep_alive = DEFAULT_SESSION_KEEP_ALIVE
 
static int session_limit = DEFAULT_SESSION_LIMIT
 
static struct ast_http_uri static_uri
 
static int static_uri_enabled
 
static struct ast_http_uri status_uri
 
static int status_uri_enabled
 
static struct uri_redirects uri_redirects = AST_RWLIST_HEAD_INIT_VALUE
 
static struct uris uris = AST_RWLIST_HEAD_INIT_VALUE
 

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

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

AMI over HTTP support - AMI over the http protocol

Definition in file http.c.

Macro Definition Documentation

◆ BASIC_LEN

#define BASIC_LEN   6

strlen(BASIC_PREFIX)

Definition at line 1675 of file http.c.

◆ BASIC_PREFIX

#define BASIC_PREFIX   "Basic "

Definition at line 1674 of file http.c.

◆ DEFAULT_PORT

#define DEFAULT_PORT   8088

Definition at line 70 of file http.c.

◆ DEFAULT_RESPONSE_HEADER_LENGTH

#define DEFAULT_RESPONSE_HEADER_LENGTH   512

Max size for the http response header

Definition at line 82 of file http.c.

◆ DEFAULT_SESSION_INACTIVITY

#define DEFAULT_SESSION_INACTIVITY   30000

(ms) Idle time waiting for data.

Definition at line 74 of file http.c.

◆ DEFAULT_SESSION_KEEP_ALIVE

#define DEFAULT_SESSION_KEEP_ALIVE   15000

(ms) Idle time between HTTP requests

Definition at line 78 of file http.c.

◆ DEFAULT_SESSION_LIMIT

#define DEFAULT_SESSION_LIMIT   100

Definition at line 72 of file http.c.

◆ DEFAULT_TLS_PORT

#define DEFAULT_TLS_PORT   8089

Definition at line 71 of file http.c.

◆ HTTP_SERVER_BUCKETS

#define HTTP_SERVER_BUCKETS   5

Number of HTTP server buckets.

Definition at line 2250 of file http.c.

◆ INITIAL_RESPONSE_BODY_BUFFER

#define INITIAL_RESPONSE_BODY_BUFFER   1024

Initial response body length.

Definition at line 93 of file http.c.

◆ MAX_CONTENT_LENGTH

#define MAX_CONTENT_LENGTH   40960

Maximum application/json or application/x-www-form-urlencoded body content length.

Definition at line 86 of file http.c.

◆ MAX_HTTP_LINE_LENGTH

#define MAX_HTTP_LINE_LENGTH   4096

Maximum line length for HTTP requests.

Definition at line 100 of file http.c.

◆ MAX_HTTP_REQUEST_HEADERS

#define MAX_HTTP_REQUEST_HEADERS   100

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

Definition at line 1886 of file http.c.

◆ MAX_PREFIX

#define MAX_PREFIX   80

Definition at line 69 of file http.c.

◆ MAX_SERVER_NAME_LENGTH

#define MAX_SERVER_NAME_LENGTH   128

Max size for the http server name

Definition at line 80 of file http.c.

◆ MIN_INITIAL_REQUEST_TIMEOUT

#define MIN_INITIAL_REQUEST_TIMEOUT   10000

(ms) Min timeout for initial HTTP request to start coming in.

Definition at line 76 of file http.c.

Enumeration Type Documentation

◆ http_private_flags

Enumerator
HTTP_FLAG_HAS_BODY 

TRUE if the HTTP request has a body.

HTTP_FLAG_BODY_READ 

TRUE if the HTTP request body has been read.

HTTP_FLAG_CLOSE_ON_COMPLETION 

TRUE if the HTTP request must close when completed.

Definition at line 505 of file http.c.

505 {
506 /*! TRUE if the HTTP request has a body. */
507 HTTP_FLAG_HAS_BODY = (1 << 0),
508 /*! TRUE if the HTTP request body has been read. */
509 HTTP_FLAG_BODY_READ = (1 << 1),
510 /*! TRUE if the HTTP request must close when completed. */
512};
@ HTTP_FLAG_BODY_READ
Definition http.c:509
@ HTTP_FLAG_CLOSE_ON_COMPLETION
Definition http.c:511
@ HTTP_FLAG_HAS_BODY
Definition http.c:507

Function Documentation

◆ __ast_http_load()

static int __ast_http_load ( int  reload)
static

Definition at line 2536 of file http.c.

2537{
2538 struct ast_config *cfg;
2539 struct ast_variable *v;
2540 int enabled = 0;
2541 int new_static_uri_enabled = 0;
2542 int new_status_uri_enabled = 0;
2543 char newprefix[MAX_PREFIX] = "";
2544 char server_name[MAX_SERVER_NAME_LENGTH];
2545 struct http_uri_redirect *redirect;
2546 struct http_restriction *restriction;
2549 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2550 uint32_t bindport = DEFAULT_PORT;
2551 int http_tls_was_enabled = 0;
2552 const char *bindaddr = NULL;
2553 const char *cat = NULL;
2554
2555 cfg = ast_config_load2("http.conf", "http", config_flags);
2556 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
2557 return 0;
2558 }
2559
2560 /* Even if the http.conf hasn't been updated, the TLS certs/keys may have been */
2561 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
2564 }
2565 return 0;
2566 }
2567
2568 http_tls_was_enabled = (reload && http_tls_cfg.enabled);
2569
2571
2574
2577
2580
2581 /* Apply modern intermediate settings according to the Mozilla OpSec team as of July 30th, 2015 but disable TLSv1 */
2583
2585 http_tls_cfg.cipher = ast_strdup("ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA");
2586
2588 while ((redirect = AST_RWLIST_REMOVE_HEAD(&uri_redirects, entry))) {
2589 ast_free(redirect);
2590 }
2592
2594
2598
2599 snprintf(server_name, sizeof(server_name), "Asterisk/%s", ast_get_version());
2600
2601 v = ast_variable_browse(cfg, "general");
2602 for (; v; v = v->next) {
2603 /* read tls config options while preventing unsupported options from being set */
2604 if (strcasecmp(v->name, "tlscafile")
2605 && strcasecmp(v->name, "tlscapath")
2606 && strcasecmp(v->name, "tlscadir")
2607 && strcasecmp(v->name, "tlsverifyclient")
2608 && strcasecmp(v->name, "tlsdontverifyserver")
2609 && strcasecmp(v->name, "tlsclientmethod")
2610 && strcasecmp(v->name, "sslclientmethod")
2612 continue;
2613 }
2614
2615 if (!strcasecmp(v->name, "servername")) {
2616 if (!ast_strlen_zero(v->value)) {
2617 ast_copy_string(server_name, v->value, sizeof(server_name));
2618 } else {
2619 server_name[0] = '\0';
2620 }
2621 } else if (!strcasecmp(v->name, "enabled")) {
2622 enabled = ast_true(v->value);
2623 } else if (!strcasecmp(v->name, "enablestatic") || !strcasecmp(v->name, "enable_static")) {
2624 new_static_uri_enabled = ast_true(v->value);
2625 } else if (!strcasecmp(v->name, "enable_status")) {
2626 new_status_uri_enabled = ast_true(v->value);
2627 } else if (!strcasecmp(v->name, "bindport")) {
2629 &bindport, DEFAULT_PORT, 0, 65535)) {
2630 ast_log(LOG_WARNING, "Invalid port %s specified. Using default port %" PRId32 "\n",
2631 v->value, DEFAULT_PORT);
2632 }
2633 } else if (!strcasecmp(v->name, "bindaddr")) {
2635 } else if (!strcasecmp(v->name, "prefix")) {
2636 if (!ast_strlen_zero(v->value)) {
2637 newprefix[0] = '/';
2638 ast_copy_string(newprefix + 1, v->value, sizeof(newprefix) - 1);
2639 } else {
2640 newprefix[0] = '\0';
2641 }
2642 } else if (!strcasecmp(v->name, "redirect")) {
2643 add_redirect(v->value);
2644 } else if (!strcasecmp(v->name, "sessionlimit")) {
2646 &session_limit, DEFAULT_SESSION_LIMIT, 1, INT_MAX)) {
2647 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
2648 v->name, v->value, v->lineno);
2649 }
2650 } else if (!strcasecmp(v->name, "session_inactivity")) {
2653 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
2654 v->name, v->value, v->lineno);
2655 }
2656 } else if (!strcasecmp(v->name, "session_keep_alive")) {
2657 if (sscanf(v->value, "%30d", &session_keep_alive) != 1
2658 || session_keep_alive < 0) {
2660 ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
2661 v->name, v->value, v->lineno);
2662 }
2663 } else {
2664 ast_log(LOG_WARNING, "Ignoring unknown option '%s' in http.conf\n", v->name);
2665 }
2666 }
2667
2668 while ((cat = ast_category_browse(cfg, cat))) {
2669 const char *type;
2670 struct http_restriction *new_restriction;
2671 struct ast_acl_list *acl = NULL;
2672 int acl_error = 0;
2673 int acl_subscription_flag = 0;
2674
2675 if (strcasecmp(cat, "general") == 0) {
2676 continue;
2677 }
2678
2679 type = ast_variable_retrieve(cfg, cat, "type");
2680 if (!type || strcasecmp(type, "restriction") != 0) {
2681 continue;
2682 }
2683
2684 new_restriction = ast_calloc(1, sizeof(*new_restriction) + strlen(cat) + 1);
2685 if (!new_restriction) {
2686 continue;
2687 }
2688
2689 /* Safe */
2690 strcpy(new_restriction->path, cat);
2691
2692 /* Parse ACL options for this restriction */
2693 for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
2694 if (!strcasecmp(v->name, "permit") ||
2695 !strcasecmp(v->name, "deny") ||
2696 !strcasecmp(v->name, "acl")) {
2697 ast_append_acl(v->name, v->value, &acl, &acl_error, &acl_subscription_flag);
2698 if (acl_error) {
2699 ast_log(LOG_ERROR, "Bad ACL '%s' at line '%d' of http.conf for restriction '%s'\n",
2700 v->value, v->lineno, cat);
2701 }
2702 }
2703 }
2704
2705 new_restriction->acl = acl;
2706
2707 AST_LIST_INSERT_TAIL(&new_restrictions, new_restriction, entry);
2708 ast_debug(2, "HTTP: Added restriction for path '%s'\n", cat);
2709 }
2710
2712 AST_RWLIST_APPEND_LIST(&old_restrictions, &restrictions, entry);
2713 AST_RWLIST_APPEND_LIST(&restrictions, &new_restrictions, entry);
2715
2716 while ((restriction = AST_LIST_REMOVE_HEAD(&old_restrictions, entry))) {
2717 if (restriction->acl) {
2718 ast_free_acl_list(restriction->acl);
2719 }
2720 ast_free(restriction);
2721 }
2722
2723 ast_config_destroy(cfg);
2724
2725 if (strcmp(prefix, newprefix)) {
2726 ast_copy_string(prefix, newprefix, sizeof(prefix));
2727 }
2728
2729 ast_copy_string(http_server_name, server_name, sizeof(http_server_name));
2730
2731 if (enabled) {
2732 http_server_get("http server", bindaddr, bindport, &global_http_server);
2733 } else if (global_http_server) {
2736 }
2737
2738 /* When no specific TLS bindaddr is specified, we just use
2739 * the non-TLS bindaddress here.
2740 */
2743
2745 /* Of course, we can't use the same port though.
2746 * Since no bind address was specified, we just use the
2747 * default TLS port
2748 */
2750 }
2751
2752 if (http_tls_was_enabled && !http_tls_cfg.enabled) {
2755 /* We can get here either because a TLS-specific address was specified
2756 * or because we copied the non-TLS address here. In the case where
2757 * we read an explicit address from the config, there may have been
2758 * no port specified, so we'll just use the default TLS port.
2759 */
2762 }
2765 }
2766 }
2767
2768 if (static_uri_enabled && !new_static_uri_enabled) {
2770 } else if (!static_uri_enabled && new_static_uri_enabled) {
2772 }
2773
2774 static_uri_enabled = new_static_uri_enabled;
2775
2776 if (status_uri_enabled && !new_status_uri_enabled) {
2778 } else if (!status_uri_enabled && new_status_uri_enabled) {
2780 }
2781
2782 status_uri_enabled = new_status_uri_enabled;
2783
2784 return 0;
2785}
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
Definition acl.c:429
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition acl.c:233
const char * ast_get_version(void)
Retrieve the Asterisk version string.
#define ast_free(a)
Definition astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define ast_log
Definition astobj2.c:42
static const char type[]
struct ast_sockaddr bindaddr
static int enabled
Definition dnsmgr.c:91
#define DEFAULT_PORT
Definition http.c:70
static struct ast_tls_config http_tls_cfg
Definition http.c:112
static char http_server_name[MAX_SERVER_NAME_LENGTH]
Definition http.c:105
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:2194
int ast_http_uri_link(struct ast_http_uri *urih)
Link the new uri into the list.
Definition http.c:747
static int status_uri_enabled
Definition http.c:147
static char prefix[MAX_PREFIX]
Definition http.c:145
static int session_inactivity
Definition http.c:108
#define DEFAULT_SESSION_INACTIVITY
Definition http.c:74
static struct ast_http_uri status_uri
Definition http.c:487
static void http_server_discard(struct ast_http_server *server)
Discard/Drop a HTTP server.
Definition http.c:2339
#define DEFAULT_SESSION_KEEP_ALIVE
Definition http.c:78
#define DEFAULT_TLS_PORT
Definition http.c:71
void ast_http_uri_unlink(struct ast_http_uri *urih)
Unregister a URI handler.
Definition http.c:779
static struct ast_http_uri static_uri
Definition http.c:496
static struct ast_http_server * http_server_get(const char *name, const char *host, uint32_t port, struct ast_http_server **replace_me)
Retrieve, or create and start a HTTP server.
Definition http.c:2449
static struct ast_tcptls_session_args https_desc
Definition http.c:132
static int static_uri_enabled
Definition http.c:146
static int session_keep_alive
Definition http.c:109
#define MAX_PREFIX
Definition http.c:69
struct ast_http_server * global_http_server
Definition http.c:130
#define MAX_SERVER_NAME_LENGTH
Definition http.c:80
static int session_limit
Definition http.c:107
#define DEFAULT_SESSION_LIMIT
Definition http.c:72
@ CONFIG_FLAG_FILEUNCHANGED
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition extconf.c:3324
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition extconf.c:1213
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_WARNING
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_RWLIST_REMOVE_HEAD
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
#define AST_RWLIST_APPEND_LIST
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition netsock2.h:517
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition netsock2.h:167
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition netsock2.h:127
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition netsock2.h:532
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition netsock2.h:138
static int reload(void)
#define NULL
Definition resample.c:96
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition utils.c:2233
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
Wrapper for an ast_acl linked list.
Definition acl.h:76
Structure used to handle boolean flags.
Definition utils.h:220
struct ast_tcptls_session_args args
Definition http.c:122
struct ast_sockaddr local_address
Definition tcptls.h:131
struct ast_tls_config * tls_cfg
Definition tcptls.h:135
char * certfile
Definition tcptls.h:90
char * cipher
Definition tcptls.h:92
char * pvtfile
Definition tcptls.h:91
char * capath
Definition tcptls.h:94
struct ast_flags flags
Definition tcptls.h:95
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
Per-path ACL restriction.
Definition http.c:182
char path[]
Definition http.c:185
struct ast_acl_list * acl
Definition http.c:184
#define AST_CERTFILE
Definition tcptls.h:63
void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
Shutdown a running server if there is one.
Definition tcptls.c:948
int ast_ssl_setup(struct ast_tls_config *cfg)
Set up an SSL server.
Definition tcptls.c:587
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:783
@ AST_SSL_SERVER_CIPHER_ORDER
Definition tcptls.h:79
@ AST_SSL_DISABLE_TLSV1
Definition tcptls.h:81
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:974
#define ast_set_flag(p, flag)
Definition utils.h:71

References ast_tcptls_session_args::accept_fd, http_restriction::acl, add_redirect(), ast_http_server::args, ast_append_acl(), ast_calloc, ast_category_browse(), AST_CERTFILE, ast_config_destroy(), ast_config_load2(), ast_copy_string(), ast_debug, ast_free, ast_free_acl_list(), ast_get_version(), ast_http_uri_link(), ast_http_uri_unlink(), AST_LIST_HEAD_NOLOCK_INIT_VALUE, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, ast_log, ast_parse_arg(), AST_RWLIST_APPEND_LIST, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), AST_SSL_DISABLE_TLSV1, AST_SSL_SERVER_CIPHER_ORDER, ast_ssl_setup(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_tcptls_server_start(), ast_tcptls_server_stop(), ast_tls_read_conf(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), bindaddr, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_PORT, DEFAULT_SESSION_INACTIVITY, DEFAULT_SESSION_KEEP_ALIVE, DEFAULT_SESSION_LIMIT, DEFAULT_TLS_PORT, ast_tls_config::enabled, enabled, ast_tls_config::flags, global_http_server, http_server_discard(), http_server_get(), http_server_name, http_tls_cfg, https_desc, ast_variable::lineno, ast_tcptls_session_args::local_address, LOG_ERROR, LOG_WARNING, MAX_PREFIX, MAX_SERVER_NAME_LENGTH, ast_variable::name, ast_variable::next, NULL, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_INT32, PARSE_UINT32, http_restriction::path, prefix, ast_tls_config::pvtfile, reload(), session_inactivity, session_keep_alive, session_limit, static_uri, static_uri_enabled, status_uri, status_uri_enabled, ast_tcptls_session_args::tls_cfg, type, and ast_variable::value.

Referenced by load_module(), and reload_module().

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2938 of file http.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2938 of file http.c.

◆ add_redirect()

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 2194 of file http.c.

2195{
2196 char *target, *dest;
2197 struct http_uri_redirect *redirect, *cur;
2198 unsigned int target_len;
2199 unsigned int total_len;
2200 size_t dest_len;
2201
2204 target = strsep(&dest, " ");
2206 target = strsep(&target, " "); /* trim trailing whitespace */
2207
2208 if (!dest) {
2209 ast_log(LOG_WARNING, "Invalid redirect '%s'\n", value);
2210 return;
2211 }
2212
2213 target_len = strlen(target) + 1;
2214 dest_len = strlen(dest) + 1;
2215 total_len = sizeof(*redirect) + target_len + dest_len;
2216
2217 if (!(redirect = ast_calloc(1, total_len))) {
2218 return;
2219 }
2220 redirect->dest = redirect->target + target_len;
2221 strcpy(redirect->target, target);
2222 ast_copy_string(redirect->dest, dest, dest_len);
2223
2225
2226 target_len--; /* So we can compare directly with strlen() */
2228 || strlen(AST_RWLIST_FIRST(&uri_redirects)->target) <= target_len ) {
2231
2232 return;
2233 }
2234
2236 if (AST_RWLIST_NEXT(cur, entry)
2237 && strlen(AST_RWLIST_NEXT(cur, entry)->target) <= target_len ) {
2240 return;
2241 }
2242 }
2243
2245
2247}
char * strsep(char **str, const char *delims)
#define AST_RWLIST_EMPTY
#define AST_RWLIST_INSERT_AFTER
#define AST_RWLIST_NEXT
#define AST_RWLIST_FIRST
#define AST_RWLIST_TRAVERSE
#define AST_RWLIST_INSERT_HEAD
#define AST_RWLIST_INSERT_TAIL
char *attribute_pure ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition strings.h:161
char * dest
Definition http.c:175
struct http_uri_redirect::@387 entry
char target[0]
Definition http.c:176
int value
Definition syslog.c:37

References ast_calloc, ast_copy_string(), 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(), http_uri_redirect::target, and value.

Referenced by __ast_http_load().

◆ AO2_STRING_FIELD_CMP_FN()

AO2_STRING_FIELD_CMP_FN ( ast_http_server  ,
address   
)

◆ AO2_STRING_FIELD_HASH_FN()

AO2_STRING_FIELD_HASH_FN ( ast_http_server  ,
address   
)

◆ ast_get_http_method()

const char * ast_get_http_method ( enum ast_http_method  method)

Return http method name string.

Since
1.8

Definition at line 207 of file http.c.

208{
209 int x;
210
211 for (x = 0; x < ARRAY_LEN(ast_http_methods_text); x++) {
213 return ast_http_methods_text[x].text;
214 }
215 }
216
217 return NULL;
218}
static const struct ast_cfhttp_methods_text ast_http_methods_text[]
const char * method
Definition res_pjsip.c:1277
const char * text
Definition http.c:196
#define ARRAY_LEN(a)
Definition utils.h:706

References ARRAY_LEN, ast_http_methods_text, method, NULL, and ast_cfhttp_methods_text::text.

Referenced by add_allow_header(), ast_ari_callback(), ast_ari_invoke(), auth_http_callback(), and handle_options().

◆ ast_get_http_method_from_string()

enum ast_http_method ast_get_http_method_from_string ( const char *  method)

Return http method from string.

Definition at line 220 of file http.c.

221{
222 int x;
223
224 for (x = 0; x < ARRAY_LEN(ast_http_methods_text); x++) {
227 }
228 }
229
230 return AST_HTTP_UNKNOWN;
231}
@ AST_HTTP_UNKNOWN
Definition http.h:59
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Definition strings.c:238
enum ast_http_method method
Definition http.c:195

References ARRAY_LEN, ast_http_methods_text, AST_HTTP_UNKNOWN, ast_strings_equal(), ast_cfhttp_methods_text::method, method, and text.

Referenced by parse_rest_request_msg().

◆ ast_http_auth()

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 696 of file http.c.

699{
700 int status_code = 401;
701 char *status_title = "Unauthorized";
702 struct ast_str *http_header_data = ast_str_create(DEFAULT_RESPONSE_HEADER_LENGTH);
703
704 if (http_header_data) {
705 ast_str_set(&http_header_data,
706 0,
707 "WWW-authenticate: Digest algorithm=MD5, realm=\"%s\", nonce=\"%08lx\", qop=\"auth\", opaque=\"%08lx\"%s\r\n"
708 "Content-type: text/html\r\n",
709 realm ? realm : "Asterisk",
710 nonce,
711 opaque,
712 stale ? ", stale=true" : "");
713 }
714
716 status_code,
717 status_title,
718 http_header_data,
719 text);
720}
void ast_http_create_response(struct ast_tcptls_session_instance *ser, int status_code, const char *status_title, struct ast_str *http_header_data, const char *text)
Creates and sends a formatted http response message.
Definition http.c:633
#define DEFAULT_RESPONSE_HEADER_LENGTH
Definition http.c:82
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
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:1113
Support for dynamic strings.
Definition strings.h:623

References ast_http_create_response(), ast_str_create, ast_str_set(), DEFAULT_RESPONSE_HEADER_LENGTH, and text.

◆ ast_http_body_discard()

int ast_http_body_discard ( struct ast_tcptls_session_instance ser)

Read and discard any unread HTTP request body.

Since
12.4.0
Parameters
serHTTP TCP/TLS session object.
Return values
0on success.
-1on error.

Definition at line 1193 of file http.c.

1194{
1196
1197 request = ser->private_data;
1200 /* No body to read or it has already been read. */
1201 return 0;
1202 }
1204
1205 ast_debug(1, "HTTP discarding unused request body\n");
1206
1207 ast_assert(request->body_length != 0);
1208 if (0 < request->body_length) {
1209 if (http_body_discard_contents(ser, request->body_length, "body")) {
1211 return -1;
1212 }
1213 return 0;
1214 }
1215
1216 /* parse chunked-body */
1217 for (;;) {
1218 int length;
1219
1220 length = http_body_get_chunk_length(ser);
1221 if (length < 0) {
1223 return -1;
1224 }
1225 if (length == 0) {
1226 /* parsed last-chunk */
1227 break;
1228 }
1229
1230 if (http_body_discard_contents(ser, length, "chunk-data")
1233 return -1;
1234 }
1235 }
1236
1237 /* Read and discard any trailer entity-header lines. */
1240 return -1;
1241 }
1242 return 0;
1243}
static int request(void *obj)
static int http_body_discard_chunk_trailer_headers(struct ast_tcptls_session_instance *ser)
Definition http.c:1173
static int http_body_discard_contents(struct ast_tcptls_session_instance *ser, int length, const char *what_getting)
Definition http.c:1037
static int http_body_check_chunk_sync(struct ast_tcptls_session_instance *ser)
Definition http.c:1142
static int http_body_get_chunk_length(struct ast_tcptls_session_instance *ser)
Definition http.c:1114
#define ast_test_flag(p, flag)
Definition utils.h:64
#define ast_assert(a)
Definition utils.h:779

References ast_assert, ast_debug, ast_set_flag, ast_test_flag, http_body_check_chunk_sync(), http_body_discard_chunk_trailer_headers(), http_body_discard_contents(), http_body_get_chunk_length(), HTTP_FLAG_BODY_READ, HTTP_FLAG_CLOSE_ON_COMPLETION, HTTP_FLAG_HAS_BODY, ast_tcptls_session_instance::private_data, and request().

Referenced by ast_http_send(), and ast_websocket_uri_cb().

◆ ast_http_body_read_status()

void ast_http_body_read_status ( struct ast_tcptls_session_instance ser,
int  read_success 
)

Update the body read success status.

Since
12.4.0
Parameters
serHTTP TCP/TLS session object.
read_successTRUE if body was read successfully.

Definition at line 972 of file http.c.

973{
975
976 request = ser->private_data;
979 /* No body to read. */
980 return;
981 }
983 if (!read_success) {
985 }
986}

References ast_set_flag, ast_test_flag, HTTP_FLAG_BODY_READ, HTTP_FLAG_CLOSE_ON_COMPLETION, HTTP_FLAG_HAS_BODY, ast_tcptls_session_instance::private_data, and request().

Referenced by http_post_callback().

◆ ast_http_create_basic_auth_header()

struct ast_variable * ast_http_create_basic_auth_header ( const char *  userid,
const char *  password 
)

Create an HTTP authorization header.

The returned ast_variable must be freed with ast_variables_destroy()

Parameters
useridUser ID or "<userid>:<password>".
passwordPassword if not in userid.
Returns
ast_variable with name="Authorization" and value="Basic <base64enc>"
Return values
NULLif memory allocation failed.

Definition at line 1734 of file http.c.

1736{
1737 int encoded_size = 0;
1738 int userinfo_len = 0;
1739 RAII_VAR(char *, userinfo, NULL, ast_free);
1740 char *encoded_userinfo = NULL;
1741 struct ast_variable *auth_header = NULL;
1742
1743 if (ast_strlen_zero(userid)) {
1744 return NULL;
1745 }
1746
1747 if (strchr(userid, ':')) {
1748 userinfo = ast_strdup(userid);
1749 userinfo_len = strlen(userinfo);
1750 } else {
1751 if (ast_strlen_zero(password)) {
1752 return NULL;
1753 }
1754 userinfo_len = ast_asprintf(&userinfo, "%s:%s", userid, password);
1755 }
1756 if (!userinfo) {
1757 return NULL;
1758 }
1759
1760 /*
1761 * The header value is "Basic " + base64(userinfo).
1762 * Doubling the userinfo length then adding the length
1763 * of the "Basic " prefix is a conservative estimate of the
1764 * final encoded size.
1765 */
1766 encoded_size = userinfo_len * 2 * sizeof(char) + 1 + BASIC_LEN;
1767 encoded_userinfo = ast_alloca(encoded_size);
1768 strcpy(encoded_userinfo, BASIC_PREFIX); /* Safe */
1769 ast_base64encode(encoded_userinfo + BASIC_LEN, (unsigned char *)userinfo,
1770 userinfo_len, encoded_size - BASIC_LEN);
1771
1772 auth_header = ast_variable_new("Authorization",
1773 encoded_userinfo, "");
1774
1775 return auth_header;
1776}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition astmm.h:267
#define BASIC_PREFIX
Definition http.c:1674
#define BASIC_LEN
Definition http.c:1675
#define ast_variable_new(name, value, filename)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition utils.c:404

References ast_alloca, ast_asprintf, ast_base64encode(), ast_free, ast_strdup, ast_strlen_zero(), ast_variable_new, BASIC_LEN, BASIC_PREFIX, NULL, and RAII_VAR.

Referenced by outbound_session_handler_thread(), websocket_client_handshake(), and websocket_proxy_handshake().

◆ ast_http_create_response()

void ast_http_create_response ( struct ast_tcptls_session_instance ser,
int  status_code,
const char *  status_title,
struct ast_str http_header_data,
const char *  text 
)

Creates and sends a formatted http response message.

Parameters
serTCP/TLS session object
status_codeHTTP response code (200/401/403/404/500)
status_titleEnglish equivalent to the status_code parameter
http_header_dataThe formatted text to use in the http header
textAdditional informational text to use in the response
Note
Function constructs response headers from the status_code, status_title and http_header_data parameters.

The response body is created as HTML content, from the status_code, status_title, and the text parameters.

The http_header_data parameter will be freed as a result of calling function.

Since
13.2.0

Definition at line 633 of file http.c.

635{
636 char server_name[MAX_SERVER_NAME_LENGTH];
637 char escaped_text[512];
638 struct ast_str *server_address = ast_str_create(MAX_SERVER_NAME_LENGTH);
640
641 if (!http_header_data || !server_address || !out) {
642 ast_free(http_header_data);
643 ast_free(server_address);
644 ast_free(out);
645 if (ser) {
646 ast_debug(1, "HTTP closing session. OOM.\n");
648 }
649 return;
650 }
651
653 ast_xml_escape(http_server_name, server_name, sizeof(server_name));
654 ast_str_set(&server_address,
655 0,
656 "<address>%s</address>\r\n",
657 server_name);
658 }
659
660 /* Escape text to prevent reflected XSS in error pages */
661 if (!ast_strlen_zero(text)) {
662 ast_xml_escape(text, escaped_text, sizeof(escaped_text));
663 } else {
664 escaped_text[0] = '\0';
665 }
666
668 0,
669 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
670 "<html><head>\r\n"
671 "<title>%d %s</title>\r\n"
672 "</head><body>\r\n"
673 "<h1>%s</h1>\r\n"
674 "<p>%s</p>\r\n"
675 "<hr />\r\n"
676 "%s"
677 "</body></html>\r\n",
678 status_code,
679 status_title,
680 status_title,
681 escaped_text,
682 ast_str_buffer(server_address));
683
684 ast_free(server_address);
685
686 ast_http_send(ser,
688 status_code,
689 status_title,
690 http_header_data,
691 out,
692 0,
693 0);
694}
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, int fd, unsigned int static_content)
Generic function for sending HTTP/1.1 response.
Definition http.c:522
#define INITIAL_RESPONSE_BODY_BUFFER
Definition http.c:93
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
Closes a tcptls session instance's file and/or file descriptor. The tcptls_session will be set to NUL...
Definition tcptls.c:938
FILE * out
Definition utils/frame.c:33
int ast_xml_escape(const char *string, char *outbuf, size_t buflen)
Escape reserved characters for use in XML.
Definition utils.c:898

References ast_debug, ast_free, ast_http_send(), AST_HTTP_UNKNOWN, ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero(), ast_tcptls_close_session_file(), ast_xml_escape(), http_server_name, INITIAL_RESPONSE_BODY_BUFFER, MAX_SERVER_NAME_LENGTH, out, and text.

Referenced by ast_http_auth(), and ast_http_error().

◆ ast_http_error()

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 722 of file http.c.

724{
725 struct ast_str *http_header_data = ast_str_create(DEFAULT_RESPONSE_HEADER_LENGTH);
726
727 if (http_header_data) {
728 ast_str_set(&http_header_data, 0, "Content-type: text/html\r\n");
729 }
730
732 status_code,
733 status_title,
734 http_header_data,
735 text);
736}

References ast_http_create_response(), ast_str_create, ast_str_set(), DEFAULT_RESPONSE_HEADER_LENGTH, and text.

Referenced by ast_ari_callback(), ast_websocket_uri_cb(), auth_http_callback(), generic_http_callback(), handle_uri(), http_callback(), http_post_callback(), http_request_headers_get(), http_request_tracking_setup(), httpd_helper_thread(), httpd_process_request(), httpstatus_callback(), incoming_ws_http_callback(), phoneprov_callback(), static_callback(), and websocket_bad_request().

◆ ast_http_ftype2mtype()

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 233 of file http.c.

234{
235 int x;
236
237 if (ftype) {
238 for (x = 0; x < ARRAY_LEN(mimetypes); x++) {
239 if (!strcasecmp(ftype, mimetypes[x].ext)) {
240 return mimetypes[x].mtype;
241 }
242 }
243 }
244 return NULL;
245}
static struct @386 mimetypes[]
Limit the kinds of files we're willing to serve up.
const char * ext
Definition http.c:151

References ARRAY_LEN, ext, mimetypes, and NULL.

Referenced by build_profile(), and static_callback().

◆ ast_http_get_auth()

struct ast_http_auth * ast_http_get_auth ( struct ast_variable headers)

Get HTTP authentication information from headers.

The returned object is AO2 managed, so clean up with ao2_cleanup().

Parameters
headersHTTP request headers.
Returns
HTTP auth structure.
Return values
NULLif no supported HTTP auth headers present.
Since
12

Definition at line 1677 of file http.c.

1678{
1679 struct ast_variable *v;
1680
1681 for (v = headers; v; v = v->next) {
1682 const char *base64;
1683 char decoded[256] = {};
1684 char *username;
1685 char *password;
1686#ifdef AST_DEVMODE
1687 int cnt;
1688#endif /* AST_DEVMODE */
1689
1690 if (strcasecmp("Authorization", v->name) != 0) {
1691 continue;
1692 }
1693
1696 "Unsupported Authorization scheme\n");
1697 continue;
1698 }
1699
1700 /* Basic auth header parsing. RFC 2617, section 2.
1701 * credentials = "Basic" basic-credentials
1702 * basic-credentials = base64-user-pass
1703 * base64-user-pass = <base64 encoding of user-pass,
1704 * except not limited to 76 char/line>
1705 * user-pass = userid ":" password
1706 */
1707
1708 base64 = v->value + BASIC_LEN;
1709
1710 /* This will truncate "userid:password" lines to
1711 * sizeof(decoded). The array is long enough that this shouldn't
1712 * be a problem */
1713#ifdef AST_DEVMODE
1714 cnt =
1715#endif /* AST_DEVMODE */
1716 ast_base64decode((unsigned char*)decoded, base64,
1717 sizeof(decoded) - 1);
1718 ast_assert(cnt < sizeof(decoded));
1719
1720 /* Split the string at the colon */
1721 password = decoded;
1722 username = strsep(&password, ":");
1723 if (!password) {
1724 ast_log(LOG_WARNING, "Invalid Authorization header\n");
1725 return NULL;
1726 }
1727
1728 return auth_create(username, password);
1729 }
1730
1731 return NULL;
1732}
static struct ast_http_auth * auth_create(const char *userid, const char *password)
Definition http.c:1643
#define LOG_DEBUG
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition strings.h:97
static char base64[64]
Definition utils.c:80
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition utils.c:296

References ast_assert, ast_base64decode(), ast_begins_with(), ast_log, auth_create(), base64, BASIC_LEN, BASIC_PREFIX, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, strsep(), and ast_variable::value.

Referenced by authenticate_user(), and http_callback().

◆ ast_http_get_contents()

static char * ast_http_get_contents ( int *  return_length,
struct ast_tcptls_session_instance ser,
struct ast_variable headers 
)
static

Returns the contents (body) of the HTTP request.

Parameters
return_lengthptr to int that returns content length
serHTTP TCP/TLS session object
headersList of HTTP headers
Returns
ptr to content (zero terminated)
Return values
NULLon failure
Note
Since returned ptr is malloc'd, it should be free'd by caller

Definition at line 1255 of file http.c.

1257{
1259 int content_length;
1260 int bufsize;
1261 char *buf;
1262
1263 request = ser->private_data;
1264 if (!ast_test_flag(&request->flags, HTTP_FLAG_HAS_BODY)) {
1265 /* no content - not an error */
1266 return NULL;
1267 }
1269 /* Already read the body. Cannot read again. Assume no content. */
1270 ast_assert(0);
1271 return NULL;
1272 }
1274
1275 ast_debug(2, "HTTP consuming request body\n");
1276
1277 ast_assert(request->body_length != 0);
1278 if (0 < request->body_length) {
1279 /* handle regular non-chunked content */
1280 content_length = request->body_length;
1281 if (content_length > MAX_CONTENT_LENGTH) {
1282 ast_log(LOG_WARNING, "Excessively long HTTP content. (%d > %d)\n",
1283 content_length, MAX_CONTENT_LENGTH);
1285 errno = EFBIG;
1286 return NULL;
1287 }
1288 buf = ast_malloc(content_length + 1);
1289 if (!buf) {
1290 /* Malloc sets ENOMEM */
1292 return NULL;
1293 }
1294
1295 if (http_body_read_contents(ser, buf, content_length, "body")) {
1297 errno = EIO;
1298 ast_free(buf);
1299 return NULL;
1300 }
1301
1302 buf[content_length] = 0;
1303 *return_length = content_length;
1304 return buf;
1305 }
1306
1307 /* pre-allocate buffer */
1308 bufsize = 250;
1309 buf = ast_malloc(bufsize);
1310 if (!buf) {
1312 return NULL;
1313 }
1314
1315 /* parse chunked-body */
1316 content_length = 0;
1317 for (;;) {
1318 int chunk_length;
1319
1320 chunk_length = http_body_get_chunk_length(ser);
1321 if (chunk_length < 0) {
1323 errno = EIO;
1324 ast_free(buf);
1325 return NULL;
1326 }
1327 if (chunk_length == 0) {
1328 /* parsed last-chunk */
1329 break;
1330 }
1331 if (content_length + chunk_length > MAX_CONTENT_LENGTH) {
1333 "Excessively long HTTP accumulated chunked body. (%d + %d > %d)\n",
1334 content_length, chunk_length, MAX_CONTENT_LENGTH);
1336 errno = EFBIG;
1337 ast_free(buf);
1338 return NULL;
1339 }
1340
1341 /* insure buffer is large enough +1 */
1342 if (content_length + chunk_length >= bufsize) {
1343 char *new_buf;
1344
1345 /* Increase bufsize until it can handle the expected data. */
1346 do {
1347 bufsize *= 2;
1348 } while (content_length + chunk_length >= bufsize);
1349
1350 new_buf = ast_realloc(buf, bufsize);
1351 if (!new_buf) {
1353 ast_free(buf);
1354 return NULL;
1355 }
1356 buf = new_buf;
1357 }
1358
1359 if (http_body_read_contents(ser, buf + content_length, chunk_length, "chunk-data")
1362 errno = EIO;
1363 ast_free(buf);
1364 return NULL;
1365 }
1366 content_length += chunk_length;
1367 }
1368
1369 /*
1370 * Read and discard any trailer entity-header lines
1371 * which we don't care about.
1372 *
1373 * XXX In the future we may need to add the trailer headers
1374 * to the passed in headers list rather than discarding them.
1375 */
1378 errno = EIO;
1379 ast_free(buf);
1380 return NULL;
1381 }
1382
1383 buf[content_length] = 0;
1384 *return_length = content_length;
1385 return buf;
1386}
#define ast_realloc(p, len)
A wrapper for realloc()
Definition astmm.h:226
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
char buf[BUFSIZE]
Definition eagi_proxy.c:66
#define MAX_CONTENT_LENGTH
Definition http.c:86
static int http_body_read_contents(struct ast_tcptls_session_instance *ser, char *buf, int length, const char *what_getting)
Definition http.c:1001
int errno

References ast_assert, ast_debug, ast_free, ast_log, ast_malloc, ast_realloc, ast_set_flag, ast_test_flag, buf, errno, http_body_check_chunk_sync(), http_body_discard_chunk_trailer_headers(), http_body_get_chunk_length(), http_body_read_contents(), HTTP_FLAG_BODY_READ, HTTP_FLAG_CLOSE_ON_COMPLETION, HTTP_FLAG_HAS_BODY, LOG_WARNING, MAX_CONTENT_LENGTH, NULL, ast_tcptls_session_instance::private_data, and request().

Referenced by ast_http_get_json(), and ast_http_get_post_vars().

◆ ast_http_get_cookies()

struct ast_variable * ast_http_get_cookies ( struct ast_variable headers)

Get cookie from Request headers.

Definition at line 1630 of file http.c.

1631{
1632 struct ast_variable *v, *cookies = NULL;
1633
1634 for (v = headers; v; v = v->next) {
1635 if (!strcasecmp(v->name, "Cookie")) {
1636 ast_variables_destroy(cookies);
1637 cookies = parse_cookies(v->value);
1638 }
1639 }
1640 return cookies;
1641}
static struct ast_variable * parse_cookies(const char *cookies)
Definition http.c:1596
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260

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

Referenced by ast_http_manid_from_vars(), and httpstatus_callback().

◆ ast_http_get_json()

struct ast_json * ast_http_get_json ( struct ast_tcptls_session_instance ser,
struct ast_variable headers 
)

Get JSON from client Request Entity-Body, if content type is application/json.

Parameters
serTCP/TLS session object
headersList of HTTP headers
Returns
Parsed JSON content body
Return values
NULLon error, if no content, or if different content type.
Since
12

Definition at line 1388 of file http.c.

1390{
1391 int content_length = 0;
1392 struct ast_json *body;
1393 RAII_VAR(char *, buf, NULL, ast_free);
1394 RAII_VAR(char *, type, get_content_type(headers), ast_free);
1395
1396 /* Use errno to distinguish errors from no body */
1397 errno = 0;
1398
1399 if (ast_strlen_zero(type) || strcasecmp(type, "application/json")) {
1400 /* Content type is not JSON. Don't read the body. */
1401 return NULL;
1402 }
1403
1404 buf = ast_http_get_contents(&content_length, ser, headers);
1405 if (!buf || !content_length) {
1406 /*
1407 * errno already set
1408 * or it is not an error to have zero content
1409 */
1410 return NULL;
1411 }
1412
1413 body = ast_json_load_buf(buf, content_length, NULL);
1414 if (!body) {
1415 /* Failed to parse JSON; treat as an I/O error */
1416 errno = EIO;
1417 return NULL;
1418 }
1419
1420 return body;
1421}
static char * get_content_type(struct ast_variable *headers)
Retrieves the content type specified in the "Content-Type" header.
Definition http.c:836
static char * ast_http_get_contents(int *return_length, struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
Returns the contents (body) of the HTTP request.
Definition http.c:1255
struct ast_json * ast_json_load_buf(const char *buffer, size_t buflen, struct ast_json_error *error)
Parse buffer with known length into a JSON object or array.
Definition json.c:585
Abstract JSON element (object, array, string, int, ...).

References ast_free, ast_http_get_contents(), ast_json_load_buf(), ast_strlen_zero(), buf, errno, get_content_type(), NULL, RAII_VAR, and type.

Referenced by ast_ari_callback().

◆ ast_http_get_post_vars()

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 1463 of file http.c.

1465{
1466 int content_length = 0;
1467 RAII_VAR(char *, buf, NULL, ast_free);
1468 RAII_VAR(char *, type, get_content_type(headers), ast_free);
1469
1470 /* Use errno to distinguish errors from no params */
1471 errno = 0;
1472
1473 if (ast_strlen_zero(type) ||
1474 strcasecmp(type, "application/x-www-form-urlencoded")) {
1475 /* Content type is not form data. Don't read the body. */
1476 return NULL;
1477 }
1478
1479 buf = ast_http_get_contents(&content_length, ser, headers);
1480 if (!buf || !content_length) {
1481 /*
1482 * errno already set
1483 * or it is not an error to have zero content
1484 */
1485 return NULL;
1486 }
1487
1488 return ast_http_parse_post_form(buf, content_length, type);
1489}
struct ast_variable * ast_http_parse_post_form(char *buf, int content_length, const char *content_type)
Get post variables from an application/x-www-form-urlencoded buffer.
Definition http.c:1427

References ast_free, ast_http_get_contents(), ast_http_parse_post_form(), ast_strlen_zero(), buf, errno, get_content_type(), NULL, RAII_VAR, and type.

Referenced by ast_ari_callback(), auth_http_callback(), and generic_http_callback().

◆ ast_http_header_match()

int ast_http_header_match ( const char *  name,
const char *  expected_name,
const char *  value,
const char *  expected_value 
)

Check if the header and value match (case insensitive) their associated expected values.

Parameters
nameheader name to check
expected_namethe expected name of the header
valueheader value to check
expected_valuethe expected value of the header
Return values
0if the name and expected name do not match
-1if the value and expected value do not match
1if the both the name and value match their expected value
Since
13

Definition at line 1852 of file http.c.

1854{
1855 if (strcasecmp(name, expected_name)) {
1856 /* no value to validate if names don't match */
1857 return 0;
1858 }
1859
1860 if (strcasecmp(value, expected_value)) {
1861 ast_log(LOG_ERROR, "Invalid header value - expected %s "
1862 "received %s", value, expected_value);
1863 return -1;
1864 }
1865 return 1;
1866}
static const char name[]
Definition format_mp3.c:68

References ast_log, LOG_ERROR, name, and value.

Referenced by websocket_client_handshake_get_response().

◆ ast_http_header_match_in()

int ast_http_header_match_in ( const char *  name,
const char *  expected_name,
const char *  value,
const char *  expected_value 
)

Check if the header name matches the expected header name. If so, then check to see if the value can be located in the expected value.

Note
Both header and value checks are case insensitive.
Parameters
nameheader name to check
expected_namethe expected name of the header
valueheader value to check if in expected value
expected_valuethe expected value(s)
Return values
0if the name and expected name do not match
-1if the value and is not in the expected value
1if the name matches expected name and value is in expected value
Since
13

Definition at line 1868 of file http.c.

1870{
1871 if (strcasecmp(name, expected_name)) {
1872 /* no value to validate if names don't match */
1873 return 0;
1874 }
1875
1876 if (!strcasestr(expected_value, value)) {
1877 ast_log(LOG_ERROR, "Header '%s' - could not locate '%s' "
1878 "in '%s'\n", name, value, expected_value);
1879 return -1;
1880
1881 }
1882 return 1;
1883}
char * strcasestr(const char *, const char *)

References ast_log, LOG_ERROR, name, strcasestr(), and value.

Referenced by websocket_client_handshake_get_response().

◆ ast_http_header_parse()

int ast_http_header_parse ( char *  buf,
char **  name,
char **  value 
)

Parse a header into the given name/value strings.

Note
This modifies the given buffer and the out parameters point (not allocated) to the start of the header name and header value, respectively.
Parameters
bufa string containing the name/value to point to
[out]nameheader name
[out]valueheader value
Return values
-1if buf is empty
0if buf could be separated into name and value
1if name or value portion don't exist
Since
13

Definition at line 1830 of file http.c.

1831{
1833 if (ast_strlen_zero(buf)) {
1834 return -1;
1835 }
1836
1837 *value = buf;
1838 *name = strsep(value, ":");
1839 if (!*value) {
1840 return 1;
1841 }
1842
1845 return 1;
1846 }
1847
1849 return 0;
1850}
static void remove_excess_lws(char *s)
Definition http.c:1801
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition strings.h:186

References ast_skip_blanks(), ast_strlen_zero(), ast_trim_blanks(), buf, name, remove_excess_lws(), strsep(), and value.

Referenced by websocket_client_handshake_get_response().

◆ ast_http_manid_from_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 247 of file http.c.

248{
249 uint32_t mngid = 0;
250 struct ast_variable *v, *cookies;
251
252 cookies = ast_http_get_cookies(headers);
253 for (v = cookies; v; v = v->next) {
254 if (!strcasecmp(v->name, "mansession_id")) {
255 sscanf(v->value, "%30x", &mngid);
256 break;
257 }
258 }
259 ast_variables_destroy(cookies);
260 return mngid;
261}
struct ast_variable * ast_http_get_cookies(struct ast_variable *headers)
Get cookie from Request headers.
Definition http.c:1630

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

Referenced by generic_http_callback(), http_post_callback(), and static_callback().

◆ ast_http_parse_post_form()

struct ast_variable * ast_http_parse_post_form ( char *  buf,
int  content_length,
const char *  content_type 
)

Get post variables from an application/x-www-form-urlencoded buffer.

Parameters
bufinput buffer
content_lenBuffer length
content_typeContent type (must be "application/x-www-form-urlencoded")
Warning
The input buffer will be modified by strsep() so pass in a copy if you need to keep the original.
Returns
List of ast_variables from the buffer. Must be freed with ast_variables_destroy().

Definition at line 1427 of file http.c.

1429{
1430 struct ast_variable *v, *post_vars=NULL, *prev = NULL;
1431 char *var, *val;
1432
1433 /* Use errno to distinguish errors from no params */
1434 errno = 0;
1435
1436 if (ast_strlen_zero(content_type) ||
1437 strcasecmp(content_type, "application/x-www-form-urlencoded") != 0) {
1438 /* Content type is not form data. Don't read the body. */
1439 return NULL;
1440 }
1441
1442 while ((val = strsep(&buf, "&"))) {
1443 var = strsep(&val, "=");
1444 if (val) {
1446 } else {
1447 val = "";
1448 }
1450 if ((v = ast_variable_new(var, val, ""))) {
1451 if (post_vars) {
1452 prev->next = v;
1453 } else {
1454 post_vars = v;
1455 }
1456 prev = v;
1457 }
1458 }
1459
1460 return post_vars;
1461}
#define var
Definition ast_expr2f.c:605
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
Definition utils.c:760
const struct ast_flags ast_uri_http_legacy
Definition utils.c:718

References ast_strlen_zero(), ast_uri_decode(), ast_uri_http_legacy, ast_variable_new, buf, errno, NULL, strsep(), and var.

Referenced by ast_http_get_post_vars(), and parse_rest_request_msg().

◆ ast_http_prefix()

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 263 of file http.c.

264{
265 if (buf) {
267 }
268}
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References ast_copy_string(), buf, len(), and prefix.

◆ ast_http_request_close_on_completion()

void ast_http_request_close_on_completion ( struct ast_tcptls_session_instance ser)

Request the HTTP connection be closed after this HTTP request.

Since
12.4.0
Parameters
serHTTP TCP/TLS session object.
Note
Call before ast_http_error() to make the connection close.

Definition at line 911 of file http.c.

References ast_set_flag, HTTP_FLAG_CLOSE_ON_COMPLETION, ast_tcptls_session_instance::private_data, and request().

Referenced by ast_ari_callback(), ast_ari_invoke(), auth_http_callback(), generic_http_callback(), handle_uri(), http_callback(), http_post_callback(), httpstatus_callback(), static_callback(), and websocket_bad_request().

◆ ast_http_response_status_line()

int ast_http_response_status_line ( const char *  buf,
const char *  version,
int  code 
)

Parse the http response status line.

Parameters
bufthe http response line information
versionthe expected http version (e.g. HTTP/1.1)
codethe expected status code
Return values
-1if version didn't match or status code conversion fails.
Returns
status code (>0)
Since
13

Definition at line 1778 of file http.c.

1779{
1780 int status_code;
1781 size_t size = strlen(version);
1782
1783 if (strncmp(buf, version, size) || buf[size] != ' ') {
1784 ast_log(LOG_ERROR, "HTTP version not supported - "
1785 "expected %s\n", version);
1786 return -1;
1787 }
1788
1789 /* skip to status code (version + space) */
1790 buf += size + 1;
1791
1792 if (sscanf(buf, "%d", &status_code) != 1) {
1793 ast_log(LOG_ERROR, "Could not read HTTP status code - "
1794 "%s\n", buf);
1795 return -1;
1796 }
1797
1798 return status_code;
1799}
static char version[AST_MAX_EXTENSION]

References ast_log, buf, LOG_ERROR, and version.

Referenced by websocket_client_handshake_get_response().

◆ ast_http_send()

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,
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 522 of file http.c.

526{
527 struct timeval now = ast_tvnow();
528 struct ast_tm tm;
529 char timebuf[80];
530 char buf[256];
531 int len;
532 int content_length = 0;
533 int close_connection;
534 struct ast_str *server_header_field = ast_str_create(MAX_SERVER_NAME_LENGTH);
535 int send_content;
536
537 if (!ser || !server_header_field) {
538 /* The connection is not open. */
539 ast_free(http_header);
540 ast_free(out);
541 ast_free(server_header_field);
542 return;
543 }
544
546 ast_str_set(&server_header_field,
547 0,
548 "Server: %s\r\n",
550 }
551
552 /*
553 * We shouldn't be sending non-final status codes to this
554 * function because we may close the connection before
555 * returning.
556 */
557 ast_assert(200 <= status_code);
558
559 if (session_keep_alive <= 0) {
560 close_connection = 1;
561 } else {
563
564 request = ser->private_data;
565 if (!request
567 || ast_http_body_discard(ser)) {
568 close_connection = 1;
569 } else {
570 close_connection = 0;
571 }
572 }
573
574 ast_strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", ast_localtime(&now, &tm, "GMT"));
575
576 /* calc content length */
577 if (out) {
578 content_length += ast_str_strlen(out);
579 }
580
581 if (fd) {
582 content_length += lseek(fd, 0, SEEK_END);
583 lseek(fd, 0, SEEK_SET);
584 }
585
586 send_content = method != AST_HTTP_HEAD || status_code >= 400;
587
588 /* send http header */
590 "HTTP/1.1 %d %s\r\n"
591 "%s"
592 "Date: %s\r\n"
593 "%s"
594 "%s"
595 "%s"
596 "Content-Length: %d\r\n"
597 "\r\n"
598 "%s",
599 status_code, status_title ? status_title : "OK",
600 ast_str_buffer(server_header_field),
601 timebuf,
602 close_connection ? "Connection: close\r\n" : "",
603 static_content ? "" : "Cache-Control: no-cache, no-store\r\n",
604 http_header ? ast_str_buffer(http_header) : "",
605 content_length,
606 send_content && out && ast_str_strlen(out) ? ast_str_buffer(out) : ""
607 ) <= 0) {
608 ast_debug(1, "ast_iostream_printf() failed: %s\n", strerror(errno));
609 close_connection = 1;
610 } else if (send_content && fd) {
611 /* send file content */
612 while ((len = read(fd, buf, sizeof(buf))) > 0) {
613 if (ast_iostream_write(ser->stream, buf, len) != len) {
614 ast_debug(1, "ast_iostream_write() failed: %s\n", strerror(errno));
615 close_connection = 1;
616 break;
617 }
618 }
619 }
620
621 ast_free(http_header);
622 ast_free(out);
623 ast_free(server_header_field);
624
625 if (close_connection) {
626 ast_debug(1, "HTTP closing session. status_code:%d\n", status_code);
628 } else {
629 ast_debug(1, "HTTP keeping session open. status_code:%d\n", status_code);
630 }
631}
int ast_http_body_discard(struct ast_tcptls_session_instance *ser)
Read and discard any unread HTTP request body.
Definition http.c:1193
@ AST_HTTP_HEAD
Definition http.h:62
ssize_t ast_iostream_printf(struct ast_iostream *stream, const char *format,...)
Write a formatted string to an iostream.
Definition iostream.c:507
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t count)
Write data to an iostream.
Definition iostream.c:390
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:1739
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:2524
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition strings.h:730
struct ast_iostream * stream
Definition tcptls.h:162
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159

References ast_assert, ast_debug, ast_free, ast_http_body_discard(), AST_HTTP_HEAD, ast_iostream_printf(), ast_iostream_write(), ast_localtime(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_strlen(), ast_strftime(), ast_strlen_zero(), ast_tcptls_close_session_file(), ast_test_flag, ast_tvnow(), buf, errno, HTTP_FLAG_CLOSE_ON_COMPLETION, http_server_name, len(), MAX_SERVER_NAME_LENGTH, method, out, ast_tcptls_session_instance::private_data, request(), session_keep_alive, and ast_tcptls_session_instance::stream.

Referenced by ast_ari_callback(), ast_http_create_response(), auth_http_callback(), generic_http_callback(), handle_uri(), http_callback(), http_callback(), httpstatus_callback(), phoneprov_callback(), static_callback(), and websocket_bad_request().

◆ ast_http_uri_link()

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 747 of file http.c.

748{
749 struct ast_http_uri *uri;
750 int len = strlen(urih->uri);
751
753
754 urih->prefix = prefix;
755
756 if ( AST_RWLIST_EMPTY(&uris) || strlen(AST_RWLIST_FIRST(&uris)->uri) <= len ) {
759 return 0;
760 }
761
763 if (AST_RWLIST_NEXT(uri, entry) &&
764 strlen(AST_RWLIST_NEXT(uri, entry)->uri) <= len) {
767
768 return 0;
769 }
770 }
771
773
775
776 return 0;
777}
Definition of a URI handler.
Definition http.h:102
const char * prefix
Definition http.h:106
const char * uri
Definition http.h:105
struct ast_http_uri::@239 entry
Definition http.c:142

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

Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), reload_module(), and reload_module().

◆ ast_http_uri_unlink()

void ast_http_uri_unlink ( struct ast_http_uri urih)

◆ ast_http_uri_unlink_all_with_key()

void ast_http_uri_unlink_all_with_key ( const char *  key)

Unregister all handlers with matching key.

Definition at line 786 of file http.c.

787{
788 struct ast_http_uri *urih;
791 if (!strcmp(urih->key, key)) {
793 if (urih->dmallocd) {
794 ast_free(urih->data);
795 }
796 if (urih->mallocd) {
797 ast_free(urih);
798 }
799 }
800 }
803}
#define AST_RWLIST_REMOVE_CURRENT
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#define AST_RWLIST_TRAVERSE_SAFE_END
unsigned int dmallocd
Definition http.h:112
void * data
Definition http.h:116
const char * key
Definition http.h:118
unsigned int mallocd
Definition http.h:110

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

Referenced by __ast_http_post_load(), and unload_module().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 2938 of file http.c.

◆ auth_create()

static struct ast_http_auth * auth_create ( const char *  userid,
const char *  password 
)
static

Definition at line 1643 of file http.c.

1644{
1645 struct ast_http_auth *auth;
1646 size_t userid_len;
1647 size_t password_len;
1648
1649 if (!userid || !password) {
1650 ast_log(LOG_ERROR, "Invalid userid/password\n");
1651 return NULL;
1652 }
1653
1654 userid_len = strlen(userid) + 1;
1655 password_len = strlen(password) + 1;
1656
1657 /* Allocate enough room to store everything in one memory block */
1658 auth = ao2_alloc(sizeof(*auth) + userid_len + password_len, NULL);
1659 if (!auth) {
1660 return NULL;
1661 }
1662
1663 /* Put the userid right after the struct */
1664 auth->userid = (char *)(auth + 1);
1665 strcpy(auth->userid, userid);
1666
1667 /* Put the password right after the userid */
1668 auth->password = auth->userid + userid_len;
1669 strcpy(auth->password, password);
1670
1671 return auth;
1672}
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
HTTP authentication information.
Definition http.h:125
char * password
Definition http.h:129
char * userid
Definition http.h:127

References ao2_alloc, ast_log, LOG_ERROR, NULL, ast_http_auth::password, and ast_http_auth::userid.

Referenced by ast_http_get_auth().

◆ check_restriction_acl()

static int check_restriction_acl ( struct ast_tcptls_session_instance ser,
const char *  uri 
)
static

Check if a URI path is allowed or denied by acl.

Parameters
serTCP/TLS session instance
uriThe URI path to check
Returns
0 if allowed, -1 if denied

Definition at line 2165 of file http.c.

2166{
2167 struct http_restriction *restriction;
2168 int denied = 0;
2169
2171 AST_RWLIST_TRAVERSE(&restrictions, restriction, entry) {
2172 if (ast_begins_with(uri, restriction->path)) {
2173 if (restriction->acl && !ast_acl_list_is_empty(restriction->acl)) {
2174 if (ast_apply_acl(restriction->acl, &ser->remote_address,
2175 "HTTP Path ACL") == AST_SENSE_DENY) {
2176 ast_debug(2, "HTTP request for uri '%s' from %s denied by acl by restriction on '%s'\n",
2177 uri, ast_sockaddr_stringify(&ser->remote_address), restriction->path);
2178 denied = -1;
2179 break;
2180 }
2181 }
2182 }
2183 }
2185
2186 return denied;
2187}
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition acl.c:799
@ AST_SENSE_DENY
Definition acl.h:37
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition acl.c:540
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition linkedlists.h:78
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition netsock2.h:256
struct ast_sockaddr remote_address
Definition tcptls.h:153
struct http_restriction::@388 entry

References http_restriction::acl, ast_acl_list_is_empty(), ast_apply_acl(), ast_begins_with(), ast_debug, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_SENSE_DENY, ast_sockaddr_stringify(), http_restriction::entry, http_restriction::path, and ast_tcptls_session_instance::remote_address.

Referenced by handle_uri().

◆ chunked_atoh()

static int chunked_atoh ( const char *  s,
int  len 
)
static

Definition at line 1060 of file http.c.

1061{
1062 int value = 0;
1063 char c;
1064
1065 if (*s < '0') {
1066 /* zero value must be 0\n not just \n */
1067 return -1;
1068 }
1069
1070 while (len--) {
1071 c = *s++;
1072 if (c == '\x0D') {
1073 return value;
1074 }
1075 if (c == ';') {
1076 /* We have a chunk-extension that we don't care about. */
1077 while (len--) {
1078 if (*s++ == '\x0D') {
1079 return value;
1080 }
1081 }
1082 break;
1083 }
1084 value <<= 4;
1085 if (c >= '0' && c <= '9') {
1086 value += c - '0';
1087 continue;
1088 }
1089 if (c >= 'a' && c <= 'f') {
1090 value += 10 + c - 'a';
1091 continue;
1092 }
1093 if (c >= 'A' && c <= 'F') {
1094 value += 10 + c - 'A';
1095 continue;
1096 }
1097 /* invalid character */
1098 return -1;
1099 }
1100 /* end of string */
1101 return -1;
1102}
static struct test_val c

References c, len(), and value.

Referenced by http_body_get_chunk_length().

◆ get_content_length()

static int get_content_length ( struct ast_variable headers)
static

Returns the value of the Content-Length header.

Parameters
headersHTTP headers.
Returns
length Value of the Content-Length header.
Return values
0if header is not present.
-1if header is invalid.

Definition at line 861 of file http.c.

862{
863 const char *content_length = get_header(headers, "Content-Length");
864 int length;
865
866 if (!content_length) {
867 /* Missing content length; assume zero */
868 return 0;
869 }
870
871 length = 0;
872 if (sscanf(content_length, "%30d", &length) != 1) {
873 /* Invalid Content-Length value */
874 length = -1;
875 }
876 return length;
877}
static const char * get_header(struct ast_variable *headers, const char *field_name)
Retrieves the header with the given field name.
Definition http.c:813

References get_header().

Referenced by http_request_tracking_setup().

◆ get_content_type()

static char * get_content_type ( struct ast_variable headers)
static

Retrieves the content type specified in the "Content-Type" header.

This function only returns the "type/subtype" and any trailing parameter is not included.

Note
the return value is an allocated string that needs to be freed.
Returns
the content type/subtype
Return values
NULLif the header is not found.

Definition at line 836 of file http.c.

837{
838 const char *content_type = get_header(headers, "Content-Type");
839 const char *param;
840 size_t size;
841
842 if (!content_type) {
843 return NULL;
844 }
845
846 param = strchr(content_type, ';');
847 size = param ? param - content_type : strlen(content_type);
848
849 return ast_strndup(content_type, size);
850}
#define ast_strndup(str, len)
A wrapper for strndup()
Definition astmm.h:256

References ast_strndup, get_header(), and NULL.

Referenced by ast_http_get_json(), and ast_http_get_post_vars().

◆ get_header()

static const char * get_header ( struct ast_variable headers,
const char *  field_name 
)
static

Retrieves the header with the given field name.

Parameters
headersHeaders to search.
field_nameName of the header to find.
Returns
Associated header value.
Return values
NULLif header is not present.

Definition at line 813 of file http.c.

814{
815 struct ast_variable *v;
816
817 for (v = headers; v; v = v->next) {
818 if (!strcasecmp(v->name, field_name)) {
819 return v->value;
820 }
821 }
822 return NULL;
823}

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

Referenced by get_content_length(), get_content_type(), get_transfer_encoding(), and http_check_connection_close().

◆ get_transfer_encoding()

static const char * get_transfer_encoding ( struct ast_variable headers)
static

Returns the value of the Transfer-Encoding header.

Parameters
headersHTTP headers.
Returns
string Value of the Transfer-Encoding header.
Return values
NULLif header is not present.

Definition at line 886 of file http.c.

887{
888 return get_header(headers, "Transfer-Encoding");
889}

References get_header().

Referenced by http_request_tracking_setup(), and httpd_process_request().

◆ handle_show_http()

static char * handle_show_http ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2787 of file http.c.

2788{
2789 struct ast_http_uri *urih;
2790 struct http_uri_redirect *redirect;
2791
2792 switch (cmd) {
2793 case CLI_INIT:
2794 e->command = "http show status";
2795 e->usage =
2796 "Usage: http show status\n"
2797 " Lists status of internal HTTP engine\n";
2798 return NULL;
2799 case CLI_GENERATE:
2800 return NULL;
2801 }
2802
2803 if (a->argc != 3) {
2804 return CLI_SHOWUSAGE;
2805 }
2806 ast_cli(a->fd, "HTTP Server Status:\n");
2807 ast_cli(a->fd, "Prefix: %s\n", prefix);
2808 ast_cli(a->fd, "Server: %s\n", http_server_name);
2809 if (!global_http_server) {
2810 ast_cli(a->fd, "Server Disabled\n\n");
2811 } else {
2812 ast_cli(a->fd, "Server Enabled and Bound to %s\n\n",
2814 if (http_tls_cfg.enabled) {
2815 ast_cli(a->fd, "HTTPS Server Enabled and Bound to %s\n\n",
2817 }
2818 }
2819
2820 ast_cli(a->fd, "Enabled URI's:\n");
2822 if (AST_RWLIST_EMPTY(&uris)) {
2823 ast_cli(a->fd, "None.\n");
2824 } else {
2826 ast_cli(a->fd, "%s/%s%s => %s\n", prefix, urih->uri, (urih->has_subtree ? "/..." : "" ), urih->description);
2827 }
2829
2830 ast_cli(a->fd, "\nEnabled Redirects:\n");
2833 ast_cli(a->fd, " None.\n");
2834 } else {
2836 ast_cli(a->fd, " %s => %s\n", redirect->target, redirect->dest);
2837 }
2839
2840 ast_cli(a->fd, "\nPath Restrictions:\n");
2843 ast_cli(a->fd, " None.\n");
2844 } else {
2845 struct http_restriction *restriction;
2846 AST_RWLIST_TRAVERSE(&restrictions, restriction, entry) {
2847 ast_cli(a->fd, " Path: %s\n", restriction->path);
2848 if (restriction->acl && !ast_acl_list_is_empty(restriction->acl)) {
2849 ast_acl_output(a->fd, restriction->acl, " ");
2850 } else {
2851 ast_cli(a->fd, " No ACL configured\n");
2852 }
2853 }
2854 }
2856
2857 return CLI_SUCCESS;
2858}
void ast_acl_output(int fd, struct ast_acl_list *acl, const char *prefix)
output an ACL to the provided fd
Definition acl.c:1115
#define CLI_SHOWUSAGE
Definition cli.h:45
#define CLI_SUCCESS
Definition cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
unsigned int has_subtree
Definition http.h:108
struct ast_sockaddr old_address
Definition tcptls.h:132
static struct test_val a

References a, http_restriction::acl, ast_http_server::args, ast_acl_list_is_empty(), ast_acl_output(), ast_cli(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_sockaddr_stringify(), 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, http_restriction::entry, global_http_server, ast_http_uri::has_subtree, http_server_name, http_tls_cfg, https_desc, NULL, ast_tcptls_session_args::old_address, http_restriction::path, prefix, http_uri_redirect::target, ast_http_uri::uri, and ast_cli_entry::usage.

◆ handle_uri()

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 1491 of file http.c.

1493{
1494 char *c;
1495 int res = 0;
1496 char *params = uri;
1497 struct ast_http_uri *urih = NULL;
1498 int l;
1499 struct ast_variable *get_vars = NULL, *v, *prev = NULL;
1500 struct http_uri_redirect *redirect;
1501
1502 ast_debug(2, "HTTP Request URI is %s \n", uri);
1503
1504 strsep(&params, "?");
1505 /* Extract arguments from the request and store them in variables. */
1506 if (params) {
1507 char *var, *val;
1508
1509 while ((val = strsep(&params, "&"))) {
1510 var = strsep(&val, "=");
1511 if (val) {
1513 } else {
1514 val = "";
1515 }
1517 if ((v = ast_variable_new(var, val, ""))) {
1518 if (get_vars) {
1519 prev->next = v;
1520 } else {
1521 get_vars = v;
1522 }
1523 prev = v;
1524 }
1525 }
1526 }
1527
1528 /* Check path-based ACL restrictions */
1529 if (check_restriction_acl(ser, uri) != 0) {
1531 ast_http_error(ser, 403, "Forbidden", "Access denied by ACL");
1532 goto cleanup;
1533 }
1534
1537 if (!strcasecmp(uri, redirect->target)) {
1538 struct ast_str *http_header = ast_str_create(128);
1539
1540 if (!http_header) {
1542 ast_http_error(ser, 500, "Server Error", "Out of memory");
1543 break;
1544 }
1545 ast_str_set(&http_header, 0, "Location: %s\r\n", redirect->dest);
1546 ast_http_send(ser, method, 302, "Moved Temporarily", http_header, NULL, 0, 0);
1547 break;
1548 }
1549 }
1551 if (redirect) {
1552 goto cleanup;
1553 }
1554
1555 /* We want requests to start with the (optional) prefix and '/' */
1556 l = strlen(prefix);
1557 if (!strncasecmp(uri, prefix, l) && uri[l] == '/') {
1558 uri += l + 1;
1559 /* scan registered uris to see if we match one. */
1561 AST_RWLIST_TRAVERSE(&uris, urih, entry) {
1562 l = strlen(urih->uri);
1563 c = uri + l; /* candidate */
1564 ast_debug(2, "match request [%s] with handler [%s] len %d\n", uri, urih->uri, l);
1565 if (strncasecmp(urih->uri, uri, l) /* no match */
1566 || (*c && *c != '/')) { /* substring */
1567 continue;
1568 }
1569 if (*c == '/') {
1570 c++;
1571 }
1572 if (!*c || urih->has_subtree) {
1573 uri = c;
1574 break;
1575 }
1576 }
1578 }
1579 if (urih) {
1580 ast_debug(1, "Match made with [%s]\n", urih->uri);
1581 if (!urih->no_decode_uri) {
1583 }
1584 res = urih->callback(ser, urih, uri, method, get_vars, headers);
1585 } else {
1586 ast_debug(1, "Request from %s for URI [%s] has no registered handler\n",
1588 ast_http_error(ser, 404, "Not Found", "The requested URL was not found on this server.");
1589 }
1590
1591cleanup:
1592 ast_variables_destroy(get_vars);
1593 return res;
1594}
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 http.c:722
void ast_http_request_close_on_completion(struct ast_tcptls_session_instance *ser)
Request the HTTP connection be closed after this HTTP request.
Definition http.c:911
static int check_restriction_acl(struct ast_tcptls_session_instance *ser, const char *uri)
Check if a URI path is allowed or denied by acl.
Definition http.c:2165
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:286
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition res_stasis.c:327
unsigned int no_decode_uri
Definition http.h:114
ast_http_callback callback
Definition http.h:107

References ast_debug, ast_http_error(), ast_http_request_close_on_completion(), ast_http_send(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_sockaddr_stringify_addr(), ast_str_create, ast_str_set(), ast_uri_decode(), ast_uri_http_legacy, ast_variable_new, ast_variables_destroy(), c, ast_http_uri::callback, check_restriction_acl(), cleanup(), http_uri_redirect::dest, http_uri_redirect::entry, ast_http_uri::has_subtree, method, ast_http_uri::no_decode_uri, NULL, prefix, ast_tcptls_session_instance::remote_address, strsep(), http_uri_redirect::target, ast_http_uri::uri, and var.

Referenced by httpd_process_request().

◆ http_body_check_chunk_sync()

static int http_body_check_chunk_sync ( struct ast_tcptls_session_instance ser)
static

Definition at line 1142 of file http.c.

1143{
1144 int res;
1145 char chunk_sync[2];
1146
1147 /* Stay in fread until get the expected CRLF or timeout. */
1148 res = ast_iostream_read(ser->stream, chunk_sync, sizeof(chunk_sync));
1149 if (res < sizeof(chunk_sync)) {
1150 ast_log(LOG_WARNING, "Short HTTP chunk sync read (Wanted %zu)\n",
1151 sizeof(chunk_sync));
1152 return -1;
1153 }
1154 if (chunk_sync[0] != 0x0D || chunk_sync[1] != 0x0A) {
1155 ast_log(LOG_WARNING, "HTTP chunk sync bytes wrong (0x%02hhX, 0x%02hhX)\n",
1156 (unsigned char) chunk_sync[0], (unsigned char) chunk_sync[1]);
1157 return -1;
1158 }
1159
1160 return 0;
1161}
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
Definition iostream.c:289

References ast_iostream_read(), ast_log, LOG_WARNING, and ast_tcptls_session_instance::stream.

Referenced by ast_http_body_discard(), and ast_http_get_contents().

◆ http_body_discard_chunk_trailer_headers()

static int http_body_discard_chunk_trailer_headers ( struct ast_tcptls_session_instance ser)
static

Definition at line 1173 of file http.c.

1174{
1175 char header_line[MAX_HTTP_LINE_LENGTH];
1176
1177 for (;;) {
1178 if (ast_iostream_gets(ser->stream, header_line, sizeof(header_line)) <= 0) {
1179 ast_log(LOG_WARNING, "Short HTTP read of chunked trailer header\n");
1180 return -1;
1181 }
1182
1183 /* Trim trailing whitespace */
1184 ast_trim_blanks(header_line);
1185 if (ast_strlen_zero(header_line)) {
1186 /* A blank line ends the chunked-body */
1187 break;
1188 }
1189 }
1190 return 0;
1191}
#define MAX_HTTP_LINE_LENGTH
Definition http.c:100
ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size)
Read a LF-terminated string from an iostream.
Definition iostream.c:316

References ast_iostream_gets(), ast_log, ast_strlen_zero(), ast_trim_blanks(), LOG_WARNING, MAX_HTTP_LINE_LENGTH, and ast_tcptls_session_instance::stream.

Referenced by ast_http_body_discard(), and ast_http_get_contents().

◆ http_body_discard_contents()

static int http_body_discard_contents ( struct ast_tcptls_session_instance ser,
int  length,
const char *  what_getting 
)
static

Definition at line 1037 of file http.c.

1038{
1039 ssize_t res;
1040
1041 res = ast_iostream_discard(ser->stream, length);
1042 if (res < length) {
1043 ast_log(LOG_WARNING, "Short HTTP request %s (Wanted %d but got %zd)\n",
1044 what_getting, length, res);
1045 return -1;
1046 }
1047 return 0;
1048}
ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t count)
Discard the specified number of bytes from an iostream.
Definition iostream.c:373

References ast_iostream_discard(), ast_log, LOG_WARNING, and ast_tcptls_session_instance::stream.

Referenced by ast_http_body_discard().

◆ http_body_get_chunk_length()

static int http_body_get_chunk_length ( struct ast_tcptls_session_instance ser)
static

Definition at line 1114 of file http.c.

1115{
1116 int length;
1117 char header_line[MAX_HTTP_LINE_LENGTH];
1118
1119 /* get the line of hexadecimal giving chunk-size w/ optional chunk-extension */
1120 if (ast_iostream_gets(ser->stream, header_line, sizeof(header_line)) <= 0) {
1121 ast_log(LOG_WARNING, "Short HTTP read of chunked header\n");
1122 return -1;
1123 }
1124 length = chunked_atoh(header_line, strlen(header_line));
1125 if (length < 0) {
1126 ast_log(LOG_WARNING, "Invalid HTTP chunk size\n");
1127 return -1;
1128 }
1129 return length;
1130}
static int chunked_atoh(const char *s, int len)
Definition http.c:1060

References ast_iostream_gets(), ast_log, chunked_atoh(), LOG_WARNING, MAX_HTTP_LINE_LENGTH, and ast_tcptls_session_instance::stream.

Referenced by ast_http_body_discard(), and ast_http_get_contents().

◆ http_body_read_contents()

static int http_body_read_contents ( struct ast_tcptls_session_instance ser,
char *  buf,
int  length,
const char *  what_getting 
)
static

Definition at line 1001 of file http.c.

1002{
1003 int res;
1004 int total = 0;
1005
1006 /* Stream is in exclusive mode so we get it all if possible. */
1007 while (total != length) {
1008 res = ast_iostream_read(ser->stream, buf + total, length - total);
1009 if (res <= 0) {
1010 break;
1011 }
1012
1013 total += res;
1014 }
1015
1016 if (total != length) {
1017 ast_log(LOG_WARNING, "Wrong HTTP content read. Request %s (Wanted %d, Read %d)\n",
1018 what_getting, length, res);
1019 return -1;
1020 }
1021
1022 return 0;
1023}
static int total
Definition res_adsi.c:970

References ast_iostream_read(), ast_log, buf, LOG_WARNING, ast_tcptls_session_instance::stream, and total.

Referenced by ast_http_get_contents().

◆ http_check_connection_close()

static int http_check_connection_close ( struct ast_variable headers)
static

Definition at line 900 of file http.c.

901{
902 const char *connection = get_header(headers, "Connection");
903 int close_connection = 0;
904
905 if (connection && !strcasecmp(connection, "close")) {
906 close_connection = -1;
907 }
908 return close_connection;
909}

References get_header().

Referenced by http_request_tracking_setup().

◆ http_request_headers_get()

static int http_request_headers_get ( struct ast_tcptls_session_instance ser,
struct ast_variable **  headers 
)
static

Definition at line 1899 of file http.c.

1900{
1901 struct ast_variable *tail = *headers;
1902 int remaining_headers;
1903 char header_line[MAX_HTTP_LINE_LENGTH];
1904
1905 remaining_headers = MAX_HTTP_REQUEST_HEADERS;
1906 for (;;) {
1907 ssize_t len;
1908 char *name;
1909 char *value;
1910
1911 len = ast_iostream_gets(ser->stream, header_line, sizeof(header_line));
1912 if (len <= 0) {
1913 ast_http_error(ser, 400, "Bad Request", "Timeout");
1914 return -1;
1915 }
1916 if (header_line[len - 1] != '\n') {
1917 /* We didn't get a full line */
1918 ast_http_error(ser, 400, "Bad Request",
1919 (len == sizeof(header_line) - 1) ? "Header line too long" : "Timeout");
1920 return -1;
1921 }
1922
1923 /* Trim trailing characters */
1924 ast_trim_blanks(header_line);
1925 if (ast_strlen_zero(header_line)) {
1926 /* A blank line ends the request header section. */
1927 break;
1928 }
1929
1930 value = header_line;
1931 name = strsep(&value, ":");
1932 if (!value) {
1933 continue;
1934 }
1935
1938 continue;
1939 }
1940
1942
1943 if (!remaining_headers--) {
1944 /* Too many headers. */
1945 ast_http_error(ser, 413, "Request Entity Too Large", "Too many headers");
1946 return -1;
1947 }
1948 if (!*headers) {
1949 *headers = ast_variable_new(name, value, __FILE__);
1950 tail = *headers;
1951 } else {
1952 tail->next = ast_variable_new(name, value, __FILE__);
1953 tail = tail->next;
1954 }
1955 if (!tail) {
1956 /*
1957 * Variable allocation failure.
1958 * Try to make some room.
1959 */
1960 ast_variables_destroy(*headers);
1961 *headers = NULL;
1962
1963 ast_http_error(ser, 500, "Server Error", "Out of memory");
1964 return -1;
1965 }
1966 }
1967
1968 return 0;
1969}
#define MAX_HTTP_REQUEST_HEADERS
Definition http.c:1886

References ast_http_error(), ast_iostream_gets(), ast_skip_blanks(), ast_strlen_zero(), ast_trim_blanks(), ast_variable_new, ast_variables_destroy(), len(), MAX_HTTP_LINE_LENGTH, MAX_HTTP_REQUEST_HEADERS, name, ast_variable::next, NULL, ast_tcptls_session_instance::stream, strsep(), and value.

Referenced by httpd_process_request().

◆ http_request_tracking_init()

static void http_request_tracking_init ( struct http_worker_private_data request)
static

Definition at line 925 of file http.c.

926{
929 /* Assume close in case request fails early */
931}
#define ast_set_flags_to(p, flag, value)
Definition utils.h:105

References ast_set_flags_to, HTTP_FLAG_BODY_READ, HTTP_FLAG_CLOSE_ON_COMPLETION, HTTP_FLAG_HAS_BODY, and request().

Referenced by httpd_helper_thread(), and httpd_process_request().

◆ http_request_tracking_setup()

static int http_request_tracking_setup ( struct ast_tcptls_session_instance ser,
struct ast_variable headers 
)
static

Definition at line 944 of file http.c.

945{
947 const char *transfer_encoding;
948
952
953 transfer_encoding = get_transfer_encoding(headers);
954 if (transfer_encoding && !strcasecmp(transfer_encoding, "chunked")) {
955 request->body_length = -1;
957 return 0;
958 }
959
960 request->body_length = get_content_length(headers);
961 if (0 < request->body_length) {
963 } else if (request->body_length < 0) {
964 /* Invalid Content-Length */
966 ast_http_error(ser, 400, "Bad Request", "Invalid Content-Length in request!");
967 return -1;
968 }
969 return 0;
970}
static int http_check_connection_close(struct ast_variable *headers)
Definition http.c:900
static const char * get_transfer_encoding(struct ast_variable *headers)
Returns the value of the Transfer-Encoding header.
Definition http.c:886
static int get_content_length(struct ast_variable *headers)
Returns the value of the Content-Length header.
Definition http.c:861

References ast_http_error(), ast_set_flag, ast_set_flags_to, get_content_length(), get_transfer_encoding(), http_check_connection_close(), HTTP_FLAG_BODY_READ, HTTP_FLAG_CLOSE_ON_COMPLETION, HTTP_FLAG_HAS_BODY, ast_tcptls_session_instance::private_data, and request().

Referenced by httpd_process_request().

◆ http_server_create()

static struct ast_http_server * http_server_create ( const char *  name,
const char *  address,
const struct ast_sockaddr addr 
)
static

Definition at line 2269 of file http.c.

2271{
2272 struct ast_http_server *server;
2273
2274 server = ao2_alloc(sizeof(*server), http_server_destroy);
2275 if (!server) {
2276 ast_log(LOG_ERROR, "Unable to allocate HTTP server '%s' at address '%s'\n",
2277 name, address);
2278 return NULL;
2279 }
2280
2281 if (!(server->address = ast_strdup(address)) || !(server->name = ast_strdup(name))) {
2282 ast_log(LOG_ERROR, "Unable to complete setup for HTTP server '%s' at address '%s'\n",
2283 name, address);
2284 ao2_ref(server, -1);
2285 return NULL;
2286 }
2287
2288 server->args.accept_fd = -1;
2289 server->args.master = AST_PTHREADT_NULL;
2290 server->args.tls_cfg = NULL;
2291 server->args.poll_timeout = -1;
2292 server->args.name = server->name;
2295
2296 ast_sockaddr_copy(&server->args.local_address, addr);
2297
2298 return server;
2299}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
char * address
Definition f2c.h:59
static void * httpd_helper_thread(void *arg)
Definition http.c:2079
static void http_server_destroy(void *obj)
Definition http.c:2257
#define AST_PTHREADT_NULL
Definition lock.h:73
char * name
Definition http.c:123
char * address
Definition http.c:124
void *(* accept_fn)(void *)
Definition tcptls.h:140
const char * name
Definition tcptls.h:143
void *(* worker_fn)(void *)
Definition tcptls.h:142
void * ast_tcptls_server_root(void *)
Definition tcptls.c:290

References ast_tcptls_session_args::accept_fd, ast_tcptls_session_args::accept_fn, ast_http_server::address, ao2_alloc, ao2_ref, ast_http_server::args, ast_log, AST_PTHREADT_NULL, ast_sockaddr_copy(), ast_strdup, ast_tcptls_server_root(), http_server_destroy(), httpd_helper_thread(), ast_tcptls_session_args::local_address, LOG_ERROR, ast_tcptls_session_args::master, name, ast_tcptls_session_args::name, ast_http_server::name, NULL, ast_tcptls_session_args::poll_timeout, ast_tcptls_session_args::tls_cfg, and ast_tcptls_session_args::worker_fn.

Referenced by http_server_get_by_addr().

◆ http_server_destroy()

static void http_server_destroy ( void *  obj)
static

Definition at line 2257 of file http.c.

2258{
2259 struct ast_http_server *server = obj;
2260
2261 ast_tcptls_server_stop(&server->args);
2262
2263 ast_verb(1, "Stopped http server '%s' listening at '%s'\n", server->name, server->address);
2264
2265 ast_free(server->name);
2266 ast_free(server->address);
2267}
#define ast_verb(level,...)

References ast_http_server::address, ast_http_server::args, ast_free, ast_tcptls_server_stop(), ast_verb, and ast_http_server::name.

Referenced by http_server_create().

◆ http_server_discard()

static void http_server_discard ( struct ast_http_server server)
static

Discard/Drop a HTTP server.

Decrements the reference to the given object, and unlinks it from the servers container if it's the last reference.

After a server object has been added to the container this method should always be called to decrement the object's reference instead of the regular ao2 methods.

Note
NULL tolerant
Parameters
serverThe server object

Definition at line 2339 of file http.c.

2340{
2341 if (!server) {
2342 return;
2343 }
2344
2345 /*
2346 * If only two references were on the object then the last one is from
2347 * the servers container, so remove from container now.
2348 */
2349 if (ao2_ref(server, -1) == 2) {
2350 ao2_unlink(http_servers, server);
2351 }
2352}
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition astobj2.h:1578
struct ao2_container * http_servers
Definition http.c:2252

References ao2_ref, ao2_unlink, and http_servers.

Referenced by __ast_http_load(), and http_server_get().

◆ http_server_get()

static struct ast_http_server * http_server_get ( const char *  name,
const char *  host,
uint32_t  port,
struct ast_http_server **  replace_me 
)
static

Retrieve, or create and start a HTTP server.

Resolve the given host, and retrieve a listening server object. If the server is not already listening then start it. If a replace_me parameter is given, and it points to a non-NULL value then that server is discarded and replaced.

Parameters
nameThe name of the server
hostThe host to resolve, and match on or create a new object with
portOptional port used if one is not specified with the host (default 8088)
[out]replace_meOptional server to be replaced
Note
If replace_me is specified the returned value is always the same as what's passed back out in the variable.
Returns
a HTTP server object, or NULL on error

Definition at line 2449 of file http.c.

2451{
2452 struct ast_http_server *server;
2453
2455
2456 server = http_server_get_by_host(name, host, port);
2457
2458 if (replace_me) {
2459 /* Only replace if different */
2460 if (*replace_me == server) {
2461 ao2_cleanup(server);
2463 return *replace_me;
2464 }
2465
2466 if (*replace_me) {
2467 http_server_discard(*replace_me);
2468 }
2469
2470 *replace_me = server;
2471 }
2472
2473 if (server && http_server_start(server)) {
2474 if (replace_me) {
2475 *replace_me = NULL;
2476 }
2477
2478 ao2_ref(server, -1);
2479 server = NULL;
2480 }
2481
2483 return server;
2484}
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_unlock(a)
Definition astobj2.h:729
#define ao2_lock(a)
Definition astobj2.h:717
static int http_server_start(struct ast_http_server *server)
Definition http.c:2301
static struct ast_http_server * http_server_get_by_host(const char *name, const char *host, uint32_t port)
Retrieve, or create a HTTP server object by host.
Definition http.c:2397

References ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, http_server_discard(), http_server_get_by_host(), http_server_start(), http_servers, name, and NULL.

Referenced by __ast_http_load().

◆ http_server_get_by_addr()

static struct ast_http_server * http_server_get_by_addr ( const char *  name,
const struct ast_sockaddr addr 
)
static

Retrieve, or create a HTTP server object by sock address.

Look for, and return a matching server object by addr. If an object is not found then create a new one.

Note
This method should be called with the http_servers container already locked.
Parameters
nameThe name of the server
addrThe address to match on, or create a new object with
Returns
a HTTP server object, or NULL on error

Definition at line 2367 of file http.c.

2369{
2370 struct ast_http_server *server;
2371 const char *address;
2372
2374 if (ast_strlen_zero(address)) {
2375 return NULL;
2376 }
2377
2379
2380 return server ?: http_server_create(name, address, addr);
2381}
#define OBJ_KEY
Definition astobj2.h:1151
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition astobj2.h:1063
static struct ast_http_server * http_server_create(const char *name, const char *address, const struct ast_sockaddr *addr)
Definition http.c:2269

References ao2_find, ast_sockaddr_stringify(), ast_strlen_zero(), http_server_create(), http_servers, name, NULL, OBJ_KEY, and OBJ_NOLOCK.

Referenced by http_server_get_by_host().

◆ http_server_get_by_host()

static struct ast_http_server * http_server_get_by_host ( const char *  name,
const char *  host,
uint32_t  port 
)
static

Retrieve, or create a HTTP server object by host.

Resolve the given host, and then look for, and return a matching server object. If an object is not found then create a new one.

Note
This method should be called with the http_servers container already locked.
Parameters
nameThe name of the server
hostThe host to resolve, and match on or create a new object with
portOptional port used if one is not specified with the host (default 8088)
Returns
a HTTP server object, or NULL on error

Definition at line 2397 of file http.c.

2399{
2400 struct ast_sockaddr *addrs = NULL;
2401 int num_addrs;
2402 int i;
2403
2404 if (!(num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC))) {
2405 ast_log(LOG_WARNING, "Unable to resolve host '%s'\n", host);
2406 return NULL;
2407 }
2408
2409 if (port == 0) {
2410 port = DEFAULT_PORT;
2411 }
2412
2413 for (i = 0; i < num_addrs; ++i) {
2414 struct ast_http_server *server;
2415
2416 /* Use the given port if one was not specified already */
2417 if (!ast_sockaddr_port(&addrs[i])) {
2418 ast_sockaddr_set_port(&addrs[i], port);
2419 }
2420
2421 server = http_server_get_by_addr(name, &addrs[i]);
2422 if (server) {
2423 ast_free(addrs);
2424 return server;
2425 }
2426 }
2427
2428 ast_free(addrs);
2429 return NULL;
2430}
static struct ast_http_server * http_server_get_by_addr(const char *name, const struct ast_sockaddr *addr)
Retrieve, or create a HTTP server object by sock address.
Definition http.c:2367
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition netsock2.c:280
@ AST_AF_UNSPEC
Definition netsock2.h:54
Socket address structure.
Definition netsock2.h:97

References AST_AF_UNSPEC, ast_free, ast_log, ast_sockaddr_port, ast_sockaddr_resolve(), ast_sockaddr_set_port, DEFAULT_PORT, http_server_get_by_addr(), LOG_WARNING, name, and NULL.

Referenced by http_server_get().

◆ http_server_start()

static int http_server_start ( struct ast_http_server server)
static

Definition at line 2301 of file http.c.

2302{
2303 if (server->args.accept_fd != -1) {
2304 /* Already running */
2305 return 0;
2306 }
2307
2308 ast_tcptls_server_start(&server->args);
2309 if (server->args.accept_fd == -1) {
2310 ast_log(LOG_WARNING, "Failed to start HTTP server '%s' at address '%s'\n",
2311 server->name, server->address);
2312 return -1;
2313 }
2314
2315 if (!ao2_link_flags(http_servers, server, OBJ_NOLOCK)) {
2316 ast_log(LOG_WARNING, "Failed to link HTTP server '%s' at address '%s'\n",
2317 server->name, server->address);
2318 return -1;
2319 }
2320
2321 ast_verb(1, "Bound HTTP server '%s' to address %s\n", server->name, server->address);
2322
2323 return 0;
2324}
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition astobj2.h:1554

References ast_tcptls_session_args::accept_fd, ast_http_server::address, ao2_link_flags, ast_http_server::args, ast_log, ast_tcptls_server_start(), ast_verb, http_servers, LOG_WARNING, ast_http_server::name, and OBJ_NOLOCK.

Referenced by http_server_get().

◆ httpd_helper_thread()

static void * httpd_helper_thread ( void *  arg)
static

Definition at line 2079 of file http.c.

2080{
2081 struct ast_tcptls_session_instance *ser = data;
2082 int timeout;
2083 int arg = 1;
2084
2085 if (!ser) {
2086 ao2_cleanup(ser);
2087 return NULL;
2088 }
2089
2091 ast_log(LOG_WARNING, "HTTP session count exceeded %d sessions.\n",
2093 goto done;
2094 }
2095 ast_debug(1, "HTTP opening session. Top level\n");
2096
2097 /*
2098 * Here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
2099 * This is necessary to prevent delays (caused by buffering) as we
2100 * write to the socket in bits and pieces.
2101 */
2102 if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
2103 ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on HTTP connection: %s\n", strerror(errno));
2104 }
2106
2107 /* Setup HTTP worker private data to keep track of request body reading. */
2111 if (!ser->private_data) {
2112 ast_http_error(ser, 500, "Server Error", "Out of memory");
2113 goto done;
2114 }
2116
2117 /* Determine initial HTTP request wait timeout. */
2118 timeout = session_keep_alive;
2119 if (timeout <= 0) {
2120 /* Persistent connections not enabled. */
2121 timeout = session_inactivity;
2122 }
2123 if (timeout < MIN_INITIAL_REQUEST_TIMEOUT) {
2125 }
2126
2127 /* We can let the stream wait for data to arrive. */
2129
2130 for (;;) {
2131 /* Wait for next potential HTTP request message. */
2133 if (httpd_process_request(ser)) {
2134 /* Break the connection or the connection closed */
2135 break;
2136 }
2137 if (!ser->stream) {
2138 /* Web-socket or similar that took the connection */
2139 break;
2140 }
2141
2142 timeout = session_keep_alive;
2143 if (timeout <= 0) {
2144 /* Persistent connections not enabled. */
2145 break;
2146 }
2147 }
2148
2149done:
2151
2152 ast_debug(1, "HTTP closing session. Top level\n");
2154
2155 ao2_ref(ser, -1);
2156 return NULL;
2157}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
#define MIN_INITIAL_REQUEST_TIMEOUT
Definition http.c:76
static void http_request_tracking_init(struct http_worker_private_data *request)
Definition http.c:925
static int session_count
Definition http.c:110
static int httpd_process_request(struct ast_tcptls_session_instance *ser)
Definition http.c:1981
void ast_iostream_set_timeout_idle_inactivity(struct ast_iostream *stream, int timeout, int timeout_reset)
Set the iostream inactivity & idle timeout timers.
Definition iostream.c:136
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition iostream.c:85
void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input)
Set the iostream if it can exclusively depend upon the set timeouts.
Definition iostream.c:154
void ast_iostream_nonblock(struct ast_iostream *stream)
Make an iostream non-blocking.
Definition iostream.c:104
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition lock.h:764
describes a server instance
Definition tcptls.h:151
int done

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, ast_atomic_fetchadd_int(), ast_debug, ast_http_error(), ast_iostream_get_fd(), ast_iostream_nonblock(), ast_iostream_set_exclusive_input(), ast_iostream_set_timeout_idle_inactivity(), ast_log, ast_tcptls_close_session_file(), done, errno, http_request_tracking_init(), httpd_process_request(), LOG_WARNING, MIN_INITIAL_REQUEST_TIMEOUT, NULL, ast_tcptls_session_instance::private_data, session_count, session_inactivity, session_keep_alive, session_limit, and ast_tcptls_session_instance::stream.

Referenced by http_server_create().

◆ httpd_process_request()

static int httpd_process_request ( struct ast_tcptls_session_instance ser)
static

Definition at line 1981 of file http.c.

1982{
1983 RAII_VAR(struct ast_variable *, headers, NULL, ast_variables_destroy);
1984 char *uri;
1985 char *method;
1986 const char *transfer_encoding;
1988 enum ast_http_method http_method = AST_HTTP_UNKNOWN;
1989 int res;
1990 ssize_t len;
1991 char request_line[MAX_HTTP_LINE_LENGTH];
1992
1993 len = ast_iostream_gets(ser->stream, request_line, sizeof(request_line));
1994 if (len <= 0) {
1995 return -1;
1996 }
1997
1998 /* Re-initialize the request body tracking data. */
1999 request = ser->private_data;
2001
2002 if (request_line[len - 1] != '\n') {
2003 /* We didn't get a full line */
2004 ast_http_error(ser, 400, "Bad Request",
2005 (len == sizeof(request_line) - 1) ? "Request line too long" : "Timeout");
2006 return -1;
2007 }
2008
2009 /* Get method */
2010 method = ast_skip_blanks(request_line);
2012 if (*uri) {
2013 *uri++ = '\0';
2014 }
2015
2016 if (!strcasecmp(method,"GET")) {
2017 http_method = AST_HTTP_GET;
2018 } else if (!strcasecmp(method,"POST")) {
2019 http_method = AST_HTTP_POST;
2020 } else if (!strcasecmp(method,"HEAD")) {
2021 http_method = AST_HTTP_HEAD;
2022 } else if (!strcasecmp(method,"PUT")) {
2023 http_method = AST_HTTP_PUT;
2024 } else if (!strcasecmp(method,"DELETE")) {
2025 http_method = AST_HTTP_DELETE;
2026 } else if (!strcasecmp(method,"OPTIONS")) {
2027 http_method = AST_HTTP_OPTIONS;
2028 }
2029
2030 uri = ast_skip_blanks(uri); /* Skip white space */
2031 if (*uri) { /* terminate at the first blank */
2032 char *c = ast_skip_nonblanks(uri);
2033
2034 if (*c) {
2035 *c = '\0';
2036 }
2037 } else {
2038 ast_http_error(ser, 400, "Bad Request", "Invalid Request");
2039 return -1;
2040 }
2041
2042 if (ast_shutdown_final()) {
2043 ast_http_error(ser, 503, "Service Unavailable", "Shutdown in progress");
2044 return -1;
2045 }
2046
2047 /* process "Request Headers" lines */
2048 if (http_request_headers_get(ser, &headers)) {
2049 return -1;
2050 }
2051
2052 transfer_encoding = get_transfer_encoding(headers);
2053 /* Transfer encoding defaults to identity */
2054 if (!transfer_encoding) {
2055 transfer_encoding = "identity";
2056 }
2057
2058 /*
2059 * RFC 2616, section 3.6, we should respond with a 501 for any transfer-
2060 * codings we don't understand.
2061 */
2062 if (strcasecmp(transfer_encoding, "identity") != 0 &&
2063 strcasecmp(transfer_encoding, "chunked") != 0) {
2064 /* Transfer encodings not supported */
2065 ast_http_error(ser, 501, "Unimplemented", "Unsupported Transfer-Encoding.");
2066 return -1;
2067 }
2068
2069 if (http_request_tracking_setup(ser, headers)
2070 || handle_uri(ser, uri, http_method, headers)
2072 res = -1;
2073 } else {
2074 res = 0;
2075 }
2076 return res;
2077}
int ast_shutdown_final(void)
Definition asterisk.c:1884
static int http_request_headers_get(struct ast_tcptls_session_instance *ser, struct ast_variable **headers)
Definition http.c:1899
static int http_request_tracking_setup(struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
Definition http.c:944
static int handle_uri(struct ast_tcptls_session_instance *ser, char *uri, enum ast_http_method method, struct ast_variable *headers)
Definition http.c:1491
ast_http_method
HTTP Request methods known by Asterisk.
Definition http.h:58
@ AST_HTTP_PUT
Definition http.h:63
@ AST_HTTP_DELETE
Definition http.h:64
@ AST_HTTP_POST
Definition http.h:61
@ AST_HTTP_GET
Definition http.h:60
@ AST_HTTP_OPTIONS
Definition http.h:65
char *attribute_pure ast_skip_nonblanks(const char *str)
Gets a pointer to first whitespace character in a string.
Definition strings.h:204

References AST_HTTP_DELETE, ast_http_error(), AST_HTTP_GET, AST_HTTP_HEAD, AST_HTTP_OPTIONS, AST_HTTP_POST, AST_HTTP_PUT, AST_HTTP_UNKNOWN, ast_iostream_gets(), ast_shutdown_final(), ast_skip_blanks(), ast_skip_nonblanks(), ast_test_flag, ast_variables_destroy(), c, get_transfer_encoding(), handle_uri(), HTTP_FLAG_CLOSE_ON_COMPLETION, http_request_headers_get(), http_request_tracking_init(), http_request_tracking_setup(), len(), MAX_HTTP_LINE_LENGTH, method, NULL, ast_tcptls_session_instance::private_data, RAII_VAR, request(), and ast_tcptls_session_instance::stream.

Referenced by httpd_helper_thread().

◆ httpstatus_callback()

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 426 of file http.c.

430{
431 struct ast_str *out;
432 struct ast_variable *v, *cookies = NULL;
433
435 ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
436 return 0;
437 }
438
439 out = ast_str_create(512);
440 if (!out) {
442 ast_http_error(ser, 500, "Server Error", "Out of memory");
443 return 0;
444 }
445
447 "<html><title>Asterisk HTTP Status</title>\r\n"
448 "<body bgcolor=\"#ffffff\">\r\n"
449 "<table bgcolor=\"#f1f1f1\" align=\"center\"><tr><td bgcolor=\"#e0e0ff\" colspan=\"2\" width=\"500\">\r\n"
450 "<h2>&nbsp;&nbsp;Asterisk&trade; HTTP Status</h2></td></tr>\r\n");
451
452 ast_str_append(&out, 0, "<tr><td><i>Server</i></td><td><b>%s</b></td></tr>\r\n", http_server_name);
453 ast_str_append(&out, 0, "<tr><td><i>Prefix</i></td><td><b>%s</b></td></tr>\r\n", prefix);
454 if (global_http_server) {
455 ast_str_append(&out, 0, "<tr><td><i>Bind Address</i></td><td><b>%s</b></td></tr>\r\n",
457 }
458 if (http_tls_cfg.enabled) {
459 ast_str_append(&out, 0, "<tr><td><i>TLS Bind Address</i></td><td><b>%s</b></td></tr>\r\n",
461 }
462 ast_str_append(&out, 0, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
463 for (v = get_vars; v; v = v->next) {
464 ast_str_append(&out, 0, "<tr><td><i>Submitted GET Variable '");
466 ast_str_append(&out, 0, "'</i></td><td>");
468 ast_str_append(&out, 0, "</td></tr>\r\n");
469 }
470 ast_str_append(&out, 0, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
471
472 cookies = ast_http_get_cookies(headers);
473 for (v = cookies; v; v = v->next) {
474 ast_str_append(&out, 0, "<tr><td><i>Cookie '");
476 ast_str_append(&out, 0, "'</i></td><td>");
478 ast_str_append(&out, 0, "</td></tr>\r\n");
479 }
480 ast_variables_destroy(cookies);
481
482 ast_str_append(&out, 0, "</table><center><font size=\"-1\"><i>Asterisk and Digium are registered trademarks of Digium, Inc.</i></font></center></body></html>\r\n");
483 ast_http_send(ser, method, 200, NULL, NULL, out, 0, 0);
484 return 0;
485}
static void str_append_escaped(struct ast_str **str, const char *in)
Definition http.c:398
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:1139

References ast_http_server::args, ast_http_error(), AST_HTTP_GET, ast_http_get_cookies(), AST_HTTP_HEAD, ast_http_request_close_on_completion(), ast_http_send(), ast_sockaddr_stringify(), ast_str_append(), ast_str_create, ast_variables_destroy(), ast_tls_config::enabled, global_http_server, http_server_name, http_tls_cfg, https_desc, method, ast_variable::name, ast_variable::next, NULL, ast_tcptls_session_args::old_address, out, prefix, str_append_escaped(), and ast_variable::value.

◆ load_module()

static int load_module ( void  )
static

Definition at line 2912 of file http.c.

2913{
2915
2917 HTTP_SERVER_BUCKETS, ast_http_server_hash_fn, NULL, ast_http_server_cmp_fn);
2918 if (!http_servers) {
2920 }
2921
2922 if (__ast_http_load(0)) {
2926 }
2927
2929}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition astobj2.h:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition astobj2.h:1303
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
static int __ast_http_load(int reload)
Definition http.c:2536
static struct ast_cli_entry cli_http[]
Definition http.c:2865
#define HTTP_SERVER_BUCKETS
Number of HTTP server buckets.
Definition http.c:2250
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70

References __ast_http_load(), AO2_ALLOC_OPT_LOCK_MUTEX, ao2_cleanup, ao2_container_alloc_hash, ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, cli_http, HTTP_SERVER_BUCKETS, http_servers, and NULL.

◆ parse_cookies()

static struct ast_variable * parse_cookies ( const char *  cookies)
static

Definition at line 1596 of file http.c.

1597{
1598 char *parse = ast_strdupa(cookies);
1599 char *cur;
1600 struct ast_variable *vars = NULL, *var;
1601
1602 while ((cur = strsep(&parse, ";"))) {
1603 char *name, *val;
1604
1605 name = val = cur;
1606 strsep(&val, "=");
1607
1609 continue;
1610 }
1611
1612 name = ast_strip(name);
1613 val = ast_strip_quoted(val, "\"", "\"");
1614
1616 continue;
1617 }
1618
1619 ast_debug(1, "HTTP Cookie, Name: '%s' Value: '%s'\n", name, val);
1620
1621 var = ast_variable_new(name, val, __FILE__);
1622 var->next = vars;
1623 vars = var;
1624 }
1625
1626 return vars;
1627}
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:1852
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition strings.h:223

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

Referenced by ast_http_get_cookies().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 2860 of file http.c.

2861{
2862 return __ast_http_load(1);
2863}

References __ast_http_load().

◆ remove_excess_lws()

static void remove_excess_lws ( char *  s)
static

Definition at line 1801 of file http.c.

1802{
1803 char *p, *res = s;
1804 char *buf = ast_malloc(strlen(s) + 1);
1805 char *buf_end;
1806
1807 if (!buf) {
1808 return;
1809 }
1810
1811 buf_end = buf;
1812
1813 while (*s && *(s = ast_skip_blanks(s))) {
1814 p = s;
1815 s = ast_skip_nonblanks(s);
1816
1817 if (buf_end != buf) {
1818 *buf_end++ = ' ';
1819 }
1820
1821 memcpy(buf_end, p, s - p);
1822 buf_end += s - p;
1823 }
1824 *buf_end = '\0';
1825 /* safe since buf will always be less than or equal to res */
1826 strcpy(res, buf);
1827 ast_free(buf);
1828}

References ast_free, ast_malloc, ast_skip_blanks(), ast_skip_nonblanks(), and buf.

Referenced by ast_http_header_parse().

◆ static_callback()

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 270 of file http.c.

274{
275 char *path;
276 const char *ftype;
277 const char *mtype;
278 char wkspace[80];
279 struct stat st;
280 int len;
281 int fd;
282 struct ast_str *http_header;
283 struct timeval tv;
284 struct ast_tm tm;
285 char timebuf[80], etag[23];
286 struct ast_variable *v;
287 int not_modified = 0;
288
290 ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
291 return 0;
292 }
293
294 /* Yuck. I'm not really sold on this, but if you don't deliver static content it
295 * makes your configuration substantially more challenging, but this seems like a
296 * rather irritating feature creep on Asterisk.
297 *
298 * XXX: It is not clear to me what this comment means or if it is any longer
299 * relevant. */
300 if (ast_strlen_zero(uri)) {
301 goto out403;
302 }
303
304 /* Disallow any funny filenames at all (checking first character only??) */
305 if ((uri[0] < 33) || strchr("./|~@#$%^&*() \t", uri[0])) {
306 goto out403;
307 }
308
309 if (strstr(uri, "/..")) {
310 goto out403;
311 }
312
313 if ((ftype = strrchr(uri, '.'))) {
314 ftype++;
315 }
316
317 if (!(mtype = ast_http_ftype2mtype(ftype))) {
318 snprintf(wkspace, sizeof(wkspace), "text/%s", S_OR(ftype, "plain"));
319 mtype = wkspace;
320 }
321
322 /* Cap maximum length */
323 if ((len = strlen(uri) + strlen(ast_config_AST_DATA_DIR) + strlen("/static-http/") + 5) > 1024) {
324 goto out403;
325 }
326
327 path = ast_alloca(len);
328 sprintf(path, "%s/static-http/%s", ast_config_AST_DATA_DIR, uri);
329 if (stat(path, &st)) {
330 goto out404;
331 }
332
333 if (S_ISDIR(st.st_mode)) {
334 goto out404;
335 }
336
337 if (strstr(path, "/private/") && !astman_is_authed(ast_http_manid_from_vars(headers))) {
338 goto out403;
339 }
340
341 fd = open(path, O_RDONLY);
342 if (fd < 0) {
343 goto out403;
344 }
345
346 /* make "Etag:" http header value */
347 snprintf(etag, sizeof(etag), "\"%ld\"", (long)st.st_mtime);
348
349 /* make "Last-Modified:" http header value */
350 tv.tv_sec = st.st_mtime;
351 tv.tv_usec = 0;
352 ast_strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", ast_localtime(&tv, &tm, "GMT"));
353
354 /* check received "If-None-Match" request header and Etag value for file */
355 for (v = headers; v; v = v->next) {
356 if (!strcasecmp(v->name, "If-None-Match")) {
357 if (!strcasecmp(v->value, etag)) {
358 not_modified = 1;
359 }
360 break;
361 }
362 }
363
364 http_header = ast_str_create(255);
365 if (!http_header) {
367 ast_http_error(ser, 500, "Server Error", "Out of memory");
368 close(fd);
369 return 0;
370 }
371
372 ast_str_set(&http_header, 0, "Content-type: %s\r\n"
373 "ETag: %s\r\n"
374 "Last-Modified: %s\r\n",
375 mtype,
376 etag,
377 timebuf);
378
379 /* ast_http_send() frees http_header, so we don't need to do it before returning */
380 if (not_modified) {
381 ast_http_send(ser, method, 304, "Not Modified", http_header, NULL, 0, 1);
382 } else {
383 ast_http_send(ser, method, 200, NULL, http_header, NULL, fd, 1); /* static content flag is set */
384 }
385 close(fd);
386 return 0;
387
388out404:
389 ast_http_error(ser, 404, "Not Found", "The requested URL was not found on this server.");
390 return 0;
391
392out403:
394 ast_http_error(ser, 403, "Access Denied", "You do not have permission to access the requested URL.");
395 return 0;
396}
const char * mtype
Definition http.c:152
const char * ast_http_ftype2mtype(const char *ftype)
Return mime type based on extension.
Definition http.c:233
uint32_t ast_http_manid_from_vars(struct ast_variable *headers)
Return manager id, if exist, from request headers.
Definition http.c:247
int astman_is_authed(uint32_t ident)
Determine if a manager session ident is authenticated.
Definition manager.c:8092
const char * ast_config_AST_DATA_DIR
Definition options.c:159
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition strings.h:80

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_request_close_on_completion(), ast_http_send(), ast_localtime(), ast_str_create, ast_str_set(), ast_strftime(), ast_strlen_zero(), astman_is_authed(), len(), method, mtype, ast_variable::name, ast_variable::next, NULL, S_OR, and ast_variable::value.

◆ str_append_escaped()

static void str_append_escaped ( struct ast_str **  str,
const char *  in 
)
static

Definition at line 398 of file http.c.

399{
400 const char *cur = in;
401
402 while(*cur) {
403 switch (*cur) {
404 case '<':
405 ast_str_append(str, 0, "&lt;");
406 break;
407 case '>':
408 ast_str_append(str, 0, "&gt;");
409 break;
410 case '&':
411 ast_str_append(str, 0, "&amp;");
412 break;
413 case '"':
414 ast_str_append(str, 0, "&quot;");
415 break;
416 default:
417 ast_str_append(str, 0, "%c", *cur);
418 break;
419 }
420 cur++;
421 }
422
423 return;
424}
const char * str
Definition app_jack.c:150
FILE * in
Definition utils/frame.c:33

References ast_str_append(), in, and str.

Referenced by httpstatus_callback().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 2869 of file http.c.

2870{
2871 struct http_uri_redirect *redirect;
2872 struct http_restriction *restriction;
2874
2877
2878 if (http_tls_cfg.enabled) {
2880 }
2885
2886 if (status_uri_enabled) {
2888 }
2889
2890 if (static_uri_enabled) {
2892 }
2893
2895 while ((redirect = AST_RWLIST_REMOVE_HEAD(&uri_redirects, entry))) {
2896 ast_free(redirect);
2897 }
2899
2901 while ((restriction = AST_RWLIST_REMOVE_HEAD(&restrictions, entry))) {
2902 if (restriction->acl) {
2903 ast_free_acl_list(restriction->acl);
2904 }
2905 ast_free(restriction);
2906 }
2908
2909 return 0;
2910}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408

References http_restriction::acl, ao2_cleanup, ARRAY_LEN, ast_cli_unregister_multiple(), ast_free, ast_free_acl_list(), ast_http_uri_unlink(), AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tcptls_server_stop(), ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, cli_http, ast_tls_config::enabled, http_restriction::entry, global_http_server, http_servers, http_tls_cfg, https_desc, ast_tls_config::pvtfile, static_uri, static_uri_enabled, status_uri, and status_uri_enabled.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Built-in HTTP Server" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
static

Definition at line 2938 of file http.c.

◆ ast_http_methods_text

const struct ast_cfhttp_methods_text ast_http_methods_text[]
static

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2938 of file http.c.

◆ cli_http

struct ast_cli_entry cli_http[]
static
Initial value:
= {
{ .handler = handle_show_http , .summary = "Display HTTP server status" ,},
}
static char * handle_show_http(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition http.c:2787

Definition at line 2865 of file http.c.

2865 {
2866 AST_CLI_DEFINE(handle_show_http, "Display HTTP server status"),
2867};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by load_module(), and unload_module().

◆ ext

const char* ext

◆ global_http_server

struct ast_http_server* global_http_server = NULL

The default configured HTTP server

Definition at line 130 of file http.c.

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

◆ http_server_name

char http_server_name[MAX_SERVER_NAME_LENGTH]
static

◆ http_servers

struct ao2_container* http_servers = NULL

◆ http_tls_cfg

struct ast_tls_config http_tls_cfg
static

Definition at line 112 of file http.c.

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

◆ https_desc

struct ast_tcptls_session_args https_desc
static

Definition at line 132 of file http.c.

132 {
133 .accept_fd = -1,
134 .master = AST_PTHREADT_NULL,
135 .tls_cfg = &http_tls_cfg,
136 .poll_timeout = -1,
137 .name = "https server",
138 .accept_fn = ast_tcptls_server_root,
139 .worker_fn = httpd_helper_thread,
140};

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

◆ [struct]

struct { ... } mimetypes[]

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

Referenced by ast_http_ftype2mtype().

◆ mtype

const char* mtype

Definition at line 152 of file http.c.

Referenced by is_msg(), and static_callback().

◆ prefix

char prefix[MAX_PREFIX]
static

Definition at line 145 of file http.c.

Referenced by __ast_http_load(), _while_exec(), aoc_amount_str(), aoc_d_event(), aoc_e_event(), aoc_s_event(), aoc_time_str(), aor_deleted_observer(), ast_acl_output(), ast_ari_get_docs(), ast_begins_with(), ast_cli_print_timestr_fromseconds(), ast_db_deltree(), ast_db_gettree(), ast_db_gettree_by_prefix(), ast_frame_dump(), ast_ha_output(), ast_http_prefix(), ast_http_uri_link(), ast_manager_build_bridge_state_string_prefix(), ast_manager_build_channel_state_string_prefix(), ast_remotecontrol(), ast_sip_location_retrieve_aor_contacts_nolock_filtered(), ast_sorcery_retrieve_by_prefix(), at_match_prefix(), clearvar_prefix(), cli_match_char_tree(), console_print(), create_prefix(), exec_clearhash(), generate_filenames_string(), get_index(), get_index(), get_key(), get_object_variables(), handle_auth(), handle_cli_database_show(), handle_show_http(), handle_uri(), hashkeys_read(), hashkeys_read2(), httpstatus_callback(), if_helper(), insert_test_duplicates(), insert_test_vector(), ip_identify_match_srv_lookup(), load_module(), log_jack_status(), manager_db_tree_get(), print_acl(), print_uptimestr(), process_config(), process_config(), refer_blind_callback(), say_date_generic(), shared_read(), shared_write(), sip_options_apply_aor_configuration(), sorcery_astdb_create(), sorcery_astdb_delete(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_astdb_update(), sorcery_config_retrieve_prefix(), sorcery_memory_cache_retrieve_prefix(), sorcery_memory_retrieve_prefix(), sorcery_realtime_retrieve_prefix(), test_ao2_callback_traversal(), test_ao2_iteration(), test_expected_duplicates(), vm_authenticate(), and while_continue_exec().

◆ restrictions

◆ session_count

int session_count = 0
static

◆ session_inactivity

int session_inactivity = DEFAULT_SESSION_INACTIVITY
static

Definition at line 108 of file http.c.

Referenced by __ast_http_load(), and httpd_helper_thread().

◆ session_keep_alive

int session_keep_alive = DEFAULT_SESSION_KEEP_ALIVE
static

Definition at line 109 of file http.c.

Referenced by __ast_http_load(), ast_http_send(), and httpd_helper_thread().

◆ session_limit

int session_limit = DEFAULT_SESSION_LIMIT
static

◆ static_uri

struct ast_http_uri static_uri
static

Definition at line 496 of file http.c.

496 {
497 .callback = static_callback,
498 .description = "Asterisk HTTP Static Delivery",
499 .uri = "static",
500 .has_subtree = 1,
501 .data = NULL,
502 .key= __FILE__,
503};
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)
Definition http.c:270

Referenced by __ast_http_load(), and unload_module().

◆ static_uri_enabled

int static_uri_enabled
static

Definition at line 146 of file http.c.

Referenced by __ast_http_load(), and unload_module().

◆ status_uri

struct ast_http_uri status_uri
static

Definition at line 487 of file http.c.

487 {
488 .callback = httpstatus_callback,
489 .description = "Asterisk HTTP General Status",
490 .uri = "httpstatus",
491 .has_subtree = 0,
492 .data = NULL,
493 .key = __FILE__,
494};
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)
Definition http.c:426

Referenced by __ast_http_load(), and unload_module().

◆ status_uri_enabled

int status_uri_enabled
static

Definition at line 147 of file http.c.

Referenced by __ast_http_load(), and unload_module().

◆ uri_redirects

◆ uris

list of supported handlers