webserver.c File Reference

Defines the Web Server and has functions to carry out operations of the Web Server. More...

`#include "config.h"`
`#include "webserver.h"`
`#include "UpnpExtraHeaders.h"`
`#include "UpnpFileInfo.h"`
`#include "UpnpIntTypes.h"`
`#include "UpnpStdInt.h"`
`#include "VirtualDir.h"`
`#include "httpparser.h"`
`#include "httpreadwrite.h"`
`#include "ithread.h"`
`#include "membuffer.h"`
`#include "ssdplib.h"`
`#include "statcodes.h"`
`#include "strintmap.h"`
`#include "unixutil.h"`
`#include "upnp.h"`
`#include "upnpapi.h"`
`#include "upnputil.h"`
`#include <assert.h>`
`#include <fcntl.h>`
`#include <sys/stat.h>`
`#include "posix_overwrites.h"`
Include dependency graph for webserver.c:

## Data Structures

struct | document_type_t
struct | xml_alias_t

## Macros

#define | AUDIO_STR "\1"
#define | VIDEO_STR "\2"
#define | IMAGE_STR "\3"
#define | APPLICATION_STR "\4"
#define | TEXT_STR "\5"
#define | APPLICATION_INDEX 4
#define | TEXT_INDEX 5
#define | NUM_MEDIA_TYPES 70
#define | NUM_HTTP_HEADER_NAMES 33
#define | ASCTIME_R_BUFFER_SIZE 26
#define | web_server_asctime_r asctime_r

## Enumerations

enum | resp_type { RESP_FILEDOC , RESP_XMLDOC , RESP_HEADERS , RESP_WEBDOC , RESP_POST }

## Functions

static UPNP_INLINE void | media_list_init (void)
| Decodes list and stores it in gMediaTypeList.
static UPNP_INLINE int | search_extension (const char *extension, const char **con_type, const char **con_subtype)
| Based on the extension, returns the content type and content subtype.
static UPNP_INLINE int | get_content_type (const char *filename, UpnpFileInfo *fileInfo)
| Based on the extension, clones an XML string based on type and content subtype. If content type and sub type are not found, unknown types are used.
static UPNP_INLINE void | glob_alias_init (void)
| Initialize the global XML document. Allocate buffers for the XML document.
static UPNP_INLINE int | is_valid_alias (const struct xml_alias_t *alias)
| Check for the validity of the XML object buffer.
static void | alias_grab (struct xml_alias_t *alias)
| Copy the contents of the global XML document into the local output parameter.
static void | alias_release (struct xml_alias_t *alias)
| Release the XML document referred to by the input parameter. Free the allocated buffers associated with this object.
int | web_server_set_alias (const char *alias_name, const char *alias_content, size_t alias_content_length, time_t last_modified)
| Replaces current alias with the given alias. To remove the current alias, set alias_name to NULL.
int | web_server_init ()
| Initilialize the different documents. Initialize the memory for root directory for web server. Call to initialize global XML document. Sets bWebServerState to WEB_SERVER_ENABLED.
void | web_server_destroy (void)
| Release memory allocated for the global web server root directory and the global XML document. Resets the flag bWebServerState to WEB_SERVER_DISABLED.
static int | get_file_info (const char *filename, UpnpFileInfo *info)
| Release memory allocated for the global web server root directory and the global XML document. Resets the flag bWebServerState to WEB_SERVER_DISABLED.
int | web_server_set_root_dir (const char *root_dir)
| Assign the path specfied by the input const char* root_dir parameter to the global Document root directory. Also check for path names ending in '/'.
int | web_server_set_cors (const char *cors_string)
| Assign the Access-Control-Allow-Origin specfied by the input const char* cors_string parameterto the global CORS string.
static UPNP_INLINE int | get_alias (const char *request_file, struct xml_alias_t *alias, UpnpFileInfo *info)
| Compare the files names between the one on the XML alias the one passed in as the input parameter. If equal extract file information.
static int | isFileInVirtualDir (char *filePath, const void **cookie)
| Compares filePath with paths from the list of virtual directory lists.
static void | ToUpperCase (char *s)
| Converts input string to upper case.
static char * | StrStr (char *s1, const char *s2)
| Finds a substring from a string in a case insensitive way.
static char * | StrTok (char **Src, const char *Del)
| Finds next token in a string.
static int | GetNextRange (char **SrcRangeStr, off_t *FirstByte, off_t *LastByte)
| Returns a range of integers from a string.
static int | CreateHTTPRangeResponseHeader (char *ByteRangeSpecifier, off_t FileLength, struct SendInstruction *Instr)
| Fills in the Offset, read size and contents to send out as an HTTP Range Response.
static int | CheckOtherHTTPHeaders (http_message_t *Req, struct SendInstruction *RespInstr, off_t FileSize)
| Get header id from the request parameter and take appropriate action based on the ids as an HTTP Range Response.
static void | FreeExtraHTTPHeaders (UpnpListHead *extraHeadersList)
static int | ExtraHTTPHeaders (http_message_t *Req, UpnpListHead *extraHeadersList)
| Build an array of unrecognized headers.
static int | process_request (SOCKINFO *info, http_message_t *req, enum resp_type *rtype, membuffer *headers, membuffer *filename, struct xml_alias_t *alias, struct SendInstruction *RespInstr)
| Processes the request and returns the result in the output parameters.
static int | http_RecvPostMessage (http_parser_t *parser, SOCKINFO *info, char *filename, struct SendInstruction *Instr)
| Receives the HTTP post message.
void | web_server_callback (http_parser_t *parser, http_message_t *req, SOCKINFO *info)
| Main entry point into web server; Handles HTTP GET and HEAD requests.

