I compiled and started test/main.c first, then ran test/run.
All tests before Chunked Request close: (expect empty) are OK, but the test server crashes when running this test.
Output from test/run:
Small Response Body:
Hello, World!
Empty Response:
Echo Body:
Echo test
Get Header:
localhost:8080
Request Body larger than max in mem size:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 48.0M 100 24.0M 100 24.0M 31.5M 31.5M --:--:-- --:--:-- --:--:-- 63.0M
Chunked Response:
Hello, World!Hello, World!Hello, World!
Chunked Response keep-alive:
Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!
Chunked Response close:
Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!
Chunked Request keep-alive: (expect empty)
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 512k 100 256k 100 256k 12.5M 12.5M --:--:-- --:--:-- --:--:-- 26.3M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 512k 100 256k 100 256k 21.9M 21.9M --:--:-- --:--:-- --:--:-- 45.4M
Chunked Request close: (expect empty)
(The test server crashed here)
I try to figure it out with gdb. Here is what i got:
☁ test [master] ⚡ egdb ./test
GNU gdb (GDB) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-unknown-openbsd7.1".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...
(gdb) r
Starting program: /home/niko/src/httpserver.h/test/test
(Reaching test "chunked Request close: (expect empty)")
Program received signal SIGABRT, Aborted.
thrkill () at /tmp/-:3
3 /tmp/-: No such file or directory.
(gdb) bt
#0 thrkill () at /tmp/-:3
#1 0x000000a6d65096ae in _libc_abort () at /usr/src/lib/libc/stdlib/abort.c:51
#2 0x000000a6d6511aaf in memcpy (dst0=<optimized out>, src0=<optimized out>, length=<optimized out>) at /usr/src/lib/libc/string/memcpy.c:74
#3 0x000000a401d319ce in hs_stream_shift (stream=0xa67da65318) at ./../httpserver.h:824
#4 0x000000a401d32553 in http_parse (parser=0xa67da65348, stream=0xa67da65318) at ./../httpserver.h:983
#5 0x000000a401d331c9 in hs_read_and_process_request (request=0xa67da65300) at ./../httpserver.h:1121
#6 0x000000a401d3341a in http_session (request=0xa67da65300) at ./../httpserver.h:1164
#7 0x000000a401d33608 in hs_session_io_cb (ev=0x7f7ffffd1cd0) at ./../httpserver.h:1578
#8 0x000000a401d34f03 in http_server_listen_addr (serv=0xa67da96d00, ipaddr=0x0) at ./../httpserver.h:1604
#9 0x000000a401d34f43 in http_server_listen (serv=0xa67da96d00) at ./../httpserver.h:1611
#10 0x000000a401d356bb in main () at main.c:119
(gdb) frame #2
Invalid character '#' in expression.
(gdb) frame 2
#2 0x00000b4cfcc73aaf in memcpy (dst0=<optimized out>, src0=<optimized out>, length=<optimized out>) at /usr/src/lib/libc/string/memcpy.c:74
74 /usr/src/lib/libc/string/memcpy.c: No such file or directory.
(gdb) frame 3
#3 0x00000b4af9ca99ce in hs_stream_shift (stream=0xb4d4ef4eb18) at ./../httpserver.h:824
824 memcpy(dst, src, bytes);
(gdb) list
819 if (stream->token.index == stream->anchor) return;
820 if (stream->token.len > 0) {
821 char* dst = stream->buf + stream->anchor;
822 char const* src = stream->buf + stream->token.index;
823 int bytes = stream->length - stream->token.index;
824 memcpy(dst, src, bytes);
825 }
826 stream->token.index = stream->anchor;
827 stream->index = stream->token.len + stream->anchor;
828 stream->length = stream->anchor + stream->token.len;
(gdb) print *dst
$1 = 102 'f'
(gdb) print *src
$2 = -32 '\340'
(gdb) print bytes
$3 = 32710
(gdb) print stream->length
$4 = 32883
(gdb) print stream->token.len
$5 = 32710
(gdb) frame 4
#4 0x00000b4af9caa553 in http_parse (parser=0xb4d4ef4eb48, stream=0xb4d4ef4eb18) at ./../httpserver.h:983
983 if (parser->state == CB) hs_stream_shift(stream);
(gdb) list
978 parser->state = to;
979 http_token_t emitted = hs_transition_action(parser, stream, c, from, to);
980 hs_stream_consume(stream);
981 if (emitted.type != HS_TOK_NONE) return emitted;
982 }
983 if (parser->state == CB) hs_stream_shift(stream);
984 token = hs_meta_emit(parser);
985 http_token_t current = hs_stream_current_token(stream);
986 if (
987 current.type != HS_TOK_CHUNK_BODY &&
(gdb) print *stream
$6 = {
buf = 0xb4d992cb000 "POST /chunked-req HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: curl/7.84.0\r\nAccept: */*\r\nTransfer-Encoding: chunked\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nfff4\r\n\340\257\240\312\375\317\343\364\253\264<\363Fj}p\252F\207\377\275\n\033$\236\021M"..., total_bytes = 32883, capacity = 65536, length = 32883, index = 32883, anchor = 167, token = {index = 173, len = 32710, type = 6}, flags = 0 '\000'}
(gdb) frame 5
#5 0x00000b4af9cab1c9 in hs_read_and_process_request (request=0xb4d4ef4eb00) at ./../httpserver.h:1121
1121 token = http_parse(&request->parser, &request->stream);
(gdb) frame 6
#6 0x00000b4af9cab41a in http_session (request=0xb4d4ef4eb00) at ./../httpserver.h:1164
1164 hs_read_and_process_request(request);
(gdb) print *request
$7 = {handler = 0xb4af9cab5a0 <hs_session_io_cb>, chunk_cb = 0xb4af9cad140 <chunk_req_cb>, data = 0xb4d4ef56bc0, stream = {
buf = 0xb4d992cb000 "POST /chunked-req HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: curl/7.84.0\r\nAccept: */*\r\nTransfer-Encoding: chunked\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nfff4\r\n\340\257\240\312\375\317\343\364\253\264<\363Fj}p\252F\207\377\275\n\033$\236\021M"..., total_bytes = 32883, capacity = 65536, length = 32883, index = 32883, anchor = 167, token = {index = 173, len = 32710, type = 6}, flags = 0 '\000'}, parser = {
content_length = 65524, body_consumed = 32710, match_index = 0, header_count = 5, state = 17 '\021', meta = 11 '\v'}, state = 1, socket = 7, timeout = 20, server = 0xb4d4ef5d500, tokens = {buf = 0xb4d4ef34c00, capacity = 32,
size = 14}, flags = 9 '\t'}
(gdb)
OS: OpenBSD 7.2 snapshot amd64 Compiler: GCC 11.2.0
I compiled and started
test/main.c
first, then rantest/run
. All tests beforeChunked Request close: (expect empty)
are OK, but the test server crashes when running this test.Output from
test/run
:I try to figure it out with gdb. Here is what i got: