This commit creates a HTTP server library. So instead of creating a complex HTTP server application for serving HTTP requests, the developer can use the HTTP server API to create HTTP server insteances. This commit also adds support for creating HTTPS servers. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
884 lines
25 KiB
C
884 lines
25 KiB
C
/*
|
|
* Copyright (c) 2017 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef __HTTP_H__
|
|
#define __HTTP_H__
|
|
|
|
#if defined(CONFIG_HTTPS)
|
|
#if defined(CONFIG_MBEDTLS)
|
|
#if !defined(CONFIG_MBEDTLS_CFG_FILE)
|
|
#include "mbedtls/config.h"
|
|
#else
|
|
#include CONFIG_MBEDTLS_CFG_FILE
|
|
#endif /* CONFIG_MBEDTLS_CFG_FILE */
|
|
|
|
#if defined(MBEDTLS_PLATFORM_C)
|
|
#include "mbedtls/platform.h"
|
|
#else
|
|
#include <stdlib.h>
|
|
#define mbedtls_time_t time_t
|
|
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
|
|
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
|
|
#endif /* MBEDTLS_PLATFORM_C */
|
|
|
|
#include <mbedtls/ssl_cookie.h>
|
|
#include <mbedtls/entropy.h>
|
|
#include <mbedtls/ctr_drbg.h>
|
|
#include <mbedtls/net_sockets.h>
|
|
#include <mbedtls/x509.h>
|
|
#include <mbedtls/x509_crt.h>
|
|
#include <mbedtls/ssl.h>
|
|
#include <mbedtls/error.h>
|
|
#include <mbedtls/debug.h>
|
|
#endif /* CONFIG_MBEDTLS */
|
|
#endif /* CONFIG_HTTPS */
|
|
|
|
#define HTTP_CRLF "\r\n"
|
|
|
|
#if defined(CONFIG_HTTP_CLIENT)
|
|
|
|
#include <net/http_parser.h>
|
|
#include <net/net_context.h>
|
|
|
|
/* Is there more data to come */
|
|
enum http_final_call {
|
|
HTTP_DATA_MORE = 0,
|
|
HTTP_DATA_FINAL = 1,
|
|
};
|
|
|
|
#ifndef HTTP_PROTOCOL
|
|
#define HTTP_PROTOCOL "HTTP/1.1"
|
|
#endif
|
|
|
|
/* Some generic configuration options, these can be overriden if needed. */
|
|
#ifndef HTTP_STATUS_STR_SIZE
|
|
#define HTTP_STATUS_STR_SIZE 32
|
|
#endif
|
|
|
|
/* Default network activity timeout in seconds */
|
|
#define HTTP_NETWORK_TIMEOUT K_SECONDS(20)
|
|
|
|
/* It seems enough to hold 'Content-Length' and its value */
|
|
#define HTTP_CONTENT_LEN_SIZE 48
|
|
|
|
/* Default HTTP Header Field values for HTTP Requests if using the
|
|
* HTTP_HEADER_FIELDS define.
|
|
*/
|
|
#ifndef HTTP_ACCEPT
|
|
#define HTTP_ACCEPT "text/plain"
|
|
#endif
|
|
|
|
#ifndef HTTP_ACCEPT_ENC
|
|
#define HTTP_ACCEPT_ENC "identity"
|
|
#endif
|
|
|
|
#ifndef HTTP_ACCEPT_LANG
|
|
#define HTTP_ACCEPT_LANG "en-US"
|
|
#endif
|
|
|
|
#ifndef HTTP_CONNECTION
|
|
#define HTTP_CONNECTION "Close"
|
|
#endif
|
|
|
|
#ifndef HTTP_USER_AGENT
|
|
#define HTTP_USER_AGENT "Zephyr-HTTP-Client/1.8"
|
|
#endif
|
|
|
|
/* This can be used in http_client_send_get_req() when supplying
|
|
* extra_header_fields parameter.
|
|
*/
|
|
#ifndef HTTP_HEADER_FIELDS
|
|
#define HTTP_HEADER_FIELDS \
|
|
"Accept: " HTTP_ACCEPT HTTP_CRLF \
|
|
"Accept-Encoding: " HTTP_ACCEPT_ENC HTTP_CRLF \
|
|
"Accept-Language: " HTTP_ACCEPT_LANG HTTP_CRLF \
|
|
"User-Agent: " HTTP_USER_AGENT HTTP_CRLF \
|
|
"Connection: " HTTP_CONNECTION HTTP_CRLF
|
|
#endif
|
|
|
|
struct http_client_ctx;
|
|
|
|
/**
|
|
* @typedef http_receive_cb_t
|
|
* @brief Callback used when TCP data has been received from peer.
|
|
*
|
|
* @param ctx HTTP context.
|
|
* @param pkt Network packet.
|
|
*/
|
|
typedef void (*http_receive_cb_t)(struct http_client_ctx *ctx,
|
|
struct net_pkt *pkt);
|
|
|
|
/**
|
|
* @typedef http_response_cb_t
|
|
* @brief Callback used when a response has been received from peer.
|
|
*
|
|
* @param ctx HTTP context.
|
|
* @param data Received data buffer
|
|
* @param buflen Data buffer len (as specified by user)
|
|
* @param datalen Received data len, if this is larger than buflen,
|
|
* then some data was skipped.
|
|
* @param final_data Does this data buffer contain all the data or
|
|
* is there still more data to come.
|
|
* @param user_data A valid pointer on some user data or NULL
|
|
*/
|
|
typedef void (*http_response_cb_t)(struct http_client_ctx *ctx,
|
|
u8_t *data, size_t buflen,
|
|
size_t datalen,
|
|
enum http_final_call final_data,
|
|
void *user_data);
|
|
|
|
/**
|
|
* HTTP client context information. This contains all the data that is
|
|
* needed when doing HTTP requests.
|
|
*/
|
|
struct http_client_ctx {
|
|
struct http_parser parser;
|
|
struct http_parser_settings settings;
|
|
|
|
/** Server name */
|
|
const char *server;
|
|
|
|
#if defined(CONFIG_DNS_RESOLVER)
|
|
/** Remember the DNS query id so that it can be cancelled
|
|
* if the HTTP context is released and the query is active
|
|
* at that time.
|
|
*/
|
|
u16_t dns_id;
|
|
#endif
|
|
|
|
struct {
|
|
/** Local socket address */
|
|
struct sockaddr local;
|
|
|
|
/** Remote (server) socket address */
|
|
struct sockaddr remote;
|
|
|
|
/** IP stack network context */
|
|
struct net_context *ctx;
|
|
|
|
/** Network timeout */
|
|
s32_t timeout;
|
|
|
|
/** User can define this callback if it wants to have
|
|
* special handling of the received raw data.
|
|
*/
|
|
http_receive_cb_t receive_cb;
|
|
} tcp;
|
|
|
|
/** HTTP request information */
|
|
struct {
|
|
/**
|
|
* Semaphore to signal HTTP request completion
|
|
*/
|
|
struct k_sem wait;
|
|
|
|
/** Hostname to be used in the request */
|
|
const char *host;
|
|
|
|
/** User provided data */
|
|
void *user_data;
|
|
|
|
/** What method we used here (GET, POST, HEAD etc.)
|
|
*/
|
|
enum http_method method;
|
|
} req;
|
|
|
|
/** HTTP response information */
|
|
struct {
|
|
/** User provided HTTP response callback which is called
|
|
* when a response is received to a sent HTTP request.
|
|
*/
|
|
http_response_cb_t cb;
|
|
|
|
/** Where the response is stored, this is to be provided
|
|
* by the user.
|
|
*/
|
|
u8_t *response_buf;
|
|
|
|
/** Where the body starts.
|
|
*/
|
|
u8_t *body_start;
|
|
|
|
/** Response buffer maximum length */
|
|
size_t response_buf_len;
|
|
|
|
/** Length of the data in the result buf. If the value is
|
|
* larger than response_buf_len, then it means that the data
|
|
* is truncated and could not be fully copied into
|
|
* response_buf. This can only happen if the user did not
|
|
* set the response callback. If the callback is set, then
|
|
* the HTTP client API will call response callback many times
|
|
* so that all the data is delivered to the user.
|
|
*/
|
|
size_t data_len;
|
|
|
|
/** HTTP Content-Length field value */
|
|
size_t content_length;
|
|
|
|
/** Content length parsed. This should be the same as the
|
|
* content_length field if parsing was ok.
|
|
*/
|
|
size_t processed;
|
|
|
|
/* https://tools.ietf.org/html/rfc7230#section-3.1.2
|
|
* The status-code element is a 3-digit integer code
|
|
*
|
|
* The reason-phrase element exists for the sole purpose of
|
|
* providing a textual description associated with the
|
|
* numeric status code. A client SHOULD ignore the
|
|
* reason-phrase content.
|
|
*/
|
|
char http_status[HTTP_STATUS_STR_SIZE];
|
|
|
|
u8_t cl_present:1;
|
|
u8_t body_found:1;
|
|
} rsp;
|
|
};
|
|
|
|
/**
|
|
* HTTP client request. This contains all the data that is needed when doing
|
|
* a HTTP request.
|
|
*/
|
|
struct http_client_request {
|
|
/** The HTTP method: GET, HEAD, OPTIONS, POST, ... */
|
|
enum http_method method;
|
|
|
|
/** The URL for this request, for example: /index.html */
|
|
const char *url;
|
|
|
|
/** The HTTP protocol: HTTP/1.1 */
|
|
const char *protocol;
|
|
|
|
/** The HTTP header fields (application specific)
|
|
* The Content-Type may be specified here or in the next field.
|
|
* Depending on your application, the Content-Type may vary, however
|
|
* some header fields may remain constant through the application's
|
|
* life cycle.
|
|
*/
|
|
const char *header_fields;
|
|
|
|
/** The value of the Content-Type header field, may be NULL */
|
|
const char *content_type_value;
|
|
|
|
/** Hostname to be used in the request */
|
|
const char *host;
|
|
|
|
/** Payload, may be NULL */
|
|
const char *payload;
|
|
|
|
/** Payload size, may be 0 */
|
|
u16_t payload_size;
|
|
};
|
|
|
|
/**
|
|
* @brief Generic function to send a HTTP request to the network. Normally
|
|
* applications would not need to use this function.
|
|
*
|
|
* @param net_ctx Network context.
|
|
* @param req HTTP request to perform.
|
|
* @param timeout Timeout when doing net_buf allocations.
|
|
*
|
|
* @return Return 0 if ok, and <0 if error.
|
|
*/
|
|
int http_request(struct net_context *net_ctx, struct http_client_request *req,
|
|
s32_t timeout);
|
|
|
|
/**
|
|
* @brief Send a HTTP request to peer.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
* @param req HTTP request to perform.
|
|
* @param cb Callback to call when the response has been received from peer.
|
|
* @param response_buf Caller supplied buffer where the HTTP response will be
|
|
* stored
|
|
* @param response_buf_len Length of the caller suppied buffer.
|
|
* @param user_data A valid pointer on some user data or NULL
|
|
* @param timeout Amount of time to wait for a reply. If the timeout is 0,
|
|
* then we return immediately and the callback (if set) will be called later.
|
|
*
|
|
* @return Return 0 if ok, and <0 if error.
|
|
*/
|
|
int http_client_send_req(struct http_client_ctx *http_ctx,
|
|
struct http_client_request *req,
|
|
http_response_cb_t cb,
|
|
u8_t *response_buf,
|
|
size_t response_buf_len,
|
|
void *user_data,
|
|
s32_t timeout);
|
|
|
|
/**
|
|
* @brief Send a HTTP GET request to peer.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
* @param url URL to use.
|
|
* @param host Host field in HTTP header. If set to NULL, then server
|
|
* name is used.
|
|
* @param extra_header_fields Any extra header fields that caller wants
|
|
* to add. This can be set to NULL. The format is "name: value\r\n"
|
|
* Example: "Accept: text/plain\r\nConnection: Close\r\n"
|
|
* @param cb Callback to call when the response has been received from peer.
|
|
* @param response_buf Caller supplied buffer where the HTTP request will be
|
|
* stored
|
|
* @param response_buf_len Length of the caller suppied buffer.
|
|
* @param user_data A valid pointer on some user data or NULL
|
|
* @param timeout Amount of time to wait for a reply. If the timeout is 0,
|
|
* then we return immediately and the callback (if set) will be called later.
|
|
*
|
|
* @return Return 0 if ok, and <0 if error.
|
|
*/
|
|
static inline int http_client_send_get_req(struct http_client_ctx *http_ctx,
|
|
const char *url,
|
|
const char *host,
|
|
const char *extra_header_fields,
|
|
http_response_cb_t cb,
|
|
u8_t *response_buf,
|
|
size_t response_buf_len,
|
|
void *user_data,
|
|
s32_t timeout)
|
|
{
|
|
struct http_client_request req = {
|
|
.method = HTTP_GET,
|
|
.url = url,
|
|
.host = host,
|
|
.protocol = " " HTTP_PROTOCOL HTTP_CRLF,
|
|
.header_fields = extra_header_fields,
|
|
};
|
|
|
|
return http_client_send_req(http_ctx, &req, cb, response_buf,
|
|
response_buf_len, user_data, timeout);
|
|
}
|
|
|
|
/**
|
|
* @brief Send a HTTP POST request to peer.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
* @param url URL to use.
|
|
* @param host Host field in HTTP header. If set to NULL, then server
|
|
* name is used.
|
|
* @param extra_header_fields Any extra header fields that caller wants
|
|
* to add. This can be set to NULL. The format is "name: value\r\n"
|
|
* Example: "Accept: text/plain\r\nConnection: Close\r\n"
|
|
* @param content_type Content type of the data.
|
|
* @param payload Payload data.
|
|
* @param cb Callback to call when the response has been received from peer.
|
|
* @param response_buf Caller supplied buffer where the HTTP response will be
|
|
* stored
|
|
* @param response_buf_len Length of the caller suppied buffer.
|
|
* @param user_data A valid pointer on some user data or NULL
|
|
* @param timeout Amount of time to wait for a reply. If the timeout is 0,
|
|
* then we return immediately and the callback (if set) will be called later.
|
|
*
|
|
* @return Return 0 if ok, and <0 if error.
|
|
*/
|
|
static inline int http_client_send_post_req(struct http_client_ctx *http_ctx,
|
|
const char *url,
|
|
const char *host,
|
|
const char *extra_header_fields,
|
|
const char *content_type,
|
|
const char *payload,
|
|
http_response_cb_t cb,
|
|
u8_t *response_buf,
|
|
size_t response_buf_len,
|
|
void *user_data,
|
|
s32_t timeout)
|
|
{
|
|
struct http_client_request req = {
|
|
.method = HTTP_POST,
|
|
.url = url,
|
|
.host = host,
|
|
.protocol = " " HTTP_PROTOCOL HTTP_CRLF,
|
|
.header_fields = extra_header_fields,
|
|
.content_type_value = content_type,
|
|
.payload = payload,
|
|
};
|
|
|
|
return http_client_send_req(http_ctx, &req, cb, response_buf,
|
|
response_buf_len, user_data, timeout);
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize user supplied HTTP context.
|
|
*
|
|
* @detail Caller can set the various fields in http_ctx after this call
|
|
* if needed.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
* @param server HTTP server address or host name. If host name is given,
|
|
* then DNS resolver support (CONFIG_DNS_RESOLVER) must be enabled. If caller
|
|
* sets the server parameter as NULL, then it no attempt is done to figure out
|
|
* the remote address and caller must set the address in http_ctx.tcp.remote
|
|
* itself.
|
|
* @param server_port HTTP server TCP port.
|
|
*
|
|
* @return Return 0 if ok, <0 if error.
|
|
*/
|
|
int http_client_init(struct http_client_ctx *http_ctx,
|
|
const char *server, u16_t server_port);
|
|
|
|
/**
|
|
* @brief Release all the resources allocated for HTTP context.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
*/
|
|
void http_client_release(struct http_client_ctx *http_ctx);
|
|
#endif /* CONFIG_HTTP_CLIENT */
|
|
|
|
#if defined(CONFIG_HTTP_SERVER)
|
|
|
|
#include <net/net_context.h>
|
|
#include <net/http_parser.h>
|
|
|
|
struct http_server_ctx;
|
|
|
|
enum http_url_flags {
|
|
HTTP_URL_STANDARD = 0,
|
|
};
|
|
|
|
/* HTTP header fields struct */
|
|
struct http_field_value {
|
|
/** Field name, this variable will point to the beginning of the string
|
|
* containing the HTTP field name
|
|
*/
|
|
const char *key;
|
|
|
|
/** Value, this variable will point to the beginning of the string
|
|
* containing the field value
|
|
*/
|
|
const char *value;
|
|
|
|
/** Length of the field name */
|
|
u16_t key_len;
|
|
|
|
/** Length of the field value */
|
|
u16_t value_len;
|
|
};
|
|
|
|
typedef int (*http_url_cb_t)(struct http_server_ctx *ctx);
|
|
|
|
/* HTTP root URL struct, used for pattern matching */
|
|
struct http_root_url {
|
|
/** URL */
|
|
const char *root;
|
|
|
|
/** Callback that is called when this URL is received */
|
|
http_url_cb_t write_cb;
|
|
|
|
/** Length of the URL */
|
|
u16_t root_len;
|
|
|
|
/** Flags for this URL (values are from enum http_url_flags) */
|
|
u8_t flags;
|
|
|
|
/** Is this URL resource used or not */
|
|
u8_t is_used;
|
|
};
|
|
|
|
/* Collection of URLs that this server will handle */
|
|
struct http_server_urls {
|
|
/* First item is the default handler and it is always there.
|
|
*/
|
|
struct http_root_url default_url;
|
|
struct http_root_url urls[CONFIG_HTTP_SERVER_NUM_URLS];
|
|
};
|
|
|
|
#if defined(CONFIG_HTTPS)
|
|
/* Internal information for managing HTTPS data */
|
|
struct https_context {
|
|
struct net_pkt *rx_pkt;
|
|
struct net_buf *frag;
|
|
struct k_sem tx_sem;
|
|
struct k_fifo rx_fifo;
|
|
int remaining;
|
|
};
|
|
|
|
/**
|
|
* @typedef https_server_cert_cb_t
|
|
* @brief Callback used when the API user needs to setup the
|
|
* HTTPS certs.
|
|
*
|
|
* @param ctx HTTPS server context.
|
|
* @param cert MBEDTLS certificate
|
|
* @param pkey MBEDTLS private key
|
|
*
|
|
* @return 0 if ok, <0 if there is an error
|
|
*/
|
|
typedef int (*https_server_cert_cb_t)(struct http_server_ctx *ctx,
|
|
mbedtls_x509_crt *cert,
|
|
mbedtls_pk_context *pkey);
|
|
|
|
/**
|
|
* @typedef https_entropy_src_cb_t
|
|
* @brief Callback used when the API user needs to setup the entropy source.
|
|
* @detail This is the same as mbedtls_entropy_f_source_ptr callback.
|
|
*
|
|
* @param data Callback-specific data pointer
|
|
* @param output Data to fill
|
|
* @param len Maximum size to provide
|
|
* @param olen The actual amount of bytes put into the buffer (Can be 0)
|
|
*/
|
|
typedef int (*https_entropy_src_cb_t)(void *data, unsigned char *output,
|
|
size_t len, size_t *olen);
|
|
#endif /* CONFIG_HTTPS */
|
|
|
|
typedef int (*http_send_data_t)(struct net_pkt *pkt,
|
|
net_context_send_cb_t cb,
|
|
s32_t timeout,
|
|
void *token,
|
|
void *user_data);
|
|
|
|
/* The HTTP server context struct */
|
|
struct http_server_ctx {
|
|
/** Collection of URLs that this server context will handle */
|
|
struct http_server_urls *urls;
|
|
|
|
#if defined(CONFIG_NET_IPV4)
|
|
/** IPv4 stack network context for listening */
|
|
struct net_context *net_ipv4_ctx;
|
|
#endif
|
|
#if defined(CONFIG_NET_IPV6)
|
|
/** IPv6 stack network context for listening */
|
|
struct net_context *net_ipv6_ctx;
|
|
#endif
|
|
|
|
/** Function that is called when data is received from network. */
|
|
net_context_recv_cb_t recv_cb;
|
|
|
|
/** Function that is called when data is sent to network. */
|
|
http_send_data_t send_data;
|
|
|
|
/** Network timeout */
|
|
s32_t timeout;
|
|
|
|
/** Running status of the server. If true, then the server is enabled.
|
|
* If false then it is disabled and will not serve clients.
|
|
* The server is disabled by default after initialization and will need
|
|
* to be enabled manually.
|
|
*/
|
|
bool enabled;
|
|
|
|
/** Is this instance HTTPS or not.
|
|
*/
|
|
bool is_https;
|
|
|
|
struct {
|
|
/** From which net_context the request came from */
|
|
struct net_context *net_ctx;
|
|
|
|
/** HTTP parser */
|
|
struct http_parser parser;
|
|
|
|
/** HTTP parser settings */
|
|
struct http_parser_settings settings;
|
|
|
|
/** Collection of header fields */
|
|
struct http_field_value
|
|
field_values[CONFIG_HTTP_HEADER_FIELD_ITEMS];
|
|
|
|
/** HTTP Request URL */
|
|
const char *url;
|
|
|
|
/** Where the request is stored, this is to be provided
|
|
* by the user.
|
|
*/
|
|
u8_t *request_buf;
|
|
|
|
/** Request buffer maximum length */
|
|
size_t request_buf_len;
|
|
|
|
/** Length of the data in the request buf. */
|
|
size_t data_len;
|
|
|
|
/** Number of header field elements */
|
|
u16_t field_values_ctr;
|
|
|
|
/** URL's length */
|
|
u16_t url_len;
|
|
} req;
|
|
|
|
#if defined(CONFIG_HTTPS)
|
|
struct {
|
|
/** HTTPS stack for mbedtls library. */
|
|
u8_t *stack;
|
|
|
|
/** HTTPS stack size. */
|
|
int stack_size;
|
|
|
|
/** HTTPS thread id */
|
|
k_tid_t tid;
|
|
|
|
/** HTTPS thread */
|
|
struct k_thread thread;
|
|
|
|
/** Memory pool for RX data */
|
|
struct k_mem_pool *pool;
|
|
|
|
/** mbedtls related configuration. */
|
|
struct {
|
|
struct https_context ssl_ctx;
|
|
https_server_cert_cb_t cert_cb;
|
|
https_entropy_src_cb_t entropy_src_cb;
|
|
mbedtls_entropy_context entropy;
|
|
mbedtls_ctr_drbg_context ctr_drbg;
|
|
mbedtls_ssl_context ssl;
|
|
mbedtls_ssl_config conf;
|
|
mbedtls_x509_crt srvcert;
|
|
mbedtls_pk_context pkey;
|
|
u8_t *personalization_data;
|
|
size_t personalization_data_len;
|
|
} mbedtls;
|
|
} https;
|
|
#endif /* CONFIG_HTTPS */
|
|
};
|
|
|
|
/**
|
|
* @brief Initialize user supplied HTTP context.
|
|
*
|
|
* @detail Caller can set the various callback fields in http_ctx and
|
|
* http_ctx.req.parser after this call if needed.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
* @param urls Array of URLs that the server instance will serve. If the
|
|
* server receives a HTTP request into one of the URLs, it will call user
|
|
* supplied callback. If no such URL is registered, a default handler will
|
|
* be called (if set by the user). If no data handler is found, the request
|
|
* is dropped.
|
|
* @param server_addr Socket address of the local network interface and TCP
|
|
* port where the data is being waited. If the socket family is set to
|
|
* AF_UNSPEC, then both IPv4 and IPv6 is started to be listened. If the
|
|
* address is set to be INADDR_ANY (for IPv4) or unspecified address (all bits
|
|
* zeros for IPv6), then the HTTP server will select proper IP address to bind
|
|
* to. If caller has not specified HTTP listening port, then port 80 is being
|
|
* listened. The parameter can be left NULL in which case a listener to port 80
|
|
* using IPv4 and IPv6 is created. Note that if IPv4 or IPv6 is disabled, then
|
|
* the corresponding disabled service listener is not created.
|
|
* @param request_buf Caller supplied buffer where the HTTP request will be
|
|
* stored
|
|
* @param request_buf_len Length of the caller suppied buffer.
|
|
* @param server_banner Print information about started service. This is only
|
|
* printed if HTTP debugging is activated. The parameter can be set to NULL if
|
|
* no extra prints are needed.
|
|
*
|
|
* @return Return 0 if ok, <0 if error.
|
|
*/
|
|
int http_server_init(struct http_server_ctx *http_ctx,
|
|
struct http_server_urls *urls,
|
|
struct sockaddr *server_addr,
|
|
u8_t *request_buf,
|
|
size_t request_buf_len,
|
|
const char *server_banner);
|
|
|
|
#if defined(CONFIG_HTTPS)
|
|
/**
|
|
* @brief Initialize user supplied HTTP context. This function must be
|
|
* used if HTTPS server is created.
|
|
*
|
|
* @detail Caller can set the various callback fields in http_ctx and
|
|
* http_ctx.req.parser after this call if needed.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
* @param urls Array of URLs that the server instance will serve. If the
|
|
* server receives a HTTP request into one of the URLs, it will call user
|
|
* supplied callback. If no such URL is registered, a default handler will
|
|
* be called (if set by the user). If no data handler is found, the request
|
|
* is dropped.
|
|
* @param server_addr Socket address of the local network interface and TCP
|
|
* port where the data is being waited. If the socket family is set to
|
|
* AF_UNSPEC, then both IPv4 and IPv6 is started to be listened. If the
|
|
* address is set to be INADDR_ANY (for IPv4) or unspecified address (all bits
|
|
* zeros for IPv6), then the HTTP server will select proper IP address to bind
|
|
* to. If caller has not specified HTTP listening port, then port 80 is being
|
|
* listened. The parameter can be left NULL in which case a listener to port 80
|
|
* using IPv4 and IPv6 is created. Note that if IPv4 or IPv6 is disabled, then
|
|
* the corresponding disabled service listener is not created.
|
|
* @param request_buf Caller supplied buffer where the HTTP request will be
|
|
* stored
|
|
* @param request_buf_len Length of the caller suppied buffer.
|
|
* @param server_banner Print information about started service. This is only
|
|
* printed if HTTP debugging is activated. The parameter can be set to NULL if
|
|
* no extra prints are needed.
|
|
* @param personalization_data Personalization data (Device specific
|
|
* identifiers) for random number generator. (Can be NULL).
|
|
* @param personalization_data_len Length of the personalization data.
|
|
* @param cert_cb User supplied callback that setups the certifacates.
|
|
* @param entropy_src_cb User supplied callback that setup the entropy. This
|
|
* can be set to NULL, in which case default entropy source is used.
|
|
* @param pool Memory pool for RX data reads.
|
|
* @param https_stack HTTPS thread stack.
|
|
* @param https_stack_len HTTP thread stack size.
|
|
*
|
|
* @return Return 0 if ok, <0 if error.
|
|
*/
|
|
int https_server_init(struct http_server_ctx *http_ctx,
|
|
struct http_server_urls *urls,
|
|
struct sockaddr *server_addr,
|
|
u8_t *request_buf,
|
|
size_t request_buf_len,
|
|
const char *server_banner,
|
|
u8_t *personalization_data,
|
|
size_t personalization_data_len,
|
|
https_server_cert_cb_t cert_cb,
|
|
https_entropy_src_cb_t entropy_src_cb,
|
|
struct k_mem_pool *pool,
|
|
u8_t *https_stack,
|
|
size_t https_stack_len);
|
|
#endif /* CONFIG_HTTPS */
|
|
|
|
/**
|
|
* @brief Release all the resources allocated for HTTP context.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
*/
|
|
void http_server_release(struct http_server_ctx *http_ctx);
|
|
|
|
/**
|
|
* @brief Enable HTTP server that is related to this context.
|
|
*
|
|
* @detail The HTTP server will start to serve request after this.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
*
|
|
* @return Previous status of the server.
|
|
*/
|
|
bool http_server_enable(struct http_server_ctx *http_ctx);
|
|
|
|
/**
|
|
* @brief Disable HTTP server that is related to this context.
|
|
*
|
|
* @detail The HTTP server will stop to serve request after this.
|
|
*
|
|
* @param http_ctx HTTP context.
|
|
*
|
|
* @return Previous status of the server.
|
|
*/
|
|
bool http_server_disable(struct http_server_ctx *http_ctx);
|
|
|
|
/**
|
|
* @brief Helper function that can be used to fill the server (local) sockaddr
|
|
* struct.
|
|
*
|
|
* @param addr Sockaddr struct to be filled.
|
|
* @param myaddr Address that the local IP address. If left NULL, then the
|
|
* proper system address is used.
|
|
* @param port TCP port to use.
|
|
*
|
|
* @return 0 if ok, <0 if error.
|
|
*/
|
|
int http_server_set_local_addr(struct sockaddr *addr, const char *myaddr,
|
|
u16_t port);
|
|
|
|
/**
|
|
* @brief Add a handler for a given URL.
|
|
*
|
|
* @detail Register a handler which is called if the server receives a
|
|
* request to a given URL.
|
|
*
|
|
* @param urls URL struct that will contain all the URLs the user wants to
|
|
* register.
|
|
* @param url URL string.
|
|
* @param flags Flags for the URL.
|
|
* @param write_cb Callback that is called when URL is requested.
|
|
*
|
|
* @return NULL if the URL is already registered, pointer to URL if
|
|
* registering was ok.
|
|
*/
|
|
struct http_root_url *http_server_add_url(struct http_server_urls *urls,
|
|
const char *url, u8_t flags,
|
|
http_url_cb_t write_cb);
|
|
|
|
/**
|
|
* @brief Delete the handler for a given URL.
|
|
*
|
|
* @detail Unregister the previously registered URL handler.
|
|
*
|
|
* @param urls URL struct that will contain all the URLs the user has
|
|
* registered.
|
|
* @param url URL string.
|
|
*
|
|
* @return 0 if ok, <0 if error.
|
|
*/
|
|
int http_server_del_url(struct http_server_urls *urls, const char *url);
|
|
|
|
/**
|
|
* @brief Add default URL handler.
|
|
*
|
|
* @detail If no URL handler is found, then call this handler. There can
|
|
* be only one default handler in the URL struct.
|
|
*
|
|
* @param urls URL struct that will contain all the URLs the user has
|
|
* registered.
|
|
* @param write_cb Callback that is called when non-registered URL is
|
|
* requested.
|
|
*
|
|
* @return NULL if default URL is already registered, pointer to default
|
|
* URL if registering was ok.
|
|
*/
|
|
struct http_root_url *http_server_add_default(struct http_server_urls *urls,
|
|
http_url_cb_t write_cb);
|
|
|
|
/**
|
|
* @brief Delete the default URL handler.
|
|
*
|
|
* @detail Unregister the previously registered default URL handler.
|
|
*
|
|
* @param urls URL struct that will contain all the URLs the user has
|
|
* registered.
|
|
*
|
|
* @return 0 if ok, <0 if error.
|
|
*/
|
|
int http_server_del_default(struct http_server_urls *urls);
|
|
|
|
/**
|
|
* @brief Send HTTP response to client.
|
|
*
|
|
* @param ctx HTTP context.
|
|
* @param http_header HTTP headers to send.
|
|
* @param html_payload HTML payload to send.
|
|
*
|
|
* @return 0 if ok, <0 if error.
|
|
*/
|
|
int http_response(struct http_server_ctx *ctx, const char *http_header,
|
|
const char *html_payload);
|
|
|
|
/**
|
|
* @brief Send HTTP 400 response to client.
|
|
*
|
|
* @detail HTTP 400 error code indicates a Bad Request
|
|
*
|
|
* @param ctx HTTP context.
|
|
* @param html_payload HTML payload to send.
|
|
*
|
|
* @return 0 if ok, <0 if error.
|
|
*/
|
|
int http_response_400(struct http_server_ctx *ctx, const char *html_payload);
|
|
|
|
/**
|
|
* @brief Send HTTP 403 response to client.
|
|
*
|
|
* @detail HTTP 403 error code indicates a Forbidden Request
|
|
*
|
|
* @param ctx HTTP context.
|
|
* @param html_payload HTML payload to send.
|
|
*
|
|
* @return 0 if ok, <0 if error.
|
|
*/
|
|
int http_response_403(struct http_server_ctx *ctx, const char *html_payload);
|
|
|
|
/**
|
|
* @brief Send HTTP 404 response to client.
|
|
*
|
|
* @detail HTTP 404 error code indicates a Not Found resource.
|
|
*
|
|
* @param ctx HTTP context.
|
|
* @param html_payload HTML payload to send.
|
|
*
|
|
* @return 0 if ok, <0 if error.
|
|
*/
|
|
int http_response_404(struct http_server_ctx *ctx, const char *html_payload);
|
|
|
|
#endif /* CONFIG_HTTP_SERVER */
|
|
|
|
#endif /* __HTTP_H__ */
|