## Variables

static const char * | gMediaTypes []
static const char * | gEncodedMediaTypes
static struct document_type_t | gMediaTypeList [70]
membuffer | gDocumentRootDir
membuffer | gWebserverCorsString
static struct xml_alias_t | gAliasDoc
static ithread_mutex_t | gWebMutex
str_int_entry | Http_Header_Names [33]

## Detailed Description

Defines the Web Server and has functions to carry out operations of the Web Server.

## Enumeration Type Documentation

## resp_type

enum resp_type

Response Types.

## Function Documentation

## alias_grab()

static void alias_grab | ( | struct xml_alias_t * | alias | ) |

static

Copy the contents of the global XML document into the local output parameter.

Parameters

  [out] | alias | XML alias object.

References xml_alias_t::ct, gAliasDoc, and is_valid_alias().

Referenced by process_request().

## alias_release()

static void alias_release | ( | struct xml_alias_t * | alias | ) |

static

Release the XML document referred to by the input parameter. Free the allocated buffers associated with this object.

Parameters

  [in] | alias | XML alias object.

References xml_alias_t::ct, xml_alias_t::doc, is_valid_alias(), and xml_alias_t::name.

Referenced by process_request(), web_server_callback(), web_server_destroy(), and web_server_set_alias().

## CheckOtherHTTPHeaders()

static int CheckOtherHTTPHeaders | ( | http_message_t * | Req,
|  | struct SendInstruction * | RespInstr,
|  | off_t | FileSize
| ) |  |

static

Get header id from the request parameter and take appropriate action based on the ids as an HTTP Range Response.

Returns
  - `HTTP_BAD_REQUEST`
  - `HTTP_INTERNAL_SERVER_ERROR`
  - `HTTP_REQUEST_RANGE_NOT_SATISFIABLE`
  - `HTTP_OK`

Parameters

  [in] | Req | HTTP Request message.
  [out] | RespInstr | Send Instruction object to data for the response.
  | FileSize | Size of the file containing the request document.

