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.
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.

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
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 \
])

View File

@ -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

View File

@ -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=<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 <FILE>, URIs will be read from stdin.
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
h2load(1)
@ -46,7 +48,7 @@ OPTIONS
.. 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.
If '-' is given as <FILE>, URIs will be read from stdin.
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 = 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):

View File

@ -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
.

View File

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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

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
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.

View File

@ -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

View File

@ -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;

View File

@ -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.

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,
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

View File

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

View File

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

View File

@ -24,12 +24,18 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* !HAVE_CONFIG_H */
#endif /* HAVE_CONFIG_H */
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h>
#include <err.h>
#include <signal.h>
@ -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 */

View File

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

View File

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

View File

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

View File

@ -36,7 +36,7 @@ extern "C" {
#endif
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.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);
p += len;
p += nwrite;
len -= nwrite;
}

View File

@ -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);

View File

@ -25,13 +25,25 @@
#include "HttpServer.h"
#include <sys/stat.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif // HAVE_NETDB_H
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif // HAVE_UNISTD_H
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif // HAVE_FCNTL_H
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H
#include <cassert>
#include <set>
@ -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);

View File

@ -27,9 +27,9 @@
#include "nghttp2_config.h"
#include <stdint.h>
#include <sys/types.h>
#include <cinttypes>
#include <cstdlib>
#include <string>
@ -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();
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,7 +26,9 @@
#include <config.h>
#endif // HAVE_CONFIG_H
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif // HAVE_UNISTD_H
#include <getopt.h>
#include <cstdio>
@ -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) {

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,9 @@
*/
#include "nghttp2_config.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif // HAVE_UNISTD_H
#include <signal.h>
#include <getopt.h>
@ -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:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,9 @@
*/
#include "shrpx_connection.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif // HAVE_UNISTD_H
#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) {
// 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)) {

View File

@ -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;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,8 +24,12 @@
*/
#include "shrpx_ssl.h"
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif // HAVE_NETDB_H
#include <netinet/tcp.h>
#include <pthread.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_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: "

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,10 @@
#ifndef UTIL_TEST_H
#define UTIL_TEST_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H
namespace shrpx {
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",
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) ||

View File

@ -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;

View File

@ -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);