Skip to content
This repository was archived by the owner on Feb 16, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions bin/varnishd/cache/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ struct ws {
*
*/

enum well_known_method {
#define WKM(wk, bit) WKM_##wk = 1U << bit,
#include "tbl/well_known_methods.h"
#undef WKM
};

struct http {
unsigned magic;
#define HTTP_MAGIC 0x6428b5c9
Expand All @@ -173,6 +179,7 @@ struct http {
struct ws *ws;
uint16_t status;
uint8_t protover;
enum well_known_method wkm;
};

/*--------------------------------------------------------------------*/
Expand Down Expand Up @@ -670,6 +677,7 @@ int HTTP_IterHdrPack(struct worker *, struct objcore *, const char **);
const char *HTTP_GetHdrPack(struct worker *, struct objcore *, hdr_t);
stream_close_t http_DoConnection(struct http *hp, stream_close_t sc_close);
int http_IsFiltered(const struct http *hp, unsigned u, unsigned how);
void http_SetWellKnownMethod(struct http *hp);

#define HTTPH_R_PASS (1 << 0) /* Request (c->b) in pass mode */
#define HTTPH_R_FETCH (1 << 1) /* Request (c->b) for fetch */
Expand All @@ -694,9 +702,8 @@ extern hdr_t H__Reason;

// rfc7230,l,1144,1144
// rfc7231,l,1156,1158
#define http_method_eq(str, tok) (!vstrcmp(str, #tok))
// l = vstrlen(str)
#define http_method_eq_l(str, l, tok) (l == vstrlen(#tok) && ! vstrcmp(str, #tok))
#define http_method_eq(check, wkm) ((check & wkm) == wkm)
#define http_method_among(check, wkms) ((check & (wkms)) != 0)

// rfc7230,l,1222,1222
// rfc7230,l,2848,2848
Expand Down
11 changes: 2 additions & 9 deletions bin/varnishd/cache/cache_fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,6 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
vtim_real now;
unsigned handling, skip_vbr = 0;
struct objcore *oc;
const char *met;
size_t met_l;

CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
Expand All @@ -407,13 +405,8 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
http_PrintfHeader(bo->bereq, "X-Varnish: %ju", VXID(bo->vsl->wid));

if (bo->bereq_body == NULL && bo->req == NULL) {
met = http_GetMethod(bo->bereq);
met_l = vstrlen(met);
if (http_method_eq_l(met, met_l, GET) ||
http_method_eq_l(met, met_l, HEAD) ||
http_method_eq_l(met, met_l, DELETE) ||
http_method_eq_l(met, met_l, OPTIONS) ||
http_method_eq_l(met, met_l, TRACE))
if (http_method_among(bo->bereq->wkm, (WKM_GET | WKM_HEAD | WKM_DELETE |
WKM_OPTIONS | WKM_TRACE)))
http_Unset(bo->bereq, H_Content_Length);
else
http_ForceHeader(bo->bereq, H_Content_Length, "0");
Expand Down
28 changes: 28 additions & 0 deletions bin/varnishd/cache/cache_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ HTTP_Setup(struct http *hp, struct ws *ws, struct vsl_log *vsl,
hp->logtag = whence;
hp->ws = ws;
hp->vsl = vsl;
hp->wkm = WKM_UNKNOWN;
}

/*--------------------------------------------------------------------
Expand Down Expand Up @@ -397,6 +398,7 @@ HTTP_Dup(struct http *to, const struct http * fm)
to->logtag = fm->logtag;
to->status = fm->status;
to->protover = fm->protover;
to->wkm = fm->wkm;
}


Expand Down Expand Up @@ -452,6 +454,8 @@ http_SetH(struct http *to, unsigned n, const char *header)
http_VSLH(to, n);
if (n == HTTP_HDR_PROTO)
http_Proto(to);
if (n == HTTP_HDR_METHOD)
http_SetWellKnownMethod(to);
}

/*--------------------------------------------------------------------*/
Expand Down Expand Up @@ -1456,6 +1460,7 @@ http_FilterReq(struct http *to, const struct http *fm, unsigned how)
CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);

http_linkh(to, fm, HTTP_HDR_METHOD);
http_SetWellKnownMethod(to);
http_linkh(to, fm, HTTP_HDR_URL);
http_linkh(to, fm, HTTP_HDR_PROTO);
to->protover = fm->protover;
Expand Down Expand Up @@ -1625,3 +1630,26 @@ http_Unset(struct http *hp, hdr_t hdr)
}
hp->nhd = v;
}

