Merge branch 'master' into v1.0.0

Conflicts:
	src/HttpServer.cc
This commit is contained in:
Tatsuhiro Tsujikawa 2015-05-15 23:24:19 +09:00
commit 0b27f005e0
75 changed files with 504 additions and 95 deletions

View File

@ -13,7 +13,7 @@ An HPACK encoder and decoder are available as a public API.
An experimental high level C++ library is also available. 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. code coverage yet.
Development Status 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. upgraded to HTTP/2 through HTTP Upgrade.
The ``--http2-bridge``, ``--client`` and ``--client-proxy`` modes use 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. the ``--backend-no-tls`` option.
``nghttpx`` supports a configuration file. See the ``--conf`` option and ``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 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 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_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 ``max_deflate_size`` but inside the ``max_size`` and make sure
that they are no longer referenced. that they are no longer referenced.

View File

@ -25,13 +25,30 @@ dnl Do not change user variables!
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
AC_PREREQ(2.61) 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_PREREQ([2.2.6])
LT_INIT() 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 See versioning rule:
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
AC_SUBST(LT_CURRENT, 13) AC_SUBST(LT_CURRENT, 13)
AC_SUBST(LT_REVISION, 3) AC_SUBST(LT_REVISION, 4)
AC_SUBST(LT_AGE, 8) AC_SUBST(LT_AGE, 8)
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"` 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_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 dnl Checks for command-line options
AC_ARG_ENABLE([werror], AC_ARG_ENABLE([werror],
[AS_HELP_STRING([--enable-werror], [AS_HELP_STRING([--enable-werror],
@ -129,10 +131,12 @@ AC_ARG_VAR([CYTHON], [the Cython executable])
dnl Checks for programs dnl Checks for programs
AC_PROG_CC AC_PROG_CC
AC_PROG_CXX AC_PROG_CXX
AC_PROG_CPP
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AM_PROG_CC_C_O AC_PROG_MKDIR_P
PKG_PROG_PKG_CONFIG([0.20]) PKG_PROG_PKG_CONFIG([0.20])
if [test "x$request_python_bindings" != "xno"]; then 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], [], AC_SEARCH_LIBS([malloc_stats_print], [jemalloc], [have_jemalloc=yes], [],
[$PTHREAD_LDFLAGS]) [$PTHREAD_LDFLAGS])
LIBS=$LIBS_OLD 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" && if test "x${have_jemalloc}" = "xyes" &&
test "x${ac_cv_search_malloc_stats_print}" != "xnone required"; then test "x${jemalloc_libs}" != "xnone required"; then
JEMALLOC_LIBS=${ac_cv_search_malloc_stats_print} JEMALLOC_LIBS=${jemalloc_libs}
AC_SUBST([JEMALLOC_LIBS]) AC_SUBST([JEMALLOC_LIBS])
fi fi
fi fi
@ -498,12 +516,19 @@ AM_CONDITIONAL([ENABLE_FAILMALLOC], [ test "x${enable_failmalloc}" = "xyes" ])
AC_HEADER_ASSERT AC_HEADER_ASSERT
AC_CHECK_HEADERS([ \ AC_CHECK_HEADERS([ \
arpa/inet.h \ arpa/inet.h \
fcntl.h \
inttypes.h \
limits.h \
netdb.h \
netinet/in.h \ netinet/in.h \
pwd.h \ pwd.h \
stddef.h \ stddef.h \
stdint.h \ stdint.h \
stdlib.h \ stdlib.h \
string.h \ string.h \
sys/socket.h \
sys/time.h \
syslog.h \
time.h \ time.h \
unistd.h \ unistd.h \
]) ])
@ -515,8 +540,16 @@ AC_TYPE_UINT8_T
AC_TYPE_UINT16_T AC_TYPE_UINT16_T
AC_TYPE_UINT32_T AC_TYPE_UINT32_T
AC_TYPE_UINT64_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_CHECK_TYPES([ptrdiff_t])
AC_C_BIGENDIAN AC_C_BIGENDIAN
AC_C_INLINE
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [have_struct_tm_tm_gmtoff=yes], 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 if test "x$cross_compiling" != "xyes"; then
AC_FUNC_MALLOC AC_FUNC_MALLOC
fi 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([ \ AC_CHECK_FUNCS([ \
_Exit \ _Exit \
accept4 \ accept4 \
dup2 \
getcwd \
getpwnam \ getpwnam \
localtime_r \
memchr \
memmove \ memmove \
memset \ memset \
socket \
sqrt \
strchr \
strdup \
strerror \
strndup \
strstr \
strtol \
strtoul \
timegm \ timegm \
]) ])

View File

@ -8,7 +8,7 @@ _nghttpd()
_get_comp_words_by_ref cur prev _get_comp_words_by_ref cur prev
case $cur in 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 _filedir

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" 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 .SH NAME
h2load \- HTTP/2 benchmarking tool h2load \- HTTP/2 benchmarking tool
. .
@ -71,7 +71,7 @@ Default: \fB1\fP
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-i, \-\-input\-file=<FILE> .B \-i, \-\-input\-file=<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. This option will disable URIs getting from command\-line.
If \(aq\-\(aq is given as <FILE>, URIs will be read from stdin. If \(aq\-\(aq is given as <FILE>, URIs will be read from stdin.
URIs are used in this order for each client. All URIs URIs are used in this order for each client. All URIs

View File

@ -1,4 +1,6 @@
.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY.
.. program:: h2load .. program:: h2load
h2load(1) h2load(1)
@ -46,7 +48,7 @@ OPTIONS
.. option:: -i, --input-file=<FILE> .. option:: -i, --input-file=<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. This option will disable URIs getting from command-line.
If '-' is given as <FILE>, URIs will be read from stdin. If '-' is given as <FILE>, URIs will be read from stdin.
URIs are used in this order for each client. All URIs URIs are used in this order for each client. All URIs

View File

@ -222,6 +222,7 @@ def process_function(domain, infile):
func_proto = ''.join(func_proto) func_proto = ''.join(func_proto)
func_proto = re.sub(r';\n$', '', func_proto) func_proto = re.sub(r';\n$', '', func_proto)
func_proto = re.sub(r'\s+', ' ', 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) return FunctionDoc(func_proto, content, domain)
def read_content(infile): def read_content(infile):

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" 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 .SH NAME
nghttp \- HTTP/2 experimental client nghttp \- HTTP/2 experimental client
. .

View File

@ -1,4 +1,6 @@
.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY.
.. program:: nghttp .. program:: nghttp
nghttp(1) nghttp(1)

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" 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 .SH NAME
nghttpd \- HTTP/2 experimental server nghttpd \- HTTP/2 experimental server
. .
@ -167,6 +167,11 @@ are used.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-echo\-upload
Send back uploaded content if method is POST or PUT.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-version .B \-\-version
Display version information and exit. Display version information and exit.
.UNINDENT .UNINDENT

View File

@ -1,4 +1,6 @@
.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY.
.. program:: nghttpd .. program:: nghttpd
nghttpd(1) nghttpd(1)
@ -126,6 +128,10 @@ OPTIONS
hex+ASCII display). If SSL/TLS is used, decrypted data hex+ASCII display). If SSL/TLS is used, decrypted data
are used. are used.
.. option:: --echo-upload
Send back uploaded content if method is POST or PUT.
.. option:: --version .. option:: --version
Display version information and exit. Display version information and exit.

View File

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" 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 .SH NAME
nghttpx \- HTTP/2 experimental proxy nghttpx \- HTTP/2 experimental proxy
. .
@ -812,7 +812,7 @@ argument in the configuration file. Specify \fByes\fP as an argument
ignored. ignored.
.sp .sp
To specify private key and certificate file which are given as 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\&. \fBcertificate\-file\fP\&.
.sp .sp
\fI\%\-\-conf\fP option cannot be used in the configuration file and \fI\%\-\-conf\fP option cannot be used in the configuration file and

View File

@ -1,4 +1,6 @@
.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY.
.. program:: nghttpx .. program:: nghttpx
nghttpx(1) nghttpx(1)
@ -727,7 +729,7 @@ FILES
ignored. ignored.
To specify private key and certificate file which are given as 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``. ``certificate-file``.
:option:`--conf` option cannot be used in the configuration file and :option:`--conf` option cannot be used in the configuration file and

View File

@ -19,7 +19,7 @@ FILES
ignored. ignored.
To specify private key and certificate file which are given as 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``. ``certificate-file``.
:option:`--conf` option cannot be used in the configuration file and :option:`--conf` option cannot be used in the configuration file and

View File

@ -87,5 +87,5 @@ If multiple URIs are specified, they are used in round robin manner.
.. note:: .. 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. and ignores those parts in the rest of the URIs.

View File

@ -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 which is omitted in the above example, is additional header fields to
send. 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". In the above example, we send string "hello, world".
The life time of req and res object ends after the callback set by 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 ``boost::asio::io_service`` object and remote server address. When
connection is made, the callback function passed to connection is made, the callback function passed to
``nghttp2::asio_http2::client::on_connect`` is invoked with connected ``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 ``nghttp2::asio_http2::session::submit`` to send request to the
server. You can submit multiple requests at once without waiting for server. You can submit multiple requests at once without waiting for
the completion of previous request. the completion of previous request.

View File

@ -21,7 +21,7 @@ SSL/TLS, the frontend also supports SPDY protocol.
By default, this mode's frontend connection is encrypted using By default, this mode's frontend connection is encrypted using
SSL/TLS. So server's private key and certificate must be supplied to SSL/TLS. So server's private key and certificate must be supplied to
the command line (or through configuration file). In this case, the 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 With ``--frontend-no-tls`` option, user can turn off SSL/TLS in
frontend connection. In this case, SPDY protocol is not available 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 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. individually.
To perform rate limit for reading, use ``--read-rate`` and To perform rate limit for reading, use ``--read-rate`` and

View File

@ -267,7 +267,7 @@ HTTP/2 servers
(byte string could be ``None``), :py:data:`DATA_EOF` must be (byte string could be ``None``), :py:data:`DATA_EOF` must be
returned as flag. If there is no data available right now, but returned as flag. If there is no data available right now, but
additional data are anticipated, return tuple (``None``, 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. :py:meth:`resume()` and restart response body transmission.
Only the body generator can pause response body generation; Only the body generator can pause response body generation;

View File

@ -65,11 +65,11 @@ its stream specific data in ``http2_stream_data`` structure and the
defined as follows:: defined as follows::
typedef struct { typedef struct {
/* The NULL-terminated URI string to retreive. */ /* The NULL-terminated URI string to retrieve. */
const char *uri; const char *uri;
/* Parsed result of the |uri| */ /* Parsed result of the |uri| */
struct http_parser_url *u; 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; char *authority;
/* The path portion of the |uri|, including query, not /* The path portion of the |uri|, including query, not
NULL-terminated */ 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 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 demonstrating the use of SETTINGS frame. To queue the SETTINGS frame
for the transmission, we use `nghttp2_submit_settings()`. Note that for the transmission, we use `nghttp2_submit_settings()`. Note that
`nghttp2_submit_settings()` function only queues the frame and not `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 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 :macro:`NGHTTP2_HCAT_RESPONSE` for HTTP response HEADERS). Also check
its stream ID. 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 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 output in the terminal may be corrupted if the response body contains
some binary data. some binary data.

View File

@ -51,7 +51,7 @@ bound of encoded result, use `nghttp2_hd_deflate_bound()` function::
size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater, size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
const nghttp2_nv *nva, size_t nvlen); 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()`. *nvlen* which will be passed to `nghttp2_hd_deflate_hd()`.
The subsequent call of `nghttp2_hd_deflate_hd()` will use current The subsequent call of `nghttp2_hd_deflate_hd()` will use current

View File

@ -35,8 +35,12 @@
// //
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H
#include <iostream> #include <iostream>
#include <string> #include <string>

View File

@ -28,16 +28,26 @@
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif /* !HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <stdint.h> #include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif /* HAVE_NETDB_H */
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <poll.h> #include <poll.h>
#include <signal.h> #include <signal.h>

View File

@ -24,12 +24,18 @@
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif /* !HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <err.h> #include <err.h>
#include <signal.h> #include <signal.h>
@ -50,11 +56,11 @@
#define ARRLEN(x) (sizeof(x) / sizeof(x[0])) #define ARRLEN(x) (sizeof(x) / sizeof(x[0]))
typedef struct { typedef struct {
/* The NULL-terminated URI string to retreive. */ /* The NULL-terminated URI string to retrieve. */
const char *uri; const char *uri;
/* Parsed result of the |uri| */ /* Parsed result of the |uri| */
struct http_parser_url *u; 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; char *authority;
/* The path portion of the |uri|, including query, not /* The path portion of the |uri|, including query, not
NULL-terminated */ NULL-terminated */

View File

@ -24,17 +24,27 @@
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif /* !HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif /* HAVE_NETDB_H */
#include <signal.h> #include <signal.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#include <ctype.h> #include <ctype.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <err.h> #include <err.h>

View File

@ -30,18 +30,30 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif /* !HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif /* HAVE_NETDB_H */
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_TIME_H
#include <time.h> #include <time.h>
#endif /* HAVE_TIME_H */
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>

View File

@ -61,6 +61,8 @@ def help2man(infile):
description.append(line) description.append(line)
print ''' print '''
.. GENERATED by help2rst.py. DO NOT EDIT DIRECTLY.
.. program:: {cmdname} .. program:: {cmdname}
{cmdname}(1) {cmdname}(1)

View File

@ -36,7 +36,7 @@ extern "C" {
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <inttypes.h>
#include <sys/types.h> #include <sys/types.h>
#include <nghttp2/nghttp2ver.h> #include <nghttp2/nghttp2ver.h>

View File

@ -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); buf->last = nghttp2_cpymem(buf->last, p, nwrite);
p += len; p += nwrite;
len -= nwrite; len -= nwrite;
} }

View File

@ -1752,8 +1752,8 @@ static int hd_inflate_remove_bufs_with_name(nghttp2_hd_inflater *inflater,
#ifndef NDEBUG #ifndef NDEBUG
rv = rv =
#endif #endif
nghttp2_bufs_remove_copy(&inflater->nvbufs, nghttp2_bufs_remove_copy(&inflater->nvbufs,
buf + ent_name->nv.namelen + 1); buf + ent_name->nv.namelen + 1);
assert(ent_name->nv.namelen + 1 + rv == buflen); assert(ent_name->nv.namelen + 1 + rv == buflen);
nghttp2_bufs_reset(&inflater->nvbufs); nghttp2_bufs_reset(&inflater->nvbufs);

View File

@ -25,13 +25,25 @@
#include "HttpServer.h" #include "HttpServer.h"
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h> #include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H
#include <cassert> #include <cassert>
#include <set> #include <set>
@ -91,7 +103,7 @@ Config::Config()
padding(0), num_worker(1), max_concurrent_streams(100), padding(0), num_worker(1), max_concurrent_streams(100),
header_table_size(-1), port(0), verbose(false), daemon(false), header_table_size(-1), port(0), verbose(false), daemon(false),
verify_client(false), no_tls(false), error_gzip(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() {} Config::~Config() {}
@ -279,7 +291,7 @@ private:
Stream::Stream(Http2Handler *handler, int32_t stream_id) Stream::Stream(Http2Handler *handler, int32_t stream_id)
: handler(handler), file_ent(nullptr), body_length(0), body_offset(0), : 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(); auto config = handler->get_config();
ev_timer_init(&rtimer, stream_timeout_cb, 0., config->stream_read_timeout); ev_timer_init(&rtimer, stream_timeout_cb, 0., config->stream_read_timeout);
ev_timer_init(&wtimer, stream_timeout_cb, 0., config->stream_write_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
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 { namespace {
void prepare_redirect_response(Stream *stream, Http2Handler *hd, void prepare_redirect_response(Stream *stream, Http2Handler *hd,
const std::string &path, int status) { const std::string &path, int status) {
@ -969,8 +1024,14 @@ void prepare_response(Stream *stream, Http2Handler *hd,
url = reqpath; 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 (!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); prepare_status_response(stream, hd, 404);
return; return;
} }
@ -984,12 +1045,18 @@ void prepare_response(Stream *stream, Http2Handler *hd,
} }
} }
} }
std::string path = hd->get_config()->htdocs + url; std::string path = hd->get_config()->htdocs + url;
if (path[path.size() - 1] == '/') { if (path[path.size() - 1] == '/') {
path += DEFAULT_HTML; 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); auto file_ent = sessions->get_cached_fd(path);
if (file_ent == nullptr) { 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) { if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
remove_stream_read_timeout(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); prepare_response(stream, hd);
} }
} else { } else {
@ -1143,14 +1210,22 @@ int hd_on_frame_recv_callback(nghttp2_session *session,
hd->submit_non_final_response("100", frame->hd.stream_id); 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); prepare_response(stream, hd);
} }
} }
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
remove_stream_read_timeout(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); prepare_response(stream, hd);
} }
} else { } else {
@ -1296,6 +1371,21 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
return 0; 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 // TODO Handle POST
add_stream_read_timeout(stream); add_stream_read_timeout(stream);

View File

@ -27,9 +27,9 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <cinttypes>
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
@ -72,6 +72,7 @@ struct Config {
bool error_gzip; bool error_gzip;
bool early_response; bool early_response;
bool hexdump; bool hexdump;
bool echo_upload;
Config(); Config();
~Config(); ~Config();
}; };
@ -100,6 +101,7 @@ struct Stream {
int64_t body_offset; int64_t body_offset;
int32_t stream_id; int32_t stream_id;
http2::HeaderIndex hdidx; http2::HeaderIndex hdidx;
bool echo_upload;
Stream(Http2Handler *handler, int32_t stream_id); Stream(Http2Handler *handler, int32_t stream_id);
~Stream(); ~Stream();
}; };