References memptr::buf, membuffer::buf, CreateHTTPRangeResponseHeader(), http_message_t::headers, memptr::length, membuffer::length, http_header_t::name, SendInstruction::RecvWriteSize, StrStr(), and http_header_t::value.

Referenced by process_request().

## CreateHTTPRangeResponseHeader()

static int CreateHTTPRangeResponseHeader | ( | char * | ByteRangeSpecifier,
|  | off_t | FileLength,
|  | struct SendInstruction * | Instr
| ) |  |

static

Fills in the Offset, read size and contents to send out as an HTTP Range Response.

Returns
  - `HTTP_BAD_REQUEST`
  - `HTTP_INTERNAL_SERVER_ERROR`
  - `HTTP_REQUEST_RANGE_NOT_SATISFIABLE`
  - `HTTP_OK`

Parameters

  | ByteRangeSpecifier | String containing the range.
  | FileLength | Length of the file.
  [out] | Instr | SendInstruction object where the range operations will be stored.

References GetNextRange(), SendInstruction::ReadSendSize, and StrStr().

Referenced by CheckOtherHTTPHeaders().

## ExtraHTTPHeaders()

static int ExtraHTTPHeaders | ( | http_message_t * | Req,
|  | UpnpListHead * | extraHeadersList
| ) |  |

static

Build an array of unrecognized headers.

Returns
  nothing

Parameters

  [in] | Req | HTTP Request message.

References memptr::buf, membuffer::buf, FreeExtraHTTPHeaders(), http_message_t::headers, memptr::length, membuffer::length, http_header_t::name, UpnpExtraHeaders_get_node(), UpnpExtraHeaders_new(), UpnpExtraHeaders_strncpy_name(), UpnpExtraHeaders_strncpy_value(), and http_header_t::value.

Referenced by process_request().

## FreeExtraHTTPHeaders()

static void FreeExtraHTTPHeaders | ( | UpnpListHead * | extraHeadersList | ) |

static

Parameters

  [in] | extraHeadersList | extra HTTP headers to free.

References UpnpExtraHeaders_delete().

Referenced by ExtraHTTPHeaders(), and process_request().

## get_alias()

static UPNP_INLINE int get_alias | ( | const char * | request_file,
|  | struct xml_alias_t * | alias,
|  | UpnpFileInfo * | info
| ) |  |

static

Compare the files names between the one on the XML alias the one passed in as the input parameter. If equal extract file information.

Returns
  - `1` - On Success
  - `0` if request is not an alias

Parameters

  [in] | request_file | request file passed in to be compared with.
  [out] | alias | xml alias object which has a file name stored.
  [out] | info | File information object which will be filled up if the file comparison succeeds.

References membuffer::buf, xml_alias_t::doc, xml_alias_t::last_modified, membuffer::length, xml_alias_t::name, UpnpFileInfo_set_FileLength(), UpnpFileInfo_set_IsDirectory(), UpnpFileInfo_set_IsReadable(), and UpnpFileInfo_set_LastModified().

Referenced by process_request().

## get_content_type()

static UPNP_INLINE int get_content_type | ( | const char * | filename,
|  | UpnpFileInfo * | fileInfo
| ) |  |

static

Based on the extension, clones an XML string based on type and content subtype. If content type and sub type are not found, unknown types are used.

Returns
  - `0` on success.
  - `UPNP_E_OUTOF_MEMORY` - on memory allocation failures.

Parameters

  [in] | filename | .
  [out] | fileInfo | .

References search_extension(), UPNP_E_OUTOF_MEMORY, UpnpFileInfo_get_ContentType(), and UpnpFileInfo_set_ContentType().

Referenced by get_file_info().

## get_file_info()

static int get_file_info | ( | const char * | filename,
|  | UpnpFileInfo * | info
| ) |  |

static

Release memory allocated for the global web server root directory and the global XML document. Resets the flag bWebServerState to WEB_SERVER_DISABLED.

Returns
  Integer.

