picow-http 0.12.1-4-g9d4fd13
HTTP server for the Raspberry Pi PicoW
|
This is the public API for picow-http, an HTTP server for the Raspberry Pi Pico W microcontroller. The API is used for:
picow-http takes the form of the C libraries (CMake INTERFACEs) picow_http
or picow_https
for use with the Pico C SDK. One or the other of the two libraries, depending on whether TLS support is required, is integrated into an application by the standard means for using a library in the SDK (see the documentation at the link for details). Except for the listener port number assigned by the default server configuration, the API is identical in the versions with and without TLS support.
To use the API, include the picow_http/http.h
header. CMake configuration ensures that the header is on the include path. http.h
includes the library's other headers (which may be optionally included separately).
For the underlying TCP stack, picow-http uses lwIP's "raw" TCP API, as provided via the Pico SDK. The TCP stack is almost entirely encapsulated by the picow-http API; in a few places (as noted in the documentation), considerations about the TCP stack may play a role in decisions about using the API.
The present documentation (mostly realized as Doxygen tags in the library's header files) is normative – the "source of truth" for the syntax and semantics of the API. For further information about picow-http, see:
This documentation assumes familiarity with the HTTP protocol; see, for example, RFC 9110 and RFC 9112.
The documentation uses RFC-style upper-case expressions such as "MUST" or "MAY NOT" to express preconditions on usage. Violations of these conditions are conceptually similar to "undefined behavior" in C – any behavior may result, including program crash.
The documentation may use words like these in lower-case, as in "must" or "may not". This usually means that the condition is checked, and an error code is returned if it is not fulfilled (so the requirement is no less relevant for proper usage).
HTTP processing involves reading and writing a variety of strings – URL paths, query strings, request and response headers, and so forth. Where strings are read as properties of a request, for example, the API usually provides a pointer into the buffer provided by the TCP stack, so that copying is not necessary. That saves both memory and time, but in such cases the string is not nul-terminated; a length value is provided.
For reasons such as these, strings that are accessed by many API functions are not nul-terminated, but rather characterized by length parameters; such as a length value passed in as a function parameter, or by an "out" parameter set in the function. Invalid assumptions about nul-termination may lead to unsafe usage; for example, it is not safe to use strlen(s)
unless s
is known to be nul-terminated.
NOTE: Conditions concerning string lengths and nul-termination are always described in the API documentation. Always check the docs to make sure.
To make this a bit easier, the API provides alternatives for a number of functions for which nul-terminated strings or literal strings (compile-time constant strings) can be assumed. For a function func()
that requires explicit string length parameters, there may be alternatives with these suffixes (which do not require the length parameters):
func_str()
, for which the strings are assumed to be nul-terminatedfunc_ltrl()
, for use with literal stringsThis comes at the price of increasing the number of functions in the API, many of which do essentially the same thing. But the *_str()
and *_ltrl()
variants are likely to be safer, and are less verbose (since they don't have the length parameters).
Where possible, prefer the use of literal strings, so that the lengths are compile-time constants (and because string constants are usually stored in flash memory, saving RAM). The API provides the macro STRLEN_LTRL() for the length of a literal string, so that you don't have to resort to hard-wired constants.
The lwIP layer for TCP/IP is almost fully encapsulated by the API, with two prominent exceptions.
The API uses err_t
, lwIP's error code type, as the return type for many of its functions. This is because some API functions return the error code that was returned internally in the TCP stack; so to keep things simple, there is only one error code type.
The declaration of err_t
is included when you include picow_http/http.h
. See the lwIP documentation to check its values.
The API uses lwIP's ip_addr_t
data type for IP addresses, which can be managed with lwIP's API for IP handling. As a short primer:
lwip/ip_addr.h
header, or lwip/ip4_addr.h
or lwip/ip6_addr.h
for IPv4- and IPv6-specific functions.ip_addr_t
's type
field distinguishes IPv4, IPv6, and "dual-stack" IPv4+IPv6 addresses (values of enum lwip_ip_addr_type
).ipaddr_ntoa_r()
to convert the binary address to a string (or ipaddr_ntoa()
, if you're willing to risk the use of a static global buffer).