View File

@ -23,11 +23,21 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <poll.h> #include <poll.h>

View File

@ -27,9 +27,11 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#include <stdint.h> #include <cinttypes>
#include <cstdlib> #include <cstdlib>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif // HAVE_SYS_TIME_H
#include <poll.h> #include <poll.h>
#include <map> #include <map>

View File

@ -25,6 +25,10 @@
#ifndef BUFFER_TEST_H #ifndef BUFFER_TEST_H
#define BUFFER_TEST_H #define BUFFER_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace nghttp2 { namespace nghttp2 {
void test_buffer_write(void); void test_buffer_write(void);

View File

@ -26,7 +26,9 @@
#include <config.h> #include <config.h>
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <getopt.h> #include <getopt.h>
#include <cstdio> #include <cstdio>

View File

@ -26,10 +26,14 @@
#include <getopt.h> #include <getopt.h>
#include <signal.h> #include <signal.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H
#include <cstdio> #include <cstdio>
#include <cassert> #include <cassert>
@ -1014,7 +1018,7 @@ Options:
Number of native threads. Number of native threads.
Default: )" << config.nthreads << R"( Default: )" << config.nthreads << R"(
-i, --input-file=<FILE> -i, --input-file=<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. This option will disable URIs getting from command-line.
If '-' is given as <FILE>, URIs will be read from stdin. If '-' is given as <FILE>, URIs will be read from stdin.
URIs are used in this order for each client. All URIs URIs are used in this order for each client. All URIs

View File

@ -28,8 +28,12 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#include <vector> #include <vector>
#include <string> #include <string>
@ -94,8 +98,7 @@ struct RequestStat {
bool completed; bool completed;
}; };
template<typename Duration> template <typename Duration> struct TimeStat {
struct TimeStat {
// min, max, mean and sd (standard deviation) // min, max, mean and sd (standard deviation)
Duration min, max, mean, sd; Duration min, max, mean, sd;
// percentage of samples inside mean -/+ sd // percentage of samples inside mean -/+ sd

View File

@ -28,7 +28,8 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h>
#include <cinttypes>
#include "h2load.h" #include "h2load.h"

View File

@ -25,6 +25,10 @@
#ifndef SHRPX_HTTP2_TEST_H #ifndef SHRPX_HTTP2_TEST_H
#define SHRPX_HTTP2_TEST_H #define SHRPX_HTTP2_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace shrpx { namespace shrpx {
void test_http2_add_header(void); void test_http2_add_header(void);

View File

@ -26,7 +26,9 @@
#include <config.h> #include <config.h>
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <getopt.h> #include <getopt.h>
#include <cstdio> #include <cstdio>
@ -99,6 +101,11 @@ static int inflate_hd(json_t *obj, nghttp2_hd_inflater *inflater, int seq) {
return -1; 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"); auto table_size = json_object_get(obj, "header_table_size");
if (table_size) { if (table_size) {

View File

@ -25,6 +25,10 @@
#ifndef MEMCHUNK_TEST_H #ifndef MEMCHUNK_TEST_H
#define MEMCHUNK_TEST_H #define MEMCHUNK_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace nghttp2 { namespace nghttp2 {
void test_pool_recycle(void); void test_pool_recycle(void);

View File

@ -25,9 +25,15 @@
#include "nghttp.h" #include "nghttp.h"
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <getopt.h> #include <getopt.h>

View File

@ -28,8 +28,12 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#include <string> #include <string>
#include <vector> #include <vector>

View File

@ -25,6 +25,10 @@
#ifndef NGHTTP2_GZIP_TEST_H #ifndef NGHTTP2_GZIP_TEST_H
#define NGHTTP2_GZIP_TEST_H #define NGHTTP2_GZIP_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -24,7 +24,9 @@
*/ */
#include "nghttp2_config.h" #include "nghttp2_config.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <signal.h> #include <signal.h>
#include <getopt.h> #include <getopt.h>
@ -153,6 +155,8 @@ Options:
--hexdump Display the incoming traffic in hexadecimal (Canonical --hexdump Display the incoming traffic in hexadecimal (Canonical
hex+ASCII display). If SSL/TLS is used, decrypted data hex+ASCII display). If SSL/TLS is used, decrypted data
are used. are used.
--echo-upload
Send back uploaded content if method is POST or PUT.
--version Display version information and exit. --version Display version information and exit.
-h, --help Display this help 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}, {"early-response", no_argument, &flag, 5},
{"trailer", required_argument, &flag, 6}, {"trailer", required_argument, &flag, 6},
{"hexdump", no_argument, &flag, 7}, {"hexdump", no_argument, &flag, 7},
{"echo-upload", no_argument, &flag, 8},
{nullptr, 0, nullptr, 0}}; {nullptr, 0, nullptr, 0}};
int option_index = 0; int option_index = 0;
int c = getopt_long(argc, argv, "DVb:c:d:ehm:n:p:va:", long_options, 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 // hexdump option
config.hexdump = true; config.hexdump = true;
break; break;
case 8:
// echo-upload option
config.echo_upload = true;
break;
} }
break; break;
default: default:

View File

@ -24,7 +24,7 @@
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif // HAVE_CONFIG_H
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>

View File

@ -24,25 +24,41 @@
*/ */
#include "shrpx.h" #include "shrpx.h"
#include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#include <sys/un.h> #include <sys/un.h>
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#include <signal.h> #include <signal.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h> #include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <getopt.h> #include <getopt.h>
#ifdef HAVE_SYSLOG_H
#include <syslog.h> #include <syslog.h>
#endif // HAVE_SYSLOG_H
#include <signal.h> #include <signal.h>
#ifdef HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#endif // HAVE_LIMITS_H
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif // HAVE_SYS_TIME_H
#include <sys/resource.h> #include <sys/resource.h>
#include <grp.h> #include <grp.h>
#include <cinttypes>
#include <limits> #include <limits>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>

View File

@ -30,7 +30,9 @@
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#include <cassert> #include <cassert>

View File

@ -24,7 +24,9 @@
*/ */
#include "shrpx_accept_handler.h" #include "shrpx_accept_handler.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <cerrno> #include <cerrno>

View File

@ -24,7 +24,9 @@
*/ */
#include "shrpx_client_handler.h" #include "shrpx_client_handler.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <cerrno> #include <cerrno>
#include "shrpx_upstream.h" #include "shrpx_upstream.h"

View File

@ -24,13 +24,23 @@
*/ */
#include "shrpx_config.h" #include "shrpx_config.h"
#ifdef HAVE_PWD_H
#include <pwd.h> #include <pwd.h>
#endif // HAVE_PWD_H
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#ifdef HAVE_SYSLOG_H
#include <syslog.h> #include <syslog.h>
#endif // HAVE_SYSLOG_H
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <cstring> #include <cstring>
#include <cerrno> #include <cerrno>

View File

@ -27,12 +27,18 @@
#include "shrpx.h" #include "shrpx.h"
#include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#include <sys/un.h> #include <sys/un.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h> #include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H
#include <cinttypes>
#include <cstdio> #include <cstdio>
#include <vector> #include <vector>
#include <memory> #include <memory>

View File

@ -24,7 +24,9 @@
*/ */
#include "shrpx_config_test.h" #include "shrpx_config_test.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <cstdlib> #include <cstdlib>

View File

@ -25,6 +25,10 @@
#ifndef SHRPX_CONFIG_TEST_H #ifndef SHRPX_CONFIG_TEST_H
#define SHRPX_CONFIG_TEST_H #define SHRPX_CONFIG_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace shrpx { namespace shrpx {
void test_shrpx_config_parse_config_str_list(void); void test_shrpx_config_parse_config_str_list(void);

View File

@ -24,7 +24,9 @@
*/ */
#include "shrpx_connection.h" #include "shrpx_connection.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <limits> #include <limits>
@ -151,13 +153,21 @@ void Connection::update_tls_warmup_writelen(size_t n) {
} }
ssize_t Connection::write_tls(const void *data, size_t len) { 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 // SSL_write requires the same arguments (buf pointer and its
// care about parameters after SSL_ERROR_WANT_READ or // length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
// SSL_ERROR_WANT_WRITE. // get_write_limit() may return smaller length than previously
len = std::min(len, wlimit.avail()); // passed to SSL_write, which violates OpenSSL assumption. To avoid
len = std::min(len, get_tls_write_limit()); // this, we keep last legnth passed to SSL_write to
if (len == 0) { // tls.last_writelen if SSL_write indicated I/O blocking.
return 0; 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); 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; return SHRPX_ERR_NETWORK;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
tls.last_writelen = len;
wlimit.startw(); wlimit.startw();
ev_timer_again(loop, &wt); ev_timer_again(loop, &wt);
return 0; 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) { ssize_t Connection::read_tls(void *data, size_t len) {
// Although SSL_read manual says it requires the same arguments (buf // SSL_read requires the same arguments (buf pointer and its
// pointer and its length) on SSL_ERROR_WANT_READ or // length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
// SSL_ERROR_WANT_WRITE. But after reading OpenSSL source code, // rlimit_.avail() or rlimit_.avail() may return different length
// there is no such requirement. // than the length previously passed to SSL_read, which violates
len = std::min(len, rlimit.avail()); // OpenSSL assumption. To avoid this, we keep last legnth passed
if (len == 0) { // to SSL_read to tls_last_readlen_ if SSL_read indicated I/O
return 0; // 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); 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); auto err = SSL_get_error(tls.ssl, rv);
switch (err) { switch (err) {
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
tls.last_readlen = len;
return 0; return 0;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {

View File

@ -42,6 +42,10 @@ struct TLSConnection {
SSL *ssl; SSL *ssl;
ev_tstamp last_write_time; ev_tstamp last_write_time;
size_t warmup_writelen; 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 initial_handshake_done;
bool reneg_started; bool reneg_started;
}; };

View File

@ -24,7 +24,9 @@
*/ */
#include "shrpx_connection_handler.h" #include "shrpx_connection_handler.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>

View File

@ -28,7 +28,9 @@
#include "shrpx.h" #include "shrpx.h"
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#include <memory> #include <memory>
#include <vector> #include <vector>

View File

@ -27,8 +27,7 @@
#include "shrpx.h" #include "shrpx.h"
#include <stdint.h> #include <cinttypes>
#include <vector> #include <vector>
#include <string> #include <string>
#include <memory> #include <memory>

View File

@ -27,8 +27,7 @@
#include "shrpx.h" #include "shrpx.h"
#include <stdint.h> #include <cinttypes>
#include <map> #include <map>
#include <set> #include <set>
#include <memory> #include <memory>

View File

@ -25,6 +25,10 @@
#ifndef SHRPX_DOWNSTREAM_TEST_H #ifndef SHRPX_DOWNSTREAM_TEST_H
#define SHRPX_DOWNSTREAM_TEST_H #define SHRPX_DOWNSTREAM_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace shrpx { namespace shrpx {
void test_downstream_index_request_headers(void); void test_downstream_index_request_headers(void);

View File

@ -24,7 +24,9 @@
*/ */
#include "shrpx_http2_downstream_connection.h" #include "shrpx_http2_downstream_connection.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include "http-parser/http_parser.h" #include "http-parser/http_parser.h"

View File

@ -25,7 +25,9 @@
#include "shrpx_http2_session.h" #include "shrpx_http2_session.h"
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <vector> #include <vector>

View File

@ -27,8 +27,7 @@
#include "shrpx.h" #include "shrpx.h"
#include <stdint.h> #include <cinttypes>
#include <memory> #include <memory>
#include "http-parser/http_parser.h" #include "http-parser/http_parser.h"

View File

@ -24,9 +24,15 @@
*/ */
#include "shrpx_log.h" #include "shrpx_log.h"
#ifdef HAVE_SYSLOG_H
#include <syslog.h> #include <syslog.h>
#endif // HAVE_SYSLOG_H
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_INTTYPES_H
#include <inttypes.h> #include <inttypes.h>
#endif // HAVE_INTTYPES_H
#include <cerrno> #include <cerrno>
#include <cstdio> #include <cstdio>

View File

@ -24,8 +24,12 @@
*/ */
#include "shrpx_ssl.h" #include "shrpx_ssl.h"
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <pthread.h> #include <pthread.h>
#include <sys/types.h> #include <sys/types.h>
@ -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_AUTO_RETRY);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS); 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) { if (get_config()->private_key_passwd) {
SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb); SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb);
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)get_config()); 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_AUTO_RETRY);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS); 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) { if (SSL_CTX_set_default_verify_paths(ssl_ctx) != 1) {
LOG(WARN) << "Could not load system trusted ca certificates: " LOG(WARN) << "Could not load system trusted ca certificates: "

View File

@ -25,6 +25,10 @@
#ifndef SHRPX_SSL_TEST_H #ifndef SHRPX_SSL_TEST_H
#define SHRPX_SSL_TEST_H #define SHRPX_SSL_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace shrpx { namespace shrpx {
void test_shrpx_ssl_create_lookup_tree(void); void test_shrpx_ssl_create_lookup_tree(void);

View File

@ -24,7 +24,9 @@
*/ */
#include "shrpx_worker.h" #include "shrpx_worker.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <memory> #include <memory>

View File

@ -26,7 +26,7 @@
#ifndef HAVE_TIMEGM #ifndef HAVE_TIMEGM
#include <stdint.h> #include <inttypes.h>
/* Counter the number of leap year in the range [0, y). The |y| is the /* Counter the number of leap year in the range [0, y). The |y| is the
year, including century (e.g., 2012) */ year, including century (e.g., 2012) */

View File

@ -33,7 +33,9 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#ifdef HAVE_TIME_H
#include <time.h> #include <time.h>
#endif // HAVE_TIME_H
#ifndef HAVE_TIMEGM #ifndef HAVE_TIMEGM

View File

@ -24,15 +24,27 @@
*/ */
#include "util.h" #include "util.h"
#ifdef HAVE_TIME_H
#include <time.h> #include <time.h>
#endif // HAVE_TIME_H
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h> #include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H
#include <cmath> #include <cmath>
#include <cerrno> #include <cerrno>

View File

@ -27,9 +27,13 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H
#include <getopt.h> #include <getopt.h>
#ifdef HAVE_NETDB_H
#include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>

View File

@ -25,6 +25,10 @@
#ifndef UTIL_TEST_H #ifndef UTIL_TEST_H
#define UTIL_TEST_H #define UTIL_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace shrpx { namespace shrpx {
void test_util_streq(void); void test_util_streq(void);

View File

@ -340,6 +340,8 @@ int main(int argc _U_, char *argv[] _U_) {
!CU_add_test(pSuite, "check_header_value", !CU_add_test(pSuite, "check_header_value",
test_nghttp2_check_header_value) || test_nghttp2_check_header_value) ||
!CU_add_test(pSuite, "bufs_add", test_nghttp2_bufs_add) || !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_addb", test_nghttp2_bufs_addb) ||
!CU_add_test(pSuite, "bufs_orb", test_nghttp2_bufs_orb) || !CU_add_test(pSuite, "bufs_orb", test_nghttp2_bufs_orb) ||
!CU_add_test(pSuite, "bufs_remove", test_nghttp2_bufs_remove) || !CU_add_test(pSuite, "bufs_remove", test_nghttp2_bufs_remove) ||

View File

@ -63,6 +63,26 @@ void test_nghttp2_bufs_add(void) {
nghttp2_bufs_free(&bufs); 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) { void test_nghttp2_bufs_addb(void) {
int rv; int rv;
nghttp2_bufs bufs; nghttp2_bufs bufs;

View File

@ -26,6 +26,7 @@
#define NGHTTP2_BUF_TEST_H #define NGHTTP2_BUF_TEST_H
void test_nghttp2_bufs_add(void); 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_addb(void);
void test_nghttp2_bufs_orb(void); void test_nghttp2_bufs_orb(void);
void test_nghttp2_bufs_remove(void); void test_nghttp2_bufs_remove(void);