Parameters

  [in] | filename | Filename having the description document.
  [out] | info | File information object having file attributes such as filelength, when was the file last modified, whether a file or a directory and whether the file or directory is readable.

References get_content_type(), UpnpFileInfo_get_FileLength(), UpnpFileInfo_get_IsReadable(), UpnpFileInfo_get_LastModified(), UpnpFileInfo_set_ContentType(), UpnpFileInfo_set_FileLength(), UpnpFileInfo_set_IsDirectory(), UpnpFileInfo_set_IsReadable(), UpnpFileInfo_set_LastModified(), and UpnpPrintf().

Referenced by process_request().

## GetNextRange()

static int GetNextRange | ( | char ** | SrcRangeStr,
|  | off_t * | FirstByte,
|  | off_t * | LastByte
| ) |  |

static

Returns a range of integers from a string.

Returns
  Always returns 1.

Parameters

  SrcRangeStr | string containing the token / range.
  FirstByte | gets the first byte of the token.
  LastByte | gets the last byte of the token.

References StrTok().

Referenced by CreateHTTPRangeResponseHeader().

## glob_alias_init()

static UPNP_INLINE void glob_alias_init | ( | void |  | ) |

static

Initialize the global XML document. Allocate buffers for the XML document.

References xml_alias_t::ct, xml_alias_t::doc, gAliasDoc, xml_alias_t::last_modified, and xml_alias_t::name.

Referenced by web_server_init().

## http_RecvPostMessage()

static int http_RecvPostMessage | ( | http_parser_t * | parser,
|  | SOCKINFO * | info,
|  | char * | filename,
|  | struct SendInstruction * | Instr
| ) |  |

static

Receives the HTTP post message.

Returns
  - `HTTP_INTERNAL_SERVER_ERROR`
  - `HTTP_UNAUTHORIZED`
  - `HTTP_BAD_REQUEST`
  - `HTTP_SERVICE_UNAVAILABLE`
  - `HTTP_OK`

Parameters

  | parser | HTTP Parser object.
  [in] | info | Socket Information object.
  | filename | File where received data is copied to.
  | Instr | Send Instruction object which gives information whether the file is a virtual file or not.

References membuffer::buf, VirtualDirCallbacks::close, SendInstruction::Cookie, http_message_t::entity, http_parser_t::entity_start_position, http_parser_t::http_error_code, memptr::length, http_message_t::msg, VirtualDirCallbacks::open, PARSE_CONTINUE_1, PARSE_INCOMPLETE, PARSE_INCOMPLETE_ENTITY, PARSE_OK, PARSE_SUCCESS, SendInstruction::RequestCookie, sock_read(), UpnpPrintf(), virtualDirCallback, and VirtualDirCallbacks::write.

Referenced by web_server_callback().

## is_valid_alias()

static UPNP_INLINE int is_valid_alias | ( | const struct xml_alias_t * | alias | ) |

static

Check for the validity of the XML object buffer.

Returns
  int.

Parameters

  [in] | alias | XML alias object.

References membuffer::buf, and xml_alias_t::doc.

Referenced by alias_grab(), alias_release(), and process_request().

## isFileInVirtualDir()

static int isFileInVirtualDir | ( | char * | filePath,
|  | const void ** | cookie
| ) |  |

static

Compares filePath with paths from the list of virtual directory lists.

Returns
  int.

Parameters

  [in] | filePath | Directory path to be tested for virtual directory.
  [out] | cookie | The cookie registered with this virtual directory, if matched.

References pVirtualDirList.

Referenced by process_request().

## media_list_init()

static UPNP_INLINE void media_list_init | ( | void |  | ) |

static

Decodes list and stores it in gMediaTypeList.

References document_type_t::content_subtype, document_type_t::content_type, document_type_t::file_ext, and gMediaTypeList.

Referenced by web_server_init().

## process_request()

