You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2015/12/29 16:30:10 UTC
svn commit: r1722149 - in /httpd/test/mod_h2/trunk: ./ mh2fuzz/
Author: icing
Date: Tue Dec 29 15:30:09 2015
New Revision: 1722149
URL: http://svn.apache.org/viewvc?rev=1722149&view=rev
Log:
own http2 test client with multiple threads/connection/requests, using nghttp2+apr, tls+POST support lacking, fuzzing tests to be done
Added:
httpd/test/mod_h2/trunk/mh2fuzz/ (with props)
httpd/test/mod_h2/trunk/mh2fuzz/Makefile.am
httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.c
httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.h
httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.c
httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.h
httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.c
httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.h
httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.c
httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.h
httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.c
httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.h
httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.c
httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.h
httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.c
httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.h
httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.c
httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.h
httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h
httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h.in
Modified:
httpd/test/mod_h2/trunk/ (props changed)
httpd/test/mod_h2/trunk/Makefile.am
httpd/test/mod_h2/trunk/configure.ac
Propchange: httpd/test/mod_h2/trunk/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Dec 29 15:30:09 2015
@@ -12,6 +12,7 @@ install-sh
libtool
ltmain.sh
missing
+depcomp
gen
Modified: httpd/test/mod_h2/trunk/Makefile.am
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/Makefile.am?rev=1722149&r1=1722148&r2=1722149&view=diff
==============================================================================
--- httpd/test/mod_h2/trunk/Makefile.am (original)
+++ httpd/test/mod_h2/trunk/Makefile.am Tue Dec 29 15:30:09 2015
@@ -13,7 +13,7 @@
# limitations under the License.
#
SUBDIRS = @BUILD_SUBDIRS@
-DIST_SUBDIRS = nghttp2 test clients bin conf htdocs
+DIST_SUBDIRS = nghttp2 test clients bin conf htdocs mh2fuzz
ACLOCAL_AMFLAGS = -I m4
@@ -102,7 +102,10 @@ install-nghttp2:
install-client:
@make -C clients install
-install: @INSTALL_DEP@
+install-mh2fuzz:
+ @make -C mh2fuzz install
+
+install: install-mh2fuzz @INSTALL_DEP@
################################################################################
# Test the local httpd
Modified: httpd/test/mod_h2/trunk/configure.ac
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/configure.ac?rev=1722149&r1=1722148&r2=1722149&view=diff
==============================================================================
--- httpd/test/mod_h2/trunk/configure.ac (original)
+++ httpd/test/mod_h2/trunk/configure.ac Tue Dec 29 15:30:09 2015
@@ -14,7 +14,7 @@
#
AC_PREREQ([2.67])
-AC_INIT([mod_h2_test], [0.0.2], [stefan.eissing@greenbytes.de])
+AC_INIT([mod_h2_test], [1.0.15-DEV], [stefan.eissing@greenbytes.de])
LT_PREREQ([2.2.6])
LT_INIT()
@@ -59,7 +59,7 @@ AC_ARG_WITH([nghttp2-version], [AS_HELP_
[NGHTTP2_VERSION_EXACT=$withval], [NGHTTP2_VERSION_EXACT=])
-export BUILD_SUBDIRS="clients"
+export BUILD_SUBDIRS="clients mh2fuzz"
AC_MSG_NOTICE("configuring build")
@@ -92,7 +92,8 @@ if test -x "${APXS}"; then
APACHECTL="$ap_bindir/apachectl"
HTTPD="$ap_bindir/httpd"
- LDFLAGS="$LDFLAGS -L$($APXS -q libdir)"
+ LIB_DIR="$($APXS -q libdir)"
+ LDFLAGS="$LDFLAGS -L$LIB_DIR"
CPPFLAGS="$CPPFLAGS -I$($APXS -q includedir) -I$($APXS -q APR_INCLUDEDIR)"
export SYSCONF_DIR="$($APXS -q sysconfdir)"
export LIBEXEC_DIR="$($APXS -q LIBEXECDIR)"
@@ -107,7 +108,8 @@ else
APACHECTL="${ap_bindir}/apachectl"
HTTPD="${ap_bindir}/httpd"
- LDFLAGS="$LDFLAGS -L${ap_prefix}/lib"
+ LIB_DIR="${ap_prefix}/lib"
+ LDFLAGS="$LDFLAGS -L$LIB_DIR"
CPPFLAGS="$CPPFLAGS -I${ap_prefix}/include"
export SYSCONF_DIR="${ap_prefix}/conf"
export LIBEXEC_DIR="$MODULES"
@@ -330,6 +332,7 @@ fi
# substitution in generated files
AC_SUBST(BUILD_SUBDIRS)
AC_SUBST(SYSCONF_DIR)
+AC_SUBST(LIB_DIR)
AC_SUBST(LIBEXEC_DIR)
AC_SUBST(SERVER_NAME)
AC_SUBST(ABS_PWD)
@@ -359,6 +362,8 @@ AC_CONFIG_FILES([
Makefile
nghttp2/Makefile
clients/Makefile
+ mh2fuzz/Makefile
+ mh2fuzz/mh2f_version.h
])
AC_OUTPUT
Propchange: httpd/test/mod_h2/trunk/mh2fuzz/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Dec 29 15:30:09 2015
@@ -0,0 +1,4 @@
+mh2fuzz
+Makefile
+Makefile.in
+.deps
Added: httpd/test/mod_h2/trunk/mh2fuzz/Makefile.am
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/Makefile.am?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/Makefile.am (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/Makefile.am Tue Dec 29 15:30:09 2015
@@ -0,0 +1,33 @@
+# Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ACLOCAL_AMFLAGS = -I m4
+
+AUTOMAKE_OPTIONS = foreign
+
+CFLAGS= -g
+LDFLAGS=-L@LIB_DIR@ -lapr-1 -laprutil-1
+
+bin_PROGRAMS = mh2fuzz
+
+mh2fuzz_SOURCES = \
+ mh2f_main.c \
+ h2c_conn.c \
+ h2c_feed.c \
+ h2c_request.c \
+ h2c_util.c \
+ h2c_session.c \
+ h2c_stream.c \
+ h2c_worker.c
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.c
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.c?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.c (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.c Tue Dec 29 15:30:09 2015
@@ -0,0 +1,220 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apr.h>
+#include <apr_strings.h>
+#include <apr_poll.h>
+#include <apr_uri.h>
+
+#include <nghttp2/nghttp2.h>
+
+#include "h2c_conn.h"
+#include "h2c_util.h"
+
+static long cid;
+
+static apr_size_t BUF_SIZE = 16 * 1024;
+
+static apr_status_t read_plain(h2c_conn *c)
+{
+ char buffer[16*1024];
+ apr_size_t len = H2_DIM(buffer);
+ apr_status_t status;
+
+ status = apr_socket_recv(c->socket, buffer, &len);
+ if (len > 0) {
+ apr_status_t s2 = h2c_conn_on_read(c, buffer, len);
+ if (status == APR_SUCCESS) {
+ status = s2;
+ }
+ }
+ return status;
+}
+
+static apr_status_t write_plain(h2c_conn *c)
+{
+ apr_status_t status = APR_SUCCESS;
+ if (c->buf_len > 0) {
+ apr_size_t len = c->buf_len;
+ status = apr_socket_send(c->socket, c->buffer + c->buf_head, &len);
+ if (len > 0) {
+ c->buf_head += len;
+ c->buf_len -= len;
+ }
+ }
+ return status;
+}
+
+apr_status_t h2c_conn_create(h2c_conn **pc, apr_pool_t *parent, apr_uri_t *uri)
+{
+ apr_pool_t *p;
+ apr_status_t status;
+ apr_sockaddr_t *addr;
+ char *ip;
+ h2c_conn *c;
+
+ status = apr_pool_create(&p, parent);
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ c = apr_pcalloc(p, sizeof(*c));
+
+ c->id = cid++;
+ c->pool = p;
+ c->uri = uri;
+ c->authority = apr_psprintf(p, "%s:%d", uri->hostname, uri->port);
+ c->read = read_plain;
+ c->write = write_plain;
+
+ c->buf_size = BUF_SIZE;
+ c->buffer = apr_pcalloc(p, c->buf_size);
+ c->buf_head = 0;
+ c->buf_len = 0;
+
+ status = apr_sockaddr_info_get(&c->addr, uri->hostname, APR_UNSPEC,
+ uri->port, 0, p);
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ apr_sockaddr_ip_get(&ip, c->addr);
+ c->ip_addr = ip;
+
+ status = apr_socket_create(&c->socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, p);
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ c->pfd = apr_pcalloc(p, sizeof *c->pfd);
+ c->pfd->desc_type = APR_POLL_SOCKET;
+ c->pfd->desc.s = c->socket;
+ c->pfd->reqevents = APR_POLLIN|APR_POLLOUT;
+ c->pfd->client_data = c;
+
+ *pc = c;
+
+ return APR_SUCCESS;
+}
+
+void h2c_conn_destroy(h2c_conn *c)
+{
+ if (c->pool) {
+ apr_pool_destroy(c->pool);
+ }
+}
+
+void h2c_conn_want_io(h2c_conn *c, int flags)
+{
+ int pf = 0;
+ if (flags & H2C_CONN_READ) {
+ pf |= APR_POLLIN;
+ }
+ if (flags & H2C_CONN_WRITE) {
+ pf |= APR_POLLOUT;
+ }
+ c->pfd->reqevents = pf;
+}
+
+apr_status_t h2c_conn_on_connect(h2c_conn *c)
+{
+ if (c->on_connect) {
+ return c->on_connect(c, c->cb_ctx);
+ }
+ return APR_SUCCESS;
+}
+
+apr_status_t h2c_conn_on_read(h2c_conn *c, const char *data, apr_size_t len)
+{
+ if (c->on_read) {
+ return c->on_read(c, data, len, c->cb_ctx);
+ }
+ return APR_SUCCESS;
+}
+
+apr_status_t h2c_conn_on_write(h2c_conn *c)
+{
+ if (c->on_write) {
+ return c->on_write(c, c->cb_ctx);
+ }
+ return APR_SUCCESS;
+}
+
+void h2c_conn_set_callback(h2c_conn *c,
+ h2c_conn_on_connect_cb *on_connect,
+ h2c_conn_on_read_cb *on_read,
+ h2c_conn_on_write_cb *on_write,
+ h2c_conn_before_close *before_close,
+ void *ctx)
+{
+ c->on_connect = on_connect;
+ c->on_read = on_read;
+ c->on_write = on_write;
+ c->before_close = before_close;
+ c->cb_ctx = ctx;
+}
+
+apr_status_t h2c_conn_read(h2c_conn *c)
+{
+ if (!c->socket) {
+ return APR_EOF;
+ }
+ return c->read(c);
+}
+
+apr_status_t h2c_conn_write(h2c_conn *c)
+{
+ if (!c->socket) {
+ return APR_EOF;
+ }
+ return c->write(c);
+}
+
+apr_status_t h2c_conn_close(h2c_conn *c)
+{
+ apr_status_t status = APR_SUCCESS;
+
+ if (c->socket) {
+ if (c->before_close) {
+ c->before_close(c, c->cb_ctx);
+ }
+ status = apr_socket_close(c->socket);
+ c->socket = NULL;
+ }
+ return status;
+}
+
+int h2c_conn_wbuf_empty(h2c_conn *c)
+{
+ return c->buf_len == 0;
+}
+
+apr_size_t h2c_conn_wbuf_left(h2c_conn *c)
+{
+ return c->buf_size - (c->buf_head + c->buf_len);
+}
+
+apr_size_t h2c_conn_wbuf_append(h2c_conn *c, const char *data, apr_size_t len)
+{
+ len = H2_MIN(h2c_conn_wbuf_left(c), len);
+ if (len > 0) {
+ if (c->buf_head && c->buf_len == 0) {
+ c->buf_head = 0;
+ }
+ memcpy(c->buffer + c->buf_head + c->buf_len, data, len);
+ c->buf_len += len;
+ }
+ return len;
+}
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_conn.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,83 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef h2c_conn_h
+#define h2c_conn_h
+
+struct apr_pollfd_t;
+
+typedef struct h2c_conn h2c_conn;
+
+typedef apr_status_t h2c_conn_on_connect_cb(h2c_conn *c, void *ctx);
+typedef apr_status_t h2c_conn_on_read_cb(h2c_conn *c, const char *data, apr_size_t len, void *ctx);
+typedef apr_status_t h2c_conn_on_write_cb(h2c_conn *c, void *ctx);
+typedef apr_status_t h2c_conn_before_close(h2c_conn *c, void *ctx);
+typedef apr_status_t h2c_conn_action(h2c_conn *c);
+
+#define H2C_CONN_READ 0x01
+#define H2C_CONN_WRITE 0x04
+
+struct h2c_conn {
+ long id;
+ apr_pool_t *pool;
+ apr_uri_t *uri;
+ struct apr_pollfd_t *pfd;
+ const char *authority;
+ apr_sockaddr_t *addr;
+ const char *ip_addr;
+ apr_socket_t *socket;
+
+ h2c_conn_action *read;
+ h2c_conn_action *write;
+
+ char *buffer;
+ apr_size_t buf_size;
+ apr_size_t buf_head;
+ apr_size_t buf_len;
+
+ void *cb_ctx;
+ h2c_conn_on_connect_cb *on_connect;
+ h2c_conn_on_read_cb *on_read;
+ h2c_conn_on_write_cb *on_write;
+ h2c_conn_before_close *before_close;
+};
+
+apr_status_t h2c_conn_create(h2c_conn **pc, apr_pool_t *parent, apr_uri_t *uri);
+
+void h2c_conn_destroy(h2c_conn *c);
+
+void h2c_conn_set_callback(h2c_conn *c,
+ h2c_conn_on_connect_cb *on_connect,
+ h2c_conn_on_read_cb *on_read,
+ h2c_conn_on_write_cb *on_write,
+ h2c_conn_before_close *before_close,
+ void *ctx);
+
+apr_status_t h2c_conn_on_connect(h2c_conn *c);
+apr_status_t h2c_conn_on_read(h2c_conn *c, const char *data, apr_size_t len);
+apr_status_t h2c_conn_on_write(h2c_conn *c);
+
+void h2c_conn_want_io(h2c_conn *c, int flags);
+
+apr_status_t h2c_conn_read(h2c_conn *c);
+apr_status_t h2c_conn_write(h2c_conn *c);
+
+apr_status_t h2c_conn_close(h2c_conn *c);
+
+apr_size_t h2c_conn_wbuf_left(h2c_conn *c);
+int h2c_conn_wbuf_empty(h2c_conn *c);
+
+apr_size_t h2c_conn_wbuf_append(h2c_conn *c, const char *data, apr_size_t len);
+
+#endif /* h2c_conn_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.c
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.c?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.c (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.c Tue Dec 29 15:30:09 2015
@@ -0,0 +1,53 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apr.h>
+#include <apr_strings.h>
+#include <apr_uri.h>
+
+#include "h2c_request.h"
+#include "h2c_session.h"
+#include "h2c_feed.h"
+
+static apr_status_t repeat_next(h2c_request **pr, h2c_feed *feed, h2c_session *s)
+{
+ if (feed->x.repeat.n > 0) {
+ --feed->x.repeat.n;
+ *pr = feed->x.repeat.r;
+ return APR_SUCCESS;
+ }
+ else {
+ return APR_EOF;
+ }
+}
+
+apr_status_t h2c_feed_repeat_create(h2c_feed **pf, apr_pool_t *p,
+ struct h2c_request *r, int n)
+{
+ h2c_feed *f;
+
+ f = apr_pcalloc(p, sizeof(*f));
+ f->x.repeat.n = n;
+ f->x.repeat.r = r;
+ f->next_fn = repeat_next;
+
+ *pf = f;
+ return APR_SUCCESS;
+}
+
+apr_status_t h2c_feed_next(h2c_request **pr, h2c_feed *feed, h2c_session *s)
+{
+ return feed->next_fn(pr, feed, s);
+}
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_feed.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,44 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef h2c_feed_h
+#define h2c_feed_h
+
+struct h2c_request;
+struct h2c_session;
+
+typedef struct h2c_feed h2c_feed;
+
+typedef apr_status_t h2c_feed_next_fn(struct h2c_request **pr, h2c_feed *feed,
+ struct h2c_session *s);
+
+typedef struct h2c_feed_repeat {
+ int n;
+ struct h2c_request *r;
+} h2c_feed_repeat;
+
+struct h2c_feed {
+ union {
+ h2c_feed_repeat repeat;
+ } x;
+ h2c_feed_next_fn *next_fn;
+};
+
+apr_status_t h2c_feed_repeat_create(h2c_feed **pf, apr_pool_t *p,
+ struct h2c_request *r, int n);
+
+apr_status_t h2c_feed_next(struct h2c_request **pr, h2c_feed *feed,
+ struct h2c_session *s);
+
+#endif /* h2c_feed_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.c
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.c?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.c (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.c Tue Dec 29 15:30:09 2015
@@ -0,0 +1,47 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apr.h>
+#include <apr_strings.h>
+#include <apr_uri.h>
+
+#include "h2c_request.h"
+
+apr_status_t h2c_request_create(h2c_request **pr, apr_pool_t *p,
+ const char *method, apr_uri_t *uri)
+{
+ h2c_request *r;
+
+ r = apr_pcalloc(p, sizeof(*r));
+
+ r->scheme = uri->scheme;
+ r->method = method;
+ if (uri->port != apr_uri_port_of_scheme(uri->scheme)) {
+ r->authority = apr_psprintf(p, "%s:%d", uri->hostname, uri->port);
+ }
+ else {
+ r->authority = uri->hostname;
+ }
+ r->path = apr_uri_unparse(p, uri, APR_URI_UNP_OMITSITEPART);
+ r->headers = apr_table_make(p, 5);
+
+ *pr = r;
+ return APR_SUCCESS;
+}
+
+void h2c_request_headers_set(h2c_request *r, const char *name, const char *val)
+{
+ apr_table_set(r->headers, name, val);
+}
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_request.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,36 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef h2c_request_h
+#define h2c_request_h
+
+struct apr_table_t;
+
+typedef struct h2c_request h2c_request;
+
+struct h2c_request {
+ const char *method;
+ const char *scheme;
+ const char *authority;
+ const char *path;
+
+ struct apr_table_t *headers;
+};
+
+apr_status_t h2c_request_create(h2c_request **pr, apr_pool_t *p,
+ const char *method, apr_uri_t *uri);
+
+void h2c_request_headers_set(h2c_request *r, const char *name, const char *val);
+
+#endif /* h2c_request_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.c
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.c?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.c (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.c Tue Dec 29 15:30:09 2015
@@ -0,0 +1,399 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apr.h>
+#include <apr_uri.h>
+
+#include <nghttp2/nghttp2.h>
+
+#include "h2c_conn.h"
+#include "h2c_feed.h"
+#include "h2c_request.h"
+#include "h2c_session.h"
+#include "h2c_stream.h"
+#include "h2c_util.h"
+
+static apr_status_t on_conn_connect(h2c_conn *c, void *ctx);
+static apr_status_t on_conn_read(h2c_conn *c, const char *data, size_t len, void *ctx);
+static apr_status_t on_conn_write(h2c_conn *c, void *ctx);
+static apr_status_t on_conn_close(h2c_conn *c, void *ctx);
+
+apr_status_t h2c_session_create(h2c_session **ps, h2c_conn *c, int max_streams)
+{
+ apr_pool_t *p;
+ apr_status_t status;
+ h2c_session *s;
+
+ s = apr_pcalloc(c->pool, sizeof(h2c_session));
+
+ s->c = c;
+ s->state = H2C_SESSION_ST_INIT;
+ s->output = stdout;
+ s->window_bits_default = 30;
+ s->window_bits_connection = 30;
+
+ s->max_streams = max_streams;
+
+ h2c_conn_set_callback(c, on_conn_connect, on_conn_read, on_conn_write,
+ on_conn_close, s);
+ *ps = s;
+
+ return APR_SUCCESS;
+}
+
+apr_status_t h2c_session_close(h2c_session *s)
+{
+ if (!s->closed) {
+ if (!s->goaway_recvd) {
+ nghttp2_submit_goaway(s->ngh2, NGHTTP2_FLAG_NONE,
+ s->max_stream_recv, 0, NULL, 0);
+ nghttp2_session_send(s->ngh2);
+ }
+ s->closed = 1;
+ }
+ return APR_SUCCESS;
+}
+
+void h2c_session_verbose_set(h2c_session *s, int verbose)
+{
+ s->verbose = verbose;
+}
+
+static ssize_t raw_send(nghttp2_session *session, const uint8_t *data,
+ size_t length, int flags, void *user_data)
+{
+ h2c_session *s = user_data;
+
+ if (h2c_conn_wbuf_left(s->c) == 0) {
+ return NGHTTP2_ERR_WOULDBLOCK;
+ }
+ return h2c_conn_wbuf_append(s->c, (const char*)data, length);
+}
+
+static void log_frame(h2c_session *s, const char *msg, const nghttp2_frame *frame)
+{
+ char scratch[128];
+ size_t s_len = sizeof(scratch)/sizeof(scratch[0]);
+ size_t len;
+
+ switch (frame->hd.type) {
+ case NGHTTP2_DATA:
+ fprintf(stderr, "%ld: %s DATA[length=%d, flags=%d, stream=%d, padlen=%d]\n",
+ s->c->id, msg, (int)frame->hd.length, frame->hd.flags,
+ frame->hd.stream_id, (int)frame->data.padlen);
+ break;
+
+ case NGHTTP2_HEADERS:
+ fprintf(stderr, "%ld: %s HEADERS[length=%d, hend=%d, stream=%d, eos=%d]\n",
+ s->c->id, msg, (int)frame->hd.length,
+ !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
+ frame->hd.stream_id,
+ !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
+ break;
+ case NGHTTP2_PRIORITY:
+ fprintf(stderr, "%ld: %s PRIORITY[length=%d, flags=%d, stream=%d]\n",
+ s->c->id, msg, (int)frame->hd.length,
+ frame->hd.flags, frame->hd.stream_id);
+ break;
+ case NGHTTP2_RST_STREAM:
+ fprintf(stderr, "%ld: %s RST_STREAM[length=%d, flags=%d, stream=%d]\n",
+ s->c->id, msg, (int)frame->hd.length,
+ frame->hd.flags, frame->hd.stream_id);
+ break;
+ case NGHTTP2_SETTINGS:
+ if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
+ fprintf(stderr, "%ld: %s SETTINGS[ack=1, stream=%d]\n",
+ s->c->id, msg, frame->hd.stream_id);
+ return;
+ }
+ fprintf(stderr, "%ld: %s SETTINGS[length=%d, stream=%d]\n",
+ s->c->id, msg, (int)frame->hd.length, frame->hd.stream_id);
+ break;
+ case NGHTTP2_PUSH_PROMISE:
+ fprintf(stderr, "%ld: %s PUSH_PROMISE[length=%d, hend=%d, stream=%d]\n",
+ s->c->id, msg, (int)frame->hd.length,
+ !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
+ frame->hd.stream_id);
+ break;
+ case NGHTTP2_PING:
+ fprintf(stderr, "%ld: %s PING[length=%d, ack=%d, stream=%d]\n",
+ s->c->id, msg, (int)frame->hd.length,
+ frame->hd.flags&NGHTTP2_FLAG_ACK,
+ frame->hd.stream_id);
+ break;
+ case NGHTTP2_GOAWAY:
+ len = ((frame->goaway.opaque_data_len < s_len)?
+ frame->goaway.opaque_data_len : s_len-1);
+ memcpy(scratch, frame->goaway.opaque_data, len);
+ scratch[len+1] = '\0';
+ fprintf(stderr, "%ld: %s GOAWAY[error=%d, reason='%s']\n",
+ s->c->id, msg, frame->goaway.error_code, scratch);
+ break;
+ case NGHTTP2_WINDOW_UPDATE:
+ fprintf(stderr, "%ld: %s WINDOW_UPDATE[length=%d, stream=%d]\n",
+ s->c->id, msg, (int)frame->hd.length, frame->hd.stream_id);
+ break;
+ default:
+ fprintf(stderr, "%ld: %s type=%d[length=%d, flags=%d, stream=%d]\n",
+ s->c->id, msg, frame->hd.type, (int)frame->hd.length,
+ frame->hd.flags, frame->hd.stream_id);
+ break;
+ }
+}
+
+static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
+ void *user_data)
+{
+ h2c_session *s = user_data;
+
+ if (s->verbose > 0) {
+ log_frame(s, "recv", frame);
+ }
+ switch (frame->hd.type) {
+ case NGHTTP2_GOAWAY:
+ s->goaway_recvd = 1;
+ h2c_session_close(s);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int before_frame_send(nghttp2_session *session,
+ const nghttp2_frame *frame, void *user_data)
+{
+ h2c_session *s = user_data;
+
+ if (s->verbose > 0) {
+ log_frame(s, "send", frame);
+ }
+ return 0;
+}
+
+static int on_data_chunk_recv(nghttp2_session *ngh2, uint8_t flags,
+ int32_t stream_id, const uint8_t *data,
+ size_t len, void *user_data)
+{
+ h2c_session *s = user_data;
+ h2c_stream *stream = nghttp2_session_get_stream_user_data(ngh2, stream_id);
+
+ nghttp2_session_consume(ngh2, stream_id, len);
+
+ if (!stream) {
+ fprintf(stderr, "stream %d not found", stream_id);
+ return 0;
+ }
+
+ h2c_stream_resp_append(stream, (const char *)data, len);
+ return 0;
+}
+
+static int on_stream_close(nghttp2_session *ngh2, int32_t stream_id,
+ uint32_t error_code, void *user_data)
+{
+ h2c_session *s = user_data;
+ h2c_stream *stream;
+
+ if (s->verbose > 0) {
+ fprintf(stderr, "closed STREAM[%d]\n", stream_id);
+ }
+
+ --s->open_streams;
+ if (!s->closed && s->open_streams <= 0) {
+ s->state = H2C_SESSION_ST_IDLE;
+ }
+
+ stream = nghttp2_session_get_stream_user_data(ngh2, stream_id);
+ if (!stream) {
+ fprintf(stderr, "stream %d not found", stream_id);
+ return 0;
+ }
+
+ h2c_stream_close(stream);
+
+ return 0;
+}
+
+static int on_header(nghttp2_session *ngh2, const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen, uint8_t flags,
+ void *user_data)
+{
+ h2c_session *s = user_data;
+ h2c_stream *stream = nghttp2_session_get_stream_user_data(ngh2, frame->hd.stream_id);
+
+ if (!stream) {
+ fprintf(stderr, "stream %d not found", frame->hd.stream_id);
+ return 0;
+ }
+ h2c_stream_resp_add(stream, (const char *)name, namelen,
+ (const char *)value, valuelen);
+
+ return 0;
+}
+
+static apr_status_t check_io_sense(h2c_session *s, apr_status_t status)
+{
+ int io_sense = 0;
+
+ if (s->feed && s->max_streams > s->open_streams) {
+ h2c_request *r;
+
+ status = h2c_feed_next(&r, s->feed, s);
+ if (status == APR_SUCCESS) {
+ status = h2c_session_submit(s, r, NULL);
+ }
+ else if (APR_STATUS_IS_EOF(status) && s->state == H2C_SESSION_ST_IDLE) {
+ h2c_session_close(s);
+ }
+ }
+
+ if (nghttp2_session_want_read(s->ngh2)) {
+ io_sense |= H2C_CONN_READ;
+ }
+ if (nghttp2_session_want_write(s->ngh2) || !h2c_conn_wbuf_empty(s->c)) {
+ io_sense |= H2C_CONN_WRITE;
+ }
+ if (!io_sense) {
+ return APR_EOF;
+ }
+
+ h2c_conn_want_io(s->c, io_sense);
+ return status;
+}
+
+static apr_status_t on_conn_read(h2c_conn *c, const char *data, size_t len, void *ctx)
+{
+ h2c_session *s = ctx;
+
+ ssize_t rv = nghttp2_session_mem_recv(s->ngh2, (const uint8_t*)data, len);
+ if (rv < 0) {
+ return APR_ECONNRESET;
+ }
+
+ return check_io_sense(s, APR_SUCCESS);
+}
+
+static apr_status_t on_conn_write(h2c_conn *c, void *ctx)
+{
+ h2c_session *s = ctx;
+ apr_status_t status = APR_SUCCESS;
+ int rv = nghttp2_session_send(s->ngh2);
+
+ if (rv != 0) {
+ return APR_ECONNRESET;
+ }
+
+ return check_io_sense(s, status);
+}
+
+static apr_status_t on_conn_connect(h2c_conn *c, void *ctx)
+{
+ h2c_session *s = ctx;
+ nghttp2_session_callbacks *cbs;
+ nghttp2_settings_entry settings[2];
+ int add_conn_window;
+ int rv;
+
+ nghttp2_session_callbacks_new(&cbs);
+
+ nghttp2_session_callbacks_set_on_frame_recv_callback(cbs, on_frame_recv);
+ nghttp2_session_callbacks_set_on_data_chunk_recv_callback(cbs, on_data_chunk_recv);
+ nghttp2_session_callbacks_set_on_stream_close_callback(cbs, on_stream_close);
+ nghttp2_session_callbacks_set_on_header_callback(cbs, on_header);
+ nghttp2_session_callbacks_set_before_frame_send_callback(cbs, before_frame_send);
+ nghttp2_session_callbacks_set_send_callback(cbs, raw_send);
+
+ nghttp2_session_client_new(&s->ngh2, cbs, s);
+
+ nghttp2_session_callbacks_del(cbs);
+
+ settings[0].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
+ settings[0].value = 0;
+ settings[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
+ settings[1].value = (1 << s->window_bits_default) - 1;
+
+ rv = nghttp2_submit_settings(s->ngh2, NGHTTP2_FLAG_NONE, settings, H2_DIM(settings));
+
+ /* If the connection window is larger than our default, trigger a WINDOW_UPDATE */
+ add_conn_window = ((1 << s->window_bits_connection) - 1 -
+ NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE);
+ if (!rv && add_conn_window != 0) {
+ rv = nghttp2_submit_window_update(s->ngh2, NGHTTP2_FLAG_NONE, 0, add_conn_window);
+ }
+
+ s->state = H2C_SESSION_ST_IDLE;
+
+ h2c_conn_want_io(c, H2C_CONN_READ|H2C_CONN_WRITE);
+ return rv? APR_EGENERAL : APR_SUCCESS;
+}
+
+static apr_status_t on_conn_close(h2c_conn *c, void *ctx)
+{
+ return h2c_session_close(ctx);
+}
+
+
+apr_status_t h2c_session_submit(h2c_session *s, struct h2c_request *r, int *pid)
+{
+ nghttp2_nv *nva;
+ size_t nvlen = 0;
+ h2c_ngheader *ngh;
+ h2c_stream *stream;
+ int stream_id;
+ apr_status_t status;
+
+ if (s->closed) {
+ return APR_EOF;
+ }
+
+ if (s->open_streams >= s->max_streams) {
+ return APR_EAGAIN;
+ }
+
+ status = h2c_stream_create(&stream, s->c->pool, s, r, s->output);
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ ngh = h2c_util_ngheader_make_req(s->c->pool, r->headers, r->scheme,
+ r->method, r->authority, r->path);
+ stream_id = nghttp2_submit_request(s->ngh2, NULL, ngh->nv, ngh->nvlen,
+ NULL, stream);
+ if (stream_id < 0) {
+ return APR_EGENERAL;
+ }
+
+ s->state = H2C_SESSION_ST_BUSY;
+ s->max_stream_sent = H2_MAX(s->max_stream_sent, stream_id);
+ ++s->open_streams;
+ stream->id = stream_id;
+
+ if (pid) {
+ *pid = stream_id;
+ }
+ return check_io_sense(s, APR_SUCCESS);
+}
+
+void h2c_session_output_set(h2c_session *s, FILE *output)
+{
+ s->output = output;
+}
+
+void h2c_session_feed_set(h2c_session *s, h2c_feed *feed)
+{
+ s->feed = feed;
+}
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_session.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,78 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef h2c_session_h
+#define h2c_session_h
+
+#include <apr_uri.h>
+
+struct h2c_conn;
+struct h2c_feed;
+struct h2c_request;
+struct h2c_stream;
+struct nghttp2_session;
+
+typedef struct h2c_session h2c_session;
+
+typedef enum {
+ H2C_SESSION_ST_INIT, /* send initial SETTINGS, etc. */
+ H2C_SESSION_ST_IDLE, /* nothing submitted */
+ H2C_SESSION_ST_BUSY, /* read/write without stop */
+ H2C_SESSION_ST_BUSY_READ, /* waiting for data from server */
+ H2C_SESSION_ST_KEEPALIVE, /* IDLE passed, hanging around */
+ H2C_SESSION_ST_CLOSING, /* shutting down */
+} h2c_session_state;
+
+struct h2c_session {
+ struct h2c_conn *c;
+ struct nghttp2_session *ngh2;
+
+ h2c_session_state state;
+ unsigned int closed : 1;
+ unsigned int goaway_recvd : 1;
+ int verbose;
+
+ int max_stream_recv;
+ int max_stream_sent;
+
+ int max_streams;
+ int open_streams;
+
+ int window_bits_default;
+ int window_bits_connection;
+
+ FILE *output;
+
+ struct h2c_feed *feed;
+};
+
+
+apr_status_t h2c_session_create(h2c_session **psession, struct h2c_conn *c,
+ int max_streams);
+
+apr_status_t h2c_session_add_request(h2c_session *session, struct h2c_request *r);
+
+apr_status_t h2c_session_close(h2c_session *session);
+
+void h2c_session_verbose_set(h2c_session *s, int verbose);
+
+apr_status_t h2c_session_on_read(h2c_session *s, const uint8_t *data, size_t len);
+apr_status_t h2c_session_on_write(h2c_session *session);
+
+apr_status_t h2c_session_submit(h2c_session *s, struct h2c_request *r, int *pid);
+
+void h2c_session_feed_set(h2c_session *s, struct h2c_feed *feed);
+void h2c_session_output_set(h2c_session *s, FILE *output);
+
+#endif /* h2c_session_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.c
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.c?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.c (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.c Tue Dec 29 15:30:09 2015
@@ -0,0 +1,83 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apr.h>
+#include <apr_strings.h>
+#include <apr_uri.h>
+
+#include "h2c_conn.h"
+#include "h2c_request.h"
+#include "h2c_session.h"
+#include "h2c_stream.h"
+
+apr_status_t h2c_stream_create(h2c_stream **pstream, apr_pool_t *p,
+ h2c_session *s, const h2c_request *r,
+ FILE *output)
+{
+ h2c_stream *stream;
+
+ stream = apr_pcalloc(p, sizeof(*stream));
+
+ stream->p = p;
+ stream->s = s;
+ stream->r = r;
+ stream->output = output;
+ stream->response = apr_pcalloc(p, sizeof(h2c_response));
+ stream->response->headers = apr_table_make(p, 5);
+
+ *pstream = stream;
+ return APR_SUCCESS;
+}
+
+apr_status_t h2c_stream_resp_add(h2c_stream *stream,
+ const char *name, apr_size_t nlen,
+ const char *value, apr_size_t vlen)
+{
+ name = apr_pstrndup(stream->p, name, nlen);
+ value = apr_pstrndup(stream->p, value, vlen);
+
+ if (!apr_strnatcasecmp(":status", name)) {
+ stream->response->status = (int)apr_atoi64(value);
+ }
+ else {
+ apr_table_setn(stream->response->headers, name, value);
+ }
+ return APR_SUCCESS;
+}
+
+apr_status_t h2c_stream_resp_append(h2c_stream *stream,
+ const char *data, apr_size_t len)
+{
+ stream->response->recv_bytes += len;
+ if (stream->output) {
+ return fwrite(data, 1, len, stream->output);
+ }
+ return APR_SUCCESS;
+}
+
+apr_status_t h2c_stream_close(h2c_stream *stream)
+{
+ if (!stream->closed) {
+ stream->closed = 1;
+ if (stream->s->verbose >= 0) {
+ fprintf(stderr, "%5ld:%05d %s %s -> %d %ld\n",
+ stream->s->c->id, stream->id,
+ stream->r->method, stream->r->path,
+ stream->response->status, (long)stream->response->recv_bytes);
+ }
+ }
+ return APR_SUCCESS;
+}
+
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_stream.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,55 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef h2c_stream_h
+#define h2c_stream_h
+
+struct h2c_session;
+
+typedef struct h2c_stream h2c_stream;
+typedef struct h2c_response h2c_response;
+
+struct h2c_response {
+ apr_table_t *headers;
+ int status;
+ apr_off_t content_length;
+ apr_off_t recv_bytes;
+};
+
+struct h2c_stream {
+ int id;
+ struct h2c_session *s;
+ apr_pool_t *p;
+
+ const h2c_request *r;
+ h2c_response *response;
+
+ unsigned int closed :1;
+ FILE *output;
+};
+
+apr_status_t h2c_stream_create(h2c_stream **pstream, apr_pool_t *p,
+ struct h2c_session *s, const h2c_request *r,
+ FILE *output);
+
+apr_status_t h2c_stream_resp_add(h2c_stream *stream,
+ const char *name, apr_size_t nlen,
+ const char *value, apr_size_t vlen);
+
+apr_status_t h2c_stream_resp_append(h2c_stream *stream,
+ const char *data, apr_size_t len);
+
+apr_status_t h2c_stream_close(h2c_stream *stream);
+
+#endif /* h2c_stream_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.c
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.c?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.c (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.c Tue Dec 29 15:30:09 2015
@@ -0,0 +1,111 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apr.h>
+#include <apr_strings.h>
+#include <apr_uri.h>
+
+#include <nghttp2/nghttp2.h>
+
+#include "h2c_util.h"
+
+
+/*******************************************************************************
+ * h2c_ngheader
+ ******************************************************************************/
+
+#define H2_HD_MATCH_LIT_CS(l, name) \
+ ((strlen(name) == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
+
+int h2c_util_ignore_header(const char *name)
+{
+ /* never forward, ch. 8.1.2.2 */
+ return (H2_HD_MATCH_LIT_CS("connection", name)
+ || H2_HD_MATCH_LIT_CS("proxy-connection", name)
+ || H2_HD_MATCH_LIT_CS("upgrade", name)
+ || H2_HD_MATCH_LIT_CS("keep-alive", name)
+ || H2_HD_MATCH_LIT_CS("transfer-encoding", name));
+}
+
+static int count_header(void *ctx, const char *key, const char *value)
+{
+ if (!h2c_util_ignore_header(key)) {
+ (*((size_t*)ctx))++;
+ }
+ return 1;
+}
+
+#define NV_ADD_LIT_CS(nv, k, v) add_header(nv, k, sizeof(k) - 1, v, strlen(v))
+#define NV_ADD_CS_CS(nv, k, v) add_header(nv, k, strlen(k), v, strlen(v))
+
+static int add_header(h2c_ngheader *ngh,
+ const char *key, size_t key_len,
+ const char *value, size_t val_len)
+{
+ nghttp2_nv *nv = &ngh->nv[ngh->nvlen++];
+
+ nv->name = (uint8_t*)key;
+ nv->namelen = key_len;
+ nv->value = (uint8_t*)value;
+ nv->valuelen = val_len;
+ return 1;
+}
+
+static int add_table_header(void *ctx, const char *key, const char *value)
+{
+ if (!h2c_util_ignore_header(key)) {
+ add_header(ctx, key, strlen(key), value, strlen(value));
+ }
+ return 1;
+}
+
+
+h2c_ngheader *h2c_util_ngheader_make(apr_pool_t *p, apr_table_t *header)
+{
+ h2c_ngheader *ngh;
+ size_t n;
+
+ n = 0;
+ apr_table_do(count_header, &n, header, NULL);
+
+ ngh = apr_pcalloc(p, sizeof(h2c_ngheader));
+ ngh->nv = apr_pcalloc(p, n * sizeof(nghttp2_nv));
+ apr_table_do(add_table_header, ngh, header, NULL);
+
+ return ngh;
+}
+
+h2c_ngheader *h2c_util_ngheader_make_req(apr_pool_t *p, apr_table_t *headers,
+ const char *scheme, const char *method,
+ const char *authority, const char *path)
+{
+
+ h2c_ngheader *ngh;
+ size_t n;
+
+ n = 4;
+ apr_table_do(count_header, &n, headers, NULL);
+
+ ngh = apr_pcalloc(p, sizeof(h2c_ngheader));
+ ngh->nv = apr_pcalloc(p, n * sizeof(nghttp2_nv));
+ NV_ADD_LIT_CS(ngh, ":scheme", scheme);
+ NV_ADD_LIT_CS(ngh, ":authority", authority);
+ NV_ADD_LIT_CS(ngh, ":path", path);
+ NV_ADD_LIT_CS(ngh, ":method", method);
+ apr_table_do(add_table_header, ngh, headers, NULL);
+
+ return ngh;
+}
+
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_util.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,35 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef h2c_util_h
+#define h2c_util_h
+
+#define H2_DIM(a) (sizeof(a)/sizeof((a)[0]))
+
+#define H2_MIN(a,b) (((a) < (b))? (a) : (b))
+#define H2_MAX(a,b) (((a) > (b))? (a) : (b))
+
+
+typedef struct h2c_ngheader {
+ nghttp2_nv *nv;
+ apr_size_t nvlen;
+} h2c_ngheader;
+
+h2c_ngheader *h2c_util_ngheader_make(apr_pool_t *p, apr_table_t *header);
+h2c_ngheader *h2c_util_ngheader_make_req(apr_pool_t *p, apr_table_t *headers,
+ const char *scheme, const char *method,
+ const char *authority, const char *path);
+
+
+#endif /* h2c_util_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.c
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.c?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.c (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.c Tue Dec 29 15:30:09 2015
@@ -0,0 +1,185 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <apr.h>
+#include <apr_strings.h>
+#include <apr_poll.h>
+#include <apr_uri.h>
+
+#include "h2c_conn.h"
+#include "h2c_feed.h"
+#include "h2c_session.h"
+#include "h2c_worker.h"
+
+static int nid;
+
+apr_status_t h2c_worker_create(h2c_worker **pw, apr_pool_t *p, apr_uri_t *uri,
+ h2c_feed *feed, int num_conns, int max_streams, int verbose)
+{
+ h2c_worker *w;
+
+ w = apr_pcalloc(p, sizeof(*w));
+
+ w->id = nid++;
+ w->p = p;
+ w->uri = uri;
+ w->feed = feed;
+ w->max_streams = max_streams;
+ w->verbose = verbose;
+
+ w->num_conns = num_conns;
+ w->connections = apr_pcalloc(w->p, sizeof(h2c_conn*)*w->num_conns);
+
+ *pw = w;
+ return APR_SUCCESS;
+}
+
+static void conn_destroy(h2c_worker *w, h2c_conn *c)
+{
+ int i;
+ for (i = 0; i < w->num_conns; ++i) {
+ if (w->connections[i] == c) {
+ w->connections[i] = NULL;
+ break;
+ }
+ }
+ h2c_conn_destroy(c);
+}
+
+apr_status_t h2c_worker_run(h2c_worker *w)
+{
+ apr_pollset_t *pollset;
+ apr_status_t status;
+ int i, live_conns = 0;
+
+ status = apr_pollset_create(&pollset, w->num_conns, w->p, APR_POLLSET_NOCOPY);
+ if (status != APR_SUCCESS) {
+ fprintf(stderr, "error %d creating poll set\n", status);
+ return status;
+ }
+
+ for (i = 0; i < w->num_conns; ++i) {
+ h2c_conn *conn;
+ h2c_session *session;
+
+ status = h2c_conn_create(&conn, w->p, w->uri);
+ if (status != APR_SUCCESS) {
+ fprintf(stderr, "error %d creating conn %s\n", status, w->uri->hostname);
+ return status;
+ }
+
+ w->connections[i] = conn;
+
+ status = apr_pollset_add(pollset, conn->pfd);
+ if (status != APR_SUCCESS) {
+ fprintf(stderr, "error %d adding to poll set\n", status);
+ return status;
+ }
+
+ status = h2c_session_create(&session, conn, w->max_streams);
+ if (status != APR_SUCCESS) {
+ fprintf(stderr, "error %d creating session\n", status);
+ return status;
+ }
+
+ h2c_session_feed_set(session, w->feed);
+ h2c_session_output_set(session, NULL);
+
+ h2c_session_verbose_set(session, w->verbose);
+ if (w->verbose > 0) {
+ printf("connecting to %s (%s %d)...", conn->addr->hostname, conn->ip_addr, w->uri->port);
+ }
+
+ status = apr_socket_connect(conn->socket, conn->addr);
+ if (status != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(status)) {
+ fprintf(stderr, "error %d connecting to %s\n", status, conn->addr->hostname);
+ return status;
+ }
+
+ if (w->verbose > 0) {
+ printf("done.\n");
+ }
+
+ apr_socket_opt_set(conn->socket, APR_SO_NONBLOCK, 1);
+
+ ++live_conns;
+ h2c_conn_on_connect(conn);
+ }
+
+
+ while (live_conns > 0) {
+ apr_int32_t numdesc;
+ const apr_pollfd_t *pdesc;
+ const char *op;
+
+ status = apr_pollset_poll(pollset, apr_time_from_sec(10),
+ &numdesc, &pdesc);
+
+ if (status != APR_SUCCESS) {
+ if (APR_STATUS_IS_TIMEUP(status)) {
+ fprintf(stderr, "timeup polling\n");
+ continue;
+ }
+ else if (APR_STATUS_IS_EINTR(status)) {
+ continue;
+ }
+ fprintf(stderr, "error %d on poll()\n", status);
+ return status;
+ }
+
+ for (i = 0; i < numdesc; ++i) {
+ const apr_pollfd_t *pfd = &pdesc[i];
+ h2c_conn *c = pfd->client_data;
+
+ if (pfd->rtnevents & APR_POLLIN) {
+ op = "reading";
+ status = h2c_conn_read(c);
+ }
+ if (pfd->rtnevents & APR_POLLOUT) {
+ op = "writing";
+ h2c_conn_on_write(c);
+ status = h2c_conn_write(c);
+ }
+ if (pfd->rtnevents & APR_POLLHUP) {
+ op = "closed";
+ status = APR_EOF;
+ }
+ if (pfd->rtnevents & APR_POLLNVAL) {
+ op = "reading";
+ status = APR_EOF;
+ }
+
+ if (status != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(status)) {
+ if (status != APR_EOF) {
+ fprintf(stderr, "error %d %s\n", status, op);
+ }
+ h2c_conn_close(c);
+ }
+
+ if (!c->socket) {
+ apr_pollset_remove(pollset, pfd);
+ --live_conns;
+ conn_destroy(w, c);
+ }
+ else if (pfd->reqevents != c->pfd->reqevents) {
+ /* change in events this connection waits for */
+ apr_pollset_remove(pollset, pfd);
+ apr_pollset_add(pollset, c->pfd);
+ }
+ }
+ }
+
+ return APR_SUCCESS;
+}
\ No newline at end of file
Added: httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/h2c_worker.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,42 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef h2c_worker_h
+#define h2c_worker_h
+
+struct h2c_conn;
+struct h2c_feed;
+
+typedef struct h2c_worker h2c_worker;
+
+struct h2c_worker {
+ int id;
+ apr_pool_t *p;
+ apr_uri_t *uri;
+ h2c_feed *feed;
+
+ int num_conns;
+ struct h2c_conn **connections;
+ int max_streams;
+ int verbose;
+};
+
+apr_status_t h2c_worker_create(h2c_worker **pw, apr_pool_t *p, apr_uri_t *uri,
+ struct h2c_feed *feed, int num_conns,
+ int max_streams, int verbose);
+
+apr_status_t h2c_worker_run(h2c_worker *w);
+
+#endif /* h2c_worker_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.c
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.c?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.c (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.c Tue Dec 29 15:30:09 2015
@@ -0,0 +1,233 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <getopt.h>
+
+#include <apr.h>
+#include <apr_uri.h>
+#include <apr_strings.h>
+#include <apr_thread_proc.h>
+
+#include "h2c_conn.h"
+#include "h2c_feed.h"
+#include "h2c_request.h"
+#include "h2c_session.h"
+#include "h2c_worker.h"
+
+#include "mh2f_version.h"
+#include "mh2f_main.h"
+
+static int usage(const char *cmd, const char *msg)
+{
+ if (msg) {
+ fprintf(stderr, "%s\n", msg);
+ }
+ fprintf(stderr, "usage: %s [options] url\n"
+ " run http2 fuzz tests against url. \n options are:\n"
+ " -v verbose\n"
+ " -V version\n"
+ , cmd);
+
+ return 2;
+}
+
+static struct option long_options[] = {
+ { "connections", required_argument, NULL, 'c'},
+ {"max-concurrent-streams", required_argument, NULL, 'm'},
+ { "quiet", no_argument, NULL, 'q'},
+ { "requests", required_argument, NULL, 'n'},
+ { "threads", required_argument, NULL, 't'},
+ { "verbose", no_argument, NULL, 'v'},
+ { "version", no_argument, NULL, 'V'},
+ { NULL, 0, NULL, 0}
+};
+
+static apr_thread_t *worker_create(apr_pool_t *parent, apr_uri_t *uri,
+ h2c_feed *feed, apr_threadattr_t *attr,
+ int num_conns, int max_streams, int verbose);
+
+int main(int argc, char **argv)
+{
+ apr_pool_t *pool;
+ apr_uri_t uri;
+ apr_status_t status;
+ char c;
+ int option_index;
+ int verbose = 0;
+ int null_out = 1;
+ int max_streams = 1;
+ int repeats = 0;
+ int repeats_rem = 0;
+ int thread_count = 1;
+ int connections = -1;
+ int connections_rem = 0;
+ int i;
+ h2c_conn *conn;
+ h2c_session *session;
+ h2c_request *r;
+ apr_thread_t **threads;
+ apr_threadattr_t *thread_attr;
+
+ apr_pool_initialize();
+ apr_pool_create_core(&pool);
+
+ while (1) {
+ c = getopt_long(argc, argv, "c:m:n:qt:vV",
+ long_options, &option_index);
+
+ if (c == -1) {
+ break;
+ }
+ switch (c) {
+ case 'c':
+ connections = (int)apr_atoi64(optarg);
+ break;
+ case 'm':
+ if (!apr_strnatcasecmp("auto", optarg)) {
+ max_streams = -1;
+ }
+ else {
+ max_streams = (int)apr_atoi64(optarg);
+ }
+ break;
+ case 'n':
+ repeats = (int)apr_atoi64(optarg);
+ break;
+ case 'q':
+ verbose = -1;
+ break;
+ case 't':
+ thread_count = (int)apr_atoi64(optarg);
+ break;
+ case 'v':
+ ++verbose;
+ break;
+ case 'V':
+ printf("%s version %s\n", argv[0], MH2F_VERSION);
+ return 2;
+ default:
+ return usage(argv[0], "unknown option");
+ }
+ }
+
+ if (argc == optind) {
+ return usage(argv[0], "no URL specified.");
+ }
+ else if (argc > optind+1) {
+ return usage(argv[0], "too many arguments.");
+ }
+
+ status = apr_uri_parse(pool, argv[optind], &uri);
+ if (status != APR_SUCCESS) {
+ fprintf(stderr, "error=%d, not an uri: %s\n", status, argv[optind]);
+ return 1;
+ }
+
+ if (!uri.hostname) {
+ return usage(argv[0], "no host name found in uri.");
+ }
+
+ if (uri.scheme) {
+ if (apr_strnatcasecmp("http", uri.scheme)
+ && apr_strnatcasecmp("https", uri.scheme)) {
+ fprintf(stderr, "uri scheme %s not supported\n", uri.scheme);
+ return 1;
+ }
+ }
+ else {
+ uri.scheme = "https";
+ }
+
+
+ if (!uri.port_str) {
+ uri.port = apr_uri_port_of_scheme(uri.scheme);
+ }
+
+ h2c_request_create(&r, pool, "GET", &uri);
+ apr_threadattr_create(&thread_attr, pool);
+ apr_threadattr_detach_set(thread_attr, 0);
+
+ threads = apr_pcalloc(pool, sizeof(apr_thread_t*) * thread_count);
+
+ if (connections <= 0) {
+ connections = thread_count;
+ }
+ connections_rem = connections % thread_count;
+
+ if (repeats <= 0) {
+ repeats = connections;
+ }
+ repeats_rem = repeats % thread_count;
+
+ for (i = 0; i < thread_count; ++i) {
+ h2c_feed *feed;
+ h2c_worker *w;
+ apr_thread_t *t;
+ int n, num_conns;
+
+ num_conns = (connections / thread_count) + (connections_rem > 0? 1 : 0);
+ --connections_rem;
+ n = (repeats / thread_count) + ((repeats_rem > 0)? 1 : 0);
+ --repeats_rem;
+
+ h2c_feed_repeat_create(&feed, pool, r, n);
+ threads[i] = worker_create(pool, &uri, feed, thread_attr,
+ num_conns, max_streams, verbose);
+ }
+
+
+ for (i = 0; i < thread_count; ++i) {
+ if (threads[i]) {
+ apr_thread_join(&status, threads[i]);
+ }
+ }
+
+ return (status == APR_SUCCESS)? 0 : 1;
+}
+
+static void* APR_THREAD_FUNC execute(apr_thread_t *thread, void *ctx)
+{
+ h2c_worker *w = ctx;
+ apr_status_t status;
+
+ status = h2c_worker_run(w);
+ apr_thread_exit(thread, status);
+ return NULL;
+}
+
+static apr_thread_t *worker_create(apr_pool_t *parent, apr_uri_t *uri,
+ h2c_feed *feed, apr_threadattr_t *attr,
+ int num_conns, int max_streams, int verbose)
+{
+ apr_allocator_t *allocator;
+ apr_pool_t *pool;
+ apr_thread_t *t;
+ apr_status_t status;
+ h2c_worker *w;
+
+ apr_allocator_create(&allocator);
+ apr_pool_create_ex(&pool, parent, NULL, allocator);
+ apr_allocator_owner_set(allocator, pool);
+
+ status = h2c_worker_create(&w, pool, uri, feed, num_conns, max_streams, verbose);
+ if (status != APR_SUCCESS) {
+ fprintf(stderr, "error %d creating worker\n", status);
+ return NULL;
+ }
+
+ apr_thread_create(&t, attr, execute, w, pool);
+ return t;
+}
+
Added: httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/mh2f_main.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,20 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef mh2f_main_h
+#define mh2f_main_h
+
+#include <stdio.h>
+
+#endif /* mh2f_main_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h Tue Dec 29 15:30:09 2015
@@ -0,0 +1,40 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef mh2f_version_h
+#define mh2f_version_h
+
+#undef PACKAGE_VERSION
+#undef PACKAGE_TARNAME
+#undef PACKAGE_STRING
+#undef PACKAGE_NAME
+#undef PACKAGE_BUGREPORT
+
+/**
+ * @macro
+ * Version number of the http2 module as c string
+ */
+#define MH2F_VERSION "1.0.15-DEV"
+
+/**
+ * @macro
+ * Numerical representation of the version number of the http2 module
+ * release. This is a 24 bit number with 8 bits for major number, 8 bits
+ * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
+ */
+#define MH2F_VERSION_NUM 0x01000f
+
+
+#endif /* mh2f_version_h */
Added: httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h.in
URL: http://svn.apache.org/viewvc/httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h.in?rev=1722149&view=auto
==============================================================================
--- httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h.in (added)
+++ httpd/test/mod_h2/trunk/mh2fuzz/mh2f_version.h.in Tue Dec 29 15:30:09 2015
@@ -0,0 +1,40 @@
+/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef mh2f_version_h
+#define mh2f_version_h
+
+#undef PACKAGE_VERSION
+#undef PACKAGE_TARNAME
+#undef PACKAGE_STRING
+#undef PACKAGE_NAME
+#undef PACKAGE_BUGREPORT
+
+/**
+ * @macro
+ * Version number of the http2 module as c string
+ */
+#define MH2F_VERSION "@PACKAGE_VERSION@"
+
+/**
+ * @macro
+ * Numerical representation of the version number of the http2 module
+ * release. This is a 24 bit number with 8 bits for major number, 8 bits
+ * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
+ */
+#define MH2F_VERSION_NUM @PACKAGE_VERSION_NUM@
+
+
+#endif /* mh2f_version_h */