Webserver+3d print

Dependents:   Nucleo

cyclone_tcp/http/http_server.h

Committer:
Sergunb
Date:
2017-02-04
Revision:
0:8918a71cdbe9

File content as of revision 0:8918a71cdbe9:

/**
 * @file http_server.h
 * @brief HTTP server (HyperText Transfer Protocol)
 *
 * @section License
 *
 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
 *
 * This file is part of CycloneTCP Open.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * @author Oryx Embedded SARL (www.oryx-embedded.com)
 * @version 1.7.6
 **/

#ifndef _HTTP_SERVER_H
#define _HTTP_SERVER_H

//Dependencies
#include "os_port.h"
#include "core/socket.h"
#include "web_socket/web_socket.h"

//HTTP server support
#ifndef HTTP_SERVER_SUPPORT
   #define HTTP_SERVER_SUPPORT ENABLED
#elif (HTTP_SERVER_SUPPORT != ENABLED && HTTP_SERVER_SUPPORT != DISABLED)
   #error HTTP_SERVER_SUPPORT parameter is not valid
#endif

//Support for persistent connections
#ifndef HTTP_SERVER_PERSISTENT_CONN_SUPPORT
   #define HTTP_SERVER_PERSISTENT_CONN_SUPPORT DISABLED
#elif (HTTP_SERVER_PERSISTENT_CONN_SUPPORT != ENABLED && HTTP_SERVER_PERSISTENT_CONN_SUPPORT != DISABLED)
   #error HTTP_SERVER_PERSISTENT_CONN_SUPPORT parameter is not valid
#endif

//File system support
#ifndef HTTP_SERVER_FS_SUPPORT
   #define HTTP_SERVER_FS_SUPPORT DISABLED
#elif (HTTP_SERVER_FS_SUPPORT != ENABLED && HTTP_SERVER_FS_SUPPORT != DISABLED)
   #error HTTP_SERVER_FS_SUPPORT parameter is not valid
#endif

//Server Side Includes support
#ifndef HTTP_SERVER_SSI_SUPPORT
   #define HTTP_SERVER_SSI_SUPPORT DISABLED
#elif (HTTP_SERVER_SSI_SUPPORT != ENABLED && HTTP_SERVER_SSI_SUPPORT != DISABLED)
   #error HTTP_SERVER_SSI_SUPPORT parameter is not valid
#endif

//HTTP over SSL/TLS
#ifndef HTTP_SERVER_TLS_SUPPORT
   #define HTTP_SERVER_TLS_SUPPORT DISABLED
#elif (HTTP_SERVER_TLS_SUPPORT != ENABLED && HTTP_SERVER_TLS_SUPPORT != DISABLED)
   #error HTTP_SERVER_TLS_SUPPORT parameter is not valid
#endif

//Basic access authentication support
#ifndef HTTP_SERVER_BASIC_AUTH_SUPPORT
   #define HTTP_SERVER_BASIC_AUTH_SUPPORT DISABLED
#elif (HTTP_SERVER_BASIC_AUTH_SUPPORT != ENABLED && HTTP_SERVER_BASIC_AUTH_SUPPORT != DISABLED)
   #error HTTP_SERVER_BASIC_AUTH_SUPPORT parameter is not valid
#endif

//Digest access authentication support
#ifndef HTTP_SERVER_DIGEST_AUTH_SUPPORT
   #define HTTP_SERVER_DIGEST_AUTH_SUPPORT DISABLED
#elif (HTTP_SERVER_DIGEST_AUTH_SUPPORT != ENABLED && HTTP_SERVER_DIGEST_AUTH_SUPPORT != DISABLED)
   #error HTTP_SERVER_DIGEST_AUTH_SUPPORT parameter is not valid
#endif

//WebSocket support
#ifndef HTTP_SERVER_WEB_SOCKET_SUPPORT
   #define HTTP_SERVER_WEB_SOCKET_SUPPORT DISABLED
#elif (HTTP_SERVER_WEB_SOCKET_SUPPORT != ENABLED && HTTP_SERVER_WEB_SOCKET_SUPPORT != DISABLED)
   #error HTTP_SERVER_WEB_SOCKET_SUPPORT parameter is not valid