static int process_request | ( | SOCKINFO * | info,
|  | http_message_t * | req,
|  | enum resp_type * | rtype,
|  | membuffer * | headers,
|  | membuffer * | filename,
|  | struct xml_alias_t * | alias,
|  | struct SendInstruction * | RespInstr
| ) |  |

static

Processes the request and returns the result in the output parameters.

Returns
  - `HTTP_BAD_REQUEST`
  - `HTTP_INTERNAL_SERVER_ERROR`
  - `HTTP_REQUEST_RANGE_NOT_SATISFIABLE`
  - `HTTP_FORBIDDEN`
  - `HTTP_NOT_FOUND`
  - `HTTP_NOT_ACCEPTABLE`
  - `HTTP_OK`

Parameters

  [in] | info | Socket info.
  [in] | req | HTTP Request message.
  [out] | rtype | Tpye of response.
  [out] | headers | Headers.
  [out] | filename | Get filename from request document.
  [out] | alias | Xml alias document from the request document.
  [out] | RespInstr | Send Instruction object where the response is set up.

References alias_grab(), alias_release(), memptr::buf, membuffer::buf, CheckOtherHTTPHeaders(), SendInstruction::Cookie, SendInstruction::CorsHeader, ExtraHTTPHeaders(), SOCKINFO::foreign_sockaddr, FreeExtraHTTPHeaders(), gAliasDoc, gDocumentRootDir, get_alias(), get_file_info(), VirtualDirCallbacks::get_info, gWebserverCorsString, http_MakeMessage(), is_valid_alias(), isFileInVirtualDir(), memptr::length, membuffer::length, http_message_t::method, SendInstruction::ReadSendSize, remove_dots(), remove_escaped_chars(), SendInstruction::RequestCookie, UPNP_E_SUCCESS, UpnpFileInfo_delete(), UpnpFileInfo_get_ContentType(), UpnpFileInfo_get_ExtraHeadersList(), UpnpFileInfo_get_FileLength(), UpnpFileInfo_get_IsDirectory(), UpnpFileInfo_get_IsReadable(), UpnpFileInfo_get_LastModified(), UpnpFileInfo_new(), UpnpFileInfo_set_ContentType(), UpnpFileInfo_set_CtrlPtIPAddr(), UpnpFileInfo_strncpy_Os(), http_message_t::uri, and virtualDirCallback.

Referenced by web_server_callback().

## search_extension()

static UPNP_INLINE int search_extension | ( | const char * | extension,
|  | const char ** | con_type,
|  | const char ** | con_subtype
| ) |  |

static

Based on the extension, returns the content type and content subtype.

Returns
  - `0` on success
  - `-1` on error

Parameters

  [in] | extension | .
  [out] | con_type | .
  [out] | con_subtype | .

References document_type_t::content_subtype, document_type_t::content_type, document_type_t::file_ext, and gMediaTypeList.

Referenced by get_content_type().

## StrStr()

static char * StrStr | ( | char * | s1,
|  | const char * | s2
| ) |  |

static

Finds a substring from a string in a case insensitive way.

Returns
  A pointer to the first occurence of s2 in s1.

Parameters

  s1 | Input string.
  s2 | Input sub-string.

References ToUpperCase().

Referenced by CheckOtherHTTPHeaders(), and CreateHTTPRangeResponseHeader().

## StrTok()

static char * StrTok | ( | char ** | Src,
|  | const char * | Del
| ) |  |

static

Finds next token in a string.

Returns
  Pointer to the next token.

Parameters

  Src | String containing the token.
  Del | Set of delimiter characters.

Referenced by GetNextRange().

## ToUpperCase()

static void ToUpperCase | ( | char * | s | ) |

static

Converts input string to upper case.

Parameters

  s | Input string to be converted.

Referenced by StrStr().

## web_server_callback()

void web_server_callback | ( | http_parser_t * | parser,
|  | http_message_t * | req,
|  | SOCKINFO * | info
| ) |  |