void
http_SetWellKnownMethod(struct http *hp)
{
size_t l;
const char *method;

CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);

method = http_GetMethod(hp);
AN(method);
hp->wkm = WKM_UNKNOWN;
#define WKM(wk, bit) \
do { \
l = vstrlen(method); \
if (l == vstrlen(#wk) && !vstrcmp(#wk, method)) { \
hp->wkm = WKM_##wk; \
return; \
} \
} while (0);
#include "tbl/well_known_methods.h"
#undef WKM
}
2 changes: 1 addition & 1 deletion bin/varnishd/cache/cache_req_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ cnt_transmit(struct worker *wrk, struct req *req)
clval = http_GetContentLength(req->resp);
/* RFC 7230, 3.3.3 */
status = http_GetStatus(req->resp);
head = http_method_eq(req->http0->hd[HTTP_HDR_METHOD].b, HEAD);
head = http_method_eq(req->http0->wkm, WKM_HEAD);

if (req->boc != NULL || (req->objcore->flags & (OC_F_FAILED)))
req->resp_len = clval;
Expand Down
1 change: 1 addition & 0 deletions bin/varnishd/http1/cache_http1.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ stream_close_t V1L_Flush(struct v1l *v1l);
stream_close_t V1L_Close(struct v1l **v1lp, uint64_t *cnt);
size_t V1L_Write(struct v1l *v1l, const void *ptr, ssize_t len);
extern const struct vdp * const VDP_v1l;
void http_SetWellKnownMethod(struct http *hp);
2 changes: 1 addition & 1 deletion bin/varnishd/http1/cache_http1_fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ V1F_FetchRespHdr(struct busyobj *bo)
* Figure out how the fetch is supposed to happen, before the
* headers are adulterated by VCL
*/
if (http_method_eq(http_GetMethod(bo->bereq), HEAD)) {
if (http_method_eq(bo->bereq->wkm, WKM_HEAD)) {
/*
* A HEAD request can never have a body in the reply,
* no matter what the headers might say.
Expand Down
7 changes: 3 additions & 4 deletions bin/varnishd/http1/cache_http1_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,6 @@ HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)
uint16_t retval;
const char *p;
const char *b = NULL, *e;
size_t l;

CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
Expand Down Expand Up @@ -389,18 +388,18 @@ HTTP1_DissectRequest(struct http_conn *htc, struct http *hp)

p = http_GetMethod(hp);
AN(p);
l = vstrlen(p);
http_SetWellKnownMethod(hp);

if (htc->body_status == BS_EOF) {
assert(hp->protover == 10);
/* RFC1945 8.3 p32 and D.1.1 p58 */
if (http_method_eq_l(p, l, POST) || http_method_eq_l(p, l, PUT))
if (http_method_among(hp->wkm, (WKM_POST | WKM_PUT)))
return (400);
htc->body_status = BS_NONE;
}

/* HEAD with a body is a hard error */
if (htc->body_status != BS_NONE && http_method_eq_l(p, l, HEAD))
if (htc->body_status != BS_NONE && http_method_eq(hp->wkm, WKM_HEAD))
return (400);

return (retval);
Expand Down
1 change: 1 addition & 0 deletions include/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ nobase_pkginclude_HEADERS = \
tbl/vsl_tags.h \
tbl/vsl_tags_http.h \
tbl/waiters.h \
tbl/well_known_methods.h \
vapi/vsc.h \
vapi/vsig.h \
vapi/vsl.h \
Expand Down
40 changes: 40 additions & 0 deletions include/tbl/well_known_methods.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*-
* Copyright 2026 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Author: Thibaut Artis <artous@uplex.de>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Define well-known HTTP methods
*/

WKM(GET, 0)
WKM(HEAD, 1)
WKM(POST, 2)
WKM(PUT, 3)
WKM(DELETE, 4)
WKM(OPTIONS, 5)
WKM(TRACE, 6)
WKM(PATCH, 7)
WKM(CONNECT, 8)
WKM(UNKNOWN, 31)
Loading