Files
mongoose/src/http.h
T
2026-06-20 13:48:09 +01:00

204 lines
9.4 KiB
C

#pragma once
#include "arch.h"
#include "config.h"
#include "fs.h"
#include "net.h"
#include "str.h"
// A single HTTP header name/value pair.
struct mg_http_header {
struct mg_str name; // Header name, e.g. "Content-Type"
struct mg_str value; // Header value, e.g. "text/html"
};
// Parsed HTTP request or response.
// Passed as ev_data in MG_EV_HTTP_MSG and MG_EV_HTTP_HDRS.
// For requests: method="GET", uri="/path", proto="a=1&b=2", proto="HTTP/1.1"
// For responses: method="HTTP/1.0", uri="200", query="", proto="OK"
struct mg_http_message {
struct mg_str method, uri, query, proto; // Request/response line
struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Parsed headers array
struct mg_str body; // Request or response body
struct mg_str head; // Raw bytes: request/status line + headers, no body
struct mg_str message; // Raw bytes: head + body
};
// Options for mg_http_serve_dir() and mg_http_serve_file().
struct mg_http_serve_opts {
const char *root_dir; // Root directory for serving files, e.g. "/web"
const char *ssi_pattern; // Pattern for Server-Side Include files, e.g. "#.shtml". NULL disables SSI
const char *extra_headers; // Extra response headers, e.g. "A: b\r\nC: d\r\n". NULL for none
const char *mime_types; // Additional MIME types: "ext1=type1,ext2=type2". NULL for defaults only
const char *page404; // Path to a custom 404 page, e.g. "/404.html". NULL for built-in
struct mg_fs *fs; // Filesystem to use. NULL defaults to POSIX
};
// A single part of a multipart/form-data body, filled by mg_http_next_multipart().
struct mg_http_part {
struct mg_str name; // Form field name, from Content-Disposition: name="..."
struct mg_str filename; // Original filename for file uploads, empty for plain fields
struct mg_str body; // Part contents, points into the original message buffer
};
// Parses HTTP request or response in buffer s/len into hm.
// Returns number of bytes consumed, 0 if incomplete, -1 on error.
int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
// Returns the byte length of HTTP headers in buf (i.e. offset of the body).
// Returns 0 if headers are incomplete, -1 on error.
int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
// Sends one chunk in HTTP chunked transfer encoding using printf-style fmt.
// Call with empty fmt ("") to send the terminating zero-length chunk.
void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
// Sends one chunk in HTTP chunked transfer encoding from a raw buffer.
// Call with len=0 to send the terminating zero-length chunk.
void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
// Creates an HTTP server on url, e.g. "http://0.0.0.0:8000".
//
// Returns:
// Listening connection, or NULL on error.
// Example:
// mg_http_listen(&mgr, "http://0.0.0.0:8000", fn, NULL);
// Full examples:
// tutorials/http/http-server, tutorials/http/*
// Related APIs:
// mg_http_reply(), mg_http_serve_dir(), mg_match()
// Notes:
// Call mg_mgr_poll() in the main loop. The user-supplied fn event handler
// receives normal connection events. It also receives MG_EV_HTTP_HDRS when
// headers are received and MG_EV_HTTP_MSG when the full request is received.
// ev_data for both HTTP events is struct mg_http_message *.
struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
mg_event_handler_t fn, void *fn_data);
// Opens an HTTP client connection to url, e.g. "http://example.org".
//
// Returns:
// Client connection, or NULL on error.
// Example:
// mg_http_connect(&mgr, "http://example.org", fn, NULL);
// Full examples:
// tutorials/http/http-client, tutorials/http/huge-response
// Related APIs:
// mg_printf(), mg_http_status(), mg_http_get_header()
// Notes:
// In the user-supplied fn event handler, send the HTTP request on
// MG_EV_CONNECT. The handler receives normal connection events. It also
// receives MG_EV_HTTP_HDRS when headers are received and MG_EV_HTTP_MSG when
// the full response is received. ev_data for both HTTP events is struct
// mg_http_message *.
struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
mg_event_handler_t fn, void *fn_data);
// Serves static files from a directory.
//
// Example:
// struct mg_http_serve_opts o = {.root_dir = "web_root", .fs = &mg_fs_posix};
// mg_http_serve_dir(c, hm, &o);
// Full examples:
// tutorials/http/http-server, tutorials/core/embedded-filesystem
// Related APIs:
// mg_http_listen(), mg_http_serve_file(), mg_http_reply(), mg_match()
// Notes:
// Call from an MG_EV_HTTP_MSG handler. The uri in hm is mapped under
// opts->root_dir. Directory listing depends on MG_ENABLE_DIRLIST; SSI uses
// opts->ssi_pattern when configured.
void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
const struct mg_http_serve_opts *);
// Serves a single file at path. Call from an MG_EV_HTTP_MSG handler.
void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
const char *path, const struct mg_http_serve_opts *);
// Sends a complete HTTP response with Content-Length.
//
// Example:
// mg_http_reply(c, 200, "Content-Type: application/json\r\n",
// "{%m:%d}", MG_ESC("temperature"), 123);
// Full examples:
// tutorials/http/http-server, tutorials/http/http-restful-server,
// tutorials/http/device-dashboard
// Related APIs:
// mg_http_listen(), mg_printf(), mg_http_printf_chunk(), MG_ESC
// Notes:
// headers must end with "\r\n"; pass "" or NULL for no extra headers.
// body_fmt is printf-style and supports %M/%m custom printers. Use MG_ESC
// when printing JSON strings.
void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
const char *body_fmt, ...);
// Looks up a request header by name (case-insensitive).
// Returns a pointer to the mg_str value, or NULL if not found.
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
// Extracts a named variable from a query string or form-encoded body (buf).
// Returns the raw (URL-encoded) value as mg_str, or an empty mg_str if not found.
// Not NUL-terminated. Use mg_url_decode() to get a decoded string.
struct mg_str mg_http_var(struct mg_str buf, struct mg_str name);
// URL-decodes variable name from query string or form body into a NUL-terminated buffer.
// Returns the length of the decoded value, or negative if not found / buffer too small.
int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
// URL-decodes s/n into to/to_len. Set form=1 to also decode '+' as space.
// Returns number of bytes written, or -1 if to buffer is too small.
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
// URL-encodes s/n into buf/len. Returns number of bytes written.
size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
// Extracts HTTP credentials into caller-supplied buffers.
// For Basic auth: fills user (buf1) and password (buf2).
// For Bearer auth: fills buf1 with "" and buf2 with the token.
void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
// Deprecated API, do not expose
long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
struct mg_fs *fs, const char *dir, size_t max_size);
// Streams the raw request body into dir/name via fs. Non-blocking: installs an
// internal handler and returns immediately. fn is called with NULL on success
// or an error string on failure.
void mg_http_start_upload(struct mg_connection *c, struct mg_http_message *hm,
struct mg_str name, struct mg_str dir,
struct mg_fs *fs,
void (*fn)(struct mg_connection *, const char *));
// Starts an OTA firmware update from an HTTP POST upload.
// Calls mg_ota_begin/write/end internally; fn is called with NULL on success,
// or an error string on failure.
void mg_http_start_ota(struct mg_connection *c, struct mg_http_message *hm,
void (*fn)(struct mg_connection *, const char *));
// Sends a 401 Unauthorized response with a Basic Auth WWW-Authenticate challenge.
void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
// Extracts a named parameter from a header value string s.
// E.g. for s="multipart/form-data; boundary=abc", v="boundary" returns "abc".
struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
// Iterates over parts of a multipart/form-data body.
//
// Returns:
// Offset for the next call, or 0 when there are no more parts.
// Example:
// size_t ofs = 0;
// struct mg_http_part part;
// while ((ofs = mg_http_next_multipart(hm->body, ofs, &part)) > 0) { ... }
// Full examples:
// tutorials/http/file-upload-html-form, tutorials/http/http-server
// Related APIs:
// mg_http_listen(), mg_http_start_upload()
// Notes:
// Call from an MG_EV_HTTP_MSG handler after the full request body is
// received. part.name, part.filename, and part.body are zero-copy slices into
// hm->body and are not NUL-terminated.
size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
// Returns the HTTP status code from a parsed response message (e.g. 200, 404).
int mg_http_status(const struct mg_http_message *hm);