#endif

//Multipart content type support
#ifndef HTTP_SERVER_MULTIPART_TYPE_SUPPORT
   #define HTTP_SERVER_MULTIPART_TYPE_SUPPORT DISABLED
#elif (HTTP_SERVER_MULTIPART_TYPE_SUPPORT != ENABLED && HTTP_SERVER_MULTIPART_TYPE_SUPPORT != DISABLED)
   #error HTTP_SERVER_MULTIPART_TYPE_SUPPORT parameter is not valid
#endif

//Stack size required to run the HTTP server
#ifndef HTTP_SERVER_STACK_SIZE
   #define HTTP_SERVER_STACK_SIZE 650
#elif (HTTP_SERVER_STACK_SIZE < 1)
   #error HTTP_SERVER_STACK_SIZE parameter is not valid
#endif

//Priority at which the HTTP server should run
#ifndef HTTP_SERVER_PRIORITY
   #define HTTP_SERVER_PRIORITY OS_TASK_PRIORITY_NORMAL
#endif

//HTTP connection timeout
#ifndef HTTP_SERVER_TIMEOUT
   #define HTTP_SERVER_TIMEOUT 10000
#elif (HTTP_SERVER_TIMEOUT < 1000)
   #error HTTP_SERVER_TIMEOUT parameter is not valid
#endif

//Maximum time the server will wait for a subsequent
//request before closing the connection
#ifndef HTTP_SERVER_IDLE_TIMEOUT
   #define HTTP_SERVER_IDLE_TIMEOUT 5000
#elif (HTTP_SERVER_IDLE_TIMEOUT < 1000)
   #error HTTP_SERVER_IDLE_TIMEOUT parameter is not valid
#endif

//Maximum length of the pending connection queue
#ifndef HTTP_SERVER_BACKLOG
   #define HTTP_SERVER_BACKLOG 4
#elif (HTTP_SERVER_BACKLOG < 1)
   #error HTTP_SERVER_BACKLOG parameter is not valid
#endif

//Maximum number of requests per connection
#ifndef HTTP_SERVER_MAX_REQUESTS
   #define HTTP_SERVER_MAX_REQUESTS 1000
#elif (HTTP_SERVER_MAX_REQUESTS < 1)
   #error HTTP_SERVER_MAX_REQUESTS parameter is not valid
#endif

//Size of buffer used for input/output operations
#ifndef HTTP_SERVER_BUFFER_SIZE
   #define HTTP_SERVER_BUFFER_SIZE 1024
#elif (HTTP_SERVER_BUFFER_SIZE < 128)
   #error HTTP_SERVER_BUFFER_SIZE parameter is not valid
#endif

//Maximum size of root directory
#ifndef HTTP_SERVER_ROOT_DIR_MAX_LEN
   #define HTTP_SERVER_ROOT_DIR_MAX_LEN 31
#elif (HTTP_SERVER_ROOT_DIR_MAX_LEN < 7)
   #error HTTP_SERVER_ROOT_DIR_MAX_LEN parameter is not valid
#endif

//Maximum size of default index file
#ifndef HTTP_SERVER_DEFAULT_DOC_MAX_LEN
   #define HTTP_SERVER_DEFAULT_DOC_MAX_LEN 31
#elif (HTTP_SERVER_DEFAULT_DOC_MAX_LEN < 7)
   #error HTTP_SERVER_DEFAULT_DOC_MAX_LEN parameter is not valid
#endif

//Maximum length of HTTP method
#ifndef HTTP_SERVER_METHOD_MAX_LEN
   #define HTTP_SERVER_METHOD_MAX_LEN 7
#elif (HTTP_SERVER_METHOD_MAX_LEN < 1)
   #error HTTP_SERVER_METHOD_MAX_LEN parameter is not valid
#endif

//Maximum length of URI
#ifndef HTTP_SERVER_URI_MAX_LEN
   #define HTTP_SERVER_URI_MAX_LEN 255
