HTTP server
Applications

## Modules

| Options

## Data Structures

struct | tCGI

## Typedefs

typedef const char *(* | tCGIHandler) (int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
typedef u16_t(* | tSSIHandler) (const char *ssi_tag_name, char *pcInsert, int iInsertLen)

## Functions

void | httpd_post_data_recved (void *connection, u16_t recved_len)
void | httpd_init (void)
void | httpd_inits (struct altcp_tls_config *conf)
void | http_set_ssi_handler (tSSIHandler ssi_handler, const char **tags, int num_tags)
void | http_set_cgi_handlers (const tCGI *cgis, int num_handlers)
err_t | httpd_post_begin (void *connection, const char *uri, const char *http_request, u16_t http_request_len, int content_len, char *response_uri, u16_t response_uri_len, u8_t *post_auto_wnd)
err_t | httpd_post_receive_data (void *connection, struct pbuf *p)
void | httpd_post_finished (void *connection, char *response_uri, u16_t response_uri_len)

## Detailed Description

This httpd supports for a rudimentary server-side-include facility which will replace tags of the form in any file whose extension is .shtml, .shtm or .ssi with strings provided by an include handler whose pointer is provided to the module via function http_set_ssi_handler(). Additionally, a simple common gateway interface (CGI) handling mechanism has been added to allow clients to hook functions to particular request URIs.

To enable SSI support, define label LWIP_HTTPD_SSI in lwipopts.h. To enable CGI support, define label LWIP_HTTPD_CGI in lwipopts.h.

By default, the server assumes that HTTP headers are already present in each file stored in the file system. By defining LWIP_HTTPD_DYNAMIC_HEADERS in lwipopts.h, this behavior can be changed such that the server inserts the headers automatically based on the extension of the file being served. If this mode is used, be careful to ensure that the file system image used does not already contain the header information.

File system images without headers can be created using the makefsfile tool with the -h command line option.

## Notes about valid SSI tags

The following assumptions are made about tags used in SSI markers:

1. No tag may contain '-' or whitespace characters within the tag name.
2. Whitespace is allowed between the tag leadin "<!--#" and the start of the tag name and between the tag name and the leadout string "-->".
3. The maximum tag name length is LWIP_HTTPD_MAX_TAG_NAME_LEN, currently 8 characters.

## Notes on CGI usage

The simple CGI support offered here works with GET method requests only and can handle up to 16 parameters encoded into the URI. The handler function may not write directly to the HTTP output but must return a filename that the HTTP server will send to the browser as a response to the incoming CGI request.

The list of supported file types is quite short, so if makefsdata complains about an unknown extension, make sure to add it (and its doctype) to the 'g_psHTTPHeaders' list.

## Typedef Documentation

## tCGIHandler

typedef const char*(* tCGIHandler) (int iIndex, int iNumParams, char *pcParam[], char *pcValue[])

Function pointer for a CGI script handler.

This function is called each time the HTTPD server is asked for a file whose name was previously registered as a CGI function using a call to http_set_cgi_handlers. The iIndex parameter provides the index of the CGI within the cgis array passed to http_set_cgi_handlers. Parameters pcParam and pcValue provide access to the parameters provided along with the URI. iNumParams provides a count of the entries in the pcParam and pcValue arrays. Each entry in the pcParam array contains the name of a parameter with the corresponding entry in the pcValue array containing the value for that parameter. Note that pcParam may contain multiple elements with the same name if, for example, a multi-selection list control is used in the form generating the data.

The function should return a pointer to a character string which is the path and filename of the response that is to be sent to the connected browser, for example "/thanks.htm" or "/response/error.ssi".

The maximum number of parameters that will be passed to this function via iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in the incoming HTTP request above this number will be discarded.

Requests intended for use by this CGI mechanism must be sent using the GET method (which encodes all parameters within the URI rather than in a block later in the request). Attempts to use the POST method will result in the request being ignored.

## tSSIHandler

typedef u16_t(* tSSIHandler) (const char *ssi_tag_name, char *pcInsert, int iInsertLen)

Function pointer for the SSI tag handler callback.

This function will be called each time the HTTPD server detects a tag of the form in files with extensions mentioned in the g_pcSSIExtensions array (currently .shtml, .shtm, .ssi, .xml, .json) where "name" appears as one of the tags supplied to http_set_ssi_handler in the tags array. The returned insert string, which will be appended after the the string "<!--#name-->" in file sent back to the client, should be written to pointer pcInsert. iInsertLen contains the size of the buffer pointed to by pcInsert. The iIndex parameter provides the zero-based index of the tag as found in the tags array and identifies the tag that is to be processed.

The handler returns the number of characters written to pcInsert excluding any terminating NULL or HTTPD_SSI_TAG_UNKNOWN when tag is not recognized.

Note that the behavior of this SSI mechanism is somewhat different from the "normal" SSI processing as found in, for example, the Apache web server. In this case, the inserted text is appended following the SSI tag rather than replacing the tag entirely. This allows for an implementation that does not require significant additional buffering of output data yet which will still offer usable SSI functionality. One downside to this approach is when attempting to use SSI within JavaScript. The SSI tag is structured to resemble an HTML comment but this syntax does not constitute a comment within JavaScript and, hence, leaving the tag in place will result in problems in these cases. In order to avoid these problems, define LWIP_HTTPD_SSI_INCLUDE_TAG as zero in your lwip options file, or use JavaScript style block comments in the form / * # name * / (without the spaces).

## Function Documentation

## http_set_cgi_handlers()

void http_set_cgi_handlers | ( | const tCGI * | cgis,
|  | int | num_handlers
| ) |  |

Set an array of CGI filenames/handler functions

Parameters

  cgis | an array of CGI filenames/handler functions
  num_handlers | number of elements in the 'cgis' array

## http_set_ssi_handler()

void http_set_ssi_handler | ( | tSSIHandler | ssi_handler,
|  | const char ** | tags,
|  | int | num_tags
| ) |  |

Set the SSI handler function.

Parameters

  ssi_handler | the SSI handler function
  tags | an array of SSI tag strings to search for in SSI-enabled files
  num_tags | number of tags in the 'tags' array

## httpd_init()

void httpd_init | ( | void |  | ) |

Initialize the httpd: set up a listening PCB and bind it to the defined port

## httpd_inits()

void httpd_inits | ( | struct altcp_tls_config * | conf | ) |

Initialize the httpd: set up a listening PCB and bind it to the defined port. Also set up TLS connection handling (HTTPS).

## httpd_post_begin()

err_t httpd_post_begin | ( | void * | connection,
|  | const char * | uri,
|  | const char * | http_request,
|  | u16_t | http_request_len,
|  | int | content_len,
|  | char * | response_uri,
|  | u16_t | response_uri_len,
|  | u8_t * | post_auto_wnd
| ) |  |

Called when a POST request has been received. The application can decide whether to accept it or not.

Parameters

  connection | Unique connection identifier, valid until httpd_post_end is called.
  uri | The HTTP header URI receiving the POST request.
  http_request | The raw HTTP request (the first packet, normally).
  http_request_len | Size of 'http_request'.
  content_len | Content-Length from HTTP header.
  response_uri | Filename of response file, to be filled when denying the request
  response_uri_len | Size of the 'response_uri' buffer.
  post_auto_wnd | Set this to 0 to let the callback code handle window updates by calling 'httpd_post_data_recved' (to throttle rx speed) default is 1 (httpd handles window updates automatically)

Returns
  ERR_OK: Accept the POST request, data may be passed in another err_t: Deny the POST request, send back 'bad request'.

## httpd_post_data_recved()

void httpd_post_data_recved | ( | void * | connection,
|  | u16_t | recved_len
| ) |  |

A POST implementation can call this function to update the TCP window. This can be used to throttle data reception (e.g. when received data is programmed to flash and data is received faster than programmed).

Parameters

  connection | A connection handle passed to httpd_post_begin for which httpd_post_finished has NOT been called yet!
  recved_len | Length of data received (for window update)

## httpd_post_finished()

void httpd_post_finished | ( | void * | connection,
|  | char * | response_uri,
|  | u16_t | response_uri_len
| ) |  |

Called when all data is received or when the connection is closed. The application must return the filename/URI of a file to send in response to this POST request. If the response_uri buffer is untouched, a 404 response is returned.

Parameters

  connection | Unique connection identifier.
  response_uri | Filename of response file, to be filled when denying the request
  response_uri_len | Size of the 'response_uri' buffer.

## httpd_post_receive_data()

err_t httpd_post_receive_data | ( | void * | connection,
|  | struct pbuf * | p
| ) |  |

Called for each pbuf of data that has been received for a POST. ATTENTION: The application is responsible for freeing the pbufs passed in!

Parameters

  connection | Unique connection identifier.
  p | Received data.

Returns
  ERR_OK: Data accepted. another err_t: Data denied, http_post_get_response_uri will be called.