summaryrefslogtreecommitdiffstats
path: root/llhttp/test/fixtures
diff options
context:
space:
mode:
Diffstat (limited to 'llhttp/test/fixtures')
-rw-r--r--llhttp/test/fixtures/extra.c457
-rw-r--r--llhttp/test/fixtures/index.ts116
2 files changed, 573 insertions, 0 deletions
diff --git a/llhttp/test/fixtures/extra.c b/llhttp/test/fixtures/extra.c
new file mode 100644
index 0000000..dadf8dc
--- /dev/null
+++ b/llhttp/test/fixtures/extra.c
@@ -0,0 +1,457 @@
+#include <stdlib.h>
+
+#include "fixture.h"
+
+int llhttp__on_url(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("url", p, endp);
+}
+
+
+int llhttp__on_url_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "url complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_URL_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_url_schema(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("url.schema", p, endp);
+}
+
+
+int llhttp__on_url_host(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("url.host", p, endp);
+}
+
+
+int llhttp__on_url_path(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("url.path", p, endp);
+}
+
+
+int llhttp__on_url_query(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("url.query", p, endp);
+}
+
+
+int llhttp__on_url_fragment(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("url.fragment", p, endp);
+}
+
+
+#ifdef LLHTTP__TEST_HTTP
+
+void llhttp__test_init_request(llparse_t* s) {
+ s->type = HTTP_REQUEST;
+}
+
+
+void llhttp__test_init_response(llparse_t* s) {
+ s->type = HTTP_RESPONSE;
+}
+
+
+void llhttp__test_init_request_lenient_all(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |=
+ LENIENT_HEADERS | LENIENT_CHUNKED_LENGTH | LENIENT_KEEP_ALIVE |
+ LENIENT_TRANSFER_ENCODING | LENIENT_VERSION | LENIENT_DATA_AFTER_CLOSE |
+ LENIENT_OPTIONAL_LF_AFTER_CR | LENIENT_OPTIONAL_CR_BEFORE_LF |
+ LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
+}
+
+
+void llhttp__test_init_response_lenient_all(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |=
+ LENIENT_HEADERS | LENIENT_CHUNKED_LENGTH | LENIENT_KEEP_ALIVE |
+ LENIENT_TRANSFER_ENCODING | LENIENT_VERSION | LENIENT_DATA_AFTER_CLOSE |
+ LENIENT_OPTIONAL_LF_AFTER_CR | LENIENT_OPTIONAL_CR_BEFORE_LF |
+ LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
+}
+
+
+void llhttp__test_init_request_lenient_headers(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_HEADERS;
+}
+
+
+void llhttp__test_init_request_lenient_chunked_length(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_CHUNKED_LENGTH;
+}
+
+
+void llhttp__test_init_request_lenient_keep_alive(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_KEEP_ALIVE;
+}
+
+void llhttp__test_init_request_lenient_transfer_encoding(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_TRANSFER_ENCODING;
+}
+
+
+void llhttp__test_init_request_lenient_version(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_VERSION;
+}
+
+
+void llhttp__test_init_response_lenient_keep_alive(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |= LENIENT_KEEP_ALIVE;
+}
+
+void llhttp__test_init_response_lenient_version(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |= LENIENT_VERSION;
+}
+
+
+void llhttp__test_init_response_lenient_headers(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |= LENIENT_HEADERS;
+}
+
+void llhttp__test_init_request_lenient_data_after_close(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_DATA_AFTER_CLOSE;
+}
+
+void llhttp__test_init_response_lenient_data_after_close(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |= LENIENT_DATA_AFTER_CLOSE;
+}
+
+void llhttp__test_init_request_lenient_optional_lf_after_cr(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_OPTIONAL_LF_AFTER_CR;
+}
+
+void llhttp__test_init_response_lenient_optional_lf_after_cr(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |= LENIENT_OPTIONAL_LF_AFTER_CR;
+}
+
+void llhttp__test_init_request_lenient_optional_cr_before_lf(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_OPTIONAL_CR_BEFORE_LF;
+}
+
+void llhttp__test_init_response_lenient_optional_cr_before_lf(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |= LENIENT_OPTIONAL_CR_BEFORE_LF;
+}
+
+void llhttp__test_init_request_lenient_optional_crlf_after_chunk(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
+}
+
+void llhttp__test_init_response_lenient_optional_crlf_after_chunk(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |= LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
+}
+
+void llhttp__test_init_request_lenient_spaces_after_chunk_size(llparse_t* s) {
+ llhttp__test_init_request(s);
+ s->lenient_flags |= LENIENT_SPACES_AFTER_CHUNK_SIZE;
+}
+
+void llhttp__test_init_response_lenient_spaces_after_chunk_size(llparse_t* s) {
+ llhttp__test_init_response(s);
+ s->lenient_flags |= LENIENT_SPACES_AFTER_CHUNK_SIZE;
+}
+
+
+void llhttp__test_finish(llparse_t* s) {
+ llparse__print(NULL, NULL, "finish=%d", s->finish);
+}
+
+
+int llhttp__on_message_begin(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "message begin");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_MESSAGE_BEGIN
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_message_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "message complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_MESSAGE_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_status(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("status", p, endp);
+}
+
+
+int llhttp__on_status_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "status complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_STATUS_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_method(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench || s->type != HTTP_REQUEST)
+ return 0;
+
+ return llparse__print_span("method", p, endp);
+}
+
+
+int llhttp__on_method_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "method complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_METHOD_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_version(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("version", p, endp);
+}
+
+
+int llhttp__on_version_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "version complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_VERSION_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+int llhttp__on_header_field(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("header_field", p, endp);
+}
+
+
+int llhttp__on_header_field_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "header_field complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_HEADER_FIELD_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_header_value(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("header_value", p, endp);
+}
+
+
+int llhttp__on_header_value_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "header_value complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_HEADER_VALUE_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_headers_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ if (s->type == HTTP_REQUEST) {
+ llparse__print(p, endp,
+ "headers complete method=%d v=%d/%d flags=%x content_length=%llu",
+ s->method, s->http_major, s->http_minor, s->flags, s->content_length);
+ } else if (s->type == HTTP_RESPONSE) {
+ llparse__print(p, endp,
+ "headers complete status=%d v=%d/%d flags=%x content_length=%llu",
+ s->status_code, s->http_major, s->http_minor, s->flags,
+ s->content_length);
+ } else {
+ llparse__print(p, endp, "invalid headers complete");
+ }
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_HEADERS_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #elif defined(LLHTTP__TEST_SKIP_BODY)
+ llparse__print(p, endp, "skip body");
+ return 1;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_body(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("body", p, endp);
+}
+
+
+int llhttp__on_chunk_header(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "chunk header len=%d", (int) s->content_length);
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_CHUNK_HEADER
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_chunk_extension_name(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("chunk_extension_name", p, endp);
+}
+
+
+int llhttp__on_chunk_extension_name_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "chunk_extension_name complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_CHUNK_EXTENSION_NAME
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_chunk_extension_value(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ return llparse__print_span("chunk_extension_value", p, endp);
+}
+
+
+int llhttp__on_chunk_extension_value_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "chunk_extension_value complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_CHUNK_EXTENSION_VALUE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+
+int llhttp__on_chunk_complete(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "chunk complete");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_CHUNK_COMPLETE
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+int llhttp__on_reset(llparse_t* s, const char* p, const char* endp) {
+ if (llparse__in_bench)
+ return 0;
+
+ llparse__print(p, endp, "reset");
+
+ #ifdef LLHTTP__TEST_PAUSE_ON_RESET
+ return LLPARSE__ERROR_PAUSE;
+ #else
+ return 0;
+ #endif
+}
+
+#endif /* LLHTTP__TEST_HTTP */
diff --git a/llhttp/test/fixtures/index.ts b/llhttp/test/fixtures/index.ts
new file mode 100644
index 0000000..1571f9d
--- /dev/null
+++ b/llhttp/test/fixtures/index.ts
@@ -0,0 +1,116 @@
+import * as fs from 'fs';
+import { ICompilerResult, LLParse } from 'llparse';
+import { Dot } from 'llparse-dot';
+import {
+ Fixture, FixtureResult, IFixtureBuildOptions,
+} from 'llparse-test-fixture';
+import * as path from 'path';
+
+import * as llhttp from '../../src/llhttp';
+
+export { FixtureResult };
+
+export type TestType = 'request' | 'response' | 'request-finish' | 'response-finish' |
+ 'request-lenient-all' | 'response-lenient-all' |
+ 'request-lenient-headers' | 'response-lenient-headers' |
+ 'request-lenient-chunked-length' | 'request-lenient-transfer-encoding' |
+ 'request-lenient-keep-alive' | 'response-lenient-keep-alive' |
+ 'request-lenient-version' | 'response-lenient-version' |
+ 'request-lenient-data-after-close' | 'response-lenient-data-after-close' |
+ 'request-lenient-optional-lf-after-cr' | 'response-lenient-optional-lf-after-cr' |
+ 'request-lenient-optional-cr-before-lf' | 'response-lenient-optional-cr-before-lf' |
+ 'request-lenient-optional-crlf-after-chunk' | 'response-lenient-optional-crlf-after-chunk' |
+ 'request-lenient-spaces-after-chunk-size' | 'response-lenient-spaces-after-chunk-size' |
+ 'none' | 'url';
+
+export const allowedTypes: TestType[] = [
+ 'request',
+ 'response',
+ 'request-finish',
+ 'response-finish',
+ 'request-lenient-all',
+ 'response-lenient-all',
+ 'request-lenient-headers',
+ 'response-lenient-headers',
+ 'request-lenient-keep-alive',
+ 'response-lenient-keep-alive',
+ 'request-lenient-chunked-length',
+ 'request-lenient-transfer-encoding',
+ 'request-lenient-version',
+ 'response-lenient-version',
+ 'request-lenient-data-after-close',
+ 'response-lenient-data-after-close',
+ 'request-lenient-optional-lf-after-cr',
+ 'response-lenient-optional-lf-after-cr',
+ 'request-lenient-optional-cr-before-lf',
+ 'response-lenient-optional-cr-before-lf',
+ 'request-lenient-optional-crlf-after-chunk',
+ 'response-lenient-optional-crlf-after-chunk',
+ 'request-lenient-spaces-after-chunk-size',
+ 'response-lenient-spaces-after-chunk-size',
+];
+
+const BUILD_DIR = path.join(__dirname, '..', 'tmp');
+const CHEADERS_FILE = path.join(BUILD_DIR, 'cheaders.h');
+
+const cheaders = new llhttp.CHeaders().build();
+try {
+ fs.mkdirSync(BUILD_DIR);
+} catch (e) {
+ // no-op
+}
+fs.writeFileSync(CHEADERS_FILE, cheaders);
+
+const fixtures = new Fixture({
+ buildDir: path.join(__dirname, '..', 'tmp'),
+ extra: [
+ '-msse4.2',
+ '-DLLHTTP__TEST',
+ '-DLLPARSE__ERROR_PAUSE=' + llhttp.constants.ERROR.PAUSED,
+ '-include', CHEADERS_FILE,
+ path.join(__dirname, 'extra.c'),
+ ],
+ maxParallel: process.env.LLPARSE_DEBUG ? 1 : undefined,
+});
+
+const cache: Map<any, ICompilerResult> = new Map();
+
+export async function build(
+ llparse: LLParse, node: any, outFile: string,
+ options: IFixtureBuildOptions = {},
+ ty: TestType = 'none'): Promise<FixtureResult> {
+ const dot = new Dot();
+ fs.writeFileSync(path.join(BUILD_DIR, outFile + '.dot'),
+ dot.build(node));
+
+ let artifacts: ICompilerResult;
+ if (cache.has(node)) {
+ artifacts = cache.get(node)!;
+ } else {
+ artifacts = llparse.build(node, {
+ c: { header: outFile },
+ debug: process.env.LLPARSE_DEBUG ? 'llparse__debug' : undefined,
+ });
+ cache.set(node, artifacts);
+ }
+
+ const extra = options.extra === undefined ? [] : options.extra.slice();
+
+ if (allowedTypes.includes(ty)) {
+ extra.push(
+ `-DLLPARSE__TEST_INIT=llhttp__test_init_${ty.replace(/-/g, '_')}`);
+ }
+
+ if (ty === 'request-finish' || ty === 'response-finish') {
+ if (ty === 'request-finish') {
+ extra.push('-DLLPARSE__TEST_INIT=llhttp__test_init_request');
+ } else {
+ extra.push('-DLLPARSE__TEST_INIT=llhttp__test_init_response');
+ }
+ extra.push('-DLLPARSE__TEST_FINISH=llhttp__test_finish');
+ }
+
+ return await fixtures.build(artifacts, outFile, Object.assign(options, {
+ extra,
+ }));
+}