#elif (HTTP_SERVER_URI_MAX_LEN < 31)
   #error HTTP_SERVER_URI_MAX_LEN parameter is not valid
#endif

//Maximum length of query strings
#ifndef HTTP_SERVER_QUERY_STRING_MAX_LEN
   #define HTTP_SERVER_QUERY_STRING_MAX_LEN 255
#elif (HTTP_SERVER_QUERY_STRING_MAX_LEN < 7)
   #error HTTP_SERVER_QUERY_STRING_MAX_LEN parameter is not valid
#endif

//Maximum host name length
#ifndef HTTP_SERVER_HOST_MAX_LEN
   #define HTTP_SERVER_HOST_MAX_LEN 31
#elif (HTTP_SERVER_HOST_MAX_LEN < 7)
   #error HTTP_SERVER_HOST_MAX_LEN parameter is not valid
#endif

//Maximum user name length
#ifndef HTTP_SERVER_USERNAME_MAX_LEN
   #define HTTP_SERVER_USERNAME_MAX_LEN 31
#elif (HTTP_SERVER_USERNAME_MAX_LEN < 7)
   #error HTTP_SERVER_USERNAME_MAX_LEN parameter is not valid
#endif

//Maximum length of CGI parameters
#ifndef HTTP_SERVER_CGI_PARAM_MAX_LEN
   #define HTTP_SERVER_CGI_PARAM_MAX_LEN 31
#elif (HTTP_SERVER_CGI_PARAM_MAX_LEN < 7)
   #error HTTP_SERVER_CGI_PARAM_MAX_LEN parameter is not valid
#endif

//Maximum recursion limit
#ifndef HTTP_SERVER_SSI_MAX_RECURSION
   #define HTTP_SERVER_SSI_MAX_RECURSION 3
#elif (HTTP_SERVER_SSI_MAX_RECURSION < 1 || HTTP_SERVER_SSI_MAX_RECURSION > 8)
   #error HTTP_SERVER_SSI_MAX_RECURSION parameter is not valid
#endif

//Maximum age for static resources
#ifndef HTTP_SERVER_MAX_AGE
   #define HTTP_SERVER_MAX_AGE 0
#elif (HTTP_SERVER_MAX_AGE < 0)
   #error HTTP_SERVER_MAX_AGE parameter is not valid
#endif

//Nonce cache size
#ifndef HTTP_SERVER_NONCE_CACHE_SIZE
   #define HTTP_SERVER_NONCE_CACHE_SIZE 8
#elif (HTTP_SERVER_NONCE_CACHE_SIZE < 1)
   #error HTTP_SERVER_NONCE_CACHE_SIZE parameter is not valid
#endif

//Lifetime of nonces
#ifndef HTTP_SERVER_NONCE_LIFETIME
   #define HTTP_SERVER_NONCE_LIFETIME 60000
#elif (HTTP_SERVER_NONCE_LIFETIME < 1000)
   #error HTTP_SERVER_NONCE_LIFETIME parameter is not valid
#endif

//Nonce size
#ifndef HTTP_SERVER_NONCE_SIZE
   #define HTTP_SERVER_NONCE_SIZE 16
#elif (HTTP_SERVER_NONCE_SIZE < 1)
   #error HTTP_SERVER_NONCE_SIZE parameter is not valid
#endif

//Maximum length for boundary string
#ifndef HTTP_SERVER_BOUNDARY_MAX_LEN
   #define HTTP_SERVER_BOUNDARY_MAX_LEN 70
#elif (HTTP_SERVER_BOUNDARY_MAX_LEN < 1)
   #error HTTP_SERVER_BOUNDARY_MAX_LEN parameter is not valid
#endif

//File system support?
#if (HTTP_SERVER_FS_SUPPORT == ENABLED)
   #include "fs_port.h"
#else
   #include "resource_manager.h"
#endif

//HTTP over SSL/TLS supported?
#if (HTTP_SERVER_TLS_SUPPORT == ENABLED)
   #include "crypto.h"
   #include "tls.h"
#endif

//Basic authentication supported?
#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED)
   #include "crypto.h"
   #include "base64.h"
#endif

