httpd: Add callbacks for GET header processing

This commit is contained in:
Mike Kleshov
2026-04-16 16:11:03 +03:00
parent 4599f551de
commit 5a0007f083
3 changed files with 121 additions and 1 deletions

View File

@@ -2131,7 +2131,29 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct altcp_pcb *pc
} else } else
#endif /* LWIP_HTTPD_SUPPORT_POST */ #endif /* LWIP_HTTPD_SUPPORT_POST */
{ {
return http_find_file(hs, uri, is_09); #if LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN
err_t err;
void *obj;
char replace_uri[LWIP_HTTPD_HEADERS_URI_REPLACE_LEN + 1];
replace_uri[0] = 0;
obj = httpd_headers_before_file_open(crlf + 2, data_len - (crlf + 2 - data),
uri, replace_uri,
LWIP_HTTPD_HEADERS_URI_REPLACE_LEN);
if (replace_uri[0] != 0) {
uri = replace_uri;
}
#endif /* LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN */
err = http_find_file(hs, uri, is_09);
#if LWIP_HTTPD_HEADERS_AFTER_FILE_OPEN
if (err == ERR_OK) {
httpd_headers_after_file_open(hs->handle, crlf + 2, data_len - (crlf + 2 - data)
#if LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN
, obj
#endif /* LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN */
);
}
#endif /* LWIP_HTTPD_HEADERS_AFTER_FILE_OPEN */
return err;
} }
} }
} else { } else {

View File

@@ -242,6 +242,73 @@ void httpd_post_data_recved(void *connection, u16_t recved_len);
#endif /* LWIP_HTTPD_SUPPORT_POST */ #endif /* LWIP_HTTPD_SUPPORT_POST */
#if LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN
/**
* @ingroup httpd
* Callback to process HTTP headers before the file is opened.
*
* Called for each HTTP GET request after the request line is parsed but
* before fs_open() is called. This allows the application to inspect
* HTTP headers (cookies, authorization, etc.) and optionally replace the
* requested URI.
*
* The return value is an opaque object that will be passed to
* httpd_headers_after_file_open() if that callback is enabled. This can
* be used to pass parsed header data to the post-open callback without
* storing it globally.
*
* @param headers Pointer to the HTTP headers section (after request line).
* This points to the first character after the CRLF that
* terminates the request line (e.g., "Host: ...\r\n...").
* @param headers_len Length of the headers data.
* @param uri The requested URI from the request line.
* @param replace_uri Buffer to optionally provide a different URI. If the
* first character is non-zero, this URI will be used
* instead of the original request URI.
* @param replace_uri_len Size of the replace_uri buffer.
* @return Opaque object pointer passed to httpd_headers_after_file_open(),
* or NULL if no object is needed.
*/
extern void* httpd_headers_before_file_open(const char* headers, u16_t headers_len,
const char *uri, char *replace_uri,
u16_t replace_uri_len);
#endif /* LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN */
#if LWIP_HTTPD_HEADERS_AFTER_FILE_OPEN
/* we have to prototype this struct here to make it available for the handler */
struct fs_file;
/**
* @ingroup httpd
* Callback to process HTTP headers after the file is opened.
*
* Called for each HTTP GET request after fs_open() succeeds and after CGI
* handling (if enabled). This allows the application to inspect HTTP headers
* (cookies, authorization, etc.) and optionally store state in the file
* structure for later use in SSI or dynamic file generation.
*
* The application can access file->state or file->pextension to retrieve or
* store per-request connection data that was initialized by fs_state_init().
*
* @param file The opened file handle (from fs_open()).
* @param headers Pointer to the HTTP headers section (after request line).
* This points to the first character after the CRLF that
* terminates the request line (e.g., "Host: ...\r\n...").
* @param headers_len Length of the headers data.
* @param state The opaque object pointer returned from
* httpd_headers_before_file_open(), if that callback is enabled.
* This can be used to pass parsed header data from the pre-open
* callback without storing it globally.
*/
extern void httpd_headers_after_file_open(struct fs_file *file, const char* headers,
u16_t headers_len
#if LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN
, void *state
#endif
);
#endif /* LWIP_HTTPD_HEADERS_AFTER_FILE_OPEN */
void httpd_init(void); void httpd_init(void);
#if HTTPD_ENABLE_HTTPS #if HTTPD_ENABLE_HTTPS

View File

@@ -163,6 +163,37 @@
#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192 #define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192
#endif #endif
/** Set this to 1 to add a callback for HTTP headers processing.
*
* The httpd_headers_before_file_open() function is called for each HTTP GET
* request received, before the file is opened.
* The callback can parse headers and replace the URI for file to be opened.
* It can also pass an object to httpd_headers_after_file_open() if it is
* enabled (see below).
*/
#if !defined LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN || defined __DOXYGEN__
#define LWIP_HTTPD_HEADERS_BEFORE_FILE_OPEN 0
#endif
/** Maximum length of the filename to replace the original URI in the
* httpd_headers_before_file_open() callback.
* This buffer is allocated on the stack.
*/
#if !defined LWIP_HTTPD_HEADERS_URI_REPLACE_LEN || defined __DOXYGEN__
#define LWIP_HTTPD_HEADERS_URI_REPLACE_LEN 63
#endif
/** Set this to 1 to add a callback for HTTP headers processing.
*
* The httpd_headers_after_file_open() function is called for each HTTP GET
* request received, after the file is opened, and after CGI handling,
* if it is enabled.
* The callback can parse headers and store state in the file structure.
*/
#if !defined LWIP_HTTPD_HEADERS_AFTER_FILE_OPEN || defined __DOXYGEN__
#define LWIP_HTTPD_HEADERS_AFTER_FILE_OPEN 0
#endif
#if !defined LWIP_HTTPD_POST_MANUAL_WND || defined __DOXYGEN__ #if !defined LWIP_HTTPD_POST_MANUAL_WND || defined __DOXYGEN__
#define LWIP_HTTPD_POST_MANUAL_WND 0 #define LWIP_HTTPD_POST_MANUAL_WND 0
#endif #endif