diff --git a/README.rst b/README.rst index 6faee5b5..d8bfb699 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ An HPACK encoder and decoder are available as a public API. An experimental high level C++ library is also available. -We have Python bindings of this libary, but we do not have full +We have Python bindings of this library, but we do not have full code coverage yet. Development Status @@ -581,7 +581,7 @@ disabled in the frontend and incoming HTTP/1.1 connections can be upgraded to HTTP/2 through HTTP Upgrade. The ``--http2-bridge``, ``--client`` and ``--client-proxy`` modes use -SSL/TLS in the backend connection by deafult. To disable SSL/TLS, use +SSL/TLS in the backend connection by default. To disable SSL/TLS, use the ``--backend-no-tls`` option. ``nghttpx`` supports a configuration file. See the ``--conf`` option and @@ -876,7 +876,7 @@ max_deflate_size The maximum header table size the encoder uses. This can be smaller than ``max_size``. In this case, the encoder only uses up to first ``max_deflate_size`` buffer. Since the header table size is still - ``max_size``, the encoder has to keep track of entries ouside the + ``max_size``, the encoder has to keep track of entries outside the ``max_deflate_size`` but inside the ``max_size`` and make sure that they are no longer referenced. diff --git a/configure.ac b/configure.ac index 5d349cb3..ce1d551f 100644 --- a/configure.ac +++ b/configure.ac @@ -25,13 +25,30 @@ dnl Do not change user variables! dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html AC_PREREQ(2.61) -AC_INIT([nghttp2], [0.7.15-DEV], [t-tujikawa@users.sourceforge.net]) +AC_INIT([nghttp2], [0.7.15], [t-tujikawa@users.sourceforge.net]) +AC_USE_SYSTEM_EXTENSIONS + LT_PREREQ([2.2.6]) LT_INIT() + +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +AM_INIT_AUTOMAKE([subdir-objects]) +# comment out for now since this requires automake 1.13 or higher and +# travis has older one. +# AM_EXTRA_RECURSIVE_TARGETS([it]) + +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADERS([config.h]) + dnl See versioning rule: dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html AC_SUBST(LT_CURRENT, 13) -AC_SUBST(LT_REVISION, 3) +AC_SUBST(LT_REVISION, 4) AC_SUBST(LT_AGE, 8) major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"` @@ -42,21 +59,6 @@ PACKAGE_VERSION_NUM=`printf "0x%02x%02x%02x" "$major" "$minor" "$patch"` AC_SUBST(PACKAGE_VERSION_NUM) -AC_CANONICAL_BUILD -AC_CANONICAL_HOST -AC_CANONICAL_TARGET - -AC_CONFIG_MACRO_DIR([m4]) - -AM_INIT_AUTOMAKE([subdir-objects]) -# comment out for now since this requires automake 1.13 or higher and -# travis has older one. -# AM_EXTRA_RECURSIVE_TARGETS([it]) - -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -AC_CONFIG_HEADERS([config.h]) - dnl Checks for command-line options AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], @@ -129,10 +131,12 @@ AC_ARG_VAR([CYTHON], [the Cython executable]) dnl Checks for programs AC_PROG_CC AC_PROG_CXX +AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET -AM_PROG_CC_C_O +AC_PROG_MKDIR_P + PKG_PROG_PKG_CONFIG([0.20]) if [test "x$request_python_bindings" != "xno"]; then @@ -358,9 +362,23 @@ if test "x${request_jemalloc}" != "xno"; then AC_SEARCH_LIBS([malloc_stats_print], [jemalloc], [have_jemalloc=yes], [], [$PTHREAD_LDFLAGS]) LIBS=$LIBS_OLD + + if test "x${have_jemalloc}" = "xyes"; then + jemalloc_libs=${ac_cv_search_malloc_stats_print} + else + # On Darwin, malloc_stats_print is je_malloc_stats_print + AC_SEARCH_LIBS([je_malloc_stats_print], [jemalloc], [have_jemalloc=yes], [], + [$PTHREAD_LDFLAGS]) + LIBS=$LIBS_OLD + + if test "x${have_jemalloc}" = "xyes"; then + jemalloc_libs=${ac_cv_search_je_malloc_stats_print} + fi + fi + if test "x${have_jemalloc}" = "xyes" && - test "x${ac_cv_search_malloc_stats_print}" != "xnone required"; then - JEMALLOC_LIBS=${ac_cv_search_malloc_stats_print} + test "x${jemalloc_libs}" != "xnone required"; then + JEMALLOC_LIBS=${jemalloc_libs} AC_SUBST([JEMALLOC_LIBS]) fi fi @@ -498,12 +516,19 @@ AM_CONDITIONAL([ENABLE_FAILMALLOC], [ test "x${enable_failmalloc}" = "xyes" ]) AC_HEADER_ASSERT AC_CHECK_HEADERS([ \ arpa/inet.h \ + fcntl.h \ + inttypes.h \ + limits.h \ + netdb.h \ netinet/in.h \ pwd.h \ stddef.h \ stdint.h \ stdlib.h \ string.h \ + sys/socket.h \ + sys/time.h \ + syslog.h \ time.h \ unistd.h \ ]) @@ -515,8 +540,16 @@ AC_TYPE_UINT8_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T +AC_TYPE_INT8_T +AC_TYPE_INT16_T +AC_TYPE_INT32_T +AC_TYPE_INT64_T +AC_TYPE_OFF_T +AC_TYPE_PID_T +AC_TYPE_UID_T AC_CHECK_TYPES([ptrdiff_t]) AC_C_BIGENDIAN +AC_C_INLINE AC_SYS_LARGEFILE AC_CHECK_MEMBER([struct tm.tm_gmtoff], [have_struct_tm_tm_gmtoff=yes], @@ -535,12 +568,34 @@ AC_CHECK_SIZEOF([int *]) if test "x$cross_compiling" != "xyes"; then AC_FUNC_MALLOC fi + +AC_FUNC_CHOWN +AC_FUNC_ERROR_AT_LINE +AC_FUNC_FORK +# Don't check realloc, since LeakSanitizer detects memory leak during check +# AC_FUNC_REALLOC +AC_FUNC_STRERROR_R +AC_FUNC_STRNLEN + AC_CHECK_FUNCS([ \ _Exit \ accept4 \ + dup2 \ + getcwd \ getpwnam \ + localtime_r \ + memchr \ memmove \ memset \ + socket \ + sqrt \ + strchr \ + strdup \ + strerror \ + strndup \ + strstr \ + strtol \ + strtoul \ timegm \ ]) diff --git a/doc/bash_completion/nghttpd b/doc/bash_completion/nghttpd index 2115c410..6de3d267 100644 --- a/doc/bash_completion/nghttpd +++ b/doc/bash_completion/nghttpd @@ -8,7 +8,7 @@ _nghttpd() _get_comp_words_by_ref cur prev case $cur in -*) - COMPREPLY=( $( compgen -W '--error-gzip --push --header-table-size --trailer --htdocs --address --padding --verbose --version --help --hexdump --dh-param-file --daemon --verify-client --workers --no-tls --color --early-response --max-concurrent-streams ' -- "$cur" ) ) + COMPREPLY=( $( compgen -W '--error-gzip --push --header-table-size --trailer --htdocs --address --padding --verbose --version --help --hexdump --dh-param-file --daemon --verify-client --echo-upload --workers --no-tls --color --early-response --max-concurrent-streams ' -- "$cur" ) ) ;; *) _filedir diff --git a/doc/h2load.1 b/doc/h2load.1 index 8a59a11a..2a86f58a 100644 --- a/doc/h2load.1 +++ b/doc/h2load.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "H2LOAD" "1" "May 08, 2015" "0.7.14" "nghttp2" +.TH "H2LOAD" "1" "May 15, 2015" "0.7.15" "nghttp2" .SH NAME h2load \- HTTP/2 benchmarking tool . @@ -71,7 +71,7 @@ Default: \fB1\fP .INDENT 0.0 .TP .B \-i, \-\-input\-file= -Path of a file with multiple URIs are seperated by EOLs. +Path of a file with multiple URIs are separated by EOLs. This option will disable URIs getting from command\-line. If \(aq\-\(aq is given as , URIs will be read from stdin. URIs are used in this order for each client. All URIs diff --git a/doc/h2load.1.rst b/doc/h2load.1.rst index 4dae19e7..2bc0f6a8 100644 --- a/doc/h2load.1.rst +++ b/doc/h2load.1.rst @@ -1,4 +1,6 @@ +.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY. + .. program:: h2load h2load(1) @@ -46,7 +48,7 @@ OPTIONS .. option:: -i, --input-file= - Path of a file with multiple URIs are seperated by EOLs. + Path of a file with multiple URIs are separated by EOLs. This option will disable URIs getting from command-line. If '-' is given as , URIs will be read from stdin. URIs are used in this order for each client. All URIs diff --git a/doc/mkapiref.py b/doc/mkapiref.py index 16382d49..23ab9cc5 100755 --- a/doc/mkapiref.py +++ b/doc/mkapiref.py @@ -222,6 +222,7 @@ def process_function(domain, infile): func_proto = ''.join(func_proto) func_proto = re.sub(r';\n$', '', func_proto) func_proto = re.sub(r'\s+', ' ', func_proto) + func_proto = re.sub(r'NGHTTP2_EXTERN ', '', func_proto) return FunctionDoc(func_proto, content, domain) def read_content(infile): diff --git a/doc/nghttp.1 b/doc/nghttp.1 index 51596f6a..4be668e6 100644 --- a/doc/nghttp.1 +++ b/doc/nghttp.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "NGHTTP" "1" "May 08, 2015" "0.7.14" "nghttp2" +.TH "NGHTTP" "1" "May 15, 2015" "0.7.15" "nghttp2" .SH NAME nghttp \- HTTP/2 experimental client . diff --git a/doc/nghttp.1.rst b/doc/nghttp.1.rst index 88cb8afd..7f2449b2 100644 --- a/doc/nghttp.1.rst +++ b/doc/nghttp.1.rst @@ -1,4 +1,6 @@ +.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY. + .. program:: nghttp nghttp(1) diff --git a/doc/nghttpd.1 b/doc/nghttpd.1 index 0c98d0d3..cb057ad4 100644 --- a/doc/nghttpd.1 +++ b/doc/nghttpd.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "NGHTTPD" "1" "May 08, 2015" "0.7.14" "nghttp2" +.TH "NGHTTPD" "1" "May 15, 2015" "0.7.15" "nghttp2" .SH NAME nghttpd \- HTTP/2 experimental server . @@ -167,6 +167,11 @@ are used. .UNINDENT .INDENT 0.0 .TP +.B \-\-echo\-upload +Send back uploaded content if method is POST or PUT. +.UNINDENT +.INDENT 0.0 +.TP .B \-\-version Display version information and exit. .UNINDENT diff --git a/doc/nghttpd.1.rst b/doc/nghttpd.1.rst index abb9c45a..e9ac30df 100644 --- a/doc/nghttpd.1.rst +++ b/doc/nghttpd.1.rst @@ -1,4 +1,6 @@ +.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY. + .. program:: nghttpd nghttpd(1) @@ -126,6 +128,10 @@ OPTIONS hex+ASCII display). If SSL/TLS is used, decrypted data are used. +.. option:: --echo-upload + + Send back uploaded content if method is POST or PUT. + .. option:: --version Display version information and exit. diff --git a/doc/nghttpx.1 b/doc/nghttpx.1 index 6399cd05..0fac2a86 100644 --- a/doc/nghttpx.1 +++ b/doc/nghttpx.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "NGHTTPX" "1" "May 08, 2015" "0.7.14" "nghttp2" +.TH "NGHTTPX" "1" "May 15, 2015" "0.7.15" "nghttp2" .SH NAME nghttpx \- HTTP/2 experimental proxy . @@ -812,7 +812,7 @@ argument in the configuration file. Specify \fByes\fP as an argument ignored. .sp To specify private key and certificate file which are given as -positional arguments in commnad\-line, use \fBprivate\-key\-file\fP and +positional arguments in command\-line, use \fBprivate\-key\-file\fP and \fBcertificate\-file\fP\&. .sp \fI\%\-\-conf\fP option cannot be used in the configuration file and diff --git a/doc/nghttpx.1.rst b/doc/nghttpx.1.rst index c4571d75..efacbb44 100644 --- a/doc/nghttpx.1.rst +++ b/doc/nghttpx.1.rst @@ -1,4 +1,6 @@ +.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY. + .. program:: nghttpx nghttpx(1) @@ -727,7 +729,7 @@ FILES ignored. To specify private key and certificate file which are given as - positional arguments in commnad-line, use ``private-key-file`` and + positional arguments in command-line, use ``private-key-file`` and ``certificate-file``. :option:`--conf` option cannot be used in the configuration file and diff --git a/doc/nghttpx.h2r b/doc/nghttpx.h2r index 9f3cf66b..2d2f90d4 100644 --- a/doc/nghttpx.h2r +++ b/doc/nghttpx.h2r @@ -19,7 +19,7 @@ FILES ignored. To specify private key and certificate file which are given as - positional arguments in commnad-line, use ``private-key-file`` and + positional arguments in command-line, use ``private-key-file`` and ``certificate-file``. :option:`--conf` option cannot be used in the configuration file and diff --git a/doc/sources/h2load-howto.rst b/doc/sources/h2load-howto.rst index 9660e07d..7c07194f 100644 --- a/doc/sources/h2load-howto.rst +++ b/doc/sources/h2load-howto.rst @@ -87,5 +87,5 @@ If multiple URIs are specified, they are used in round robin manner. .. note:: - Please note that h2load uses sheme, host and port in the first URI + Please note that h2load uses scheme, host and port in the first URI and ignores those parts in the rest of the URIs. diff --git a/doc/sources/libnghttp2_asio.rst b/doc/sources/libnghttp2_asio.rst index 85d2e01e..76999f9f 100644 --- a/doc/sources/libnghttp2_asio.rst +++ b/doc/sources/libnghttp2_asio.rst @@ -80,7 +80,7 @@ status code, in the above example, which is 200. The second argument, which is omitted in the above example, is additional header fields to send. -``nghttp2::asio_http2::server::response::end`` sends responde body. +``nghttp2::asio_http2::server::response::end`` sends response body. In the above example, we send string "hello, world". The life time of req and res object ends after the callback set by @@ -277,7 +277,7 @@ response header fields and response body to the console screen: ``boost::asio::io_service`` object and remote server address. When connection is made, the callback function passed to ``nghttp2::asio_http2::client::on_connect`` is invoked with connected -address as its paramter. After this callback call, use +address as its parameter. After this callback call, use ``nghttp2::asio_http2::session::submit`` to send request to the server. You can submit multiple requests at once without waiting for the completion of previous request. diff --git a/doc/sources/nghttpx-howto.rst b/doc/sources/nghttpx-howto.rst index 541e4a45..1f7d87e2 100644 --- a/doc/sources/nghttpx-howto.rst +++ b/doc/sources/nghttpx-howto.rst @@ -21,7 +21,7 @@ SSL/TLS, the frontend also supports SPDY protocol. By default, this mode's frontend connection is encrypted using SSL/TLS. So server's private key and certificate must be supplied to the command line (or through configuration file). In this case, the -fontend protocol selection will is done via ALPN or NPN. +frontend protocol selection will is done via ALPN or NPN. With ``--frontend-no-tls`` option, user can turn off SSL/TLS in frontend connection. In this case, SPDY protocol is not available @@ -243,7 +243,7 @@ Read/write rate limit --------------------- nghttpx supports transfer rate limiting on frontend connections. You -can do rate limit per frontend connection for reading and writeing +can do rate limit per frontend connection for reading and writing individually. To perform rate limit for reading, use ``--read-rate`` and diff --git a/doc/sources/python-apiref.rst b/doc/sources/python-apiref.rst index fd9e1111..d9d8494c 100644 --- a/doc/sources/python-apiref.rst +++ b/doc/sources/python-apiref.rst @@ -267,7 +267,7 @@ HTTP/2 servers (byte string could be ``None``), :py:data:`DATA_EOF` must be returned as flag. If there is no data available right now, but additional data are anticipated, return tuple (``None``, - :py:data:`DATA_DEFERRD`). When data arrived, call + :py:data:`DATA_DEFERRED`). When data arrived, call :py:meth:`resume()` and restart response body transmission. Only the body generator can pause response body generation; diff --git a/doc/sources/tutorial-client.rst b/doc/sources/tutorial-client.rst index ceaa14c8..6ce1238b 100644 --- a/doc/sources/tutorial-client.rst +++ b/doc/sources/tutorial-client.rst @@ -65,11 +65,11 @@ its stream specific data in ``http2_stream_data`` structure and the defined as follows:: typedef struct { - /* The NULL-terminated URI string to retreive. */ + /* The NULL-terminated URI string to retrieve. */ const char *uri; /* Parsed result of the |uri| */ struct http_parser_url *u; - /* The authroity portion of the |uri|, not NULL-terminated */ + /* The authority portion of the |uri|, not NULL-terminated */ char *authority; /* The path portion of the |uri|, including query, not NULL-terminated */ @@ -203,7 +203,7 @@ automatically sent by nghttp2 library. We send SETTINGS frame in } Here we specify SETTINGS_MAX_CONCURRENT_STREAMS to 100, which is -really not needed for this tiny example progoram, but we are +really not needed for this tiny example program, but we are demonstrating the use of SETTINGS frame. To queue the SETTINGS frame for the transmission, we use `nghttp2_submit_settings()`. Note that `nghttp2_submit_settings()` function only queues the frame and not @@ -387,7 +387,7 @@ After all name/value pairs are emitted for a frame, } In this tutorial, we are just interested in the HTTP response -HEADERS. We check te frame type and its category (it should be +HEADERS. We check the frame type and its category (it should be :macro:`NGHTTP2_HCAT_RESPONSE` for HTTP response HEADERS). Also check its stream ID. @@ -406,7 +406,7 @@ of data is received from the remote peer:: } In our case, a chunk of data is response body. After checking stream -ID, we just write the recieved data to the stdout. Note that the +ID, we just write the received data to the stdout. Note that the output in the terminal may be corrupted if the response body contains some binary data. diff --git a/doc/sources/tutorial-hpack.rst b/doc/sources/tutorial-hpack.rst index 3bfc834d..0b4d59f1 100644 --- a/doc/sources/tutorial-hpack.rst +++ b/doc/sources/tutorial-hpack.rst @@ -51,7 +51,7 @@ bound of encoded result, use `nghttp2_hd_deflate_bound()` function:: size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater, const nghttp2_nv *nva, size_t nvlen); -Pass this function with the same paramters *deflater*, *nva* and +Pass this function with the same parameters *deflater*, *nva* and *nvlen* which will be passed to `nghttp2_hd_deflate_hd()`. The subsequent call of `nghttp2_hd_deflate_hd()` will use current diff --git a/examples/asio-sv2.cc b/examples/asio-sv2.cc index 6cc2d5c0..8d2580ed 100644 --- a/examples/asio-sv2.cc +++ b/examples/asio-sv2.cc @@ -35,8 +35,12 @@ // #include #include +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H +#ifdef HAVE_FCNTL_H #include +#endif // HAVE_FCNTL_H #include #include diff --git a/examples/client.c b/examples/client.c index b202df18..4b4deeeb 100644 --- a/examples/client.c +++ b/examples/client.c @@ -28,16 +28,26 @@ */ #ifdef HAVE_CONFIG_H #include -#endif /* !HAVE_CONFIG_H */ +#endif /* HAVE_CONFIG_H */ -#include +#include #include +#ifdef HAVE_UNISTD_H #include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_FCNTL_H #include +#endif /* HAVE_FCNTL_H */ #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif /* HAVE_SYS_SOCKET_H */ +#ifdef HAVE_NETDB_H #include +#endif /* HAVE_NETDB_H */ +#ifdef HAVE_NETINET_IN_H #include +#endif /* HAVE_NETINET_IN_H */ #include #include #include diff --git a/examples/libevent-client.c b/examples/libevent-client.c index b3e86fda..17ed94be 100644 --- a/examples/libevent-client.c +++ b/examples/libevent-client.c @@ -24,12 +24,18 @@ */ #ifdef HAVE_CONFIG_H #include -#endif /* !HAVE_CONFIG_H */ +#endif /* HAVE_CONFIG_H */ #include +#ifdef HAVE_UNISTD_H #include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_SYS_SOCKET_H #include +#endif /* HAVE_SYS_SOCKET_H */ +#ifdef HAVE_NETINET_IN_H #include +#endif /* HAVE_NETINET_IN_H */ #include #include #include @@ -50,11 +56,11 @@ #define ARRLEN(x) (sizeof(x) / sizeof(x[0])) typedef struct { - /* The NULL-terminated URI string to retreive. */ + /* The NULL-terminated URI string to retrieve. */ const char *uri; /* Parsed result of the |uri| */ struct http_parser_url *u; - /* The authroity portion of the |uri|, not NULL-terminated */ + /* The authority portion of the |uri|, not NULL-terminated */ char *authority; /* The path portion of the |uri|, including query, not NULL-terminated */ diff --git a/examples/libevent-server.c b/examples/libevent-server.c index ef4c2f7d..412c6d0d 100644 --- a/examples/libevent-server.c +++ b/examples/libevent-server.c @@ -24,17 +24,27 @@ */ #ifdef HAVE_CONFIG_H #include -#endif /* !HAVE_CONFIG_H */ +#endif /* HAVE_CONFIG_H */ #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif /* HAVE_SYS_SOCKET_H */ +#ifdef HAVE_NETDB_H #include +#endif /* HAVE_NETDB_H */ #include +#ifdef HAVE_UNISTD_H #include +#endif /* HAVE_UNISTD_H */ #include +#ifdef HAVE_FCNTL_H #include +#endif /* HAVE_FCNTL_H */ #include +#ifdef HAVE_NETINET_IN_H #include +#endif /* HAVE_NETINET_IN_H */ #include #include diff --git a/examples/tiny-nghttpd.c b/examples/tiny-nghttpd.c index 3476ad60..3410e9df 100644 --- a/examples/tiny-nghttpd.c +++ b/examples/tiny-nghttpd.c @@ -30,18 +30,30 @@ #ifdef HAVE_CONFIG_H #include -#endif /* !HAVE_CONFIG_H */ +#endif /* HAVE_CONFIG_H */ #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif /* HAVE_SYS_SOCKET_H */ #include +#ifdef HAVE_FCNTL_H #include +#endif /* HAVE_FCNTL_H */ +#ifdef HAVE_NETDB_H #include +#endif /* HAVE_NETDB_H */ +#ifdef HAVE_NETINET_IN_H #include +#endif /* HAVE_NETINET_IN_H */ #include +#ifdef HAVE_UNISTD_H #include +#endif /* HAVE_UNISTD_H */ #include +#ifdef HAVE_TIME_H #include +#endif /* HAVE_TIME_H */ #include #include #include diff --git a/help2rst.py b/help2rst.py index 4beda7b0..2c9c46c0 100755 --- a/help2rst.py +++ b/help2rst.py @@ -61,6 +61,8 @@ def help2man(infile): description.append(line) print ''' +.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY. + .. program:: {cmdname} {cmdname}(1) diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h index d92c6d92..5f5fdabd 100644 --- a/lib/includes/nghttp2/nghttp2.h +++ b/lib/includes/nghttp2/nghttp2.h @@ -36,7 +36,7 @@ extern "C" { #endif #include -#include +#include #include #include diff --git a/lib/nghttp2_buf.c b/lib/nghttp2_buf.c index 0941f78b..96454a89 100644 --- a/lib/nghttp2_buf.c +++ b/lib/nghttp2_buf.c @@ -320,7 +320,7 @@ int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len) { } buf->last = nghttp2_cpymem(buf->last, p, nwrite); - p += len; + p += nwrite; len -= nwrite; } diff --git a/lib/nghttp2_hd.c b/lib/nghttp2_hd.c index 7aac859c..f9444e09 100644 --- a/lib/nghttp2_hd.c +++ b/lib/nghttp2_hd.c @@ -1752,8 +1752,8 @@ static int hd_inflate_remove_bufs_with_name(nghttp2_hd_inflater *inflater, #ifndef NDEBUG rv = #endif - nghttp2_bufs_remove_copy(&inflater->nvbufs, - buf + ent_name->nv.namelen + 1); + nghttp2_bufs_remove_copy(&inflater->nvbufs, + buf + ent_name->nv.namelen + 1); assert(ent_name->nv.namelen + 1 + rv == buflen); nghttp2_bufs_reset(&inflater->nvbufs); diff --git a/src/HttpServer.cc b/src/HttpServer.cc index d752dad1..0465395d 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -25,13 +25,25 @@ #include "HttpServer.h" #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H +#ifdef HAVE_FCNTL_H #include +#endif // HAVE_FCNTL_H +#ifdef HAVE_NETINET_IN_H #include +#endif // HAVE_NETINET_IN_H #include +#ifdef HAVE_ARPA_INET_H #include +#endif // HAVE_ARPA_INET_H #include #include @@ -91,7 +103,7 @@ Config::Config() padding(0), num_worker(1), max_concurrent_streams(100), header_table_size(-1), port(0), verbose(false), daemon(false), verify_client(false), no_tls(false), error_gzip(false), - early_response(false), hexdump(false) {} + early_response(false), hexdump(false), echo_upload(false) {} Config::~Config() {} @@ -279,7 +291,7 @@ private: Stream::Stream(Http2Handler *handler, int32_t stream_id) : handler(handler), file_ent(nullptr), body_length(0), body_offset(0), - stream_id(stream_id) { + stream_id(stream_id), echo_upload(false) { auto config = handler->get_config(); ev_timer_init(&rtimer, stream_timeout_cb, 0., config->stream_read_timeout); ev_timer_init(&wtimer, stream_timeout_cb, 0., config->stream_write_timeout); @@ -915,6 +927,49 @@ void prepare_status_response(Stream *stream, Http2Handler *hd, int status) { } } // namespace +namespace { +void prepare_echo_response(Stream *stream, Http2Handler *hd) { + auto length = lseek(stream->file_ent->fd, 0, SEEK_END); + if (length == -1) { + hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR); + return; + } + stream->body_length = length; + if (lseek(stream->file_ent->fd, 0, SEEK_SET) == -1) { + hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR); + return; + } + nghttp2_data_provider data_prd; + data_prd.source.fd = stream->file_ent->fd; + data_prd.read_callback = file_read_callback; + + Headers headers; + headers.emplace_back("nghttpd-response", "echo"); + headers.emplace_back("content-length", util::utos(length)); + + hd->submit_response("200", stream->stream_id, headers, &data_prd); +} +} // namespace + +namespace { +bool prepare_upload_temp_store(Stream *stream, Http2Handler *hd) { + auto sessions = hd->get_sessions(); + + char tempfn[] = "/tmp/nghttpd.temp.XXXXXX"; + auto fd = mkstemp(tempfn); + if (fd == -1) { + return false; + } + unlink(tempfn); + // Ordinary request never start with "echo:". The length is 0 for + // now. We will update it when we get whole request body. + stream->file_ent = sessions->cache_fd(std::string("echo:") + tempfn, + FileEntry(tempfn, 0, 0, fd)); + stream->echo_upload = true; + return true; +} +} // namespace + namespace { void prepare_redirect_response(Stream *stream, Http2Handler *hd, const std::string &path, int status) { @@ -969,8 +1024,14 @@ void prepare_response(Stream *stream, Http2Handler *hd, url = reqpath; } - url = util::percentDecode(url.begin(), url.end()); + auto sessions = hd->get_sessions(); + + url = util::percentDecode(std::begin(url), std::end(url)); if (!util::check_path(url)) { + if (stream->file_ent) { + sessions->release_fd(stream->file_ent->path); + stream->file_ent = nullptr; + } prepare_status_response(stream, hd, 404); return; } @@ -984,12 +1045,18 @@ void prepare_response(Stream *stream, Http2Handler *hd, } } } + std::string path = hd->get_config()->htdocs + url; if (path[path.size() - 1] == '/') { path += DEFAULT_HTML; } - auto sessions = hd->get_sessions(); + if (stream->echo_upload) { + assert(stream->file_ent); + prepare_echo_response(stream, hd); + return; + } + auto file_ent = sessions->get_cached_fd(path); if (file_ent == nullptr) { @@ -1119,7 +1186,7 @@ int hd_on_frame_recv_callback(nghttp2_session *session, if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { remove_stream_read_timeout(stream); - if (!hd->get_config()->early_response) { + if (stream->echo_upload || !hd->get_config()->early_response) { prepare_response(stream, hd); } } else { @@ -1143,14 +1210,22 @@ int hd_on_frame_recv_callback(nghttp2_session *session, hd->submit_non_final_response("100", frame->hd.stream_id); } - if (hd->get_config()->early_response) { + auto &method = http2::get_header(stream->hdidx, http2::HD__METHOD, + stream->headers)->value; + if (hd->get_config()->echo_upload && + (method == "POST" || method == "PUT")) { + if (!prepare_upload_temp_store(stream, hd)) { + hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR); + return 0; + } + } else if (hd->get_config()->early_response) { prepare_response(stream, hd); } } if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { remove_stream_read_timeout(stream); - if (!hd->get_config()->early_response) { + if (stream->echo_upload || !hd->get_config()->early_response) { prepare_response(stream, hd); } } else { @@ -1296,6 +1371,21 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags, return 0; } + if (stream->echo_upload) { + assert(stream->file_ent); + while (len) { + ssize_t n; + while ((n = write(stream->file_ent->fd, data, len)) == -1 && + errno == EINTR) + ; + if (n == -1) { + hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR); + return 0; + } + len -= n; + data += n; + } + } // TODO Handle POST add_stream_read_timeout(stream); diff --git a/src/HttpServer.h b/src/HttpServer.h index 220807e0..212f12ad 100644 --- a/src/HttpServer.h +++ b/src/HttpServer.h @@ -27,9 +27,9 @@ #include "nghttp2_config.h" -#include #include +#include #include #include @@ -72,6 +72,7 @@ struct Config { bool error_gzip; bool early_response; bool hexdump; + bool echo_upload; Config(); ~Config(); }; @@ -100,6 +101,7 @@ struct Stream { int64_t body_offset; int32_t stream_id; http2::HeaderIndex hdidx; + bool echo_upload; Stream(Http2Handler *handler, int32_t stream_id); ~Stream(); }; diff --git a/src/app_helper.cc b/src/app_helper.cc index f2981bc2..58f8439c 100644 --- a/src/app_helper.cc +++ b/src/app_helper.cc @@ -23,11 +23,21 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H +#ifdef HAVE_FCNTL_H #include +#endif // HAVE_FCNTL_H +#ifdef HAVE_NETINET_IN_H #include +#endif // HAVE_NETINET_IN_H #include #include diff --git a/src/app_helper.h b/src/app_helper.h index 9f11661f..408adac2 100644 --- a/src/app_helper.h +++ b/src/app_helper.h @@ -27,9 +27,11 @@ #include "nghttp2_config.h" -#include +#include #include +#ifdef HAVE_SYS_TIME_H #include +#endif // HAVE_SYS_TIME_H #include #include diff --git a/src/buffer_test.h b/src/buffer_test.h index d1a889b5..abdc9879 100644 --- a/src/buffer_test.h +++ b/src/buffer_test.h @@ -25,6 +25,10 @@ #ifndef BUFFER_TEST_H #define BUFFER_TEST_H +#ifdef HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H + namespace nghttp2 { void test_buffer_write(void); diff --git a/src/deflatehd.cc b/src/deflatehd.cc index dd67ebdb..cd0c5d59 100644 --- a/src/deflatehd.cc +++ b/src/deflatehd.cc @@ -26,7 +26,9 @@ #include #endif // HAVE_CONFIG_H +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include #include diff --git a/src/h2load.cc b/src/h2load.cc index 8e1fa822..55784156 100644 --- a/src/h2load.cc +++ b/src/h2load.cc @@ -26,10 +26,14 @@ #include #include +#ifdef HAVE_NETINET_IN_H #include +#endif // HAVE_NETINET_IN_H #include #include +#ifdef HAVE_FCNTL_H #include +#endif // HAVE_FCNTL_H #include #include @@ -1014,7 +1018,7 @@ Options: Number of native threads. Default: )" << config.nthreads << R"( -i, --input-file= - Path of a file with multiple URIs are seperated by EOLs. + Path of a file with multiple URIs are separated by EOLs. This option will disable URIs getting from command-line. If '-' is given as , URIs will be read from stdin. URIs are used in this order for each client. All URIs diff --git a/src/h2load.h b/src/h2load.h index e731a305..78a20389 100644 --- a/src/h2load.h +++ b/src/h2load.h @@ -28,8 +28,12 @@ #include "nghttp2_config.h" #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H #include #include @@ -94,8 +98,7 @@ struct RequestStat { bool completed; }; -template -struct TimeStat { +template struct TimeStat { // min, max, mean and sd (standard deviation) Duration min, max, mean, sd; // percentage of samples inside mean -/+ sd diff --git a/src/h2load_session.h b/src/h2load_session.h index 4231b914..18175748 100644 --- a/src/h2load_session.h +++ b/src/h2load_session.h @@ -28,7 +28,8 @@ #include "nghttp2_config.h" #include -#include + +#include #include "h2load.h" diff --git a/src/http2_test.h b/src/http2_test.h index 1171b926..36c5a59a 100644 --- a/src/http2_test.h +++ b/src/http2_test.h @@ -25,6 +25,10 @@ #ifndef SHRPX_HTTP2_TEST_H #define SHRPX_HTTP2_TEST_H +#ifdef HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H + namespace shrpx { void test_http2_add_header(void); diff --git a/src/inflatehd.cc b/src/inflatehd.cc index 353941af..98338bef 100644 --- a/src/inflatehd.cc +++ b/src/inflatehd.cc @@ -26,7 +26,9 @@ #include #endif // HAVE_CONFIG_H +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include #include @@ -99,6 +101,11 @@ static int inflate_hd(json_t *obj, nghttp2_hd_inflater *inflater, int seq) { return -1; } + if (!json_is_string(wire)) { + fprintf(stderr, "'wire' value is not string at %d\n", seq); + return -1; + } + auto table_size = json_object_get(obj, "header_table_size"); if (table_size) { diff --git a/src/memchunk_test.h b/src/memchunk_test.h index 31e2665c..9d170a43 100644 --- a/src/memchunk_test.h +++ b/src/memchunk_test.h @@ -25,6 +25,10 @@ #ifndef MEMCHUNK_TEST_H #define MEMCHUNK_TEST_H +#ifdef HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H + namespace nghttp2 { void test_pool_recycle(void); diff --git a/src/nghttp.cc b/src/nghttp.cc index b203803d..8f6361e3 100644 --- a/src/nghttp.cc +++ b/src/nghttp.cc @@ -25,9 +25,15 @@ #include "nghttp.h" #include +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H +#ifdef HAVE_FCNTL_H #include +#endif // HAVE_FCNTL_H +#ifdef HAVE_NETINET_IN_H #include +#endif // HAVE_NETINET_IN_H #include #include diff --git a/src/nghttp.h b/src/nghttp.h index 67e94722..0a7ee351 100644 --- a/src/nghttp.h +++ b/src/nghttp.h @@ -28,8 +28,12 @@ #include "nghttp2_config.h" #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H #include #include diff --git a/src/nghttp2_gzip_test.h b/src/nghttp2_gzip_test.h index ff2598d5..2defcdc8 100644 --- a/src/nghttp2_gzip_test.h +++ b/src/nghttp2_gzip_test.h @@ -25,6 +25,10 @@ #ifndef NGHTTP2_GZIP_TEST_H #define NGHTTP2_GZIP_TEST_H +#ifdef HAVE_CONFIG_H +#include +#endif /* HAVE_CONFIG_H */ + #ifdef __cplusplus extern "C" { #endif diff --git a/src/nghttpd.cc b/src/nghttpd.cc index 5126cea1..4ffc0bc9 100644 --- a/src/nghttpd.cc +++ b/src/nghttpd.cc @@ -24,7 +24,9 @@ */ #include "nghttp2_config.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include #include @@ -153,6 +155,8 @@ Options: --hexdump Display the incoming traffic in hexadecimal (Canonical hex+ASCII display). If SSL/TLS is used, decrypted data are used. + --echo-upload + Send back uploaded content if method is POST or PUT. --version Display version information and exit. -h, --help Display this help and exit. @@ -188,6 +192,7 @@ int main(int argc, char **argv) { {"early-response", no_argument, &flag, 5}, {"trailer", required_argument, &flag, 6}, {"hexdump", no_argument, &flag, 7}, + {"echo-upload", no_argument, &flag, 8}, {nullptr, 0, nullptr, 0}}; int option_index = 0; int c = getopt_long(argc, argv, "DVb:c:d:ehm:n:p:va:", long_options, @@ -310,6 +315,10 @@ int main(int argc, char **argv) { // hexdump option config.hexdump = true; break; + case 8: + // echo-upload option + config.echo_upload = true; + break; } break; default: diff --git a/src/shrpx-unittest.cc b/src/shrpx-unittest.cc index 34428e07..86edb1e0 100644 --- a/src/shrpx-unittest.cc +++ b/src/shrpx-unittest.cc @@ -24,7 +24,7 @@ */ #ifdef HAVE_CONFIG_H #include -#endif /* HAVE_CONFIG_H */ +#endif // HAVE_CONFIG_H #include #include diff --git a/src/shrpx.cc b/src/shrpx.cc index adda705f..5becb798 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -24,25 +24,41 @@ */ #include "shrpx.h" -#include #include #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H #include +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H #include +#ifdef HAVE_NETINET_IN_H #include +#endif // HAVE_NETINET_IN_H #include +#ifdef HAVE_ARPA_INET_H #include +#endif // HAVE_ARPA_INET_H +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include +#ifdef HAVE_SYSLOG_H #include +#endif // HAVE_SYSLOG_H #include +#ifdef HAVE_LIMITS_H #include +#endif // HAVE_LIMITS_H +#ifdef HAVE_SYS_TIME_H #include +#endif // HAVE_SYS_TIME_H #include #include +#include #include #include #include diff --git a/src/shrpx.h b/src/shrpx.h index 85c4d343..bd91c766 100644 --- a/src/shrpx.h +++ b/src/shrpx.h @@ -30,7 +30,9 @@ #endif // HAVE_CONFIG_H #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H #include diff --git a/src/shrpx_accept_handler.cc b/src/shrpx_accept_handler.cc index d69a05cc..0d448306 100644 --- a/src/shrpx_accept_handler.cc +++ b/src/shrpx_accept_handler.cc @@ -24,7 +24,9 @@ */ #include "shrpx_accept_handler.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include diff --git a/src/shrpx_client_handler.cc b/src/shrpx_client_handler.cc index 6a2b7d74..354b95e7 100644 --- a/src/shrpx_client_handler.cc +++ b/src/shrpx_client_handler.cc @@ -24,7 +24,9 @@ */ #include "shrpx_client_handler.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include #include "shrpx_upstream.h" diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index 9e0ac424..6577343d 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -24,13 +24,23 @@ */ #include "shrpx_config.h" +#ifdef HAVE_PWD_H #include +#endif // HAVE_PWD_H +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H +#ifdef HAVE_SYSLOG_H #include +#endif // HAVE_SYSLOG_H #include #include +#ifdef HAVE_FCNTL_H #include +#endif // HAVE_FCNTL_H +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include #include diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 4856fb8e..8afccd51 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -27,12 +27,18 @@ #include "shrpx.h" -#include #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H #include +#ifdef HAVE_NETINET_IN_H #include +#endif // HAVE_NETINET_IN_H +#ifdef HAVE_ARPA_INET_H #include +#endif // HAVE_ARPA_INET_H +#include #include #include #include diff --git a/src/shrpx_config_test.cc b/src/shrpx_config_test.cc index e326b4af..ad570bbc 100644 --- a/src/shrpx_config_test.cc +++ b/src/shrpx_config_test.cc @@ -24,7 +24,9 @@ */ #include "shrpx_config_test.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include diff --git a/src/shrpx_config_test.h b/src/shrpx_config_test.h index 9db5d4e3..6d6d0353 100644 --- a/src/shrpx_config_test.h +++ b/src/shrpx_config_test.h @@ -25,6 +25,10 @@ #ifndef SHRPX_CONFIG_TEST_H #define SHRPX_CONFIG_TEST_H +#ifdef HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H + namespace shrpx { void test_shrpx_config_parse_config_str_list(void); diff --git a/src/shrpx_connection.cc b/src/shrpx_connection.cc index 51a5d39c..30c2ec98 100644 --- a/src/shrpx_connection.cc +++ b/src/shrpx_connection.cc @@ -24,7 +24,9 @@ */ #include "shrpx_connection.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include @@ -151,13 +153,21 @@ void Connection::update_tls_warmup_writelen(size_t n) { } ssize_t Connection::write_tls(const void *data, size_t len) { - // We set SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, so we don't have to - // care about parameters after SSL_ERROR_WANT_READ or - // SSL_ERROR_WANT_WRITE. - len = std::min(len, wlimit.avail()); - len = std::min(len, get_tls_write_limit()); - if (len == 0) { - return 0; + // SSL_write requires the same arguments (buf pointer and its + // length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. + // get_write_limit() may return smaller length than previously + // passed to SSL_write, which violates OpenSSL assumption. To avoid + // this, we keep last legnth passed to SSL_write to + // tls.last_writelen if SSL_write indicated I/O blocking. + if (tls.last_writelen == 0) { + len = std::min(len, wlimit.avail()); + len = std::min(len, get_tls_write_limit()); + if (len == 0) { + return 0; + } + } else { + len = tls.last_writelen; + tls.last_writelen = 0; } auto rv = SSL_write(tls.ssl, data, len); @@ -177,6 +187,7 @@ ssize_t Connection::write_tls(const void *data, size_t len) { } return SHRPX_ERR_NETWORK; case SSL_ERROR_WANT_WRITE: + tls.last_writelen = len; wlimit.startw(); ev_timer_again(loop, &wt); return 0; @@ -196,13 +207,21 @@ ssize_t Connection::write_tls(const void *data, size_t len) { } ssize_t Connection::read_tls(void *data, size_t len) { - // Although SSL_read manual says it requires the same arguments (buf - // pointer and its length) on SSL_ERROR_WANT_READ or - // SSL_ERROR_WANT_WRITE. But after reading OpenSSL source code, - // there is no such requirement. - len = std::min(len, rlimit.avail()); - if (len == 0) { - return 0; + // SSL_read requires the same arguments (buf pointer and its + // length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. + // rlimit_.avail() or rlimit_.avail() may return different length + // than the length previously passed to SSL_read, which violates + // OpenSSL assumption. To avoid this, we keep last legnth passed + // to SSL_read to tls_last_readlen_ if SSL_read indicated I/O + // blocking. + if (tls.last_readlen == 0) { + len = std::min(len, rlimit.avail()); + if (len == 0) { + return 0; + } + } else { + len = tls.last_readlen; + tls.last_readlen = 0; } auto rv = SSL_read(tls.ssl, data, len); @@ -211,6 +230,7 @@ ssize_t Connection::read_tls(void *data, size_t len) { auto err = SSL_get_error(tls.ssl, rv); switch (err) { case SSL_ERROR_WANT_READ: + tls.last_readlen = len; return 0; case SSL_ERROR_WANT_WRITE: if (LOG_ENABLED(INFO)) { diff --git a/src/shrpx_connection.h b/src/shrpx_connection.h index 4e348412..055d32c3 100644 --- a/src/shrpx_connection.h +++ b/src/shrpx_connection.h @@ -42,6 +42,10 @@ struct TLSConnection { SSL *ssl; ev_tstamp last_write_time; size_t warmup_writelen; + // length passed to SSL_write and SSL_read last time. This is + // required since these functions require the exact same parameters + // on non-blocking I/O. + size_t last_writelen, last_readlen; bool initial_handshake_done; bool reneg_started; }; diff --git a/src/shrpx_connection_handler.cc b/src/shrpx_connection_handler.cc index 8779779d..ceebf61b 100644 --- a/src/shrpx_connection_handler.cc +++ b/src/shrpx_connection_handler.cc @@ -24,7 +24,9 @@ */ #include "shrpx_connection_handler.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include #include diff --git a/src/shrpx_connection_handler.h b/src/shrpx_connection_handler.h index d8c328c5..00e4be49 100644 --- a/src/shrpx_connection_handler.h +++ b/src/shrpx_connection_handler.h @@ -28,7 +28,9 @@ #include "shrpx.h" #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H #include #include diff --git a/src/shrpx_downstream.h b/src/shrpx_downstream.h index f761b6a0..2bd29312 100644 --- a/src/shrpx_downstream.h +++ b/src/shrpx_downstream.h @@ -27,8 +27,7 @@ #include "shrpx.h" -#include - +#include #include #include #include diff --git a/src/shrpx_downstream_queue.h b/src/shrpx_downstream_queue.h index ee5028bd..d327a05f 100644 --- a/src/shrpx_downstream_queue.h +++ b/src/shrpx_downstream_queue.h @@ -27,8 +27,7 @@ #include "shrpx.h" -#include - +#include #include #include #include diff --git a/src/shrpx_downstream_test.h b/src/shrpx_downstream_test.h index b1e1aee5..67e8f6bd 100644 --- a/src/shrpx_downstream_test.h +++ b/src/shrpx_downstream_test.h @@ -25,6 +25,10 @@ #ifndef SHRPX_DOWNSTREAM_TEST_H #define SHRPX_DOWNSTREAM_TEST_H +#ifdef HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H + namespace shrpx { void test_downstream_index_request_headers(void); diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index d8d83d73..f5cba83e 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -24,7 +24,9 @@ */ #include "shrpx_http2_downstream_connection.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include "http-parser/http_parser.h" diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index e504ba82..c071a722 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -25,7 +25,9 @@ #include "shrpx_http2_session.h" #include +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include diff --git a/src/shrpx_https_upstream.h b/src/shrpx_https_upstream.h index 1b0c648a..3b9d5320 100644 --- a/src/shrpx_https_upstream.h +++ b/src/shrpx_https_upstream.h @@ -27,8 +27,7 @@ #include "shrpx.h" -#include - +#include #include #include "http-parser/http_parser.h" diff --git a/src/shrpx_log.cc b/src/shrpx_log.cc index 621aad8e..1446df6e 100644 --- a/src/shrpx_log.cc +++ b/src/shrpx_log.cc @@ -24,9 +24,15 @@ */ #include "shrpx_log.h" +#ifdef HAVE_SYSLOG_H #include +#endif // HAVE_SYSLOG_H +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H +#ifdef HAVE_INTTYPES_H #include +#endif // HAVE_INTTYPES_H #include #include diff --git a/src/shrpx_ssl.cc b/src/shrpx_ssl.cc index cb27749a..3d3687e5 100644 --- a/src/shrpx_ssl.cc +++ b/src/shrpx_ssl.cc @@ -24,8 +24,12 @@ */ #include "shrpx_ssl.h" +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H #include #include #include @@ -392,7 +396,6 @@ SSL_CTX *create_ssl_context(const char *private_key_file, SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS); - SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); if (get_config()->private_key_passwd) { SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)get_config()); @@ -501,7 +504,6 @@ SSL_CTX *create_ssl_client_context() { SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS); - SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); if (SSL_CTX_set_default_verify_paths(ssl_ctx) != 1) { LOG(WARN) << "Could not load system trusted ca certificates: " diff --git a/src/shrpx_ssl_test.h b/src/shrpx_ssl_test.h index fbb1fa62..89b00449 100644 --- a/src/shrpx_ssl_test.h +++ b/src/shrpx_ssl_test.h @@ -25,6 +25,10 @@ #ifndef SHRPX_SSL_TEST_H #define SHRPX_SSL_TEST_H +#ifdef HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H + namespace shrpx { void test_shrpx_ssl_create_lookup_tree(void); diff --git a/src/shrpx_worker.cc b/src/shrpx_worker.cc index 6b2b658b..a9bf6e65 100644 --- a/src/shrpx_worker.cc +++ b/src/shrpx_worker.cc @@ -24,7 +24,9 @@ */ #include "shrpx_worker.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include diff --git a/src/timegm.c b/src/timegm.c index bf572b72..90bf53ff 100644 --- a/src/timegm.c +++ b/src/timegm.c @@ -26,7 +26,7 @@ #ifndef HAVE_TIMEGM -#include +#include /* Counter the number of leap year in the range [0, y). The |y| is the year, including century (e.g., 2012) */ diff --git a/src/timegm.h b/src/timegm.h index 529235cf..32a9526d 100644 --- a/src/timegm.h +++ b/src/timegm.h @@ -33,7 +33,9 @@ extern "C" { #endif /* __cplusplus */ +#ifdef HAVE_TIME_H #include +#endif // HAVE_TIME_H #ifndef HAVE_TIMEGM diff --git a/src/util.cc b/src/util.cc index 4c2b3f60..9eb5258b 100644 --- a/src/util.cc +++ b/src/util.cc @@ -24,15 +24,27 @@ */ #include "util.h" +#ifdef HAVE_TIME_H #include +#endif // HAVE_TIME_H #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif // HAVE_SYS_SOCKET_H +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H #include +#ifdef HAVE_FCNTL_H #include +#endif // HAVE_FCNTL_H +#ifdef HAVE_NETINET_IN_H #include +#endif // HAVE_NETINET_IN_H #include +#ifdef HAVE_ARPA_INET_H #include +#endif // HAVE_ARPA_INET_H #include #include diff --git a/src/util.h b/src/util.h index 06861f6c..88e1ff59 100644 --- a/src/util.h +++ b/src/util.h @@ -27,9 +27,13 @@ #include "nghttp2_config.h" +#ifdef HAVE_UNISTD_H #include +#endif // HAVE_UNISTD_H #include +#ifdef HAVE_NETDB_H #include +#endif // HAVE_NETDB_H #include #include diff --git a/src/util_test.h b/src/util_test.h index d8f7dd47..00290b89 100644 --- a/src/util_test.h +++ b/src/util_test.h @@ -25,6 +25,10 @@ #ifndef UTIL_TEST_H #define UTIL_TEST_H +#ifdef HAVE_CONFIG_H +#include +#endif // HAVE_CONFIG_H + namespace shrpx { void test_util_streq(void); diff --git a/tests/main.c b/tests/main.c index b1ef7743..1d187f70 100644 --- a/tests/main.c +++ b/tests/main.c @@ -340,6 +340,8 @@ int main(int argc _U_, char *argv[] _U_) { !CU_add_test(pSuite, "check_header_value", test_nghttp2_check_header_value) || !CU_add_test(pSuite, "bufs_add", test_nghttp2_bufs_add) || + !CU_add_test(pSuite, "bufs_add_stack_buffer_overflow_bug", + test_nghttp2_bufs_add_stack_buffer_overflow_bug) || !CU_add_test(pSuite, "bufs_addb", test_nghttp2_bufs_addb) || !CU_add_test(pSuite, "bufs_orb", test_nghttp2_bufs_orb) || !CU_add_test(pSuite, "bufs_remove", test_nghttp2_bufs_remove) || diff --git a/tests/nghttp2_buf_test.c b/tests/nghttp2_buf_test.c index 01f31fcf..8860554f 100644 --- a/tests/nghttp2_buf_test.c +++ b/tests/nghttp2_buf_test.c @@ -63,6 +63,26 @@ void test_nghttp2_bufs_add(void) { nghttp2_bufs_free(&bufs); } +/* Test for GH-232, stack-buffer-overflow */ +void test_nghttp2_bufs_add_stack_buffer_overflow_bug(void) { + int rv; + nghttp2_bufs bufs; + uint8_t data[1024]; + nghttp2_mem *mem; + + mem = nghttp2_mem_default(); + + rv = nghttp2_bufs_init(&bufs, 100, 200, mem); + CU_ASSERT(0 == rv); + + rv = nghttp2_bufs_add(&bufs, data, sizeof(data)); + + CU_ASSERT(0 == rv); + CU_ASSERT(sizeof(data) == nghttp2_bufs_len(&bufs)); + + nghttp2_bufs_free(&bufs); +} + void test_nghttp2_bufs_addb(void) { int rv; nghttp2_bufs bufs; diff --git a/tests/nghttp2_buf_test.h b/tests/nghttp2_buf_test.h index 5da388e7..0b94a3f4 100644 --- a/tests/nghttp2_buf_test.h +++ b/tests/nghttp2_buf_test.h @@ -26,6 +26,7 @@ #define NGHTTP2_BUF_TEST_H void test_nghttp2_bufs_add(void); +void test_nghttp2_bufs_add_stack_buffer_overflow_bug(void); void test_nghttp2_bufs_addb(void); void test_nghttp2_bufs_orb(void); void test_nghttp2_bufs_remove(void);