//Digest authentication supported?
#if (HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   #include "crypto.h"
   #include "md5.h"
#endif

//WebSocket supported?
#if (HTTP_SERVER_WEB_SOCKET_SUPPORT == ENABLED)
   #include "crypto.h"
   #include "base64.h"
#endif

//HTTP port number
#define HTTP_PORT 80
//HTTPS port number (HTTP over SSL/TLS)
#define HTTPS_PORT 443

//Forward declaration of HttpServerContext structure
struct _HttpServerContext;
#define HttpServerContext struct _HttpServerContext

//Forward declaration of HttpConnection structure
struct _HttpConnection;
#define HttpConnection struct _HttpConnection


/**
 * @brief HTTP version numbers
 **/

typedef enum
{
   HTTP_VERSION_0_9 = 0x0009,
   HTTP_VERSION_1_0 = 0x0100,
   HTTP_VERSION_1_1 = 0x0101
} HttpVersion;


/**
 * @brief HTTP authentication schemes
 **/

typedef enum
{
   HTTP_AUTH_MODE_NONE   = 0,
   HTTP_AUTH_MODE_BASIC  = 1,
   HTTP_AUTH_MODE_DIGEST = 2
} HttpAuthMode;


/**
 * @brief Access status
 **/

typedef enum
{
   HTTP_ACCESS_DENIED               = 0,
   HTTP_ACCESS_ALLOWED              = 1,
   HTTP_ACCESS_BASIC_AUTH_REQUIRED  = 2,
   HTTP_ACCESS_DIGEST_AUTH_REQUIRED = 3
} HttpAccessStatus;


/**
 * @brief Flags used by I/O functions
 **/

typedef enum
{
   HTTP_FLAG_WAIT_ALL   = 0x0800,
   HTTP_FLAG_BREAK_CHAR = 0x1000,
   HTTP_FLAG_BREAK_CRLF = 0x100A,
   HTTP_FLAG_WAIT_ACK   = 0x2000,
   HTTP_FLAG_NO_DELAY   = 0x4000,
   HTTP_FLAG_DELAY      = 0x8000
} HttpFlags;


/**
 * @brief HTTP connection states
 **/

typedef enum
{
   HTTP_CONN_STATE_IDLE        = 0,
   HTTP_CONN_STATE_REQ_LINE    = 1,
   HTTP_CONN_STATE_REQ_HEADER  = 2,
   HTTP_CONN_STATE_REQ_BODY    = 3,
   HTTP_CONN_STATE_RESP_HEADER = 4,
   HTTP_CONN_STATE_RESP_BODY   = 5,
   HTTP_CONN_STATE_SHUTDOWN    = 6,
   HTTP_CONN_STATE_CLOSE       = 7
} HttpConnState;


//The HTTP_FLAG_BREAK macro causes the httpReadStream() function to stop
//reading data whenever the specified break character is encountered
#define HTTP_FLAG_BREAK(c) (HTTP_FLAG_BREAK_CHAR | LSB(c))


//HTTP over SSL/TLS supported?
#if (HTTP_SERVER_TLS_SUPPORT == ENABLED)

/**
 * @brief SSL/TLS initialization callback function
 **/

typedef error_t (*TlsInitCallback)(HttpConnection *connection,
   TlsContext *tlsContext);

#endif


/**
 * @brief Random data generation callback function
 **/

typedef error_t (*HttpRandCallback)(uint8_t *data, size_t length);


/**
 * @brief HTTP authentication callback function
 **/

typedef HttpAccessStatus (*HttpAuthCallback)(HttpConnection *connection,
   const char_t *user, const char_t *uri);


/**
 * @brief CGI callback function
 **/

typedef error_t (*HttpCgiCallback)(HttpConnection *connection,
   const char_t *param);


/**
 * @brief HTTP request callback function
 **/

typedef error_t (*HttpRequestCallback)(HttpConnection *connection,
   const char_t *uri);


/**
 * @brief URI not found callback function
 **/

typedef error_t (*HttpUriNotFoundCallback)(HttpConnection *connection,
   const char_t *uri);


/**
 * @brief HTTP status code
 **/

