/* Flags used by HTTP parsers */
#define HTTP_PF_DIR_RES 0x00000001 /* direction: 0: request; 1: response */
+#define HTTP_PF_UPCASE_OK 0x00000002 /* upper case hdr names: 0: forbidden (h2/h3); 1: ok (h1) */
+#define HTTP_PF_PSEUDO_OK 0x00000004 /* pseudo headers: 0: forbidden (h1); 1: ok (h2/h3) */
/* HTTP parser error codes */
* field-name = token
*/
for (i = 0; i < list[idx].n.len; i++) {
- if ((uint8_t)(list[idx].n.ptr[i] - 'A') <= 'Z' - 'A' ||
- !HTTP_IS_TOKEN(list[idx].n.ptr[i])) {
+ if (!(flags & HTTP_PF_UPCASE_OK) &&
+ (uint8_t)(list[idx].n.ptr[i] - 'A') <= 'Z' - 'A') {
+ ret = HTTP_PRS_INV_HNAME;
+ goto fail;
+ }
+
+ if (!HTTP_IS_TOKEN(list[idx].n.ptr[i])) {
ret = HTTP_PRS_INV_HNAME;
goto fail;
}
/* All field names affecting decoding or routing are forbidden
* in trailers.
*/
- if (isteq(list[idx].n, ist("host")) ||
- isteq(list[idx].n, ist("content-length")) ||
- isteq(list[idx].n, ist("connection")) ||
- isteq(list[idx].n, ist("proxy-connection")) ||
- isteq(list[idx].n, ist("keep-alive")) ||
- isteq(list[idx].n, ist("upgrade")) ||
- isteq(list[idx].n, ist("te")) ||
- isteq(list[idx].n, ist("transfer-encoding"))) {
+ if (isteqi(list[idx].n, ist("host")) ||
+ isteqi(list[idx].n, ist("content-length")) ||
+ isteqi(list[idx].n, ist("connection")) ||
+ isteqi(list[idx].n, ist("proxy-connection")) ||
+ isteqi(list[idx].n, ist("keep-alive")) ||
+ isteqi(list[idx].n, ist("upgrade")) ||
+ isteqi(list[idx].n, ist("te")) ||
+ isteqi(list[idx].n, ist("transfer-encoding"))) {
ret = HTTP_PRS_FORB_TRL;
goto fail;
}