diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-07-06 22:58:13 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2021-09-04 08:08:26 -0400 |
commit | 91472ab7681b26f36b813f3b245c0e98f91b4c3f (patch) | |
tree | c0a71cb0f9d52747ec4c0409f8863b9f64233e83 /src | |
parent | a0a8cf821d2292e6662119e158e73c175452f1c3 (diff) | |
download | lighttpd-git-91472ab7681b26f36b813f3b245c0e98f91b4c3f.tar.gz |
[tests] t/test_mod_staticfile
move some tests from tests/request.t to src/t/test_mod_staticfile.c
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 27 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/meson.build | 44 | ||||
-rw-r--r-- | src/mod_staticfile.c | 32 | ||||
-rw-r--r-- | src/t/test_mod_staticfile.c | 458 |
5 files changed, 551 insertions, 15 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5fec0207..c92a85b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -927,6 +927,30 @@ add_executable(test_mod_simple_vhost ) add_test(NAME test_mod_simple_vhost COMMAND test_mod_simple_vhost) +add_executable(test_mod_staticfile + t/test_mod_staticfile.c + request.c + base64.c + buffer.c + burl.c + array.c + chunk.c + fdevent.c + http-header-glue.c + http_cgi.c + http_chunk.c + http_date.c + http_etag.c + http_header.c + http_kv.c + log.c + sock_addr.c + stat_cache.c + algo_splaytree.c + ck.c +) +add_test(NAME test_mod_staticfile COMMAND test_mod_staticfile) + add_executable(test_mod_userdir t/test_mod_userdir.c buffer.c @@ -1084,6 +1108,7 @@ endif() if(HAVE_LIBFAM) target_link_libraries(lighttpd fam) + target_link_libraries(test_mod_staticfile fam) endif() if(HAVE_GDBM_H) @@ -1204,6 +1229,8 @@ if(WITH_LIBUNWIND) add_target_properties(test_mod_evhost COMPILE_FLAGS ${LIBUNWIND_CFLAGS}) target_link_libraries(test_mod_simple_vhost ${LIBUNWIND_LDFLAGS}) add_target_properties(test_mod_simple_vhost COMPILE_FLAGS ${LIBUNWIND_CFLAGS}) + target_link_libraries(test_mod_staticfile ${LIBUNWIND_LDFLAGS}) + add_target_properties(test_mod_staticfile COMPILE_FLAGS ${LIBUNWIND_CFLAGS}) target_link_libraries(test_mod_userdir ${LIBUNWIND_LDFLAGS}) add_target_properties(test_mod_userdir COMPILE_FLAGS ${LIBUNWIND_CFLAGS}) target_link_libraries(test_request ${LIBUNWIND_LDFLAGS}) diff --git a/src/Makefile.am b/src/Makefile.am index fe7341e6..1f15aec4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,6 +10,7 @@ noinst_PROGRAMS=\ t/test_mod_access \ t/test_mod_evhost \ t/test_mod_simple_vhost \ + t/test_mod_staticfile \ t/test_mod_userdir \ t/test_request @@ -26,6 +27,7 @@ TESTS=\ t/test_mod_access$(EXEEXT) \ t/test_mod_evhost$(EXEEXT) \ t/test_mod_simple_vhost$(EXEEXT) \ + t/test_mod_staticfile$(EXEEXT) \ t/test_mod_userdir$(EXEEXT) \ t/test_request$(EXEEXT) @@ -663,6 +665,9 @@ t_test_mod_evhost_LDADD = $(LIBUNWIND_LIBS) t_test_mod_simple_vhost_SOURCES = t/test_mod_simple_vhost.c buffer.c array.c log.c ck.c t_test_mod_simple_vhost_LDADD = $(LIBUNWIND_LIBS) +t_test_mod_staticfile_SOURCES = t/test_mod_staticfile.c request.c base64.c buffer.c burl.c array.c chunk.c fdevent.c http-header-glue.c http_cgi.c http_chunk.c http_date.c http_etag.c http_header.c http_kv.c log.c sock_addr.c stat_cache.c algo_splaytree.c ck.c +t_test_mod_staticfile_LDADD = $(LIBUNWIND_LIBS) $(FAM_LIBS) + t_test_mod_userdir_SOURCES = t/test_mod_userdir.c buffer.c array.c log.c ck.c t_test_mod_userdir_LDADD = $(LIBUNWIND_LIBS) diff --git a/src/meson.build b/src/meson.build index fdf57ca9..a0c6ee9e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -895,7 +895,11 @@ test('test_configfile', executable('test_configfile', 'sock_addr.c', 'ck.c', ], - dependencies: common_flags + libpcre + libunwind, + dependencies: [ common_flags + , libpcre + , libunwind + , libws2_32 + ], build_by_default: false, )) @@ -949,6 +953,38 @@ test('test_mod_simple_vhost', executable('test_mod_simple_vhost', build_by_default: false, )) +test('test_mod_staticfile', executable('test_mod_staticfile', + sources: [ + 't/test_mod_staticfile.c', + 'request.c', + 'base64.c', + 'buffer.c', + 'burl.c', + 'array.c', + 'chunk.c', + 'fdevent.c', + 'http-header-glue.c', + 'http_cgi.c', + 'http_chunk.c', + 'http_date.c', + 'http_etag.c', + 'http_header.c', + 'http_kv.c', + 'log.c', + 'sock_addr.c', + 'stat_cache.c', + 'algo_splaytree.c', + 'ck.c' + ], + dependencies: [ common_flags + , libfam + , libpcre + , libunwind + , libws2_32 + ], + build_by_default: false, +)) + test('test_mod_userdir', executable('test_mod_userdir', sources: [ 't/test_mod_userdir.c', @@ -974,7 +1010,11 @@ test('test_request', executable('test_request', 'sock_addr.c', 'ck.c', ], - dependencies: common_flags + libunwind, + dependencies: [ common_flags + , libpcre + , libunwind + , libws2_32 + ], build_by_default: false, )) diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c index 763cc521..d39abe29 100644 --- a/src/mod_staticfile.c +++ b/src/mod_staticfile.c @@ -107,25 +107,19 @@ mod_staticfile_not_handled(request_st * const r, const char * const msg) return HANDLER_GO_ON; } -URIHANDLER_FUNC(mod_staticfile_subrequest) { - if (NULL != r->handler_module) return HANDLER_GO_ON; - if (!http_method_get_head_post(r->http_method)) return HANDLER_GO_ON; - /* r->physical.path is non-empty for handle_subrequest_start */ - /*if (buffer_is_blank(&r->physical.path)) return HANDLER_GO_ON;*/ - - plugin_data * const p = p_d; - mod_staticfile_patch_config(r, p); - - if (p->conf.disable_pathinfo && !buffer_is_blank(&r->pathinfo)) { +static handler_t +mod_staticfile_process (request_st * const r, plugin_config * const pconf) +{ + if (pconf->disable_pathinfo && !buffer_is_blank(&r->pathinfo)) { return mod_staticfile_not_handled(r, "pathinfo"); } - if (p->conf.exclude_ext - && array_match_value_suffix(p->conf.exclude_ext, &r->physical.path)) { + if (pconf->exclude_ext + && array_match_value_suffix(pconf->exclude_ext, &r->physical.path)) { return mod_staticfile_not_handled(r, "extension"); } - if (!p->conf.etags_used) r->conf.etag_flags = 0; + if (!pconf->etags_used) r->conf.etag_flags = 0; /* r->tmp_sce is set in http_response_physical_path_check() and is valid * in handle_subrequest_start callback -- handle_subrequest_start callbacks @@ -138,6 +132,18 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) { return HANDLER_FINISHED; } +URIHANDLER_FUNC(mod_staticfile_subrequest) { + if (NULL != r->handler_module) return HANDLER_GO_ON; + if (!http_method_get_head_post(r->http_method)) return HANDLER_GO_ON; + /* r->physical.path is non-empty for handle_subrequest_start */ + /*if (buffer_is_blank(&r->physical.path)) return HANDLER_GO_ON;*/ + + plugin_data * const p = p_d; + mod_staticfile_patch_config(r, p); + + return mod_staticfile_process(r, &p->conf); +} + int mod_staticfile_plugin_init(plugin *p); int mod_staticfile_plugin_init(plugin *p) { diff --git a/src/t/test_mod_staticfile.c b/src/t/test_mod_staticfile.c new file mode 100644 index 00000000..58e4e968 --- /dev/null +++ b/src/t/test_mod_staticfile.c @@ -0,0 +1,458 @@ +#include "first.h" + +#undef NDEBUG +#include <sys/types.h> +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> + +#include "mod_staticfile.c" +#include "http_date.h" +#include "http_etag.h" +#include "http_header.h" + +__attribute_noinline__ +static void test_mod_staticfile_reset (request_st * const r) +{ + r->http_status = 0; + r->resp_htags = 0; + array_reset_data_strings(&r->resp_headers); + http_response_body_clear(r, 0); + buffer_clear(&r->physical.etag); + r->conf.etag_flags = ETAG_USE_INODE | ETAG_USE_MTIME | ETAG_USE_SIZE; +} + +__attribute_noinline__ +static void +run_http_response_send_file (request_st * const r, int line, int status, const char *desc) +{ + http_response_send_file(r, &r->physical.path, NULL); + if (r->http_status != status) { + fprintf(stderr, + "%s.%d: %s() failed: expected '%d', got '%d' for test %s\n", + __FILE__, line, "http_response_send_file", status, + r->http_status, desc); + fflush(stderr); + abort(); + } +} + +static void +test_http_response_send_file (request_st * const r, time_t lmtime) +{ + test_mod_staticfile_reset(r); + const buffer *vb; + + /*(mismatch test must be first, else stat_cache will have cached mimetype)*/ + array * const mimetypes_empty = array_init(0); + const array * const mimetypes_orig = r->conf.mimetypes; + r->conf.mimetypes = mimetypes_empty; + run_http_response_send_file(r, __LINE__, 200, + "basic static file (w/o mimetype match)"); + vb = http_header_response_get(r, HTTP_HEADER_CONTENT_TYPE, + CONST_STR_LEN("Content-Type")); + assert(vb && buffer_eq_slen(vb, CONST_STR_LEN("application/octet-stream"))); + test_mod_staticfile_reset(r); + r->conf.mimetypes = mimetypes_orig; + array_free(mimetypes_empty); + + run_http_response_send_file(r, __LINE__, 200, + "basic static file (w/ mimetype match)"); + vb = http_header_response_get(r, HTTP_HEADER_CONTENT_TYPE, + CONST_STR_LEN("Content-Type")); + assert(vb && buffer_eq_slen(vb, CONST_STR_LEN("text/plain"))); + vb = http_header_response_get(r, HTTP_HEADER_ETAG, + CONST_STR_LEN("ETag")); + assert(vb && vb->ptr[0] == '"' && vb->ptr[buffer_clen(vb)-1] == '"'); + vb = http_header_response_get(r, HTTP_HEADER_LAST_MODIFIED, + CONST_STR_LEN("Last-Modified")); + assert(vb); + test_mod_staticfile_reset(r); + + const uint32_t plen = buffer_clen(&r->physical.path); + buffer_append_string_len(&r->physical.path, CONST_STR_LEN("-nonexistent")); + run_http_response_send_file(r, __LINE__, 404, + "non-existent file"); + test_mod_staticfile_reset(r); + buffer_truncate(&r->physical.path, plen); + + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + CONST_STR_LEN("")); + run_http_response_send_file(r, __LINE__, 200, + "if-modified-since invalid (empty)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + CONST_STR_LEN("foobar")); + run_http_response_send_file(r, __LINE__, 200, + "if-modified-since invalid (not time string)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + CONST_STR_LEN("this string is too long to be a valid timestamp")); + run_http_response_send_file(r, __LINE__, 200, + "if-modified-since invalid (too long to be valid time string)"); + test_mod_staticfile_reset(r); + + char lmtime_str[HTTP_DATE_SZ]; + uint32_t lmtime_len; + + lmtime_len = http_date_time_to_str(lmtime_str,sizeof(lmtime_str), + lmtime ? lmtime-1 : lmtime); + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + lmtime_str, lmtime_len); + run_http_response_send_file(r, __LINE__, 200, + "if-modified-since older than st_mtime"); + test_mod_staticfile_reset(r); + + lmtime_len = http_date_time_to_str(lmtime_str,sizeof(lmtime_str),lmtime); + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + lmtime_str, lmtime_len); + run_http_response_send_file(r, __LINE__, 304, + "if-modified-since matches st_mtime"); + test_mod_staticfile_reset(r); + + lmtime_len = http_date_time_to_str(lmtime_str,sizeof(lmtime_str),lmtime+1); + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + lmtime_str, lmtime_len); + run_http_response_send_file(r, __LINE__, 304, + "if-modified-since newer than st_mtime"); + test_mod_staticfile_reset(r); + + buffer_append_string_len( + http_header_request_get(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since")), + CONST_STR_LEN("; foo")); + run_http_response_send_file(r, __LINE__, 200, + "if-modified-since newer but overload (invalid)"); + test_mod_staticfile_reset(r); + + http_header_request_unset(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since")); + + buffer *etag = buffer_init(); + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_STR_LEN("foo")); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (etag mismatch)"); + vb = http_header_response_get(r, HTTP_HEADER_ETAG, + CONST_STR_LEN("ETag")); + assert(vb); + buffer_copy_buffer(etag, vb); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_BUF_LEN(etag)); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag match)"); + test_mod_staticfile_reset(r); + + r->conf.etag_flags = 0; + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_BUF_LEN(etag)); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (etag would match, but etags disabled in config)"); + test_mod_staticfile_reset(r); + r->conf.etag_flags = ETAG_USE_INODE | ETAG_USE_MTIME | ETAG_USE_SIZE; + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_BUF_LEN(etag)); + lmtime_len = http_date_time_to_str(lmtime_str,sizeof(lmtime_str), + lmtime ? lmtime-1 : lmtime); + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + lmtime_str, lmtime_len); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag match), " + "if-modified-since (old) (should be ignored)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_BUF_LEN(etag)); + lmtime_len = http_date_time_to_str(lmtime_str,sizeof(lmtime_str),lmtime); + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + lmtime_str, lmtime_len); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag match), " + "if-modified-since (now) (should be ignored)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_BUF_LEN(etag)); + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + CONST_STR_LEN("Sun, 01 Jan 1970 00:00:01 GMT foo")); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag match), " + "if-modified-since (overlong; invalid) (should be ignored)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_STR_LEN("foo")); + lmtime_len = http_date_time_to_str(lmtime_str,sizeof(lmtime_str), + lmtime ? lmtime-1 : lmtime); + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + lmtime_str, lmtime_len); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (etag mismatch), " + "if-modified-since (old) (should be ignored)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_STR_LEN("foo")); + lmtime_len = http_date_time_to_str(lmtime_str,sizeof(lmtime_str),lmtime); + http_header_request_set(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since"), + lmtime_str, lmtime_len); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (etag mismatch), " + "if-modified-since (now) (should be ignored)"); + test_mod_staticfile_reset(r); + + http_header_request_unset(r, HTTP_HEADER_IF_MODIFIED_SINCE, + CONST_STR_LEN("If-Modified-Since")); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + etag->ptr, buffer_clen(etag)-1); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (etag invalid; mismatched quotes)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + etag->ptr+1, buffer_clen(etag)-2); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (etag invalid; no quotes)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_STR_LEN("*")); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag * (unquoted) matches any ETag)"); + test_mod_staticfile_reset(r); + + http_header_request_set(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match"), + CONST_STR_LEN("\"*\"")); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (etag \"*\" (quoted) is a regular ETag)"); + test_mod_staticfile_reset(r); + + buffer * const rqst_etag = + http_header_request_set_ptr(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match")); + + buffer_copy_string_len(rqst_etag, CONST_STR_LEN("W/")); + buffer_append_buffer(rqst_etag, etag); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (weak etag) matches like ETag for GET and HEAD)"); + test_mod_staticfile_reset(r); + + /*(200 expected here instead of 206 since Range is handled later)*/ + http_header_request_set(r, HTTP_HEADER_RANGE, + CONST_STR_LEN("Range"), + CONST_STR_LEN("bytes=0-0")); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (weak etag) does not match for Range request)"); + test_mod_staticfile_reset(r); + http_header_request_unset(r, HTTP_HEADER_RANGE, CONST_STR_LEN("Range")); + + buffer_copy_string_len(rqst_etag, CONST_STR_LEN("W/\"12345\"")); + run_http_response_send_file(r, __LINE__, 200, + "if-none-match (weak etag no match)"); + test_mod_staticfile_reset(r); + + buffer_append_string_len(rqst_etag, CONST_STR_LEN(", ")); + buffer_append_buffer(rqst_etag, etag); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag list, second etag matches)"); + test_mod_staticfile_reset(r); + + buffer_append_string_len(rqst_etag, CONST_STR_LEN(", W/")); + buffer_append_buffer(rqst_etag, etag); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag list, second etag matches weakly)"); + test_mod_staticfile_reset(r); + + buffer_copy_string_len(rqst_etag, CONST_STR_LEN("\"12345\",, ,, , ")); + buffer_append_buffer(rqst_etag, etag); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag list non-normalized, ending with etag match)"); + test_mod_staticfile_reset(r); + + buffer_copy_string_len(rqst_etag, CONST_STR_LEN("\"1234\", ")); + buffer_append_buffer(rqst_etag, etag); + buffer_append_string_len(rqst_etag, CONST_STR_LEN(", \"brokentrailing")); + run_http_response_send_file(r, __LINE__, 304, + "if-none-match (etag list with etag match then invalid trailing data)"); + test_mod_staticfile_reset(r); + + http_header_request_unset(r, HTTP_HEADER_IF_NONE_MATCH, + CONST_STR_LEN("If-None-Match")); + + buffer_free(etag); +} + +__attribute_noinline__ +static void +run_mod_staticfile_process (request_st * const r, plugin_config * const pconf, int line, int status, const char *desc) +{ + handler_t rc = mod_staticfile_process(r, pconf); + if (r->http_status != status + || rc != (status ? HANDLER_FINISHED : HANDLER_GO_ON)) { + fprintf(stderr, + "%s.%d: %s() failed: expected '%d', got '%d' for test %s\n", + __FILE__, line, "mod_staticfile_process", status, + r->http_status, desc); + fflush(stderr); + abort(); + } +} + +static void +test_mod_staticfile_process (request_st * const r, plugin_config * const pconf) +{ + test_mod_staticfile_reset(r); + + pconf->disable_pathinfo = 0; + buffer_copy_string_len(&r->pathinfo, CONST_STR_LEN("/pathinfo")); + run_mod_staticfile_process(r, pconf, __LINE__, 200, + "pathinfo allowed and present"); + test_mod_staticfile_reset(r); + pconf->disable_pathinfo = 1; + run_mod_staticfile_process(r, pconf, __LINE__, 0, + "pathinfo denied and present"); + test_mod_staticfile_reset(r); + buffer_clear(&r->pathinfo); + run_mod_staticfile_process(r, pconf, __LINE__, 200, + "pathinfo denied and not present"); + test_mod_staticfile_reset(r); + pconf->disable_pathinfo = 0; + + array * const a = array_init(1); + array_insert_value(a, CONST_STR_LEN(".exe")); + pconf->exclude_ext = a; + run_mod_staticfile_process(r, pconf, __LINE__, 200, + "extension disallowed (no match)"); + test_mod_staticfile_reset(r); + buffer_append_string_len(&r->physical.path, CONST_STR_LEN(".exe")); + run_mod_staticfile_process(r, pconf, __LINE__, 0, + "extension disallowed (match)"); + test_mod_staticfile_reset(r); + pconf->exclude_ext = NULL; + array_free(a); +} + +#include <unistd.h> /* unlink() */ + +int main (void) +{ + char fn[] = "/tmp/lighttpd_mod_staticfile.XXXXXX"; + #ifdef __COVERITY__ + /* POSIX-2008 requires mkstemp create file with 0600 perms */ + umask(0600); + #endif + /* coverity[secure_temp : FALSE] */ + int fd = mkstemp(fn); + if (fd < 0) { + perror("mkstemp()"); + exit(1); + } + struct stat st; + if (0 != fstat(fd, &st)) { + perror("fstat()"); + exit(1); + } + + plugin_data * const p = mod_staticfile_init(); + assert(NULL != p); + p->conf.etags_used = 1; + + request_st r; + + memset(&r, 0, sizeof(request_st)); + r.http_method = HTTP_METHOD_GET; + r.http_version = HTTP_VERSION_1_1; + r.tmp_buf = buffer_init(); + r.conf.errh = log_error_st_init(); + r.conf.errh->errorlog_fd = -1; /* (disable) */ + r.conf.follow_symlink = 1; + buffer_copy_string_len(&r.uri.path, CONST_STR_LEN("/")); + array * const mimetypes = array_init(1); + r.conf.mimetypes = mimetypes; + array_set_key_value(mimetypes, fn+sizeof(fn)-8, 7, + CONST_STR_LEN("text/plain")); + + strftime_cache_reset(); + + buffer_copy_string_len(&r.physical.path, fn, sizeof(fn)-1); + test_http_response_send_file(&r, st.st_mtime); + + r.rqst_htags = 0; + array_reset_data_strings(&r.rqst_headers); + + buffer_copy_string_len(&r.physical.path, fn, sizeof(fn)-1); + test_mod_staticfile_process(&r, &p->conf); + + array_free(mimetypes); + log_error_st_free(r.conf.errh); + buffer_free(r.tmp_buf); + chunkqueue_reset(&r.write_queue); + + free(r.uri.path.ptr); + free(r.physical.etag.ptr); + free(r.physical.path.ptr); + free(r.physical.rel_path.ptr); + free(r.physical.doc_root.ptr); + + free(p); + stat_cache_free(); + unlink(fn); + return 0; +} + + +/* + * stub functions + */ + +#include "fdevent_impl.h" +int fdevent_select_init(struct fdevents *ev) { return NULL == ev; } +int fdevent_poll_init(struct fdevents *ev) { return NULL == ev; } +int fdevent_linux_sysepoll_init(struct fdevents *ev) { return NULL == ev; } +int fdevent_solaris_devpoll_init(struct fdevents *ev) { return NULL == ev; } +int fdevent_solaris_port_init(struct fdevents *ev) { return NULL == ev; } +int fdevent_freebsd_kqueue_init(struct fdevents *ev) { return NULL == ev; } +int fdevent_libev_init(struct fdevents *ev) { return NULL == ev; } + +int config_plugin_values_init(server *srv, void *p_d, const config_plugin_keys_t *cpk, const char *mname) { + UNUSED(srv); + UNUSED(p_d); + UNUSED(cpk); + UNUSED(mname); + return 0; +} + +int config_check_cond(request_st *r, int context_ndx) { + UNUSED(r); + UNUSED(context_ndx); + return 0; +} |