typedef struct
{
   uint_t value;
   const char_t message[28];
} HttpStatusCodeDesc;


/**
 * @brief Authorization header
 **/

typedef struct
{
   bool_t found;                                  ///<The Authorization header has been found
   HttpAuthMode mode;                             ///<Authentication scheme
   char_t user[HTTP_SERVER_USERNAME_MAX_LEN + 1]; ///<User name
#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED)
   const char_t *password;                        ///<Password
#endif
#if (HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   const char_t *realm;
   const char_t *nonce;                           ///<Server nonce
   const char_t *uri;                             ///<Digest URI
   const char_t *qop;
   const char_t *nc;                              ///<Nonce count
   const char_t *cnonce;                          ///<Client nonce
   const char_t *response;
   const char_t *opaque;
#endif
} HttpAuthorizationHeader;


/**
 * @brief Authenticate header
 **/

typedef struct
{
   HttpAuthMode mode; ///<Authentication scheme
#if (HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   bool_t stale;      ///<STALE flag
#endif
} HttpAuthenticateHeader;


/**
 * @brief HTTP request
 **/

typedef struct
{
   uint_t version;                                           ///<HTTP version number
   char_t method[HTTP_SERVER_METHOD_MAX_LEN + 1];            ///<HTTP method
   char_t uri[HTTP_SERVER_URI_MAX_LEN + 1];                  ///<Resource identifier
   char_t queryString[HTTP_SERVER_QUERY_STRING_MAX_LEN + 1]; ///<Query string
   char_t host[HTTP_SERVER_HOST_MAX_LEN + 1];                ///<Host name
   bool_t keepAlive;
   bool_t chunkedEncoding;
   size_t contentLength;
   size_t byteCount;
   bool_t firstChunk;
   bool_t lastChunk;
#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED || HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   HttpAuthorizationHeader auth;                             ///<Authorization header
#endif
#if (HTTP_SERVER_WEB_SOCKET_SUPPORT == ENABLED)
   bool_t upgradeWebSocket;
   bool_t connectionUpgrade;
   char_t clientKey[WEB_SOCKET_CLIENT_KEY_SIZE + 1];
#endif
#if (HTTP_SERVER_MULTIPART_TYPE_SUPPORT == ENABLED)
   char_t boundary[HTTP_SERVER_BOUNDARY_MAX_LEN + 1];        ///<Boundary string
   size_t boundaryLength;                                    ///<Boundary string length
#endif
} HttpRequest;


/**
 * @brief HTTP response
 **/

typedef struct
{
   uint_t version;              ///<HTTP version number
   uint_t statusCode;           ///<HTTP status code
   bool_t keepAlive;
   bool_t noCache;
   uint_t maxAge;
   const char_t *location;
   const char_t *contentType;
   bool_t chunkedEncoding;
   size_t contentLength;
   size_t byteCount;
#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED || HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   HttpAuthenticateHeader auth; ///<Authenticate header
#endif
} HttpResponse;


/**
 * @brief HTTP server settings
 **/

typedef struct
{
   NetInterface *interface;                                     ///<Underlying network interface
   uint16_t port;                                               ///<HTTP server port number
   uint_t backlog;                                              ///<Maximum length of the pending connection queue
   uint_t maxConnections;                                       ///<Maximum number of simultaneous connections
   HttpConnection *connections;                                 ///<HTTP client connections
   char_t rootDirectory[HTTP_SERVER_ROOT_DIR_MAX_LEN + 1];      ///<Web root directory
   char_t defaultDocument[HTTP_SERVER_DEFAULT_DOC_MAX_LEN + 1]; ///<Default home page
#if (HTTP_SERVER_TLS_SUPPORT == ENABLED)
   bool_t useTls;                                               ///<HTTP over SSL/TLS
   TlsInitCallback tlsInitCallback;                             ///<SSL/TLS initialization callback function
#endif
#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED || HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   HttpRandCallback randCallback;                               ///<Random data generation callback function
   HttpAuthCallback authCallback;                               ///<HTTP authentication callback function
#endif
   HttpCgiCallback cgiCallback;                                 ///<CGI callback function
   HttpRequestCallback requestCallback;                         ///<HTTP request callback function
   HttpUriNotFoundCallback uriNotFoundCallback;                 ///<URI not found callback function
} HttpServerSettings;


