Browse Source

[multiple] extend enum http_header_e list

master
Glenn Strauss 1 year ago
parent
commit
367f30a645
  1. 8
      src/buffer.h
  2. 98
      src/http-header-glue.c
  3. 98
      src/http_header.c
  4. 46
      src/http_header.h
  5. 8
      src/mod_auth.c
  6. 8
      src/mod_authn_gssapi.c
  7. 4
      src/mod_expire.c
  8. 4
      src/mod_uploadprogress.c
  9. 14
      src/mod_webdav.c
  10. 4
      src/request.h
  11. 13
      src/response.c

8
src/buffer.h

@ -217,10 +217,10 @@ static inline int light_isalnum(int c) {
#define light_isupper(c) ((uint32_t)(c)-'A' <= 'Z'-'A')
#define light_islower(c) ((uint32_t)(c)-'a' <= 'z'-'a')
#define light_bshift(b) (1u << (b))
#define light_btst(a,b) ((a) & (1u << (b)))
#define light_bclr(a,b) ((a) &= ~(1u << (b)))
#define light_bset(a,b) ((a) |= (1u << (b)))
#define light_bshift(b) ((uint64_t)1uL << (b))
#define light_btst(a,b) ((a) & ((uint64_t)1uL << (b)))
#define light_bclr(a,b) ((a) &= ~((uint64_t)1uL << (b)))
#define light_bset(a,b) ((a) |= ((uint64_t)1uL << (b)))
__attribute_pure__

98
src/http-header-glue.c

@ -117,12 +117,16 @@ int http_response_redirect_to_directory(request_st * const r, int status) {
}
if (status >= 300) {
http_header_response_set(r, HTTP_HEADER_LOCATION, CONST_STR_LEN("Location"), CONST_BUF_LEN(o));
http_header_response_set(r, HTTP_HEADER_LOCATION,
CONST_STR_LEN("Location"),
CONST_BUF_LEN(o));
r->http_status = status;
r->resp_body_finished = 1;
}
else {
http_header_response_set(r, HTTP_HEADER_CONTENT_LOCATION, CONST_STR_LEN("Content-Location"), CONST_BUF_LEN(o));
http_header_response_set(r, HTTP_HEADER_CONTENT_LOCATION,
CONST_STR_LEN("Content-Location"),
CONST_BUF_LEN(o));
}
return 0;
@ -178,12 +182,14 @@ int http_response_handle_cachable(request_st * const r, const buffer * const mti
* return a 304 (Not Modified) response.
*/
if ((vb = http_header_request_get(r, HTTP_HEADER_IF_NONE_MATCH, CONST_STR_LEN("If-None-Match")))) {
if ((vb = http_header_request_get(r, HTTP_HEADER_IF_NONE_MATCH,
CONST_STR_LEN("If-None-Match")))) {
/*(weak etag comparison must not be used for ranged requests)*/
int range_request =
(r->conf.range_requests
&& (200 == r->http_status || 0 == r->http_status)
&& NULL != http_header_request_get(r, HTTP_HEADER_RANGE, CONST_STR_LEN("Range")));
&& NULL != http_header_request_get(r, HTTP_HEADER_RANGE,
CONST_STR_LEN("Range")));
if (etag_is_equal(&r->physical.etag, vb->ptr, !range_request)) {
if (http_method_get_or_head(r->http_method)) {
r->http_status = 304;
@ -195,7 +201,8 @@ int http_response_handle_cachable(request_st * const r, const buffer * const mti
}
}
} else if (http_method_get_or_head(r->http_method)
&& (vb = http_header_request_get(r, HTTP_HEADER_IF_MODIFIED_SINCE, CONST_STR_LEN("If-Modified-Since")))) {
&& (vb = http_header_request_get(r, HTTP_HEADER_IF_MODIFIED_SINCE,
CONST_STR_LEN("If-Modified-Since")))) {
/* last-modified handling */
size_t used_len;
char *semicolon;
@ -247,12 +254,14 @@ int http_response_handle_cachable(request_st * const r, const buffer * const mti
void http_response_body_clear (request_st * const r, int preserve_length) {
r->resp_send_chunked = 0;
if (light_btst(r->resp_htags, HTTP_HEADER_TRANSFER_ENCODING)) {
http_header_response_unset(r, HTTP_HEADER_TRANSFER_ENCODING, CONST_STR_LEN("Transfer-Encoding"));
http_header_response_unset(r, HTTP_HEADER_TRANSFER_ENCODING,
CONST_STR_LEN("Transfer-Encoding"));
}
if (!preserve_length) { /* preserve for HEAD responses and no-content responses (204, 205, 304) */
r->content_length = -1;
if (light_btst(r->resp_htags, HTTP_HEADER_CONTENT_LENGTH)) {
http_header_response_unset(r, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"));
http_header_response_unset(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length"));
}
/*(if not preserving Content-Length, do not preserve trailers, if any)*/
r->resp_decode_chunked = 0;
@ -306,7 +315,9 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
off_t start, end;
const char *s, *minus;
static const char boundary[] = "fkj49sn38dcn3";
const buffer *content_type = http_header_response_get(r, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"));
const buffer *content_type =
http_header_response_get(r, HTTP_HEADER_CONTENT_TYPE,
CONST_STR_LEN("Content-Type"));
start = 0;
end = sce->st.st_size - 1;
@ -474,7 +485,9 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
buffer_append_string_len(tb, boundary, sizeof(boundary)-1);
/* overwrite content-type */
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(tb));
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE,
CONST_STR_LEN("Content-Type"),
CONST_BUF_LEN(tb));
} else {
/* add Content-Range-header */
@ -485,7 +498,9 @@ static int http_response_parse_range(request_st * const r, buffer * const path,
buffer_append_string_len(tb, CONST_STR_LEN("/"));
buffer_append_int(tb, sce->st.st_size);
http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(tb));
http_header_response_set(r, HTTP_HEADER_CONTENT_RANGE,
CONST_STR_LEN("Content-Range"),
CONST_BUF_LEN(tb));
}
/* ok, the file is set-up */
@ -545,7 +560,8 @@ void http_response_send_file (request_st * const r, buffer * const path) {
/* set response content-type, if not set already */
if (NULL == http_header_response_get(r, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"))) {
if (NULL == http_header_response_get(r, HTTP_HEADER_CONTENT_TYPE,
CONST_STR_LEN("Content-Type"))) {
const buffer *content_type = stat_cache_content_type_get(sce, r);
if (buffer_string_is_empty(content_type)) {
/* we are setting application/octet-stream, but also announce that
@ -554,16 +570,22 @@ void http_response_send_file (request_st * const r, buffer * const path) {
* This should fix the aggressive caching of FF and the script download
* seen by the first installations
*/
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("application/octet-stream"));
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE,
CONST_STR_LEN("Content-Type"),
CONST_STR_LEN("application/octet-stream"));
allow_caching = 0;
} else {
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(content_type));
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE,
CONST_STR_LEN("Content-Type"),
CONST_BUF_LEN(content_type));
}
}
if (r->conf.range_requests) {
http_header_response_append(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Accept-Ranges"), CONST_STR_LEN("bytes"));
http_header_response_append(r, HTTP_HEADER_ACCEPT_RANGES,
CONST_STR_LEN("Accept-Ranges"),
CONST_STR_LEN("bytes"));
}
if (allow_caching) {
@ -571,18 +593,25 @@ void http_response_send_file (request_st * const r, buffer * const path) {
? stat_cache_etag_get(sce, r->conf.etag_flags)
: NULL;
if (!buffer_string_is_empty(etag)) {
if (NULL == http_header_response_get(r, HTTP_HEADER_ETAG, CONST_STR_LEN("ETag"))) {
if (NULL == http_header_response_get(r, HTTP_HEADER_ETAG,
CONST_STR_LEN("ETag"))) {
/* generate e-tag */
etag_mutate(&r->physical.etag, etag);
http_header_response_set(r, HTTP_HEADER_ETAG, CONST_STR_LEN("ETag"), CONST_BUF_LEN(&r->physical.etag));
http_header_response_set(r, HTTP_HEADER_ETAG,
CONST_STR_LEN("ETag"),
CONST_BUF_LEN(&r->physical.etag));
}
}
/* prepare header */
if (NULL == (mtime = http_header_response_get(r, HTTP_HEADER_LAST_MODIFIED, CONST_STR_LEN("Last-Modified")))) {
mtime = http_header_response_get(r, HTTP_HEADER_LAST_MODIFIED,
CONST_STR_LEN("Last-Modified"));
if (NULL == mtime) {
mtime = strftime_cache_get(sce->st.st_mtime);
http_header_response_set(r, HTTP_HEADER_LAST_MODIFIED, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
http_header_response_set(r, HTTP_HEADER_LAST_MODIFIED,
CONST_STR_LEN("Last-Modified"),
CONST_BUF_LEN(mtime));
}
if (HANDLER_FINISHED == http_response_handle_cachable(r, mtime)) {
@ -603,13 +632,16 @@ void http_response_send_file (request_st * const r, buffer * const path) {
if (r->conf.range_requests
&& (200 == r->http_status || 0 == r->http_status)
&& NULL != (vb = http_header_request_get(r, HTTP_HEADER_RANGE, CONST_STR_LEN("Range")))
&& NULL == http_header_response_get(r, HTTP_HEADER_CONTENT_ENCODING, CONST_STR_LEN("Content-Encoding"))) {
&& NULL != (vb = http_header_request_get(r, HTTP_HEADER_RANGE,
CONST_STR_LEN("Range")))
&& NULL == http_header_response_get(r, HTTP_HEADER_CONTENT_ENCODING,
CONST_STR_LEN("Content-Encoding"))) {
const buffer *range = vb;
int do_range_request = 1;
/* check if we have a conditional GET */
if (NULL != (vb = http_header_request_get(r, HTTP_HEADER_OTHER, CONST_STR_LEN("If-Range")))) {
if (NULL != (vb = http_header_request_get(r, HTTP_HEADER_IF_RANGE,
CONST_STR_LEN("If-Range")))) {
/* if the value is the same as our ETag, we do a Range-request,
* otherwise a full 200 */
@ -679,7 +711,8 @@ static void http_response_xsendfile (request_st * const r, buffer * const path,
* determined by open(), fstat() to reduces race conditions if the file
* is modified between stat() (stat_cache_get_entry()) and open(). */
if (light_btst(r->resp_htags, HTTP_HEADER_CONTENT_LENGTH)) {
http_header_response_unset(r, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"));
http_header_response_unset(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length"));
r->content_length = -1;
}
@ -739,7 +772,8 @@ static void http_response_xsendfile2(request_st * const r, const buffer * const
/* reset Content-Length, if set by backend */
if (light_btst(r->resp_htags, HTTP_HEADER_CONTENT_LENGTH)) {
http_header_response_unset(r, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"));
http_header_response_unset(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length"));
r->content_length = -1;
}
@ -946,7 +980,8 @@ static handler_t http_response_process_local_redir(request_st * const r, size_t
/* r->http_status >= 300 && r->http_status < 400) */
size_t ulen = buffer_string_length(&r->uri.path);
const buffer *vb = http_header_response_get(r, HTTP_HEADER_LOCATION, CONST_STR_LEN("Location"));
const buffer *vb = http_header_response_get(r, HTTP_HEADER_LOCATION,
CONST_STR_LEN("Location"));
if (NULL != vb
&& vb->ptr[0] == '/'
&& (0 != strncmp(vb->ptr, r->uri.path.ptr, ulen)
@ -1082,10 +1117,8 @@ static int http_response_process_headers(request_st * const r, http_response_opt
case HTTP_HEADER_UPGRADE:
/*(technically, should also verify Connection: upgrade)*/
/*(flag only for mod_proxy and mod_cgi (for now))*/
if (opts->backend != BACKEND_PROXY
&& opts->backend != BACKEND_CGI) {
id = HTTP_HEADER_OTHER;
}
if (opts->backend != BACKEND_PROXY && opts->backend != BACKEND_CGI)
continue;
if (r->http_version >= HTTP_VERSION_2) continue;
break;
case HTTP_HEADER_CONNECTION:
@ -1297,16 +1330,19 @@ handler_t http_response_parse_headers(request_st * const r, http_response_opts *
buffer *vb;
/* X-Sendfile2 is deprecated; historical for fastcgi */
if (opts->backend == BACKEND_FASTCGI
&& NULL != (vb = http_header_response_get(r, HTTP_HEADER_OTHER, CONST_STR_LEN("X-Sendfile2")))) {
&& NULL != (vb = http_header_response_get(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("X-Sendfile2")))) {
http_response_xsendfile2(r, vb, opts->xsendfile_docroot);
/* http_header_response_unset() shortcut for HTTP_HEADER_OTHER */
buffer_clear(vb); /*(do not send to client)*/
if (NULL == r->handler_module)
r->resp_body_started = 0;
return HANDLER_FINISHED;
} else if (NULL != (vb = http_header_response_get(r, HTTP_HEADER_OTHER, CONST_STR_LEN("X-Sendfile")))
} else if (NULL != (vb = http_header_response_get(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("X-Sendfile")))
|| (opts->backend == BACKEND_FASTCGI /* X-LIGHTTPD-send-file is deprecated; historical for fastcgi */
&& NULL != (vb = http_header_response_get(r, HTTP_HEADER_OTHER, CONST_STR_LEN("X-LIGHTTPD-send-file"))))) {
&& NULL != (vb = http_header_response_get(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("X-LIGHTTPD-send-file"))))) {
http_response_xsendfile(r, vb, opts->xsendfile_docroot);
/* http_header_response_unset() shortcut for HTTP_HEADER_OTHER */
buffer_clear(vb); /*(do not send to client)*/

98
src/http_header.c

@ -16,48 +16,78 @@
typedef struct keyvlenvalue {
const int key;
const uint32_t vlen;
const char value[24];
const int16_t key;
const uint16_t vlen;
const char value[28];
} keyvlenvalue;
/* Note: must be sorted by length */
/* Note: must be kept in sync with http_header.h enum http_header_e */
/* Note: must be kept in sync http_headers[] and http_headers_off[] */
/* http_headers_off lists first offset at which string of specific len occur */
int8_t http_headers_off[] = {
-1, -1, -1, -1, 0, 4, 5, 9, 10, 11, 12, -1, 15, 16, 20, 22, 24, 26
static const int8_t http_headers_off[] = {
-1, -1, 0, 1, 4, 9, 11, 17, 21, 25, 27, -1, 30, 31,
37, 40, 45, 49, -1, 52, -1, -1, 53, 54, -1, 55, -1, 57
};
static const keyvlenvalue http_headers[] = {
{ HTTP_HEADER_HOST, CONST_LEN_STR("host") }
,{ HTTP_HEADER_DATE, CONST_LEN_STR("date") }
,{ HTTP_HEADER_ETAG, CONST_LEN_STR("etag") }
,{ HTTP_HEADER_VARY, CONST_LEN_STR("vary") }
,{ HTTP_HEADER_RANGE, CONST_LEN_STR("range") }
,{ HTTP_HEADER_COOKIE, CONST_LEN_STR("cookie") }
,{ HTTP_HEADER_EXPECT, CONST_LEN_STR("expect") }
,{ HTTP_HEADER_STATUS, CONST_LEN_STR("status") }
,{ HTTP_HEADER_SERVER, CONST_LEN_STR("server") }
,{ HTTP_HEADER_UPGRADE, CONST_LEN_STR("upgrade") }
,{ HTTP_HEADER_LOCATION, CONST_LEN_STR("location") }
,{ HTTP_HEADER_FORWARDED, CONST_LEN_STR("forwarded") }
,{ HTTP_HEADER_CONNECTION, CONST_LEN_STR("connection") }
,{ HTTP_HEADER_SET_COOKIE, CONST_LEN_STR("set-cookie") }
,{ HTTP_HEADER_USER_AGENT, CONST_LEN_STR("user-agent") }
,{ HTTP_HEADER_CONTENT_TYPE, CONST_LEN_STR("content-type") }
,{ HTTP_HEADER_LAST_MODIFIED, CONST_LEN_STR("last-modified") }
,{ HTTP_HEADER_AUTHORIZATION, CONST_LEN_STR("authorization") }
,{ HTTP_HEADER_IF_NONE_MATCH, CONST_LEN_STR("if-none-match") }
,{ HTTP_HEADER_CACHE_CONTROL, CONST_LEN_STR("cache-control") }
,{ HTTP_HEADER_CONTENT_LENGTH, CONST_LEN_STR("content-length") }
,{ HTTP_HEADER_HTTP2_SETTINGS, CONST_LEN_STR("http2-settings") }
,{ HTTP_HEADER_ACCEPT_ENCODING, CONST_LEN_STR("accept-encoding") }
,{ HTTP_HEADER_X_FORWARDED_FOR, CONST_LEN_STR("x-forwarded-for") }
,{ HTTP_HEADER_CONTENT_ENCODING, CONST_LEN_STR("content-encoding") }
,{ HTTP_HEADER_CONTENT_LOCATION, CONST_LEN_STR("content-location") }
,{ HTTP_HEADER_IF_MODIFIED_SINCE, CONST_LEN_STR("if-modified-since") }
,{ HTTP_HEADER_TRANSFER_ENCODING, CONST_LEN_STR("transfer-encoding") }
,{ HTTP_HEADER_X_FORWARDED_PROTO, CONST_LEN_STR("x-forwarded-proto") }
{ HTTP_HEADER_TE, CONST_LEN_STR("te") }
,{ HTTP_HEADER_AGE, CONST_LEN_STR("age") }
,{ HTTP_HEADER_DNT, CONST_LEN_STR("dnt") }
,{ HTTP_HEADER_P3P, CONST_LEN_STR("p3p") }
,{ HTTP_HEADER_HOST, CONST_LEN_STR("host") }
,{ HTTP_HEADER_DATE, CONST_LEN_STR("date") }
,{ HTTP_HEADER_ETAG, CONST_LEN_STR("etag") }
,{ HTTP_HEADER_VARY, CONST_LEN_STR("vary") }
,{ HTTP_HEADER_LINK, CONST_LEN_STR("link") }
,{ HTTP_HEADER_ALLOW, CONST_LEN_STR("allow") }
,{ HTTP_HEADER_RANGE, CONST_LEN_STR("range") }
,{ HTTP_HEADER_COOKIE, CONST_LEN_STR("cookie") }
,{ HTTP_HEADER_ACCEPT, CONST_LEN_STR("accept") }
,{ HTTP_HEADER_STATUS, CONST_LEN_STR("status") }
,{ HTTP_HEADER_SERVER, CONST_LEN_STR("server") }
,{ HTTP_HEADER_EXPECT, CONST_LEN_STR("expect") }
,{ HTTP_HEADER_PRAGMA, CONST_LEN_STR("pragma") }
,{ HTTP_HEADER_UPGRADE, CONST_LEN_STR("upgrade") }
,{ HTTP_HEADER_REFERER, CONST_LEN_STR("referer") }
,{ HTTP_HEADER_EXPIRES, CONST_LEN_STR("expires") }
,{ HTTP_HEADER_ALT_SVC, CONST_LEN_STR("alt-svc") }
,{ HTTP_HEADER_LOCATION, CONST_LEN_STR("location") }
,{ HTTP_HEADER_IF_MATCH, CONST_LEN_STR("if-match") }
,{ HTTP_HEADER_IF_RANGE, CONST_LEN_STR("if-range") }
,{ HTTP_HEADER_ALT_USED, CONST_LEN_STR("alt-used") }
,{ HTTP_HEADER_FORWARDED, CONST_LEN_STR("forwarded") }
,{ HTTP_HEADER_EXPECT_CT, CONST_LEN_STR("expect-ct") }
,{ HTTP_HEADER_CONNECTION, CONST_LEN_STR("connection") }
,{ HTTP_HEADER_SET_COOKIE, CONST_LEN_STR("set-cookie") }
,{ HTTP_HEADER_USER_AGENT, CONST_LEN_STR("user-agent") }
,{ HTTP_HEADER_CONTENT_TYPE, CONST_LEN_STR("content-type") }
,{ HTTP_HEADER_LAST_MODIFIED, CONST_LEN_STR("last-modified") }
,{ HTTP_HEADER_AUTHORIZATION, CONST_LEN_STR("authorization") }
,{ HTTP_HEADER_IF_NONE_MATCH, CONST_LEN_STR("if-none-match") }
,{ HTTP_HEADER_CACHE_CONTROL, CONST_LEN_STR("cache-control") }
,{ HTTP_HEADER_ACCEPT_RANGES, CONST_LEN_STR("accept-ranges") }
,{ HTTP_HEADER_CONTENT_RANGE, CONST_LEN_STR("content-range") }
,{ HTTP_HEADER_CONTENT_LENGTH, CONST_LEN_STR("content-length") }
,{ HTTP_HEADER_HTTP2_SETTINGS, CONST_LEN_STR("http2-settings") }
,{ HTTP_HEADER_ONION_LOCATION, CONST_LEN_STR("onion-location") }
,{ HTTP_HEADER_ACCEPT_ENCODING, CONST_LEN_STR("accept-encoding") }
,{ HTTP_HEADER_ACCEPT_LANGUAGE, CONST_LEN_STR("accept-language") }
,{ HTTP_HEADER_REFERRER_POLICY, CONST_LEN_STR("referrer-policy") }
,{ HTTP_HEADER_X_FORWARDED_FOR, CONST_LEN_STR("x-forwarded-for") }
,{ HTTP_HEADER_X_FRAME_OPTIONS, CONST_LEN_STR("x-frame-options") }
,{ HTTP_HEADER_WWW_AUTHENTICATE, CONST_LEN_STR("www-authenticate") }
,{ HTTP_HEADER_CONTENT_ENCODING, CONST_LEN_STR("content-encoding") }
,{ HTTP_HEADER_CONTENT_LOCATION, CONST_LEN_STR("content-location") }
,{ HTTP_HEADER_X_XSS_PROTECTION, CONST_LEN_STR("x-xss-protection") }
,{ HTTP_HEADER_IF_MODIFIED_SINCE, CONST_LEN_STR("if-modified-since") }
,{ HTTP_HEADER_TRANSFER_ENCODING, CONST_LEN_STR("transfer-encoding") }
,{ HTTP_HEADER_X_FORWARDED_PROTO, CONST_LEN_STR("x-forwarded-proto") }
,{ HTTP_HEADER_IF_UNMODIFIED_SINCE, CONST_LEN_STR("if-unmodified-since") }
,{ HTTP_HEADER_X_CONTENT_TYPE_OPTIONS, CONST_LEN_STR("x-content-type-options") }
,{ HTTP_HEADER_CONTENT_SECURITY_POLICY, CONST_LEN_STR("content-security-policy") }
,{ HTTP_HEADER_STRICT_TRANSPORT_SECURITY, CONST_LEN_STR("strict-transport-security") }
,{ HTTP_HEADER_UPGRADE_INSECURE_REQUESTS, CONST_LEN_STR("upgrade-insecure-requests") }
,{ HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, CONST_LEN_STR("access-control-allow-origin") }
,{ HTTP_HEADER_OTHER, 0, "" }
};

46
src/http_header.h

@ -5,39 +5,83 @@
#include "base_decls.h"
#include "buffer.h"
/* HTTP header enum for select HTTP field-names
* reference:
* https://www.iana.org/assignments/message-headers/message-headers.xml
* https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
*/
/* Note: must be kept in sync with http_header.c http_headers[] */
/* Note: when adding new items, must replace OTHER in existing code for item */
/* Note: current implementation has limit of 64 htags
* Use of htags is an optimization for quick existence checks in lighttpd.
* (In the future, these values may also be used to map to HPACK indices.)
* However, listing all possible headers here is highly discouraged,
* as extending the bitmap greater than 64-bits may make quick bitmasks
* check more expensive, and the cost for looking up unmarked headers
* (HTTP_HEADER_OTHER) is not substantially more. In the future, this
* list may be revisitied and reviewed, and less frequent headers removed
* or replaced.
*/
enum http_header_e {
HTTP_HEADER_OTHER = 0
,HTTP_HEADER_ACCEPT
,HTTP_HEADER_ACCEPT_ENCODING
,HTTP_HEADER_ACCEPT_LANGUAGE
,HTTP_HEADER_ACCEPT_RANGES
,HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN
,HTTP_HEADER_AGE
,HTTP_HEADER_ALLOW
,HTTP_HEADER_ALT_SVC
,HTTP_HEADER_ALT_USED
,HTTP_HEADER_AUTHORIZATION
,HTTP_HEADER_CACHE_CONTROL
,HTTP_HEADER_CONNECTION
,HTTP_HEADER_CONTENT_ENCODING
,HTTP_HEADER_CONTENT_LENGTH
,HTTP_HEADER_CONTENT_LOCATION
,HTTP_HEADER_CONTENT_RANGE
,HTTP_HEADER_CONTENT_SECURITY_POLICY
,HTTP_HEADER_CONTENT_TYPE
,HTTP_HEADER_COOKIE
,HTTP_HEADER_DATE
,HTTP_HEADER_DNT
,HTTP_HEADER_ETAG
,HTTP_HEADER_EXPECT
,HTTP_HEADER_EXPECT_CT
,HTTP_HEADER_EXPIRES
,HTTP_HEADER_FORWARDED
,HTTP_HEADER_HOST
,HTTP_HEADER_HTTP2_SETTINGS
,HTTP_HEADER_IF_MATCH
,HTTP_HEADER_IF_MODIFIED_SINCE
,HTTP_HEADER_IF_NONE_MATCH
,HTTP_HEADER_IF_RANGE
,HTTP_HEADER_IF_UNMODIFIED_SINCE
,HTTP_HEADER_LAST_MODIFIED
,HTTP_HEADER_LINK
,HTTP_HEADER_LOCATION
,HTTP_HEADER_ONION_LOCATION
,HTTP_HEADER_P3P
,HTTP_HEADER_PRAGMA
,HTTP_HEADER_RANGE
,HTTP_HEADER_REFERER
,HTTP_HEADER_REFERRER_POLICY
,HTTP_HEADER_SERVER
,HTTP_HEADER_SET_COOKIE
,HTTP_HEADER_STATUS
,HTTP_HEADER_STRICT_TRANSPORT_SECURITY
,HTTP_HEADER_TE
,HTTP_HEADER_TRANSFER_ENCODING
,HTTP_HEADER_UPGRADE
,HTTP_HEADER_UPGRADE_INSECURE_REQUESTS
,HTTP_HEADER_USER_AGENT
,HTTP_HEADER_VARY
,HTTP_HEADER_WWW_AUTHENTICATE
,HTTP_HEADER_X_CONTENT_TYPE_OPTIONS
,HTTP_HEADER_X_FORWARDED_FOR
,HTTP_HEADER_X_FORWARDED_PROTO
,HTTP_HEADER_HTTP2_SETTINGS
,HTTP_HEADER_X_FRAME_OPTIONS
,HTTP_HEADER_X_XSS_PROTECTION
};
__attribute_pure__

8
src/mod_auth.c

@ -727,7 +727,9 @@ static handler_t mod_auth_send_401_unauthorized_basic(request_st * const r, cons
buffer_append_string_buffer(tb, realm);
buffer_append_string_len(tb, CONST_STR_LEN("\", charset=\"UTF-8\""));
http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tb));
http_header_response_set(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"),
CONST_BUF_LEN(tb));
return HANDLER_FINISHED;
}
@ -1513,7 +1515,9 @@ static handler_t mod_auth_check_digest(request_st * const r, void *p_d, const st
static handler_t mod_auth_send_401_unauthorized_digest(request_st * const r, const struct http_auth_require_t * const require, int nonce_stale) {
buffer * const tb = r->tmp_buf;
mod_auth_digest_www_authenticate(tb, log_epoch_secs, require, nonce_stale);
http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tb));
http_header_response_set(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"),
CONST_BUF_LEN(tb));
r->http_status = 401;
r->handler_module = NULL;

8
src/mod_authn_gssapi.c

@ -253,7 +253,9 @@ static handler_t mod_authn_gssapi_send_401_unauthorized_negotiate (request_st *
{
r->http_status = 401;
r->handler_module = NULL;
http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"), CONST_STR_LEN("Negotiate"));
http_header_response_set(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"),
CONST_STR_LEN("Negotiate"));
return HANDLER_FINISHED;
}
@ -603,7 +605,9 @@ static handler_t mod_authn_gssapi_send_401_unauthorized_basic (request_st * cons
{
r->http_status = 401;
r->handler_module = NULL;
http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"), CONST_STR_LEN("Basic realm=\"Kerberos\""));
http_header_response_set(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"),
CONST_STR_LEN("Basic realm=\"Kerberos\""));
return HANDLER_FINISHED;
}

4
src/mod_expire.c

@ -318,7 +318,9 @@ REQUEST_FUNC(mod_expire_handler) {
/* HTTP/1.0 */
buffer_clear(tb);
buffer_append_strftime(tb, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(expires)));
http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Expires"), CONST_BUF_LEN(tb));
http_header_response_set(r, HTTP_HEADER_EXPIRES,
CONST_STR_LEN("Expires"),
CONST_BUF_LEN(tb));
/* HTTP/1.1 */
buffer_copy_string_len(tb, CONST_STR_LEN("max-age="));

4
src/mod_uploadprogress.c

@ -277,8 +277,8 @@ URIHANDLER_FUNC(mod_uploadprogress_uri_handler) {
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml"));
/* just an attempt the force the IE/proxies to NOT cache the request ... doesn't help :( */
http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Pragma"), CONST_STR_LEN("no-cache"));
http_header_response_set(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Expires"), CONST_STR_LEN("Thu, 19 Nov 1981 08:52:00 GMT"));
http_header_response_set(r, HTTP_HEADER_PRAGMA, CONST_STR_LEN("Pragma"), CONST_STR_LEN("no-cache"));
http_header_response_set(r, HTTP_HEADER_EXPIRES, CONST_STR_LEN("Expires"), CONST_STR_LEN("Thu, 19 Nov 1981 08:52:00 GMT"));
http_header_response_set(r, HTTP_HEADER_CACHE_CONTROL, CONST_STR_LEN("Cache-Control"), CONST_STR_LEN("no-store, no-cache, must-revalidate, post-check=0, pre-check=0"));
/* prepare XML */

14
src/mod_webdav.c

@ -577,11 +577,11 @@ URIHANDLER_FUNC(mod_webdav_uri_handler)
CONST_STR_LEN("DAV"));
if (pconf.is_readonly)
http_header_response_append(r, HTTP_HEADER_OTHER,
http_header_response_append(r, HTTP_HEADER_ALLOW,
CONST_STR_LEN("Allow"),
CONST_STR_LEN("PROPFIND"));
else
http_header_response_append(r, HTTP_HEADER_OTHER,
http_header_response_append(r, HTTP_HEADER_ALLOW,
CONST_STR_LEN("Allow"),
#ifdef USE_PROPPATCH
#ifdef USE_LOCKS
@ -2160,7 +2160,7 @@ static int
webdav_if_match_or_unmodified_since (request_st * const r, struct stat *st)
{
const buffer *im = (0 != r->conf.etag_flags)
? http_header_request_get(r, HTTP_HEADER_OTHER,
? http_header_request_get(r, HTTP_HEADER_IF_MATCH,
CONST_STR_LEN("If-Match"))
: NULL;
@ -2170,7 +2170,7 @@ webdav_if_match_or_unmodified_since (request_st * const r, struct stat *st)
: NULL;
const buffer *ius =
http_header_request_get(r, HTTP_HEADER_OTHER,
http_header_request_get(r, HTTP_HEADER_IF_UNMODIFIED_SINCE,
CONST_STR_LEN("If-Unmodified-Since"));
if (NULL == im && NULL == inm && NULL == ius) return 0;
@ -4303,7 +4303,7 @@ mod_webdav_put_0 (request_st * const r, const plugin_config * const pconf)
static handler_t
mod_webdav_put_prep (request_st * const r, const plugin_config * const pconf)
{
if (NULL != http_header_request_get(r, HTTP_HEADER_OTHER,
if (NULL != http_header_request_get(r, HTTP_HEADER_CONTENT_RANGE,
CONST_STR_LEN("Content-Range"))) {
if (pconf->opts & MOD_WEBDAV_UNSAFE_PARTIAL_PUT_COMPAT)
return HANDLER_GO_ON;
@ -4551,7 +4551,7 @@ mod_webdav_put (request_st * const r, const plugin_config * const pconf)
if (pconf->opts & MOD_WEBDAV_UNSAFE_PARTIAL_PUT_COMPAT) {
const buffer * const h =
http_header_request_get(r, HTTP_HEADER_OTHER,
http_header_request_get(r, HTTP_HEADER_CONTENT_RANGE,
CONST_STR_LEN("Content-Range"));
if (NULL != h)
return
@ -5057,7 +5057,7 @@ static handler_t
mod_webdav_proppatch (request_st * const r, const plugin_config * const pconf)
{
if (!pconf->sql) {
http_header_response_set(r, HTTP_HEADER_OTHER,
http_header_response_set(r, HTTP_HEADER_ALLOW,
CONST_STR_LEN("Allow"),
CONST_STR_LEN("GET, HEAD, PROPFIND, DELETE, "
"MKCOL, PUT, MOVE, COPY"));

4
src/request.h

@ -142,8 +142,8 @@ struct request_st {
request_config conf;
/* request */
uint32_t rqst_htags;/* bitfield of flagged headers present in request */
uint32_t rqst_header_len;
uint64_t rqst_htags;/* bitfield of flagged headers present in request */
array rqst_headers;
request_uri uri;
@ -165,8 +165,8 @@ struct request_st {
/* response */
off_t content_length;
uint32_t resp_htags; /*bitfield of flagged headers present in response*/
uint32_t resp_header_len;
uint64_t resp_htags; /*bitfield of flagged headers present in response*/
array resp_headers;
char resp_body_finished;
char resp_body_started;

13
src/response.c

@ -172,7 +172,8 @@ static handler_t http_response_physical_path_check(request_st * const r) {
/* file name to be read was too long. return 404 */
case ENOENT:
if (r->http_method == HTTP_METHOD_OPTIONS
&& NULL != http_header_response_get(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Allow"))) {
&& NULL != http_header_response_get(r, HTTP_HEADER_ALLOW,
CONST_STR_LEN("Allow"))) {
r->http_status = 200;
return HANDLER_FINISHED;
}
@ -412,7 +413,9 @@ http_response_prepare (request_st * const r)
r->uri.path.ptr[0] == '*' && r->uri.path.ptr[1] == '\0') {
/* option requests are handled directly without checking of the path */
http_header_response_append(r, HTTP_HEADER_OTHER, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
http_header_response_append(r, HTTP_HEADER_ALLOW,
CONST_STR_LEN("Allow"),
CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
r->http_status = 200;
r->resp_body_finished = 1;
@ -659,7 +662,7 @@ http_response_errdoc_init (request_st * const r)
buffer *www_auth = NULL;
if (401 == r->http_status) {
const buffer * const vb =
http_header_response_get(r, HTTP_HEADER_OTHER,
http_header_response_get(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"));
if (NULL != vb) www_auth = buffer_init_buffer(vb);
}
@ -670,7 +673,7 @@ http_response_errdoc_init (request_st * const r)
http_response_body_clear(r, 0);
if (NULL != www_auth) {
http_header_response_set(r, HTTP_HEADER_OTHER,
http_header_response_set(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"),
CONST_BUF_LEN(www_auth));
buffer_free(www_auth);
@ -791,7 +794,7 @@ http_response_write_prepare(request_st * const r)
&& !buffer_string_is_empty(&r->uri.path)
&& r->uri.path.ptr[0] != '*') {
http_response_body_clear(r, 0);
http_header_response_append(r, HTTP_HEADER_OTHER,
http_header_response_append(r, HTTP_HEADER_ALLOW,
CONST_STR_LEN("Allow"),
CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
r->http_status = 200;

Loading…
Cancel
Save