mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
This commit is contained in:
@@ -223,17 +223,8 @@ struct us_socket_context_t *us_create_socket_context(int ssl, struct us_loop_t *
|
||||
|
||||
struct us_socket_context_t *context = us_calloc(1, sizeof(struct us_socket_context_t) + context_ext_size);
|
||||
context->loop = loop;
|
||||
context->head_sockets = 0;
|
||||
context->head_listen_sockets = 0;
|
||||
context->iterator = 0;
|
||||
context->next = 0;
|
||||
context->is_low_prio = default_is_low_prio_handler;
|
||||
|
||||
/* Begin at 0 */
|
||||
context->timestamp = 0;
|
||||
context->long_timestamp = 0;
|
||||
context->global_tick = 0;
|
||||
|
||||
us_internal_loop_link(loop, context);
|
||||
|
||||
/* If we are called from within SSL code, SSL code will make further changes to us */
|
||||
@@ -253,17 +244,8 @@ struct us_socket_context_t *us_create_bun_socket_context(int ssl, struct us_loop
|
||||
|
||||
struct us_socket_context_t *context = us_calloc(1, sizeof(struct us_socket_context_t) + context_ext_size);
|
||||
context->loop = loop;
|
||||
context->head_sockets = 0;
|
||||
context->head_listen_sockets = 0;
|
||||
context->iterator = 0;
|
||||
context->next = 0;
|
||||
context->is_low_prio = default_is_low_prio_handler;
|
||||
|
||||
/* Begin at 0 */
|
||||
context->timestamp = 0;
|
||||
context->long_timestamp = 0;
|
||||
context->global_tick = 0;
|
||||
|
||||
us_internal_loop_link(loop, context);
|
||||
|
||||
/* If we are called from within SSL code, SSL code will make further changes to us */
|
||||
|
||||
@@ -262,15 +262,15 @@ namespace uWS
|
||||
hasMore(x, 'z');
|
||||
}
|
||||
|
||||
static inline void *consumeFieldName(char *p) {
|
||||
static inline void *consumeFieldName(unsigned char *p) {
|
||||
//for (; true; p += 8) {
|
||||
//uint64_t word;
|
||||
//memcpy(&word, p, sizeof(uint64_t));
|
||||
//if (notFieldNameWord(word)) {
|
||||
while (isFieldNameByte(*(unsigned char *)p)) {
|
||||
*(p++) |= 0x20;
|
||||
}
|
||||
return (void *)p;
|
||||
while (isFieldNameByte(*(unsigned char *)p)) {
|
||||
*(p++) |= p[0] <= 'Z' ? 32 : 0;
|
||||
}
|
||||
return (void *)p;
|
||||
//}
|
||||
//word |= 0x2020202020202020ull;
|
||||
//memcpy(p, &word, sizeof(uint64_t));
|
||||
@@ -386,7 +386,7 @@ namespace uWS
|
||||
{
|
||||
/* Lower case and consume the field name */
|
||||
preliminaryKey = postPaddedBuffer;
|
||||
postPaddedBuffer = (char *)consumeFieldName(postPaddedBuffer);
|
||||
postPaddedBuffer = (char *)consumeFieldName(reinterpret_cast<unsigned char*>(postPaddedBuffer));
|
||||
headers->key = std::string_view(preliminaryKey, (size_t)(postPaddedBuffer - preliminaryKey));
|
||||
|
||||
/* We should not accept whitespace between key and colon, so colon must foloow immediately */
|
||||
|
||||
@@ -31,6 +31,15 @@ namespace WebCore {
|
||||
namespace RFC7230 {
|
||||
|
||||
bool isTokenCharacter(UChar c)
|
||||
{
|
||||
return c < 0x80 && isTokenCharacter(static_cast<LChar>(c));
|
||||
}
|
||||
bool isDelimiter(UChar c)
|
||||
{
|
||||
return c < 0x80 && isDelimiter(static_cast<LChar>(c));
|
||||
}
|
||||
|
||||
bool isTokenCharacter(LChar c)
|
||||
{
|
||||
return isASCIIAlpha(c) || isASCIIDigit(c)
|
||||
|| c == '!' || c == '#' || c == '$'
|
||||
@@ -40,7 +49,7 @@ bool isTokenCharacter(UChar c)
|
||||
|| c == '`' || c == '|' || c == '~';
|
||||
}
|
||||
|
||||
bool isDelimiter(UChar c)
|
||||
bool isDelimiter(LChar c)
|
||||
{
|
||||
return c == '(' || c == ')' || c == ','
|
||||
|| c == '/' || c == ':' || c == ';'
|
||||
|
||||
@@ -43,7 +43,8 @@ private:
|
||||
HTTPHeaderField(String&& name, String&& value)
|
||||
: m_name(WTFMove(name))
|
||||
, m_value(WTFMove(value))
|
||||
{ }
|
||||
{
|
||||
}
|
||||
String m_name;
|
||||
String m_value;
|
||||
};
|
||||
@@ -68,12 +69,14 @@ std::optional<HTTPHeaderField> HTTPHeaderField::decode(Decoder& decoder)
|
||||
if (!value)
|
||||
return std::nullopt;
|
||||
|
||||
return {{ WTFMove(*name), WTFMove(*value) }};
|
||||
return { { WTFMove(*name), WTFMove(*value) } };
|
||||
}
|
||||
|
||||
namespace RFC7230 {
|
||||
bool isTokenCharacter(UChar);
|
||||
bool isWhitespace(UChar);
|
||||
bool isTokenCharacter(LChar);
|
||||
bool isWhitespace(LChar);
|
||||
bool isCommentText(UChar);
|
||||
bool isQuotedPairSecondOctet(UChar);
|
||||
bool isDelimiter(UChar);
|
||||
|
||||
@@ -197,6 +197,17 @@ bool isValidHTTPToken(StringView value)
|
||||
{
|
||||
if (value.isEmpty())
|
||||
return false;
|
||||
|
||||
if (value.is8Bit()) {
|
||||
const LChar* characters = value.characters8();
|
||||
const LChar* end = characters + value.length();
|
||||
while (characters < end) {
|
||||
if (!RFC7230::isTokenCharacter(*characters++))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (UChar c : value.codeUnits()) {
|
||||
if (!RFC7230::isTokenCharacter(c))
|
||||
return false;
|
||||
|
||||
38
test/js/bun/http/bun-serve-headers.test.ts
Normal file
38
test/js/bun/http/bun-serve-headers.test.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { test, expect } from "bun:test";
|
||||
|
||||
// https://github.com/oven-sh/bun/issues/9180
|
||||
test("weird headers", async () => {
|
||||
const server = Bun.serve({
|
||||
port: 0,
|
||||
development: false,
|
||||
fetch(req) {
|
||||
const headers = new Headers();
|
||||
req.headers.forEach((value, key) => {
|
||||
headers.append(key, value);
|
||||
});
|
||||
|
||||
return new Response("OK", {
|
||||
headers,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
for (let i = 0; i < 255; i++) {
|
||||
const headers = new Headers();
|
||||
const name = "X-" + String.fromCharCode(i);
|
||||
try {
|
||||
headers.set(name, "1");
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
|
||||
const res = await fetch(server.url, {
|
||||
headers,
|
||||
});
|
||||
expect(res.headers.get(name)).toBe("1");
|
||||
}
|
||||
} finally {
|
||||
server.stop(true);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user