/**
 * @brief Nonce cache entry
 **/

typedef struct
{
   char_t nonce[HTTP_SERVER_NONCE_SIZE * 2 + 1]; ///<Nonce
   uint32_t count;                               ///<Nonce count
   systime_t timestamp;                          ///<Time stamp to manage entry lifetime
} HttpNonceCacheEntry;


/**
 * @brief HTTP server context
 **/

struct _HttpServerContext
{
   HttpServerSettings settings;                                  ///<User settings
   OsTask *taskHandle;                                           ///<Listener task handle
   OsSemaphore semaphore;                                        ///<Semaphore limiting the number of connections
   Socket *socket;                                               ///<Listening socket
   HttpConnection *connections;                                  ///<HTTP client connections
#if (HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   OsMutex nonceCacheMutex;                                      ///<Mutex preventing simultaneous access to the nonce cache
   HttpNonceCacheEntry nonceCache[HTTP_SERVER_NONCE_CACHE_SIZE]; ///<Nonce cache
#endif
};


/**
 * @brief HTTP connection
 *
 * An HttpConnection instance represents one
 * transaction with an HTTP client
 *
 **/

struct _HttpConnection
{
   HttpServerSettings *settings;                       ///<Reference to the HTTP server settings
   HttpServerContext *serverContext;                   ///<Reference to the HTTP server context
   OsTask *taskHandle;                                 ///<Client task handle
   OsEvent startEvent;
   bool_t running;
   Socket *socket;                                     ///<Socket
#if (HTTP_SERVER_TLS_SUPPORT == ENABLED)
   TlsContext *tlsContext;                             ///<SSL/TLS context
#endif
   HttpRequest request;                                ///<Incoming HTTP request header
   HttpResponse response;                              ///<HTTP response header
   HttpAccessStatus status;                            ///<Access status
   char_t cgiParam[HTTP_SERVER_CGI_PARAM_MAX_LEN + 1]; ///<CGI parameter
   uint32_t dummy;                                     ///<Force alignment of the buffer on 32-bit boundaries
   char_t buffer[HTTP_SERVER_BUFFER_SIZE];             ///<Memory buffer for input/output operations
#if (NET_RTOS_SUPPORT == DISABLED)
   HttpConnState state;                                ///<Connection state
   systime_t timestamp;
   size_t bufferPos;
   size_t bufferLen;
   uint8_t *bodyStart;
   size_t bodyPos;
   size_t bodyLen;
#endif
};


//HTTP server related functions
void httpServerGetDefaultSettings(HttpServerSettings *settings);
error_t httpServerInit(HttpServerContext *context, const HttpServerSettings *settings);
error_t httpServerStart(HttpServerContext *context);

void httpListenerTask(void *param);
void httpConnectionTask(void *param);

error_t httpWriteHeader(HttpConnection *connection);

error_t httpReadStream(HttpConnection *connection,
   void *data, size_t size, size_t *received, uint_t flags);

error_t httpWriteStream(HttpConnection *connection,
   const void *data, size_t length);

error_t httpCloseStream(HttpConnection *connection);

error_t httpSendResponse(HttpConnection *connection, const char_t *uri);

error_t httpSendErrorResponse(HttpConnection *connection,
   uint_t statusCode, const char_t *message);

error_t httpSendRedirectResponse(HttpConnection *connection,
   uint_t statusCode, const char_t *uri);

//HTTP authentication related functions
bool_t httpCheckPassword(HttpConnection *connection,
   const char_t *password, HttpAuthMode mode);

//WebSocket related functions
bool_t httpCheckWebSocketHandshake(HttpConnection *connection);
WebSocket *httpUpgradeToWebSocket(HttpConnection *connection);

//Miscellaneous functions
error_t httpDecodePercentEncodedString(const char_t *input,
   char_t *output, size_t outputSize);

#endif