[tests] test_request unit tests
unit tests for request processing collect existing request processing tests from Perl tests/*.t (test_request.c runs *much* more quickly than Perl tests/*.t)
This commit is contained in:
parent
e8c1efd5df
commit
1b62dc325c
|
@ -50,4 +50,5 @@ stamp-h1
|
|||
test_base64
|
||||
test_buffer
|
||||
test_configfile
|
||||
test_request
|
||||
versionstamp.h
|
||||
|
|
|
@ -671,6 +671,18 @@ add_executable(test_configfile
|
|||
)
|
||||
add_test(NAME test_configfile COMMAND test_configfile)
|
||||
|
||||
add_executable(test_request
|
||||
test_request.c
|
||||
request.c
|
||||
buffer.c
|
||||
array.c
|
||||
data_string.c
|
||||
keyvalue.c
|
||||
log.c
|
||||
sock_addr.c
|
||||
)
|
||||
add_test(NAME test_request COMMAND test_request)
|
||||
|
||||
if(HAVE_PCRE_H)
|
||||
target_link_libraries(lighttpd ${PCRE_LDFLAGS})
|
||||
add_target_properties(lighttpd COMPILE_FLAGS ${PCRE_CFLAGS})
|
||||
|
@ -682,6 +694,8 @@ if(HAVE_PCRE_H)
|
|||
add_target_properties(mod_redirect COMPILE_FLAGS ${PCRE_CFLAGS})
|
||||
target_link_libraries(test_configfile ${PCRE_LDFLAGS})
|
||||
add_target_properties(test_configfile COMPILE_FLAGS ${PCRE_CFLAGS})
|
||||
target_link_libraries(test_request ${PCRE_LDFLAGS})
|
||||
add_target_properties(test_request COMPILE_FLAGS ${PCRE_CFLAGS})
|
||||
endif()
|
||||
|
||||
if(WITH_PCRE AND (WITH_MEMCACHED OR WITH_GDBM))
|
||||
|
@ -864,6 +878,8 @@ if(WITH_LIBUNWIND)
|
|||
add_target_properties(test_base64 COMPILE_FLAGS ${LIBUNWIND_CFLAGS})
|
||||
target_link_libraries(test_configfile ${PCRE_LDFLAGS} ${LIBUNWIND_LDFLAGS})
|
||||
add_target_properties(test_configfile COMPILE_FLAGS ${PCRE_CFLAGS} ${LIBUNWIND_CFLAGS})
|
||||
target_link_libraries(test_request ${PCRE_LDFLAGS} ${LIBUNWIND_LDFLAGS})
|
||||
add_target_properties(test_request COMPILE_FLAGS ${PCRE_CFLAGS} ${LIBUNWIND_CFLAGS})
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
AM_CFLAGS = $(FAM_CFLAGS) $(LIBUNWIND_CFLAGS)
|
||||
|
||||
noinst_PROGRAMS=proc_open test_buffer test_base64 test_configfile
|
||||
noinst_PROGRAMS=proc_open test_buffer test_base64 test_configfile test_request
|
||||
sbin_PROGRAMS=lighttpd lighttpd-angel
|
||||
LEMON=$(top_builddir)/src/lemon$(BUILD_EXEEXT)
|
||||
|
||||
TESTS=\
|
||||
test_buffer$(EXEEXT) \
|
||||
test_base64$(EXEEXT) \
|
||||
test_configfile$(EXEEXT)
|
||||
test_configfile$(EXEEXT) \
|
||||
test_request$(EXEEXT)
|
||||
|
||||
lemon$(BUILD_EXEEXT): lemon.c
|
||||
$(AM_V_CC)$(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -o $@ $(srcdir)/lemon.c
|
||||
|
@ -523,6 +524,9 @@ test_base64_LDADD = $(LIBUNWIND_LIBS)
|
|||
test_configfile_SOURCES = test_configfile.c buffer.c array.c data_config.c data_string.c keyvalue.c vector.c log.c sock_addr.c
|
||||
test_configfile_LDADD = $(PCRE_LIB) $(LIBUNWIND_LIBS)
|
||||
|
||||
test_request_SOURCES = test_request.c request.c buffer.c array.c data_string.c keyvalue.c log.c sock_addr.c
|
||||
test_request_LDADD = $(PCRE_LIB) $(LIBUNWIND_LIBS)
|
||||
|
||||
noinst_HEADERS = $(hdr)
|
||||
EXTRA_DIST = \
|
||||
mod_skeleton.c \
|
||||
|
|
|
@ -714,6 +714,21 @@ test('test_configfile', executable('test_configfile',
|
|||
build_by_default: false,
|
||||
))
|
||||
|
||||
test('test_request', executable('test_request',
|
||||
sources: [
|
||||
'test_request.c',
|
||||
'request.c',
|
||||
'buffer.c',
|
||||
'array.c',
|
||||
'data_string.c',
|
||||
'keyvalue.c',
|
||||
'log.c',
|
||||
'sock_addr.c',
|
||||
],
|
||||
dependencies: common_flags + libpcre + libunwind,
|
||||
build_by_default: false,
|
||||
))
|
||||
|
||||
modules = [
|
||||
[ 'mod_access', [ 'mod_access.c' ] ],
|
||||
[ 'mod_accesslog', [ 'mod_accesslog.c' ] ],
|
||||
|
|
|
@ -0,0 +1,462 @@
|
|||
#include "request.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "base.h"
|
||||
|
||||
static void test_request_connection_reset(connection *con)
|
||||
{
|
||||
con->request.http_method = HTTP_METHOD_UNSET;
|
||||
con->request.http_version = HTTP_VERSION_UNSET;
|
||||
con->request.http_host = NULL;
|
||||
con->request.http_range = NULL;
|
||||
con->request.http_content_type = NULL;
|
||||
con->request.http_if_modified_since = NULL;
|
||||
con->request.http_if_none_match = NULL;
|
||||
con->request.content_length = 0;
|
||||
con->header_len = 0;
|
||||
con->http_status = 0;
|
||||
buffer_reset(con->proto);
|
||||
buffer_reset(con->parse_request);
|
||||
buffer_reset(con->request.request);
|
||||
buffer_reset(con->request.request_line);
|
||||
buffer_reset(con->request.orig_uri);
|
||||
buffer_reset(con->request.uri);
|
||||
array_reset(con->request.headers);
|
||||
}
|
||||
|
||||
static void run_http_request_parse(server *srv, connection *con, int line, int status, const char *desc, const char *req, size_t reqlen)
|
||||
{
|
||||
test_request_connection_reset(con);
|
||||
buffer_copy_string_len(con->request.request, req, reqlen);
|
||||
http_request_parse(srv, con);
|
||||
if (con->http_status != status) {
|
||||
fprintf(stderr,
|
||||
"%s.%d: %s() failed: expected '%d', got '%d' for test %s\n",
|
||||
__FILE__, line, "http_request_parse", status, con->http_status,
|
||||
desc);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void test_request_http_request_parse(server *srv, connection *con)
|
||||
{
|
||||
data_string *ds;
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"hostname",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: www.example.org\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("www.example.org")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"IPv4 address",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: 127.0.0.1\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("127.0.0.1")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"IPv6 address",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: [::1]\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("[::1]")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"hostname + port",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: www.example.org:80\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("www.example.org")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"IPv4 address + port",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: 127.0.0.1:80\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("127.0.0.1")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"IPv6 address + port",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: [::1]:80\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("[::1]")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"directory traversal",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: ../123.org\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"leading and trailing dot",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: .jsdh.sfdg.sdfg.\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"trailing dot is ok",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: jsdh.sfdg.sdfg.\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("jsdh.sfdg.sdfg")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"leading dot",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: .jsdh.sfdg.sdfg\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"two dots",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: jsdh..sfdg.sdfg\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"broken port-number",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: jsdh.sfdg.sdfg:asd\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"negative port-number",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: jsdh.sfdg.sdfg:-1\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"port given but host missing",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: :80\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"port and host are broken",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: .jsdh.sfdg.:sdfg.\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"allowed characters in host-name",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: a.b-c.d123\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("a.b-c.d123")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"leading dash",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: -a.c\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"dot only",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: .\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"broken IPv4 address - non-digit",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: a192.168.2.10:1234\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"broken IPv4 address - too short",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: 192.168.2:1234\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"IPv6 address + SQL injection",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: [::1]' UNION SELECT '/\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"IPv6 address + path traversal",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: [::1]/../../../\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"negative Content-Length",
|
||||
CONST_STR_LEN("POST /12345.txt HTTP/1.0\r\n"
|
||||
"Content-Length: -2\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 411,
|
||||
"Content-Length is empty",
|
||||
CONST_STR_LEN("POST /12345.txt HTTP/1.0\r\n"
|
||||
"Host: 123.example.org\r\n"
|
||||
"Content-Length:\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"Host missing",
|
||||
CONST_STR_LEN("GET / HTTP/1.1\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"empty request-URI",
|
||||
CONST_STR_LEN("GET HTTP/1.0\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"#1232 - duplicate headers with line-wrapping",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Location: foo\r\n"
|
||||
"Location: foobar\r\n"
|
||||
" baz\r\n"
|
||||
"\r\n"));
|
||||
ds = (data_string *)
|
||||
array_get_element_klen(con->request.headers, CONST_STR_LEN("Location"));
|
||||
assert(ds
|
||||
&& buffer_is_equal_string(ds->value,
|
||||
CONST_STR_LEN("foo, foobar baz")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"#1232 - duplicate headers with line-wrapping - test 2",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Location: \r\n"
|
||||
"Location: foobar\r\n"
|
||||
" baz\r\n"
|
||||
"\r\n"));
|
||||
ds = (data_string *)
|
||||
array_get_element_klen(con->request.headers, CONST_STR_LEN("Location"));
|
||||
assert(ds
|
||||
&& buffer_is_equal_string(ds->value, CONST_STR_LEN("foobar baz")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"#1232 - duplicate headers with line-wrapping - test 3",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"A: \r\n"
|
||||
"Location: foobar\r\n"
|
||||
" baz\r\n"
|
||||
"\r\n"));
|
||||
ds = (data_string *)
|
||||
array_get_element_klen(con->request.headers, CONST_STR_LEN("Location"));
|
||||
assert(ds
|
||||
&& buffer_is_equal_string(ds->value, CONST_STR_LEN("foobar baz")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"missing protocol",
|
||||
CONST_STR_LEN("GET /\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"zeros in protocol version",
|
||||
CONST_STR_LEN("GET / HTTP/01.01\r\n"
|
||||
"Host: foo\r\n"
|
||||
"\r\n"));
|
||||
assert(con->request.http_version == HTTP_VERSION_1_1);
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"missing major version",
|
||||
CONST_STR_LEN("GET / HTTP/.01\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"missing minor version",
|
||||
CONST_STR_LEN("GET / HTTP/01.\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"strings as version",
|
||||
CONST_STR_LEN("GET / HTTP/a.b\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"missing protocol + unknown method",
|
||||
CONST_STR_LEN("BC /\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"missing protocol + unknown method + missing URI",
|
||||
CONST_STR_LEN("ABC\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 501,
|
||||
"unknown method",
|
||||
CONST_STR_LEN("ABC / HTTP/1.0\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 505,
|
||||
"unknown protocol",
|
||||
CONST_STR_LEN("GET / HTTP/1.3\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"absolute URI",
|
||||
CONST_STR_LEN("GET http://www.example.org/ HTTP/1.0\r\n"
|
||||
"\r\n"));
|
||||
assert(buffer_is_equal_string(con->request.http_host,
|
||||
CONST_STR_LEN("www.example.org")));
|
||||
assert(buffer_is_equal_string(con->request.uri,
|
||||
CONST_STR_LEN("/")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"whitespace after key",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"ABC : foo\r\n"
|
||||
"\r\n"));
|
||||
ds = (data_string *)
|
||||
array_get_element_klen(con->request.headers, CONST_STR_LEN("ABC"));
|
||||
assert(ds && buffer_is_equal_string(ds->value, CONST_STR_LEN("foo")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"whitespace within key",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"ABC a: foo\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"no whitespace",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"ABC:foo\r\n"
|
||||
"\r\n"));
|
||||
ds = (data_string *)
|
||||
array_get_element_klen(con->request.headers, CONST_STR_LEN("ABC"));
|
||||
assert(ds && buffer_is_equal_string(ds->value, CONST_STR_LEN("foo")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"line-folding",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"ABC:foo\r\n"
|
||||
" bc\r\n"
|
||||
"\r\n"));
|
||||
ds = (data_string *)
|
||||
array_get_element_klen(con->request.headers, CONST_STR_LEN("ABC"));
|
||||
assert(ds && buffer_is_equal_string(ds->value, CONST_STR_LEN("foo bc")));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 411,
|
||||
"POST request, no Content-Length",
|
||||
CONST_STR_LEN("POST / HTTP/1.0\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"Duplicate Host headers, Bug #25",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: www.example.org\r\n"
|
||||
"Host: 123.example.org\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"Duplicate Content-Length headers",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Content-Length: 5\r\n"
|
||||
"Content-Length: 4\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"Duplicate Content-Type headers",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Content-Type: 5\r\n"
|
||||
"Content-Type: 4\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"Duplicate Range headers",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Range: bytes=5-6\r\n"
|
||||
"Range: bytes=5-9\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"Duplicate If-None-Match headers",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"If-None-Match: 5\r\n"
|
||||
"If-None-Match: 4\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"Duplicate If-Modified-Since headers",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"If-Modified-Since: 5\r\n"
|
||||
"If-Modified-Since: 4\r\n"
|
||||
"\r\n"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"GET with Content-Length",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Content-Length: 4\r\n"
|
||||
"\r\n"
|
||||
"1234"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"HEAD with Content-Length",
|
||||
CONST_STR_LEN("HEAD / HTTP/1.0\r\n"
|
||||
"Content-Length: 4\r\n"
|
||||
"\r\n"
|
||||
"1234"));
|
||||
|
||||
run_http_request_parse(srv, con, __LINE__, 400,
|
||||
"invalid chars in Header values (bug #1286)",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"If-Modified-Since: \0\r\n"
|
||||
"\r\n"));
|
||||
|
||||
/* (quick check that none of above tests were left in a state
|
||||
* which resulted in subsequent tests returning 400 for other
|
||||
* reasons) */
|
||||
run_http_request_parse(srv, con, __LINE__, 0,
|
||||
"valid",
|
||||
CONST_STR_LEN("GET / HTTP/1.0\r\n"
|
||||
"Host: www.example.org\r\n"
|
||||
"\r\n"));
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
server srv;
|
||||
connection con;
|
||||
|
||||
memset(&srv, 0, sizeof(server));
|
||||
srv.errorlog_fd = -1; /* use 2 for STDERR_FILENO from unistd.h */
|
||||
srv.errorlog_mode = ERRORLOG_FD;
|
||||
srv.errorlog_buf = buffer_init();
|
||||
srv.split_vals = array_init();
|
||||
|
||||
memset(&con, 0, sizeof(connection));
|
||||
con.proto = buffer_init();
|
||||
con.parse_request = buffer_init();
|
||||
con.request.request = buffer_init();
|
||||
con.request.request_line = buffer_init();
|
||||
con.request.orig_uri = buffer_init();
|
||||
con.request.uri = buffer_init();
|
||||
con.request.headers = array_init();
|
||||
con.conf.allow_http11 = 1;
|
||||
con.conf.http_parseopts = HTTP_PARSEOPT_HEADER_STRICT
|
||||
| HTTP_PARSEOPT_HOST_STRICT
|
||||
| HTTP_PARSEOPT_HOST_NORMALIZE;
|
||||
|
||||
test_request_http_request_parse(&srv, &con);
|
||||
|
||||
buffer_free(con.proto);
|
||||
buffer_free(con.parse_request);
|
||||
buffer_free(con.request.request);
|
||||
buffer_free(con.request.request_line);
|
||||
buffer_free(con.request.orig_uri);
|
||||
buffer_free(con.request.uri);
|
||||
array_free(con.request.headers);
|
||||
|
||||
array_free(srv.split_vals);
|
||||
buffer_free(srv.errorlog_buf);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -30,7 +30,6 @@ CONFS=\
|
|||
core-request.t \
|
||||
core-response.t \
|
||||
core-var-include.t \
|
||||
core.t \
|
||||
fastcgi-10.conf \
|
||||
fastcgi-13.conf \
|
||||
fastcgi-auth.conf \
|
||||
|
|
|
@ -18,7 +18,6 @@ extra_dist = Split('fastcgi-10.conf \
|
|||
core-request.t \
|
||||
core-response.t \
|
||||
core-keepalive.t \
|
||||
core.t \
|
||||
mod-access.t \
|
||||
mod-auth.t \
|
||||
mod-cgi.t \
|
||||
|
|
|
@ -8,7 +8,7 @@ BEGIN {
|
|||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
use Test::More tests => 38;
|
||||
use Test::More tests => 12;
|
||||
use LightyTest;
|
||||
|
||||
my $tf = LightyTest->new();
|
||||
|
@ -16,6 +16,31 @@ my $t;
|
|||
|
||||
ok($tf->start_proc == 0, "Starting lighttpd") or die();
|
||||
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Valid HTTP/1.0 Request') or die();
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
OPTIONS * HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'OPTIONS');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
OPTIONS / HTTP/1.1
|
||||
Host: www.example.org
|
||||
Connection: close
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'OPTIONS');
|
||||
|
||||
|
||||
## Low-Level Request-Header Parsing - URI
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
|
@ -32,201 +57,6 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ];
|
||||
ok($tf->handle_http($t) == 0, 'URL-encoding, %00');
|
||||
|
||||
|
||||
|
||||
## Low-Level Request-Header Parsing - Host
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: www.example.org
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'hostname');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: 127.0.0.1
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'IPv4 address');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: [::1]
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'IPv6 address');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: www.example.org:80
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'hostname + port');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: 127.0.0.1:80
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'IPv4 address + port');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: [::1]:80
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'IPv6 address + port');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: ../123.org
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'directory traversal');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: .jsdh.sfdg.sdfg.
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'leading and trailing dot');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: jsdh.sfdg.sdfg.
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'trailing dot is ok');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: .jsdh.sfdg.sdfg
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'leading dot');
|
||||
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: jsdh..sfdg.sdfg
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'two dots');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: jsdh.sfdg.sdfg:asd
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'broken port-number');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: jsdh.sfdg.sdfg:-1
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'negative port-number');
|
||||
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: :80
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'port given but host missing');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: .jsdh.sfdg.:sdfg.
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'port and host are broken');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: a.b-c.d123
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'allowed characters in host-name');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: -a.c
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'leading dash');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: .
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'dot only');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: a192.168.2.10:1234
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'broken IPv4 address - non-digit');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: 192.168.2:1234
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'broken IPv4 address - too short');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: [::1]' UNION SELECT '/
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'IPv6 address + SQL injection');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: [::1]/../../../
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'IPv6 address + path traversal');
|
||||
|
||||
|
||||
|
||||
## Low-Level Request-Header Parsing - Content-Length
|
||||
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET /index.html HTTP/1.0
|
||||
Content-Length: -2
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'negative Content-Length');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
POST /12345.txt HTTP/1.0
|
||||
Host: 123.example.org
|
||||
|
@ -236,22 +66,6 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 413 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Content-Length > max-request-size');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
POST /12345.txt HTTP/1.0
|
||||
Host: 123.example.org
|
||||
Content-Length:
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 411 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Content-Length is empty');
|
||||
|
||||
print "\nLow-Level Request-Header Parsing - HTTP/1.1\n";
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.1
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Host missing');
|
||||
|
||||
print "\nContent-Type\n";
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
|
@ -275,13 +89,6 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'application/octet-stream' } ];
|
||||
ok($tf->handle_http($t) == 0, 'Content-Type - unknown');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'empty request-URI');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET /Foo.txt HTTP/1.0
|
||||
EOF
|
||||
|
@ -289,38 +96,5 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'uppercase filenames');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Location: foo
|
||||
Location: foobar
|
||||
baz
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Location:
|
||||
Location: foobar
|
||||
baz
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping - test 2');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
A:
|
||||
Location: foobar
|
||||
baz
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, '#1232 - duplicate headers with line-wrapping - test 3');
|
||||
|
||||
|
||||
|
||||
|
||||
ok($tf->stop_proc == 0, "Stopping lighttpd");
|
||||
|
||||
|
|
166
tests/core.t
166
tests/core.t
|
@ -1,166 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
BEGIN {
|
||||
# add current source dir to the include-path
|
||||
# we need this for make distcheck
|
||||
(my $srcdir = $0) =~ s,/[^/]+$,/,;
|
||||
unshift @INC, $srcdir;
|
||||
}
|
||||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
use Test::More tests => 21;
|
||||
use LightyTest;
|
||||
|
||||
my $tf = LightyTest->new();
|
||||
my $t;
|
||||
|
||||
ok($tf->start_proc == 0, "Starting lighttpd") or die();
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Valid HTTP/1.0 Request') or die();
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET /
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'missing Protocol');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/01.01
|
||||
Host: foo
|
||||
Connection: close
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'zeros in protocol version');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/.01
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'missing major version');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/01.
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'missing minor version');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/a.b
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'strings as version');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
BC /
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'missing protocol + unknown method');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
ABC
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'missing protocol + unknown method + missing URI');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
ABC / HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 501 } ];
|
||||
ok($tf->handle_http($t) == 0, 'unknown method');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.3
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 505 } ];
|
||||
ok($tf->handle_http($t) == 0, 'unknown protocol');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET http://www.example.org/ HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'absolute URI');
|
||||
|
||||
print "\nLow-Level Request-Header Parsing\n";
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
ABC : foo
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'whitespace after key');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
ABC a: foo
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'whitespace with-in key');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
ABC:foo
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'no whitespace');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
ABC:foo
|
||||
bc
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'line-folding');
|
||||
|
||||
print "\nLow-Level Request-Header Parsing - URI\n";
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET /index%2ehtml HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'URL-encoding');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET /index.html%00 HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ];
|
||||
ok($tf->handle_http($t) == 0, 'URL-encoding, %00');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
OPTIONS * HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'OPTIONS');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
OPTIONS / HTTP/1.1
|
||||
Host: www.example.org
|
||||
Connection: close
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'OPTIONS');
|
||||
|
||||
|
||||
|
||||
ok($tf->stop_proc == 0, "Stopping lighttpd");
|
||||
|
|
@ -29,7 +29,6 @@ tests = [
|
|||
'core-request.t',
|
||||
'core-response.t',
|
||||
'core-var-include.t',
|
||||
'core.t',
|
||||
'lowercase.t',
|
||||
'mod-access.t',
|
||||
'mod-auth.t',
|
||||
|
|
|
@ -8,7 +8,7 @@ BEGIN {
|
|||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
use Test::More tests => 60;
|
||||
use Test::More tests => 50;
|
||||
use LightyTest;
|
||||
|
||||
my $tf = LightyTest->new();
|
||||
|
@ -56,13 +56,6 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'application/octet-stream' } ];
|
||||
ok($tf->handle_http($t) == 0, 'GET, content == 12345, mimetype application/octet-stream');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
POST / HTTP/1.0
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 411 } ];
|
||||
ok($tf->handle_http($t) == 0, 'POST request, no Content-Length');
|
||||
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
POST / HTTP/1.0
|
||||
|
@ -390,61 +383,6 @@ $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
|||
ok($tf->handle_http($t) == 0, 'larger headers');
|
||||
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: www.example.org
|
||||
Host: 123.example.org
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Duplicate Host headers, Bug #25');
|
||||
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Content-Length: 5
|
||||
Content-Length: 4
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Duplicate Content-Length headers');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Content-Type: 5
|
||||
Content-Type: 4
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Duplicate Content-Type headers');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Range: bytes=5-6
|
||||
Range: bytes=5-9
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Duplicate Range headers');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
If-None-Match: 5
|
||||
If-None-Match: 4
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Duplicate If-None-Match headers');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
If-Modified-Since: 5
|
||||
If-Modified-Since: 4
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Duplicate If-Modified-Since headers');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET /range.pdf HTTP/1.0
|
||||
Range: bytes=0-
|
||||
|
@ -453,16 +391,6 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'GET, Range with range-requests-disabled');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Content-Length: 4
|
||||
|
||||
1234
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'GET with Content-Length');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
OPTIONS / HTTP/1.0
|
||||
Content-Length: 4
|
||||
|
@ -481,16 +409,6 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'OPTIONS for RTSP');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
HEAD / HTTP/1.0
|
||||
Content-Length: 4
|
||||
|
||||
1234
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'HEAD with Content-Length');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET /index.html HTTP/1.0
|
||||
If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT
|
||||
|
@ -500,10 +418,6 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Duplicate If-Mod-Since, with equal timestamps');
|
||||
|
||||
$t->{REQUEST} = ( "GET / HTTP/1.0\r\nIf-Modified-Since: \0\r\n\r\n" );
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'invalid chars in Header values (bug #1286)');
|
||||
|
||||
$t->{REQUEST} = ( "GET / HTTP/1.0\r\nIf-Modified-Since: \r\n\r\n" );
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'empty If-Modified-Since');
|
||||
|
|
Loading…
Reference in New Issue