Main entry point into web server; Handles HTTP GET and HEAD requests.

Parameters

  [in] | parser | .
  [in] | req | .
  [in,out] | info | .

References alias_release(), membuffer::buf, xml_alias_t::doc, http_MakeMessage(), http_RecvPostMessage(), http_SendMessage(), membuffer::length, process_request(), and UpnpPrintf().

Referenced by UpnpEnableWebserver().

## web_server_destroy()

void web_server_destroy | ( | void |  | ) |

Release memory allocated for the global web server root directory and the global XML document. Resets the flag bWebServerState to WEB_SERVER_DISABLED.

References alias_release(), bWebServerState, gAliasDoc, gDocumentRootDir, and gWebserverCorsString.

Referenced by UpnpEnableWebserver(), and UpnpFinish().

## web_server_init()

int web_server_init | ( | void |  | ) |

Initilialize the different documents. Initialize the memory for root directory for web server. Call to initialize global XML document. Sets bWebServerState to WEB_SERVER_ENABLED.

Note
  alias_content is not freed here

Returns
  - `0` - OK
  - `UPNP_E_OUTOF_MEMORY`

References bWebServerState, VirtualDirCallbacks::close, gDocumentRootDir, VirtualDirCallbacks::get_info, glob_alias_init(), gWebserverCorsString, media_list_init(), VirtualDirCallbacks::open, pVirtualDirList, VirtualDirCallbacks::read, VirtualDirCallbacks::seek, UPNP_E_OUTOF_MEMORY, UPNP_E_SUCCESS, virtualDirCallback, and VirtualDirCallbacks::write.

Referenced by UpnpEnableWebserver().

## web_server_set_alias()

int web_server_set_alias | ( | const char * | alias_name,
|  | const char * | alias_content,
|  | size_t | alias_content_length,
|  | time_t | last_modified
| ) |  |

Replaces current alias with the given alias. To remove the current alias, set alias_name to NULL.

Note
  alias_content is not freed here

Returns
  - `0` - OK
  - `UPNP_E_OUTOF_MEMORY`

Parameters

  [in] | alias_name | Webserver name of alias; created by caller and freed by caller (doesn't even have to be malloc()d.
  [in] | alias_content | The xml doc; this is allocated by the caller; and freed by the web server.
  [in] | alias_content_length | Length of alias body in bytes.
  [in] | last_modified | Time when the contents of alias were last changed (local time).

References alias_release(), xml_alias_t::ct, xml_alias_t::doc, gAliasDoc, xml_alias_t::last_modified, xml_alias_t::name, and UPNP_E_OUTOF_MEMORY.

Referenced by UpnpUnRegisterRootDeviceLowPower().

## web_server_set_cors()

int web_server_set_cors | ( | const char * | cors_string | ) |

Assign the Access-Control-Allow-Origin specfied by the input const char* cors_string parameterto the global CORS string.

Returns
  Integer.

Parameters

  [in] | cors_string | String having the Access-Control-Allow-Origin string.

References gWebserverCorsString.

## web_server_set_root_dir()

int web_server_set_root_dir | ( | const char * | root_dir | ) |

Assign the path specfied by the input const char* root_dir parameter to the global Document root directory. Also check for path names ending in '/'.

Returns
  Integer.

Parameters

  [in] | root_dir | String having the root directory for the document.

References membuffer::buf, gDocumentRootDir, and membuffer::length.

## Variable Documentation

## gAliasDoc

struct xml_alias_t gAliasDoc

static

XML document.

Referenced by alias_grab(), glob_alias_init(), process_request(), web_server_destroy(), and web_server_set_alias().

## gMediaTypeList

struct document_type_t gMediaTypeList[70]

static

module variables - Globals, static and externs.

Referenced by media_list_init(), and search_extension().

## gMediaTypes

const char* gMediaTypes[]

static

Initial value:
= {
NULL,
"audio",
"video",
"image",
"application",
"text"}