diff --git a/.github/workflows/gha.yml b/.github/workflows/gha.yml new file mode 100644 index 0000000..61519e7 --- /dev/null +++ b/.github/workflows/gha.yml @@ -0,0 +1,105 @@ +name: CI + +on: + pull_request: + types: [opened, synchronize] + paths-ignore: + - '**.md' + - 'ChangeLog*' + - 'LICENSE' + push: + paths-ignore: + - '**.md' + - 'ChangeLog*' + - 'LICENSE' + +jobs: + linux-cmake: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-18.04] + EVHTP_MATRIX: + - Debug + + steps: + - uses: actions/checkout@v2.0.0 + - name: Cache Build + uses: actions/cache@v1.1.0 + with: + path: build + key: ${{ matrix.os }}-cmake-${{ matrix.EVHTP_MATRIX }} + + - name: Install Dependes + run: | + sudo apt install libevent-dev libonig-dev + + - name: Build And Test + shell: bash + run: | + if [ "${{ matrix.EVHTP_MATRIX }}" == "Debug" ]; then + EVHTP_CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Debug" + fi + + mkdir -p build + cd build + echo [cmake]: cmake .. $EVHTP_CMAKE_OPTIONS + cmake .. $EVHTP_CMAKE_OPTIONS + cmake --build . + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: ${{ matrix.os }}-cmake-${{ matrix.EVHTP_MATRIX }}-build + path: build + + windows-mingw: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + EVHTP_MATRIX: + - Debug + + steps: + - uses: actions/checkout@v2.0.0 + + - name: Cache MinGW + id: cache-mingw-cmake + uses: actions/cache@v1.1.2 + with: + path: D:\a\_temp\msys + key: windows-mingw-cmake + + - name: Cache Build + uses: actions/cache@v1.1.2 + with: + path: build + key: mingw-cmake-${{ matrix.EVHTP_MATRIX }} + + - uses: numworks/setup-msys2@v1 + if: steps.cache-mingw-cmake.outputs.cache-hit != 'true' + with: + msystem: MINGW64 + + - name: Install Dependes + if: steps.cache-mingw-cmake.outputs.cache-hit != 'true' + run: | + msys2do pacman -S --noconfirm mingw-w64-x86_64-gcc mingw-w64-x86_64-libevent mingw-w64-x86_64-oniguruma + - name: Build And Test + shell: powershell + run: | + if ( "${{ matrix.EVHTP_MATRIX }}" -ne "Debug" ) { + $EVHTP_CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Debug" + } + $env:PATH="D:\a\_temp\msys\msys64\mingw64\bin;D:\a\_temp\msys\msys64;$env:PATH" + mkdir build -ea 0 + cd build + cmake .. -G "MSYS Makefiles" $EVHTP_CMAKE_OPTIONS -DCMAKE_C_FLAGS=-w + cmake --build . + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: mingw-${{ matrix.EVHTP_MATRIX }}-build + path: build \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6ef0f85..ccdfee2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ build/* !build/.gitkeep cmake-build-debug .idea +.vscode/ +.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt index 481ddd0..6662833 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,7 +115,7 @@ target_link_libraries(evhtp PUBLIC ${LIBEVHTP_EXTERNAL_LIBS}) target_include_directories(evhtp PUBLIC ${LIBEVHTP_EXTERNAL_INCLUDES}) target_compile_definitions(evhtp PUBLIC "PROJECT_VERSION=${PROJECT_VERSION}") -if(has_stack_protector) +if(NOT WIN32 AND has_stack_protector) target_compile_options(evhtp PUBLIC -fstack-protector-strong) endif() @@ -186,10 +186,9 @@ if(OPENSSL_FOUND AND APPLE) endif() if(WIN32) - target_compile_definitions(evhtp PUBLIC WIN32) - target_compile_options(evhtp PUBLIC -march=i486) - find_library(LIB_WS32 ws2_32) - list(APPEND SYS_LIBS ${LIB_WS32}) + target_compile_definitions(evhtp PUBLIC WIN32 _CRT_SECURE_NO_WARNINGS) + target_link_libraries(evhtp PUBLIC ws2_32 iphlpapi) + list(APPEND SYS_LIBS ws2_32 iphlpapi) endif() configure_file( diff --git a/cmake/options.cmake b/cmake/options.cmake index f7d6f22..4ced5f2 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -2,7 +2,17 @@ option (EVHTP_DISABLE_SSL "Disable ssl support" OFF) # -DEVHTP_DISABLE_EVTHR=ON -option (EVHTP_DISABLE_EVTHR "Disable evthread support" OFF) +if (WIN32) + set(disable_evthread_default ON) +else() + set(disable_evthread_default OFF) +endif() +option (EVHTP_DISABLE_EVTHR "Disable evthread support" + ${disable_evthread_default}) +if (WIN32 AND NOT EVHTP_DISABLE_EVTHR) + message(WARNING "EVHTP_DISABLE_EVTHR is overridden to ON since evthread is not supported on Windows") + set(EVHTP_DISABLE_EVTHR ON) +endif() # -DEVHTP_DISABLE_REGEX=ON find_package(Oniguruma) diff --git a/compat/getopt.c b/compat/getopt.c new file mode 100644 index 0000000..0fcba5d --- /dev/null +++ b/compat/getopt.c @@ -0,0 +1,149 @@ +/* $NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $ */ + +/* + * Copyright (c) 1987, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if 0 +static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; +#endif + +#include +#include +#include +#include + +#define __P(x) x +#define _DIAGASSERT(x) assert(x) + +#ifdef __weak_alias +__weak_alias(getopt,_getopt); +#endif + + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +static char * _progname __P((char *)); +int getopt_internal __P((int, char * const *, const char *)); + +static char * +_progname(nargv0) + char * nargv0; +{ + char * tmp; + + _DIAGASSERT(nargv0 != NULL); + + tmp = strrchr(nargv0, '/'); + if (tmp) + tmp++; + else + tmp = nargv0; + return(tmp); +} + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(nargc, nargv, ostr) + int nargc; + char * const nargv[]; + const char *ostr; +{ + static char *__progname = 0; + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + __progname = __progname?__progname:_progname(*nargv); + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(ostr != NULL); + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-' /* found "--" */ + && place[1] == '\0') { + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", __progname, optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname, optopt); + return (BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} + diff --git a/compat/getopt.h b/compat/getopt.h new file mode 100644 index 0000000..796f455 --- /dev/null +++ b/compat/getopt.h @@ -0,0 +1,33 @@ +#ifndef __GETOPT_H__ +#define __GETOPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern int optreset; /* reset getopt */ +extern char *optarg; /* argument associated with option */ + +struct option +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +int getopt(int, char**, const char*); +int getopt_long(int, char**, const char*, const struct option*, int*); + +#ifdef __cplusplus +} +#endif + +#endif /* __GETOPT_H__ */ diff --git a/compat/getopt_long.c b/compat/getopt_long.c new file mode 100644 index 0000000..092defb --- /dev/null +++ b/compat/getopt_long.c @@ -0,0 +1,234 @@ + +/* + * Copyright (c) 1987, 1993, 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "getopt.h" + +extern int opterr; /* if error message should be printed */ +extern int optind; /* index into parent argv vector */ +extern int optopt; /* character checked for validity */ +extern int optreset; /* reset getopt */ +extern char *optarg; /* argument associated with option */ + +#define __P(x) x +#define _DIAGASSERT(x) assert(x) + +static char * __progname __P((char *)); +int getopt_internal __P((int, char * const *, const char *)); + +static char * +__progname(nargv0) + char * nargv0; +{ + char * tmp; + + _DIAGASSERT(nargv0 != NULL); + + tmp = strrchr(nargv0, '/'); + if (tmp) + tmp++; + else + tmp = nargv0; + return(tmp); +} + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt_internal(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(ostr != NULL); + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + /* ++optind; */ + place = EMSG; + return (-2); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", __progname(nargv[0]), optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if ((opterr) && (*ostr != ':')) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname(nargv[0]), optopt); + return (BADARG); + } else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} + +#if 0 +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt2(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ + int retval; + + if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) { + retval = -1; + ++optind; + } + return(retval); +} +#endif + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(nargc, nargv, options, long_options, index) + int nargc; + char ** nargv; + const char * options; + const struct option * long_options; + int * index; +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + _DIAGASSERT(long_options != NULL); + /* index may be NULL */ + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + char *current_argv = nargv[optind++] + 2, *has_equal; + int i, match = -1; + size_t current_argv_len; + + if (*current_argv == '\0') { + return(-1); + } + if ((has_equal = strchr(current_argv, '=')) != NULL) { + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + if (strncmp(current_argv, long_options[i].name, current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + match = i; + break; + } + if (match == -1) + match = i; + } + if (match != -1) { + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else + optarg = nargv[optind++]; + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument, leading : + * indicates no error should be generated + */ + if ((opterr) && (*options != ':')) + (void)fprintf(stderr, + "%s: option requires an argument -- %s\n", + __progname(nargv[0]), current_argv); + return (BADARG); + } + } else { /* No matching argument */ + if ((opterr) && (*options != ':')) + (void)fprintf(stderr, + "%s: illegal option -- %s\n", __progname(nargv[0]), current_argv); + return (BADCH); + } + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + retval = 0; + } else + retval = long_options[match].val; + if (index) + *index = match; + } + return(retval); +} diff --git a/evhtp.c b/evhtp.c index 63fdf18..8e97fd2 100644 --- a/evhtp.c +++ b/evhtp.c @@ -10,11 +10,10 @@ #include #include #include -#include #include #include -#include /* MIN/MAX macro */ #ifndef WIN32 +#include /* MIN/MAX macro */ #include #include #include @@ -36,6 +35,10 @@ #include "numtoa.h" #include "evhtp/evhtp.h" +/* `MIN' is not defined on Windows and mingw */ +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif /** * @brief structure containing a single callback and configuration * @@ -329,7 +332,7 @@ evhtp_set_mem_functions(void *(*mallocfn_)(size_t len), realloc_ = reallocfn_; free_ = freefn_; - return event_set_mem_functions(malloc_, realloc_, free_); + event_set_mem_functions(malloc_, realloc_, free_); #endif } @@ -466,7 +469,7 @@ static int ssl_locks_initialized = 0; * @return length of string * */ -static size_t +size_t strnlen(const char * s, size_t maxlen) { const char * e; @@ -491,7 +494,7 @@ strnlen(const char * s, size_t maxlen) * @return length limited string duplicate or NULL if fail * */ -static char * +char * strndup(const char * s, size_t n) { size_t len = strnlen(s, n); @@ -2019,6 +2022,7 @@ static int htp__evbuffer_add_iovec_(struct evbuffer * buf, struct evbuffer_iovec * vec, int n_vec) { int n; + int res; size_t to_alloc; char * bufptr; size_t to_copy; @@ -2029,7 +2033,15 @@ htp__evbuffer_add_iovec_(struct evbuffer * buf, struct evbuffer_iovec * vec, int to_alloc += vec[n].iov_len; } +#ifdef _MSC_VER + char *buffer; + buffer = htp__malloc_(to_alloc * sizeof(char)); + if (evhtp_unlikely(buffer == NULL)) { + return -1; + } +#else char buffer[to_alloc]; +#endif bufptr = buffer; to_copy = to_alloc; @@ -2038,7 +2050,8 @@ htp__evbuffer_add_iovec_(struct evbuffer * buf, struct evbuffer_iovec * vec, int { size_t copy = MIN(vec[n].iov_len, to_copy); - bufptr = mempcpy(bufptr, vec[n].iov_base, copy); + memcpy(bufptr, vec[n].iov_base, copy); + bufptr += copy; to_copy -= copy; if (evhtp_unlikely(to_copy == 0)) { @@ -2046,7 +2059,11 @@ htp__evbuffer_add_iovec_(struct evbuffer * buf, struct evbuffer_iovec * vec, int } } - return evbuffer_add(buf, buffer, to_alloc); + res = evbuffer_add(buf, buffer, to_alloc); +#ifdef _MSV_VER + htp__free_(buffer); +#endif + return res; } static int @@ -3324,7 +3341,7 @@ evhtp_header_find(evhtp_headers_t * headers, const char * key) void evhtp_headers_add_header(evhtp_headers_t * headers, evhtp_header_t * header) { - return evhtp_kvs_add_kv(headers, header); + evhtp_kvs_add_kv(headers, header); } evhtp_header_t * diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c53a116..3c3d0dd 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,11 +1,20 @@ +include(CheckIncludeFile) +check_include_file(getopt.h HAVE_GETOPT_H) +if (NOT HAVE_GETOPT_H) + include_directories(${CMAKE_SOURCE_DIR}/compat) + set(GETOPT_SRC + ${CMAKE_SOURCE_DIR}/compat/getopt.c + ${CMAKE_SOURCE_DIR}/compat/getopt_long.c) +endif() + add_custom_target(examples) -add_executable(test_extensive EXCLUDE_FROM_ALL test.c) +add_executable(test_extensive EXCLUDE_FROM_ALL test.c ${GETOPT_SRC}) add_executable(test_basic EXCLUDE_FROM_ALL test_basic.c) add_executable(test_vhost EXCLUDE_FROM_ALL test_vhost.c) add_executable(test_client EXCLUDE_FROM_ALL test_client.c) add_executable(test_query EXCLUDE_FROM_ALL test_query.c) -add_executable(test_perf EXCLUDE_FROM_ALL test_perf.c) +add_executable(test_perf EXCLUDE_FROM_ALL test_perf.c ${GETOPT_SRC}) add_executable(example_vhost EXCLUDE_FROM_ALL example_vhost.c) add_executable(example_pause EXCLUDE_FROM_ALL example_pause.c) add_executable(example_chunked EXCLUDE_FROM_ALL example_chunked.c) @@ -51,10 +60,10 @@ if(NOT EVHTP_DISABLE_SSL) configure_file(https/bin/generate.sh.in https/bin/generate.sh @ONLY) - add_executable(example_https_server EXCLUDE_FROM_ALL https/example_https_server.c) + add_executable(example_https_server EXCLUDE_FROM_ALL https/example_https_server.c ${GETOPT_SRC}) target_link_libraries(example_https_server evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS}) - add_executable(example_https_client EXCLUDE_FROM_ALL https/example_https_client.c) + add_executable(example_https_client EXCLUDE_FROM_ALL https/example_https_client.c ${GETOPT_SRC}) target_link_libraries(example_https_client evhtp ${LIBEVHTP_EXTERNAL_LIBS} ${SYS_LIBS}) add_dependencies(examples example_https_server example_https_client) diff --git a/examples/eutils.h b/examples/eutils.h index a683af8..e2d5f52 100644 --- a/examples/eutils.h +++ b/examples/eutils.h @@ -3,6 +3,10 @@ #include #include #include +#ifdef _WIN32 +#include +#endif +#include "evhtp.h" static void * mm__dup_(const void * src, size_t size) @@ -15,17 +19,19 @@ mm__dup_(const void * src, size_t size) #define mm__alloc_(type, ...) \ (type *)mm__dup_((type[]) {__VA_ARGS__ }, sizeof(type)) -#define bind__sock_port0_(HTP) ({ \ - struct sockaddr_in sin; \ - socklen_t len = sizeof(struct sockaddr); \ - uint16_t port = 0; \ - \ - evhtp_bind_socket(HTP, "127.0.0.1", 9999, 128); \ - \ - if (getsockname( \ - evconnlistener_get_fd(HTP->server), \ - (struct sockaddr *)&sin, &len) == 0) { \ - port = ntohs(sin.sin_port); \ - } \ - port; \ - }) +static inline uint16_t +bind__sock_port0_(struct evhtp *HTP) +{ + struct sockaddr_in sin; + socklen_t len = sizeof(struct sockaddr); + uint16_t port = 0; + + evhtp_bind_socket(HTP, "127.0.0.1", 9999, 128); + + if (getsockname( + evconnlistener_get_fd(HTP->server), + (struct sockaddr *)&sin, &len) == 0) { + port = ntohs(sin.sin_port); + } + return port; +} diff --git a/examples/example_basic.c b/examples/example_basic.c index 9948152..b0bf7c9 100644 --- a/examples/example_basic.c +++ b/examples/example_basic.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "./eutils.h" #include "internal.h" @@ -28,7 +27,10 @@ main(int argc, char ** argv) struct event_base * evbase; struct evhtp * htp; void * log; - +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); htp = evhtp_new(evbase, NULL); log = evhtp_log_new("$rhost $host '$ua' [$ts] '$meth $path HTTP/$proto' $status"); @@ -44,5 +46,9 @@ main(int argc, char ** argv) log_info("Basic server, run: curl http://127.0.0.1:%d/", bind__sock_port0_(htp)); event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif + return 0; } diff --git a/examples/example_chunked.c b/examples/example_chunked.c index cfab23d..33b5cb9 100644 --- a/examples/example_chunked.c +++ b/examples/example_chunked.c @@ -137,6 +137,10 @@ main(int argc, char ** argv) { evhtp_t * htp; struct event_base * evbase; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif if (argc < 2) { printf("Usage: %s \n", argv[0]); @@ -158,7 +162,9 @@ main(int argc, char ** argv) log_info("curl http://127.0.0.1:%d/", bind__sock_port0_(htp)); event_base_loop(evbase, 0); - +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } diff --git a/examples/example_locality.c b/examples/example_locality.c index 328aec4..e757b35 100644 --- a/examples/example_locality.c +++ b/examples/example_locality.c @@ -127,6 +127,10 @@ main(int argc, char ** argv) struct event_base * evbase; struct event * dummy_ev; evthr_pool_t * workers; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); dummy_ev = event_new(evbase, -1, @@ -142,6 +146,9 @@ main(int argc, char ** argv) evthr_pool_start(workers); event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } diff --git a/examples/example_pause.c b/examples/example_pause.c index 0cccac2..836e683 100644 --- a/examples/example_pause.c +++ b/examples/example_pause.c @@ -87,9 +87,14 @@ http_pause__callback_(evhtp_request_t * req, void * arg) { int main(int argc, char ** argv) { + int res; evhtp_t * htp; struct event_base * evbase; struct timeval timeo = { 10, 0 }; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); evhtp_alloc_assert(evbase); @@ -106,5 +111,9 @@ main(int argc, char ** argv) { log_info("response delayed for 10s: " "curl http://127.0.0.1:%d/", bind__sock_port0_(htp)); - return event_base_loop(evbase, 0); + res = event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif + return res; } diff --git a/examples/example_request_fini.c b/examples/example_request_fini.c index d4d6da6..2677dde 100644 --- a/examples/example_request_fini.c +++ b/examples/example_request_fini.c @@ -29,9 +29,14 @@ request__callback_(evhtp_request_t * req, void * arg) { int main(int argc, char ** argv) { + int res; struct event_base * evbase; evhtp_callback_t * req_callback; evhtp_t * htp; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); evhtp_alloc_assert(evbase); @@ -59,5 +64,9 @@ main(int argc, char ** argv) { GENCHAR(), GENCHAR(), GENCHAR()); - return event_base_loop(evbase, 0); + res = event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif + return res; } diff --git a/examples/example_vhost.c b/examples/example_vhost.c index 3b6881c..149c9c9 100644 --- a/examples/example_vhost.c +++ b/examples/example_vhost.c @@ -34,10 +34,15 @@ vhost_2__callback_(evhtp_request_t * req, void * arg) { int main(int argc, char ** argv) { + int res; struct event_base * evbase; evhtp_t * htp; evhtp_t * htp_vhost_1; evhtp_t * htp_vhost_2; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); evhtp_alloc_assert(evbase); @@ -112,5 +117,9 @@ main(int argc, char ** argv) { log_info("curl -H'Host: gmail.google.com' http://127.0.0.1:%d/vhost", port); } - return event_base_loop(evbase, 0); + res = event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif + return res; } /* main */ diff --git a/examples/https/example_https_client.c b/examples/https/example_https_client.c index ca66d5a..ce46611 100644 --- a/examples/https/example_https_client.c +++ b/examples/https/example_https_client.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include "internal.h" @@ -58,6 +57,10 @@ main(int argc, char ** argv) { int long_index = 0; int res; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif static struct option long_options[] = { { "cert", required_argument, 0, OPTARG_CERT }, { "key", required_argument, 0, OPTARG_KEY }, @@ -67,7 +70,7 @@ main(int argc, char ** argv) { { NULL, 0, 0, 0 } }; - while ((opt = getopt_long_only(argc, argv, "", long_options, &long_index)) != -1) { + while ((opt = getopt_long(argc, argv, "", long_options, &long_index)) != -1) { switch (opt) { case 'h': printf("Usage: %s\n" @@ -130,7 +133,7 @@ main(int argc, char ** argv) { /* create a new connection to the server */ conn = evhtp_connection_ssl_new(evbase, - addr ? : "127.0.0.1", + addr ? addr : "127.0.0.1", port, ctx); evhtp_assert(conn != NULL); @@ -160,6 +163,9 @@ main(int argc, char ** argv) { free(key); free(addr); } +#ifdef _WIN32 + WSACleanup(); +#endif return 0; #else diff --git a/examples/https/example_https_server.c b/examples/https/example_https_server.c index 3e020b2..4db634e 100644 --- a/examples/https/example_https_server.c +++ b/examples/https/example_https_server.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include "internal.h" @@ -128,7 +127,7 @@ parse__ssl_opts_(int argc, char ** argv) { { NULL, 0, 0, 0 } }; - while ((opt = getopt_long_only(argc, argv, "", long_options, &long_index)) != -1) { + while ((opt = getopt_long(argc, argv, "", long_options, &long_index)) != -1) { switch (opt) { case 'h': printf(help, argv[0]); @@ -240,6 +239,10 @@ main(int argc, char ** argv) { evhtp_t * htp; struct event_base * evbase; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); evhtp_alloc_assert(evbase); @@ -253,6 +256,9 @@ main(int argc, char ** argv) { log_info("curl https://127.0.0.1:4443/"); event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; #else log_error("Not compiled with SSL support, go away"); diff --git a/examples/reuse_thread_svr.c b/examples/reuse_thread_svr.c index 4adc2c3..5bc15ec 100644 --- a/examples/reuse_thread_svr.c +++ b/examples/reuse_thread_svr.c @@ -45,6 +45,7 @@ on_request_user_register(evhtp_request_t * req, void * _) #define upm_eoff uri->path->matched_eoff #define upm_soff uri->path->matched_soff +#ifndef EVHTP_DISABLE_REGEX static void on_request_user_index(evhtp_request_t * req, void * _) { @@ -58,6 +59,7 @@ on_request_user_index(evhtp_request_t * req, void * _) return evhtp_send_reply(req, EVHTP_RES_400); } +#endif static void dummy_eventcb_(int sock, short which, void * args) @@ -106,7 +108,9 @@ htp_worker_init_(evthr_t * thread, void * args) return; } +#ifndef EVHTP_DISABLE_REGEX evhtp_set_regex_cb(htp, "^/user/([^/]+)", on_request_user_index, NULL); +#endif evhtp_set_cb(htp, "/user", on_request_user_register, NULL); evhtp_set_cb(htp, "/", on_request_index, NULL); @@ -142,6 +146,10 @@ main(int argc, char ** argv) struct event_base * evbase; struct event * dummy_ev; evthr_pool_t * workers; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); dummy_ev = event_new(evbase, -1, EV_READ | EV_PERSIST, @@ -156,6 +164,9 @@ main(int argc, char ** argv) evthr_pool_start(workers); event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } diff --git a/examples/test.c b/examples/test.c index d705ff0..c6cd27c 100644 --- a/examples/test.c +++ b/examples/test.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -7,6 +6,7 @@ #include #include #include +#include #include "internal.h" #include "evhtp/evhtp.h" @@ -542,6 +542,10 @@ main(int argc, char ** argv) { evhtp_callback_t * cb_11 = NULL; evhtp_callback_t * cb_12 = NULL; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif if (parse_args(argc, argv) < 0) { exit(1); } @@ -676,6 +680,9 @@ main(int argc, char ** argv) { evhtp_safe_free(htp, evhtp_free); evhtp_safe_free(evbase, event_base_free); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } /* main */ diff --git a/examples/test_basic.c b/examples/test_basic.c index 2a5e3ac..665ab1f 100644 --- a/examples/test_basic.c +++ b/examples/test_basic.c @@ -36,8 +36,14 @@ issue161cb(evhtp_request_t * req, void * a) { int main(int argc, char ** argv) { - evbase_t * evbase = event_base_new(); - evhtp_t * htp = evhtp_new(evbase, NULL); + evbase_t * evbase; + evhtp_t * htp; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif + evbase = event_base_new(); + htp = evhtp_new(evbase, NULL); evhtp_set_cb(htp, "/simple/", testcb, "simple"); evhtp_set_cb(htp, "/1/ping", testcb, "one"); @@ -53,6 +59,9 @@ main(int argc, char ** argv) { evhtp_unbind_socket(htp); evhtp_safe_free(htp, evhtp_free); evhtp_safe_free(evbase, event_base_free); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } diff --git a/examples/test_client.c b/examples/test_client.c index aa5ac4c..b67d491 100644 --- a/examples/test_client.c +++ b/examples/test_client.c @@ -50,6 +50,10 @@ main(int argc, char ** argv) evbase_t * evbase; evhtp_connection_t * conn; evhtp_request_t * request; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); conn = evhtp_connection_new(evbase, "104.27.150.225", 80); @@ -72,6 +76,9 @@ main(int argc, char ** argv) event_base_loop(evbase, 0); evhtp_safe_free(evbase, event_base_free); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } diff --git a/examples/test_perf.c b/examples/test_perf.c index 47232ab..4d51763 100644 --- a/examples/test_perf.c +++ b/examples/test_perf.c @@ -1,11 +1,11 @@ #include -#include #include #include #include #include #include #include +#include #include "internal.h" #include "evhtp/evhtp.h" @@ -81,8 +81,15 @@ main(int argc, char ** argv) { struct event_base * evbase; evhtp_t * htp; +#ifdef _MSC_VER + char * payload; +#else char payload[payload_sz]; - +#endif +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); evhtp_alloc_assert(evbase); @@ -106,10 +113,16 @@ main(int argc, char ** argv) evhtp_enable_flag(htp, EVHTP_FLAG_ENABLE_REUSEPORT); } +#ifdef _MSC_VER + payload = (char *)malloc(payload_sz * sizeof(char)); +#endif memset(payload, 0x42, payload_sz); evhtp_assert(evhtp_set_cb(htp, "/data", response_cb, payload)); +#ifdef _MSC_VER + free(payload); +#endif #ifndef EVHTP_DISABLE_EVTHR if (num_threads > 0) { @@ -119,6 +132,9 @@ main(int argc, char ** argv) evhtp_errno_assert(evhtp_bind_socket(htp, baddr, bport, backlog) >= 0); event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif } diff --git a/examples/test_proxy.c b/examples/test_proxy.c index daba6e5..41d6d72 100644 --- a/examples/test_proxy.c +++ b/examples/test_proxy.c @@ -98,10 +98,15 @@ init_thread_cb(evhtp_t * htp, evthr_t * thr, void * arg) { int main(int argc, char ** argv) { - struct event *ev_sigterm; - evbase_t * evbase = event_base_new(); - evhtp_t * evhtp = evhtp_new(evbase, NULL); - + struct event * ev_sigterm; + evbase_t * evbase; + evhtp_t * evhtp; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif + evbase = event_base_new(); + evhtp = evhtp_new(evbase, NULL); evhtp_set_gencb(evhtp, frontend_cb, NULL); #if 0 @@ -124,6 +129,10 @@ main(int argc, char ** argv) { event_base_loop(evbase, 0); printf("Clean exit\n"); +#ifdef _WIN32 + WSACleanup(); +#endif + return 0; } diff --git a/examples/test_query.c b/examples/test_query.c index 3824a29..40d6dc4 100644 --- a/examples/test_query.c +++ b/examples/test_query.c @@ -225,6 +225,10 @@ int main(int argc, char ** argv) { int i; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif #define PARSE_QUERY_TEST(tests, flags) do { \ printf("- " # tests "\n"); \ @@ -246,6 +250,9 @@ main(int argc, char ** argv) unsigned char *ptr = unescaped_string; evhtp_unescape_string(&ptr, escaped_string, strlen(escaped_string)); printf("%s\n", ptr); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } diff --git a/examples/test_vhost.c b/examples/test_vhost.c index 1af3592..2f68c12 100644 --- a/examples/test_vhost.c +++ b/examples/test_vhost.c @@ -13,10 +13,18 @@ testcb(evhtp_request_t * req, void * a) { int main(int argc, char ** argv) { - evbase_t * evbase = event_base_new(); - evhtp_t * evhtp = evhtp_new(evbase, NULL); - evhtp_t * v1 = evhtp_new(evbase, NULL); - evhtp_t * v2 = evhtp_new(evbase, NULL); + evbase_t * evbase; + evhtp_t * evhtp; + evhtp_t * v1; + evhtp_t * v2; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif + evbase = event_base_new(); + evhtp = evhtp_new(evbase, NULL); + v1 = evhtp_new(evbase, NULL); + v2 = evhtp_new(evbase, NULL); evhtp_set_cb(v1, "/host1", NULL, "host1.com"); evhtp_set_cb(v2, "/localhost", testcb, "localhost"); @@ -49,6 +57,9 @@ main(int argc, char ** argv) { evhtp_safe_free(v1, evhtp_free); evhtp_safe_free(evhtp, evhtp_free); evhtp_safe_free(evbase, event_base_free); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } diff --git a/examples/thread_design.c b/examples/thread_design.c index a337503..62a0c02 100644 --- a/examples/thread_design.c +++ b/examples/thread_design.c @@ -269,6 +269,10 @@ main(int argc, char ** argv) { evbase_t * evbase; evhtp_t * evhtp; struct app_parent * app_p; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); evhtp = evhtp_new(evbase, NULL); @@ -284,6 +288,9 @@ main(int argc, char ** argv) { evhtp_bind_socket(evhtp, "127.0.0.1", 9090, 1024); event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } diff --git a/examples/v6_v4.c b/examples/v6_v4.c index 367c3a7..b166bb6 100644 --- a/examples/v6_v4.c +++ b/examples/v6_v4.c @@ -25,6 +25,10 @@ main(int argc, char ** argv) { evhtp_t * htp_v6; evhtp_t * htp_v4; int rc; +#ifdef _WIN32 + WSADATA wsaData; + (void)WSAStartup(0x0202, &wsaData); +#endif evbase = event_base_new(); evhtp_alloc_assert(evbase); @@ -45,6 +49,9 @@ main(int argc, char ** argv) { evhtp_errno_assert(rc != -1); event_base_loop(evbase, 0); +#ifdef _WIN32 + WSACleanup(); +#endif return 0; } /* main */ \ No newline at end of file diff --git a/include/evhtp/config.h.in b/include/evhtp/config.h.in index e5e434f..1766aff 100644 --- a/include/evhtp/config.h.in +++ b/include/evhtp/config.h.in @@ -8,6 +8,8 @@ extern "C" { #ifndef EVHTP_EXPORT # if (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER || defined __clang__ # define EVHTP_EXPORT __attribute__ ((visibility("default"))) +# elif defined(_MSC_VER) +# define EVHTP_EXPORT __declspec(dllexport) # else # define EVHTP_EXPORT # endif diff --git a/include/evhtp/evhtp.h b/include/evhtp/evhtp.h index 9bcee44..afa23ad 100644 --- a/include/evhtp/evhtp.h +++ b/include/evhtp/evhtp.h @@ -607,8 +607,8 @@ EVHTP_EXPORT int evhtp_ssl_init(evhtp_t * htp, evhtp_ssl_cfg_t * ssl_cfg); * * @param htp */ -EVHTP_EXPORT void evhtp_disable_100_continue(evhtp_t * htp) -DEPRECATED("evhtp_disable_100 will soon be deprecated, use htp->flags instead"); +DEPRECATED("evhtp_disable_100 will soon be deprecated, use htp->flags instead") +EVHTP_EXPORT void evhtp_disable_100_continue(evhtp_t * htp); /** * @brief creates a lock around callbacks and hooks, allowing for threaded @@ -858,8 +858,8 @@ EVHTP_EXPORT int evhtp_bind_sockaddr(evhtp_t * htp, struct sockaddr *, * * @return */ -EVHTP_EXPORT int evhtp_use_threads(evhtp_t *, evhtp_thread_init_cb, int nthreads, void *) -DEPRECATED("will take on the syntax of evhtp_use_threads_wexit"); +DEPRECATED("will take on the syntax of evhtp_use_threads_wexit") +EVHTP_EXPORT int evhtp_use_threads(evhtp_t *, evhtp_thread_init_cb, int nthreads, void *); /** * @brief Temporary function which will be renamed evhtp_use_threads in the @@ -1125,7 +1125,7 @@ EVHTP_EXPORT int evhtp_kvs_for_each(evhtp_kvs_t * kvs, evhtp_kvs_iterator cb, vo * * @return evhtp_query_t * on success, NULL on error */ -EVHTP_EXPORT evhtp_query_t * evhtp_parse_query_wflags(const char * query, size_t len, int flags); +EVHTP_EXPORT evhtp_query_t * evhtp_parse_query_wflags(const char * query, const size_t len, const int flags); /** * @brief Parses the query portion of the uri into a set of key/values in a diff --git a/include/evhtp/thread.h b/include/evhtp/thread.h index 7479aa8..e4b49d6 100644 --- a/include/evhtp/thread.h +++ b/include/evhtp/thread.h @@ -35,8 +35,8 @@ typedef void (* evthr_cb)(evthr_t * thr, void * cmd_arg, void * shared); typedef void (* evthr_init_cb)(evthr_t * thr, void * shared); typedef void (* evthr_exit_cb)(evthr_t * thr, void * shared); -EVHTP_EXPORT evthr_t * evthr_new(evthr_init_cb, void *) - DEPRECATED("will take on the syntax of evthr_wexit_new"); +DEPRECATED("will take on the syntax of evthr_wexit_new") +EVHTP_EXPORT evthr_t * evthr_new(evthr_init_cb, void *); EVHTP_EXPORT evbase_t * evthr_get_base(evthr_t * thr); EVHTP_EXPORT void evthr_set_aux(evthr_t * thr, void * aux); @@ -46,8 +46,8 @@ EVHTP_EXPORT evthr_res evthr_stop(evthr_t * evthr); EVHTP_EXPORT evthr_res evthr_defer(evthr_t * evthr, evthr_cb cb, void *); EVHTP_EXPORT void evthr_free(evthr_t * evthr); -EVHTP_EXPORT evthr_pool_t * evthr_pool_new(int nthreads, evthr_init_cb, void *) - DEPRECATED("will take on the syntax of evthr_pool_wexit_new"); +DEPRECATED("will take on the syntax of evthr_pool_wexit_new") +EVHTP_EXPORT evthr_pool_t * evthr_pool_new(int nthreads, evthr_init_cb, void *); EVHTP_EXPORT int evthr_pool_start(evthr_pool_t * pool); EVHTP_EXPORT evthr_res evthr_pool_stop(evthr_pool_t * pool); diff --git a/include/internal.h b/include/internal.h index 194823c..3a277df 100644 --- a/include/internal.h +++ b/include/internal.h @@ -33,6 +33,7 @@ extern "C" { #define clean_errno() \ (errno == 0 ? "None" : strerror(errno)) +#ifndef _MSC_VER #define __log_debug_color(X) "[\x1b[1;36m" X "\x1b[0;39m]" #define __log_error_color(X) "[\x1b[1;31m" X "\x1b[0;39m]" #define __log_warn_color(X) "[\x1b[1;33m" X "\x1b[0;39m]" @@ -40,7 +41,15 @@ extern "C" { #define __log_func_color(X) "\x1b[33m" X "\x1b[39m" #define __log_args_color(X) "\x1b[94m" X "\x1b[39m" #define __log_errno_color(X) "\x1b[35m" X "\x1b[39m" - +#else +#define __log_debug_color(X) X +#define __log_error_color(X) X +#define __log_warn_color(X) X +#define __log_info_color(X) X +#define __log_func_color(X) X +#define __log_args_color(X) X +#define __log_errno_color(X) X +#endif #if !defined(EVHTP_DEBUG) /* compile with all debug messages removed */ @@ -127,8 +136,21 @@ extern "C" { #define evhtp_errno_assert(x) #endif +#ifdef _MSC_VER +#define strcasecmp stricmp +#define strncasecmp strnicmp +/* On MSVC, ssize_t is SSIZE_T */ +#include +typedef SSIZE_T ssize_t; +#endif +#ifdef NO_STRNLEN +size_t strnlen(const char * s, size_t maxlen) +#endif +#ifdef NO_STRNDUP +char * strndup(const char * s, size_t n); +#endif #ifdef __cplusplus } diff --git a/log.c b/log.c index 0455283..e241164 100644 --- a/log.c +++ b/log.c @@ -4,10 +4,15 @@ #include #include #include +#ifdef _WIN32 +#include +#include +#else #include #include #include - +#endif +#include "internal.h" #include "evhtp/evhtp.h" #include "evhtp/log.h" @@ -232,6 +237,7 @@ evhtp_log_request_f(void * format_p, evhtp_request_t * request, FILE * fp) struct tm * tm; struct sockaddr_in * sin; char tmp[64]; + time_t sec; TAILQ_FOREACH(op, format, next) { const char * logstr = NULL; @@ -255,8 +261,8 @@ evhtp_log_request_f(void * format_p, evhtp_request_t * request, FILE * fp) break; case HTP_LOG_OP_TIMESTAMP: event_base_gettimeofday_cached(request->conn->evbase, &tv); - - tm = localtime(&tv.tv_sec); + sec = tv.tv_sec; + tm = localtime(&sec); strftime(tmp, sizeof(tmp), "%d/%b/%Y:%X %z", tm); logstr = tmp; @@ -278,7 +284,7 @@ evhtp_log_request_f(void * format_p, evhtp_request_t * request, FILE * fp) continue; case HTP_LOG_OP_HOST: logstr = - request->htp->server_name ? : evhtp_header_find(request->headers_in, "host"); + request->htp->server_name ? request->htp->server_name : evhtp_header_find(request->headers_in, "host"); break; case HTP_LOG_OP_PROTO: @@ -293,7 +299,7 @@ evhtp_log_request_f(void * format_p, evhtp_request_t * request, FILE * fp) break; } /* switch */ - fputs(logstr ? : "-", fp); + fputs(logstr ? logstr : "-", fp); } fputc('\n', fp);