From 1430e0a292679a86e5a100ebf7cfd0a21dc43dfb Mon Sep 17 00:00:00 2001
From: Stefan Eissing
Date: Thu, 23 Sep 2021 09:53:01 +0000
Subject: [PATCH] * merging test/modules from trunk
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1893546 13f79535-47bb-0310-9956-ffa450edef68
---
test/modules/http2/.gitignore | 3 +
test/modules/http2/Makefile.in | 20 +
test/modules/http2/conf/httpd.conf.template | 53 +
test/modules/http2/conf/mime.types | 1588 ++++++++++++
test/modules/http2/conf/test.conf | 1 +
test/modules/http2/config.ini.in | 29 +
test/modules/http2/conftest.py | 52 +
.../http2/data/nghttp-output-100k-1.txt | 1153 +++++++++
.../http2/data/nghttp-output-10k-1.txt | 166 ++
.../modules/http2/data/nghttp-output-1k-1.txt | 68 +
test/modules/http2/h2_certs.py | 444 ++++
test/modules/http2/h2_conf.py | 147 ++
test/modules/http2/h2_env.py | 608 +++++
test/modules/http2/h2_nghttp.py | 288 +++
test/modules/http2/h2_result.py | 71 +
test/modules/http2/htdocs/alive.json | 4 +
test/modules/http2/htdocs/cgi/echo.py | 14 +
test/modules/http2/htdocs/cgi/echohd.py | 23 +
test/modules/http2/htdocs/cgi/env.py | 39 +
test/modules/http2/htdocs/cgi/files/empty.txt | 0
test/modules/http2/htdocs/cgi/hecho.py | 46 +
test/modules/http2/htdocs/cgi/hello.py | 15 +
test/modules/http2/htdocs/cgi/mnot164.py | 21 +
test/modules/http2/htdocs/cgi/necho.py | 54 +
test/modules/http2/htdocs/cgi/upload.py | 62 +
test/modules/http2/htdocs/forbidden.html | 11 +
test/modules/http2/htdocs/index.html | 9 +
test/modules/http2/htdocs/noh2/alive.json | 5 +
test/modules/http2/htdocs/noh2/index.html | 9 +
test/modules/http2/htdocs/test1/001.html | 10 +
test/modules/http2/htdocs/test1/002.jpg | Bin 0 -> 90364 bytes
test/modules/http2/htdocs/test1/003.html | 11 +
.../http2/htdocs/test1/003/003_img.jpg | Bin 0 -> 90364 bytes
test/modules/http2/htdocs/test1/004.html | 23 +
.../http2/htdocs/test1/004/gophertiles.jpg | Bin 0 -> 742 bytes
test/modules/http2/htdocs/test1/006.html | 23 +
test/modules/http2/htdocs/test1/006/006.css | 21 +
test/modules/http2/htdocs/test1/006/006.js | 31 +
.../http2/htdocs/test1/006/header.html | 1 +
test/modules/http2/htdocs/test1/007.html | 21 +
test/modules/http2/htdocs/test1/007/007.py | 29 +
test/modules/http2/htdocs/test1/009.py | 21 +
test/modules/http2/htdocs/test1/alive.json | 5 +
.../htdocs/test1/apache.org-files/ant.jpg | Bin 0 -> 6437 bytes
.../test1/apache.org-files/asf_logo.png | Bin 0 -> 29982 bytes
.../test1/apache.org-files/async-ads.js | 278 ++
.../test1/apache.org-files/async-ads.js.br | Bin 0 -> 50272 bytes
.../htdocs/test1/apache.org-files/cse.js | 0
.../htdocs/test1/apache.org-files/css.css | 0
.../htdocs/test1/apache.org-files/default.css | 676 +++++
.../test1/apache.org-files/defaulten.css | 2284 +++++++++++++++++
.../test1/apache.org-files/defaulten.js | 674 +++++
.../htdocs/test1/apache.org-files/jquery-2.js | 4 +
.../htdocs/test1/apache.org-files/jsapi.js | 0
.../htdocs/test1/apache.org-files/min.css | 1 +
.../htdocs/test1/apache.org-files/min.css.br | Bin 0 -> 10116 bytes
.../htdocs/test1/apache.org-files/mrunit.jpg | Bin 0 -> 4460 bytes
.../apache.org-files/search_box_icon.png | Bin 0 -> 1018 bytes
.../test1/apache.org-files/small-logo.png | Bin 0 -> 1499 bytes
.../htdocs/test1/apache.org-files/styles.css | 131 +
.../htdocs/test1/apache.org-files/synapse.jpg | Bin 0 -> 4396 bytes
.../http2/htdocs/test1/apache.org.html | 899 +++++++
test/modules/http2/htdocs/test1/index.html | 46 +
test/modules/http2/htdocs/test2/alive.json | 4 +
test/modules/http2/mod_h2test/mod_h2test.c | 165 ++
test/modules/http2/mod_h2test/mod_h2test.h | 21 +
test/modules/http2/test_000_infra.py | 17 +
test/modules/http2/test_001_httpd_alive.py | 28 +
test/modules/http2/test_002_curl_basics.py | 68 +
test/modules/http2/test_003_get.py | 213 ++
test/modules/http2/test_004_post.py | 217 ++
test/modules/http2/test_005_status.py | 70 +
test/modules/http2/test_006_assets.py | 74 +
test/modules/http2/test_100_conn_reuse.py | 56 +
test/modules/http2/test_101_ssl_reneg.py | 126 +
test/modules/http2/test_102_require.py | 38 +
test/modules/http2/test_103_upgrade.py | 119 +
test/modules/http2/test_104_padding.py | 100 +
test/modules/http2/test_105_timeout.py | 96 +
test/modules/http2/test_106_shutdown.py | 45 +
test/modules/http2/test_200_header_invalid.py | 177 ++
.../http2/test_201_header_conditional.py | 69 +
test/modules/http2/test_202_trailer.py | 81 +
test/modules/http2/test_300_interim.py | 39 +
test/modules/http2/test_400_push.py | 199 ++
test/modules/http2/test_401_early_hints.py | 46 +
test/modules/http2/test_500_proxy.py | 119 +
test/modules/http2/test_600_h2proxy.py | 27 +
test/modules/http2/test_700_load_get.py | 54 +
.../http2/test_710_load_post_static.py | 62 +
test/modules/http2/test_711_load_post_cgi.py | 70 +
test/modules/http2/test_712_buffering.py | 175 ++
92 files changed, 12767 insertions(+)
create mode 100644 test/modules/http2/.gitignore
create mode 100644 test/modules/http2/Makefile.in
create mode 100644 test/modules/http2/conf/httpd.conf.template
create mode 100644 test/modules/http2/conf/mime.types
create mode 100644 test/modules/http2/conf/test.conf
create mode 100644 test/modules/http2/config.ini.in
create mode 100644 test/modules/http2/conftest.py
create mode 100644 test/modules/http2/data/nghttp-output-100k-1.txt
create mode 100644 test/modules/http2/data/nghttp-output-10k-1.txt
create mode 100644 test/modules/http2/data/nghttp-output-1k-1.txt
create mode 100644 test/modules/http2/h2_certs.py
create mode 100644 test/modules/http2/h2_conf.py
create mode 100644 test/modules/http2/h2_env.py
create mode 100644 test/modules/http2/h2_nghttp.py
create mode 100644 test/modules/http2/h2_result.py
create mode 100644 test/modules/http2/htdocs/alive.json
create mode 100644 test/modules/http2/htdocs/cgi/echo.py
create mode 100644 test/modules/http2/htdocs/cgi/echohd.py
create mode 100644 test/modules/http2/htdocs/cgi/env.py
create mode 100644 test/modules/http2/htdocs/cgi/files/empty.txt
create mode 100644 test/modules/http2/htdocs/cgi/hecho.py
create mode 100644 test/modules/http2/htdocs/cgi/hello.py
create mode 100644 test/modules/http2/htdocs/cgi/mnot164.py
create mode 100644 test/modules/http2/htdocs/cgi/necho.py
create mode 100644 test/modules/http2/htdocs/cgi/upload.py
create mode 100644 test/modules/http2/htdocs/forbidden.html
create mode 100644 test/modules/http2/htdocs/index.html
create mode 100644 test/modules/http2/htdocs/noh2/alive.json
create mode 100644 test/modules/http2/htdocs/noh2/index.html
create mode 100644 test/modules/http2/htdocs/test1/001.html
create mode 100644 test/modules/http2/htdocs/test1/002.jpg
create mode 100644 test/modules/http2/htdocs/test1/003.html
create mode 100644 test/modules/http2/htdocs/test1/003/003_img.jpg
create mode 100644 test/modules/http2/htdocs/test1/004.html
create mode 100644 test/modules/http2/htdocs/test1/004/gophertiles.jpg
create mode 100644 test/modules/http2/htdocs/test1/006.html
create mode 100644 test/modules/http2/htdocs/test1/006/006.css
create mode 100644 test/modules/http2/htdocs/test1/006/006.js
create mode 100644 test/modules/http2/htdocs/test1/006/header.html
create mode 100644 test/modules/http2/htdocs/test1/007.html
create mode 100644 test/modules/http2/htdocs/test1/007/007.py
create mode 100644 test/modules/http2/htdocs/test1/009.py
create mode 100644 test/modules/http2/htdocs/test1/alive.json
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/ant.jpg
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/asf_logo.png
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/async-ads.js
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/async-ads.js.br
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/cse.js
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/css.css
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/default.css
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/defaulten.css
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/defaulten.js
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/jquery-2.js
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/jsapi.js
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/min.css
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/min.css.br
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/mrunit.jpg
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/search_box_icon.png
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/small-logo.png
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/styles.css
create mode 100644 test/modules/http2/htdocs/test1/apache.org-files/synapse.jpg
create mode 100644 test/modules/http2/htdocs/test1/apache.org.html
create mode 100644 test/modules/http2/htdocs/test1/index.html
create mode 100644 test/modules/http2/htdocs/test2/alive.json
create mode 100644 test/modules/http2/mod_h2test/mod_h2test.c
create mode 100644 test/modules/http2/mod_h2test/mod_h2test.h
create mode 100644 test/modules/http2/test_000_infra.py
create mode 100644 test/modules/http2/test_001_httpd_alive.py
create mode 100644 test/modules/http2/test_002_curl_basics.py
create mode 100644 test/modules/http2/test_003_get.py
create mode 100644 test/modules/http2/test_004_post.py
create mode 100644 test/modules/http2/test_005_status.py
create mode 100644 test/modules/http2/test_006_assets.py
create mode 100644 test/modules/http2/test_100_conn_reuse.py
create mode 100644 test/modules/http2/test_101_ssl_reneg.py
create mode 100644 test/modules/http2/test_102_require.py
create mode 100644 test/modules/http2/test_103_upgrade.py
create mode 100644 test/modules/http2/test_104_padding.py
create mode 100644 test/modules/http2/test_105_timeout.py
create mode 100644 test/modules/http2/test_106_shutdown.py
create mode 100644 test/modules/http2/test_200_header_invalid.py
create mode 100644 test/modules/http2/test_201_header_conditional.py
create mode 100644 test/modules/http2/test_202_trailer.py
create mode 100644 test/modules/http2/test_300_interim.py
create mode 100644 test/modules/http2/test_400_push.py
create mode 100644 test/modules/http2/test_401_early_hints.py
create mode 100644 test/modules/http2/test_500_proxy.py
create mode 100644 test/modules/http2/test_600_h2proxy.py
create mode 100644 test/modules/http2/test_700_load_get.py
create mode 100644 test/modules/http2/test_710_load_post_static.py
create mode 100644 test/modules/http2/test_711_load_post_cgi.py
create mode 100644 test/modules/http2/test_712_buffering.py
diff --git a/test/modules/http2/.gitignore b/test/modules/http2/.gitignore
new file mode 100644
index 00000000000..d68cd09332f
--- /dev/null
+++ b/test/modules/http2/.gitignore
@@ -0,0 +1,3 @@
+gen
+config.ini
+__pycache__
diff --git a/test/modules/http2/Makefile.in b/test/modules/http2/Makefile.in
new file mode 100644
index 00000000000..15d404d208d
--- /dev/null
+++ b/test/modules/http2/Makefile.in
@@ -0,0 +1,20 @@
+
+# no targets: we don't want to build anything by default. if you want the
+# test programs, then "make test"
+TARGETS =
+
+bin_PROGRAMS =
+
+PROGRAM_LDADD = $(EXTRA_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS)
+PROGRAM_DEPENDENCIES = \
+ $(top_srcdir)/srclib/apr-util/libaprutil.la \
+ $(top_srcdir)/srclib/apr/libapr.la
+
+include $(top_builddir)/build/rules.mk
+
+test: $(bin_PROGRAMS)
+
+# example for building a test proggie
+# dbu_OBJECTS = dbu.lo
+# dbu: $(dbu_OBJECTS)
+# $(LINK) $(dbu_OBJECTS) $(PROGRAM_LDADD)
diff --git a/test/modules/http2/conf/httpd.conf.template b/test/modules/http2/conf/httpd.conf.template
new file mode 100644
index 00000000000..bd0606b4025
--- /dev/null
+++ b/test/modules/http2/conf/httpd.conf.template
@@ -0,0 +1,53 @@
+ServerName localhost
+ServerRoot "${server_dir}"
+
+Include "conf/modules.conf"
+
+DocumentRoot "${server_dir}/htdocs"
+
+
+ LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %k" combined
+ LogFormat "%h %l %u %t \"%r\" %>s %b" common
+ CustomLog "logs/access_log" combined
+
+
+
+TypesConfig "${gen_dir}/apache/conf/mime.types"
+
+Listen ${http_port}
+Listen ${https_port}
+
+# Insert our test specific configuration before the first vhost,
+# so that its vhosts can be the default one. This is relevant in
+# certain behaviours, such as protocol selection during SSL ALPN
+# negotiation.
+#
+Include "conf/test.conf"
+
+RequestReadTimeout header=10 body=10
+
+
+ AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
+
+
+ AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
+
+
+
+ ServerName not-forbidden.org
+ ServerAlias www.not-forbidden.org
+
+ DocumentRoot "${server_dir}/htdocs"
+
+
+
+ Options Indexes FollowSymLinks
+ AllowOverride None
+ Require all granted
+
+ AddHandler cgi-script .py
+ AddHandler cgi-script .cgi
+ Options +ExecCGI
+
+
+
diff --git a/test/modules/http2/conf/mime.types b/test/modules/http2/conf/mime.types
new file mode 100644
index 00000000000..b90b1658761
--- /dev/null
+++ b/test/modules/http2/conf/mime.types
@@ -0,0 +1,1588 @@
+# This file maps Internet media types to unique file extension(s).
+# Although created for httpd, this file is used by many software systems
+# and has been placed in the public domain for unlimited redisribution.
+#
+# The table below contains both registered and (common) unregistered types.
+# A type that has no unique extension can be ignored -- they are listed
+# here to guide configurations toward known types and to make it easier to
+# identify "new" types. File extensions are also commonly used to indicate
+# content languages and encodings, so choose them carefully.
+#
+# Internet media types should be registered as described in RFC 4288.
+# The registry is at .
+#
+# MIME type (lowercased) Extensions
+# ============================================ ==========
+# application/1d-interleaved-parityfec
+# application/3gpp-ims+xml
+# application/activemessage
+application/andrew-inset ez
+# application/applefile
+application/applixware aw
+application/atom+xml atom
+application/atomcat+xml atomcat
+# application/atomicmail
+application/atomsvc+xml atomsvc
+# application/auth-policy+xml
+# application/batch-smtp
+# application/beep+xml
+# application/calendar+xml
+# application/cals-1840
+# application/ccmp+xml
+application/ccxml+xml ccxml
+application/cdmi-capability cdmia
+application/cdmi-container cdmic
+application/cdmi-domain cdmid
+application/cdmi-object cdmio
+application/cdmi-queue cdmiq
+# application/cea-2018+xml
+# application/cellml+xml
+# application/cfw
+# application/cnrp+xml
+# application/commonground
+# application/conference-info+xml
+# application/cpl+xml
+# application/csta+xml
+# application/cstadata+xml
+application/cu-seeme cu
+# application/cybercash
+application/davmount+xml davmount
+# application/dca-rft
+# application/dec-dx
+# application/dialog-info+xml
+# application/dicom
+# application/dns
+application/docbook+xml dbk
+# application/dskpp+xml
+application/dssc+der dssc
+application/dssc+xml xdssc
+# application/dvcs
+application/ecmascript ecma
+# application/edi-consent
+# application/edi-x12
+# application/edifact
+application/emma+xml emma
+# application/epp+xml
+application/epub+zip epub
+# application/eshop
+# application/example
+application/exi exi
+# application/fastinfoset
+# application/fastsoap
+# application/fits
+application/font-tdpfr pfr
+# application/framework-attributes+xml
+application/gml+xml gml
+application/gpx+xml gpx
+application/gxf gxf
+# application/h224
+# application/held+xml
+# application/http
+application/hyperstudio stk
+# application/ibe-key-request+xml
+# application/ibe-pkg-reply+xml
+# application/ibe-pp-data
+# application/iges
+# application/im-iscomposing+xml
+# application/index
+# application/index.cmd
+# application/index.obj
+# application/index.response
+# application/index.vnd
+application/inkml+xml ink inkml
+# application/iotp
+application/ipfix ipfix
+# application/ipp
+# application/isup
+application/java-archive jar
+application/java-serialized-object ser
+application/java-vm class
+application/javascript js
+application/json json
+application/jsonml+json jsonml
+# application/kpml-request+xml
+# application/kpml-response+xml
+application/lost+xml lostxml
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+# application/macwriteii
+application/mads+xml mads
+application/marc mrc
+application/marcxml+xml mrcx
+application/mathematica ma nb mb
+# application/mathml-content+xml
+# application/mathml-presentation+xml
+application/mathml+xml mathml
+# application/mbms-associated-procedure-description+xml
+# application/mbms-deregister+xml
+# application/mbms-envelope+xml
+# application/mbms-msk+xml
+# application/mbms-msk-response+xml
+# application/mbms-protection-description+xml
+# application/mbms-reception-report+xml
+# application/mbms-register+xml
+# application/mbms-register-response+xml
+# application/mbms-user-service-description+xml
+application/mbox mbox
+# application/media_control+xml
+application/mediaservercontrol+xml mscml
+application/metalink+xml metalink
+application/metalink4+xml meta4
+application/mets+xml mets
+# application/mikey
+application/mods+xml mods
+# application/moss-keys
+# application/moss-signature
+# application/mosskey-data
+# application/mosskey-request
+application/mp21 m21 mp21
+application/mp4 mp4s
+# application/mpeg4-generic
+# application/mpeg4-iod
+# application/mpeg4-iod-xmt
+# application/msc-ivr+xml
+# application/msc-mixer+xml
+application/msword doc dot
+application/mxf mxf
+# application/nasdata
+# application/news-checkgroups
+# application/news-groupinfo
+# application/news-transmission
+# application/nss
+# application/ocsp-request
+# application/ocsp-response
+application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy
+application/oda oda
+application/oebps-package+xml opf
+application/ogg ogx
+application/omdoc+xml omdoc
+application/onenote onetoc onetoc2 onetmp onepkg
+application/oxps oxps
+# application/parityfec
+application/patch-ops-error+xml xer
+application/pdf pdf
+application/pgp-encrypted pgp
+# application/pgp-keys
+application/pgp-signature asc sig
+application/pics-rules prf
+# application/pidf+xml
+# application/pidf-diff+xml
+application/pkcs10 p10
+application/pkcs7-mime p7m p7c
+application/pkcs7-signature p7s
+application/pkcs8 p8
+application/pkix-attr-cert ac
+application/pkix-cert cer
+application/pkix-crl crl
+application/pkix-pkipath pkipath
+application/pkixcmp pki
+application/pls+xml pls
+# application/poc-settings+xml
+application/postscript ai eps ps
+# application/prs.alvestrand.titrax-sheet
+application/prs.cww cww
+# application/prs.nprend
+# application/prs.plucker
+# application/prs.rdf-xml-crypt
+# application/prs.xsf+xml
+application/pskc+xml pskcxml
+# application/qsig
+application/rdf+xml rdf
+application/reginfo+xml rif
+application/relax-ng-compact-syntax rnc
+# application/remote-printing
+application/resource-lists+xml rl
+application/resource-lists-diff+xml rld
+# application/riscos
+# application/rlmi+xml
+application/rls-services+xml rs
+application/rpki-ghostbusters gbr
+application/rpki-manifest mft
+application/rpki-roa roa
+# application/rpki-updown
+application/rsd+xml rsd
+application/rss+xml rss
+application/rtf rtf
+# application/rtx
+# application/samlassertion+xml
+# application/samlmetadata+xml
+application/sbml+xml sbml
+application/scvp-cv-request scq
+application/scvp-cv-response scs
+application/scvp-vp-request spq
+application/scvp-vp-response spp
+application/sdp sdp
+# application/set-payment
+application/set-payment-initiation setpay
+# application/set-registration
+application/set-registration-initiation setreg
+# application/sgml
+# application/sgml-open-catalog
+application/shf+xml shf
+# application/sieve
+# application/simple-filter+xml
+# application/simple-message-summary
+# application/simplesymbolcontainer
+# application/slate
+# application/smil
+application/smil+xml smi smil
+# application/soap+fastinfoset
+# application/soap+xml
+application/sparql-query rq
+application/sparql-results+xml srx
+# application/spirits-event+xml
+application/srgs gram
+application/srgs+xml grxml
+application/sru+xml sru
+application/ssdl+xml ssdl
+application/ssml+xml ssml
+# application/tamp-apex-update
+# application/tamp-apex-update-confirm
+# application/tamp-community-update
+# application/tamp-community-update-confirm
+# application/tamp-error
+# application/tamp-sequence-adjust
+# application/tamp-sequence-adjust-confirm
+# application/tamp-status-query
+# application/tamp-status-response
+# application/tamp-update
+# application/tamp-update-confirm
+application/tei+xml tei teicorpus
+application/thraud+xml tfi
+# application/timestamp-query
+# application/timestamp-reply
+application/timestamped-data tsd
+# application/tve-trigger
+# application/ulpfec
+# application/vcard+xml
+# application/vemmi
+# application/vividence.scriptfile
+# application/vnd.3gpp.bsf+xml
+application/vnd.3gpp.pic-bw-large plb
+application/vnd.3gpp.pic-bw-small psb
+application/vnd.3gpp.pic-bw-var pvb
+# application/vnd.3gpp.sms
+# application/vnd.3gpp2.bcmcsinfo+xml
+# application/vnd.3gpp2.sms
+application/vnd.3gpp2.tcap tcap
+application/vnd.3m.post-it-notes pwn
+application/vnd.accpac.simply.aso aso
+application/vnd.accpac.simply.imp imp
+application/vnd.acucobol acu
+application/vnd.acucorp atc acutc
+application/vnd.adobe.air-application-installer-package+zip air
+application/vnd.adobe.formscentral.fcdt fcdt
+application/vnd.adobe.fxp fxp fxpl
+# application/vnd.adobe.partial-upload
+application/vnd.adobe.xdp+xml xdp
+application/vnd.adobe.xfdf xfdf
+# application/vnd.aether.imp
+# application/vnd.ah-barcode
+application/vnd.ahead.space ahead
+application/vnd.airzip.filesecure.azf azf
+application/vnd.airzip.filesecure.azs azs
+application/vnd.amazon.ebook azw
+application/vnd.americandynamics.acc acc
+application/vnd.amiga.ami ami
+# application/vnd.amundsen.maze+xml
+application/vnd.android.package-archive apk
+application/vnd.anser-web-certificate-issue-initiation cii
+application/vnd.anser-web-funds-transfer-initiation fti
+application/vnd.antix.game-component atx
+application/vnd.apple.installer+xml mpkg
+application/vnd.apple.mpegurl m3u8
+# application/vnd.arastra.swi
+application/vnd.aristanetworks.swi swi
+application/vnd.astraea-software.iota iota
+application/vnd.audiograph aep
+# application/vnd.autopackage
+# application/vnd.avistar+xml
+application/vnd.blueice.multipass mpm
+# application/vnd.bluetooth.ep.oob
+application/vnd.bmi bmi
+application/vnd.businessobjects rep
+# application/vnd.cab-jscript
+# application/vnd.canon-cpdl
+# application/vnd.canon-lips
+# application/vnd.cendio.thinlinc.clientconf
+application/vnd.chemdraw+xml cdxml
+application/vnd.chipnuts.karaoke-mmd mmd
+application/vnd.cinderella cdy
+# application/vnd.cirpack.isdn-ext
+application/vnd.claymore cla
+application/vnd.cloanto.rp9 rp9
+application/vnd.clonk.c4group c4g c4d c4f c4p c4u
+application/vnd.cluetrust.cartomobile-config c11amc
+application/vnd.cluetrust.cartomobile-config-pkg c11amz
+# application/vnd.collection+json
+# application/vnd.commerce-battelle
+application/vnd.commonspace csp
+application/vnd.contact.cmsg cdbcmsg
+application/vnd.cosmocaller cmc
+application/vnd.crick.clicker clkx
+application/vnd.crick.clicker.keyboard clkk
+application/vnd.crick.clicker.palette clkp
+application/vnd.crick.clicker.template clkt
+application/vnd.crick.clicker.wordbank clkw
+application/vnd.criticaltools.wbs+xml wbs
+application/vnd.ctc-posml pml
+# application/vnd.ctct.ws+xml
+# application/vnd.cups-pdf
+# application/vnd.cups-postscript
+application/vnd.cups-ppd ppd
+# application/vnd.cups-raster
+# application/vnd.cups-raw
+# application/vnd.curl
+application/vnd.curl.car car
+application/vnd.curl.pcurl pcurl
+# application/vnd.cybank
+application/vnd.dart dart
+application/vnd.data-vision.rdz rdz
+application/vnd.dece.data uvf uvvf uvd uvvd
+application/vnd.dece.ttml+xml uvt uvvt
+application/vnd.dece.unspecified uvx uvvx
+application/vnd.dece.zip uvz uvvz
+application/vnd.denovo.fcselayout-link fe_launch
+# application/vnd.dir-bi.plate-dl-nosuffix
+application/vnd.dna dna
+application/vnd.dolby.mlp mlp
+# application/vnd.dolby.mobile.1
+# application/vnd.dolby.mobile.2
+application/vnd.dpgraph dpg
+application/vnd.dreamfactory dfac
+application/vnd.ds-keypoint kpxx
+application/vnd.dvb.ait ait
+# application/vnd.dvb.dvbj
+# application/vnd.dvb.esgcontainer
+# application/vnd.dvb.ipdcdftnotifaccess
+# application/vnd.dvb.ipdcesgaccess
+# application/vnd.dvb.ipdcesgaccess2
+# application/vnd.dvb.ipdcesgpdd
+# application/vnd.dvb.ipdcroaming
+# application/vnd.dvb.iptv.alfec-base
+# application/vnd.dvb.iptv.alfec-enhancement
+# application/vnd.dvb.notif-aggregate-root+xml
+# application/vnd.dvb.notif-container+xml
+# application/vnd.dvb.notif-generic+xml
+# application/vnd.dvb.notif-ia-msglist+xml
+# application/vnd.dvb.notif-ia-registration-request+xml
+# application/vnd.dvb.notif-ia-registration-response+xml
+# application/vnd.dvb.notif-init+xml
+# application/vnd.dvb.pfr
+application/vnd.dvb.service svc
+# application/vnd.dxr
+application/vnd.dynageo geo
+# application/vnd.easykaraoke.cdgdownload
+# application/vnd.ecdis-update
+application/vnd.ecowin.chart mag
+# application/vnd.ecowin.filerequest
+# application/vnd.ecowin.fileupdate
+# application/vnd.ecowin.series
+# application/vnd.ecowin.seriesrequest
+# application/vnd.ecowin.seriesupdate
+# application/vnd.emclient.accessrequest+xml
+application/vnd.enliven nml
+# application/vnd.eprints.data+xml
+application/vnd.epson.esf esf
+application/vnd.epson.msf msf
+application/vnd.epson.quickanime qam
+application/vnd.epson.salt slt
+application/vnd.epson.ssf ssf
+# application/vnd.ericsson.quickcall
+application/vnd.eszigno3+xml es3 et3
+# application/vnd.etsi.aoc+xml
+# application/vnd.etsi.cug+xml
+# application/vnd.etsi.iptvcommand+xml
+# application/vnd.etsi.iptvdiscovery+xml
+# application/vnd.etsi.iptvprofile+xml
+# application/vnd.etsi.iptvsad-bc+xml
+# application/vnd.etsi.iptvsad-cod+xml
+# application/vnd.etsi.iptvsad-npvr+xml
+# application/vnd.etsi.iptvservice+xml
+# application/vnd.etsi.iptvsync+xml
+# application/vnd.etsi.iptvueprofile+xml
+# application/vnd.etsi.mcid+xml
+# application/vnd.etsi.overload-control-policy-dataset+xml
+# application/vnd.etsi.sci+xml
+# application/vnd.etsi.simservs+xml
+# application/vnd.etsi.tsl+xml
+# application/vnd.etsi.tsl.der
+# application/vnd.eudora.data
+application/vnd.ezpix-album ez2
+application/vnd.ezpix-package ez3
+# application/vnd.f-secure.mobile
+application/vnd.fdf fdf
+application/vnd.fdsn.mseed mseed
+application/vnd.fdsn.seed seed dataless
+# application/vnd.ffsns
+# application/vnd.fints
+application/vnd.flographit gph
+application/vnd.fluxtime.clip ftc
+# application/vnd.font-fontforge-sfd
+application/vnd.framemaker fm frame maker book
+application/vnd.frogans.fnc fnc
+application/vnd.frogans.ltf ltf
+application/vnd.fsc.weblaunch fsc
+application/vnd.fujitsu.oasys oas
+application/vnd.fujitsu.oasys2 oa2
+application/vnd.fujitsu.oasys3 oa3
+application/vnd.fujitsu.oasysgp fg5
+application/vnd.fujitsu.oasysprs bh2
+# application/vnd.fujixerox.art-ex
+# application/vnd.fujixerox.art4
+# application/vnd.fujixerox.hbpl
+application/vnd.fujixerox.ddd ddd
+application/vnd.fujixerox.docuworks xdw
+application/vnd.fujixerox.docuworks.binder xbd
+# application/vnd.fut-misnet
+application/vnd.fuzzysheet fzs
+application/vnd.genomatix.tuxedo txd
+# application/vnd.geocube+xml
+application/vnd.geogebra.file ggb
+application/vnd.geogebra.tool ggt
+application/vnd.geometry-explorer gex gre
+application/vnd.geonext gxt
+application/vnd.geoplan g2w
+application/vnd.geospace g3w
+# application/vnd.globalplatform.card-content-mgt
+# application/vnd.globalplatform.card-content-mgt-response
+application/vnd.gmx gmx
+application/vnd.google-earth.kml+xml kml
+application/vnd.google-earth.kmz kmz
+application/vnd.grafeq gqf gqs
+# application/vnd.gridmp
+application/vnd.groove-account gac
+application/vnd.groove-help ghf
+application/vnd.groove-identity-message gim
+application/vnd.groove-injector grv
+application/vnd.groove-tool-message gtm
+application/vnd.groove-tool-template tpl
+application/vnd.groove-vcard vcg
+# application/vnd.hal+json
+application/vnd.hal+xml hal
+application/vnd.handheld-entertainment+xml zmm
+application/vnd.hbci hbci
+# application/vnd.hcl-bireports
+application/vnd.hhe.lesson-player les
+application/vnd.hp-hpgl hpgl
+application/vnd.hp-hpid hpid
+application/vnd.hp-hps hps
+application/vnd.hp-jlyt jlt
+application/vnd.hp-pcl pcl
+application/vnd.hp-pclxl pclxl
+# application/vnd.httphone
+application/vnd.hydrostatix.sof-data sfd-hdstx
+# application/vnd.hzn-3d-crossword
+# application/vnd.ibm.afplinedata
+# application/vnd.ibm.electronic-media
+application/vnd.ibm.minipay mpy
+application/vnd.ibm.modcap afp listafp list3820
+application/vnd.ibm.rights-management irm
+application/vnd.ibm.secure-container sc
+application/vnd.iccprofile icc icm
+application/vnd.igloader igl
+application/vnd.immervision-ivp ivp
+application/vnd.immervision-ivu ivu
+# application/vnd.informedcontrol.rms+xml
+# application/vnd.informix-visionary
+# application/vnd.infotech.project
+# application/vnd.infotech.project+xml
+# application/vnd.innopath.wamp.notification
+application/vnd.insors.igm igm
+application/vnd.intercon.formnet xpw xpx
+application/vnd.intergeo i2g
+# application/vnd.intertrust.digibox
+# application/vnd.intertrust.nncp
+application/vnd.intu.qbo qbo
+application/vnd.intu.qfx qfx
+# application/vnd.iptc.g2.conceptitem+xml
+# application/vnd.iptc.g2.knowledgeitem+xml
+# application/vnd.iptc.g2.newsitem+xml
+# application/vnd.iptc.g2.newsmessage+xml
+# application/vnd.iptc.g2.packageitem+xml
+# application/vnd.iptc.g2.planningitem+xml
+application/vnd.ipunplugged.rcprofile rcprofile
+application/vnd.irepository.package+xml irp
+application/vnd.is-xpr xpr
+application/vnd.isac.fcs fcs
+application/vnd.jam jam
+# application/vnd.japannet-directory-service
+# application/vnd.japannet-jpnstore-wakeup
+# application/vnd.japannet-payment-wakeup
+# application/vnd.japannet-registration
+# application/vnd.japannet-registration-wakeup
+# application/vnd.japannet-setstore-wakeup
+# application/vnd.japannet-verification
+# application/vnd.japannet-verification-wakeup
+application/vnd.jcp.javame.midlet-rms rms
+application/vnd.jisp jisp
+application/vnd.joost.joda-archive joda
+application/vnd.kahootz ktz ktr
+application/vnd.kde.karbon karbon
+application/vnd.kde.kchart chrt
+application/vnd.kde.kformula kfo
+application/vnd.kde.kivio flw
+application/vnd.kde.kontour kon
+application/vnd.kde.kpresenter kpr kpt
+application/vnd.kde.kspread ksp
+application/vnd.kde.kword kwd kwt
+application/vnd.kenameaapp htke
+application/vnd.kidspiration kia
+application/vnd.kinar kne knp
+application/vnd.koan skp skd skt skm
+application/vnd.kodak-descriptor sse
+application/vnd.las.las+xml lasxml
+# application/vnd.liberty-request+xml
+application/vnd.llamagraphics.life-balance.desktop lbd
+application/vnd.llamagraphics.life-balance.exchange+xml lbe
+application/vnd.lotus-1-2-3 123
+application/vnd.lotus-approach apr
+application/vnd.lotus-freelance pre
+application/vnd.lotus-notes nsf
+application/vnd.lotus-organizer org
+application/vnd.lotus-screencam scm
+application/vnd.lotus-wordpro lwp
+application/vnd.macports.portpkg portpkg
+# application/vnd.marlin.drm.actiontoken+xml
+# application/vnd.marlin.drm.conftoken+xml
+# application/vnd.marlin.drm.license+xml
+# application/vnd.marlin.drm.mdcf
+application/vnd.mcd mcd
+application/vnd.medcalcdata mc1
+application/vnd.mediastation.cdkey cdkey
+# application/vnd.meridian-slingshot
+application/vnd.mfer mwf
+application/vnd.mfmp mfm
+application/vnd.micrografx.flo flo
+application/vnd.micrografx.igx igx
+application/vnd.mif mif
+# application/vnd.minisoft-hp3000-save
+# application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf daf
+application/vnd.mobius.dis dis
+application/vnd.mobius.mbk mbk
+application/vnd.mobius.mqy mqy
+application/vnd.mobius.msl msl
+application/vnd.mobius.plc plc
+application/vnd.mobius.txf txf
+application/vnd.mophun.application mpn
+application/vnd.mophun.certificate mpc
+# application/vnd.motorola.flexsuite
+# application/vnd.motorola.flexsuite.adsi
+# application/vnd.motorola.flexsuite.fis
+# application/vnd.motorola.flexsuite.gotap
+# application/vnd.motorola.flexsuite.kmr
+# application/vnd.motorola.flexsuite.ttc
+# application/vnd.motorola.flexsuite.wem
+# application/vnd.motorola.iprm
+application/vnd.mozilla.xul+xml xul
+application/vnd.ms-artgalry cil
+# application/vnd.ms-asf
+application/vnd.ms-cab-compressed cab
+# application/vnd.ms-color.iccprofile
+application/vnd.ms-excel xls xlm xla xlc xlt xlw
+application/vnd.ms-excel.addin.macroenabled.12 xlam
+application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
+application/vnd.ms-excel.sheet.macroenabled.12 xlsm
+application/vnd.ms-excel.template.macroenabled.12 xltm
+application/vnd.ms-fontobject eot
+application/vnd.ms-htmlhelp chm
+application/vnd.ms-ims ims
+application/vnd.ms-lrm lrm
+# application/vnd.ms-office.activex+xml
+application/vnd.ms-officetheme thmx
+# application/vnd.ms-opentype
+# application/vnd.ms-package.obfuscated-opentype
+application/vnd.ms-pki.seccat cat
+application/vnd.ms-pki.stl stl
+# application/vnd.ms-playready.initiator+xml
+application/vnd.ms-powerpoint ppt pps pot
+application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
+application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
+application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
+application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
+application/vnd.ms-powerpoint.template.macroenabled.12 potm
+# application/vnd.ms-printing.printticket+xml
+application/vnd.ms-project mpp mpt
+# application/vnd.ms-tnef
+# application/vnd.ms-wmdrm.lic-chlg-req
+# application/vnd.ms-wmdrm.lic-resp
+# application/vnd.ms-wmdrm.meter-chlg-req
+# application/vnd.ms-wmdrm.meter-resp
+application/vnd.ms-word.document.macroenabled.12 docm
+application/vnd.ms-word.template.macroenabled.12 dotm
+application/vnd.ms-works wps wks wcm wdb
+application/vnd.ms-wpl wpl
+application/vnd.ms-xpsdocument xps
+application/vnd.mseq mseq
+# application/vnd.msign
+# application/vnd.multiad.creator
+# application/vnd.multiad.creator.cif
+# application/vnd.music-niff
+application/vnd.musician mus
+application/vnd.muvee.style msty
+application/vnd.mynfc taglet
+# application/vnd.ncd.control
+# application/vnd.ncd.reference
+# application/vnd.nervana
+# application/vnd.netfpx
+application/vnd.neurolanguage.nlu nlu
+application/vnd.nitf ntf nitf
+application/vnd.noblenet-directory nnd
+application/vnd.noblenet-sealer nns
+application/vnd.noblenet-web nnw
+# application/vnd.nokia.catalogs
+# application/vnd.nokia.conml+wbxml
+# application/vnd.nokia.conml+xml
+# application/vnd.nokia.isds-radio-presets
+# application/vnd.nokia.iptv.config+xml
+# application/vnd.nokia.landmark+wbxml
+# application/vnd.nokia.landmark+xml
+# application/vnd.nokia.landmarkcollection+xml
+# application/vnd.nokia.n-gage.ac+xml
+application/vnd.nokia.n-gage.data ngdat
+application/vnd.nokia.n-gage.symbian.install n-gage
+# application/vnd.nokia.ncd
+# application/vnd.nokia.pcd+wbxml
+# application/vnd.nokia.pcd+xml
+application/vnd.nokia.radio-preset rpst
+application/vnd.nokia.radio-presets rpss
+application/vnd.novadigm.edm edm
+application/vnd.novadigm.edx edx
+application/vnd.novadigm.ext ext
+# application/vnd.ntt-local.file-transfer
+# application/vnd.ntt-local.sip-ta_remote
+# application/vnd.ntt-local.sip-ta_tcp_stream
+application/vnd.oasis.opendocument.chart odc
+application/vnd.oasis.opendocument.chart-template otc
+application/vnd.oasis.opendocument.database odb
+application/vnd.oasis.opendocument.formula odf
+application/vnd.oasis.opendocument.formula-template odft
+application/vnd.oasis.opendocument.graphics odg
+application/vnd.oasis.opendocument.graphics-template otg
+application/vnd.oasis.opendocument.image odi
+application/vnd.oasis.opendocument.image-template oti
+application/vnd.oasis.opendocument.presentation odp
+application/vnd.oasis.opendocument.presentation-template otp
+application/vnd.oasis.opendocument.spreadsheet ods
+application/vnd.oasis.opendocument.spreadsheet-template ots
+application/vnd.oasis.opendocument.text odt
+application/vnd.oasis.opendocument.text-master odm
+application/vnd.oasis.opendocument.text-template ott
+application/vnd.oasis.opendocument.text-web oth
+# application/vnd.obn
+# application/vnd.oftn.l10n+json
+# application/vnd.oipf.contentaccessdownload+xml
+# application/vnd.oipf.contentaccessstreaming+xml
+# application/vnd.oipf.cspg-hexbinary
+# application/vnd.oipf.dae.svg+xml
+# application/vnd.oipf.dae.xhtml+xml
+# application/vnd.oipf.mippvcontrolmessage+xml
+# application/vnd.oipf.pae.gem
+# application/vnd.oipf.spdiscovery+xml
+# application/vnd.oipf.spdlist+xml
+# application/vnd.oipf.ueprofile+xml
+# application/vnd.oipf.userprofile+xml
+application/vnd.olpc-sugar xo
+# application/vnd.oma-scws-config
+# application/vnd.oma-scws-http-request
+# application/vnd.oma-scws-http-response
+# application/vnd.oma.bcast.associated-procedure-parameter+xml
+# application/vnd.oma.bcast.drm-trigger+xml
+# application/vnd.oma.bcast.imd+xml
+# application/vnd.oma.bcast.ltkm
+# application/vnd.oma.bcast.notification+xml
+# application/vnd.oma.bcast.provisioningtrigger
+# application/vnd.oma.bcast.sgboot
+# application/vnd.oma.bcast.sgdd+xml
+# application/vnd.oma.bcast.sgdu
+# application/vnd.oma.bcast.simple-symbol-container
+# application/vnd.oma.bcast.smartcard-trigger+xml
+# application/vnd.oma.bcast.sprov+xml
+# application/vnd.oma.bcast.stkm
+# application/vnd.oma.cab-address-book+xml
+# application/vnd.oma.cab-feature-handler+xml
+# application/vnd.oma.cab-pcc+xml
+# application/vnd.oma.cab-user-prefs+xml
+# application/vnd.oma.dcd
+# application/vnd.oma.dcdc
+application/vnd.oma.dd2+xml dd2
+# application/vnd.oma.drm.risd+xml
+# application/vnd.oma.group-usage-list+xml
+# application/vnd.oma.pal+xml
+# application/vnd.oma.poc.detailed-progress-report+xml
+# application/vnd.oma.poc.final-report+xml
+# application/vnd.oma.poc.groups+xml
+# application/vnd.oma.poc.invocation-descriptor+xml
+# application/vnd.oma.poc.optimized-progress-report+xml
+# application/vnd.oma.push
+# application/vnd.oma.scidm.messages+xml
+# application/vnd.oma.xcap-directory+xml
+# application/vnd.omads-email+xml
+# application/vnd.omads-file+xml
+# application/vnd.omads-folder+xml
+# application/vnd.omaloc-supl-init
+application/vnd.openofficeorg.extension oxt
+# application/vnd.openxmlformats-officedocument.custom-properties+xml
+# application/vnd.openxmlformats-officedocument.customxmlproperties+xml
+# application/vnd.openxmlformats-officedocument.drawing+xml
+# application/vnd.openxmlformats-officedocument.drawingml.chart+xml
+# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml
+# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml
+# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml
+# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml
+# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml
+# application/vnd.openxmlformats-officedocument.extended-properties+xml
+# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml
+# application/vnd.openxmlformats-officedocument.presentationml.comments+xml
+# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml
+# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml
+# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml
+application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
+# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
+# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml
+application/vnd.openxmlformats-officedocument.presentationml.slide sldx
+# application/vnd.openxmlformats-officedocument.presentationml.slide+xml
+# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml
+# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
+# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml
+# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml
+# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml
+# application/vnd.openxmlformats-officedocument.presentationml.tags+xml
+application/vnd.openxmlformats-officedocument.presentationml.template potx
+# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
+# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
+# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
+# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml
+# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
+# application/vnd.openxmlformats-officedocument.theme+xml
+# application/vnd.openxmlformats-officedocument.themeoverride+xml
+# application/vnd.openxmlformats-officedocument.vmldrawing
+# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
+# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
+# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
+# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml
+# application/vnd.openxmlformats-package.core-properties+xml
+# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml
+# application/vnd.openxmlformats-package.relationships+xml
+# application/vnd.quobject-quoxdocument
+# application/vnd.osa.netdeploy
+application/vnd.osgeo.mapguide.package mgp
+# application/vnd.osgi.bundle
+application/vnd.osgi.dp dp
+application/vnd.osgi.subsystem esa
+# application/vnd.otps.ct-kip+xml
+application/vnd.palm pdb pqa oprc
+# application/vnd.paos.xml
+application/vnd.pawaafile paw
+application/vnd.pg.format str
+application/vnd.pg.osasli ei6
+# application/vnd.piaccess.application-licence
+application/vnd.picsel efif
+application/vnd.pmi.widget wg
+# application/vnd.poc.group-advertisement+xml
+application/vnd.pocketlearn plf
+application/vnd.powerbuilder6 pbd
+# application/vnd.powerbuilder6-s
+# application/vnd.powerbuilder7
+# application/vnd.powerbuilder7-s
+# application/vnd.powerbuilder75
+# application/vnd.powerbuilder75-s
+# application/vnd.preminet
+application/vnd.previewsystems.box box
+application/vnd.proteus.magazine mgz
+application/vnd.publishare-delta-tree qps
+application/vnd.pvi.ptid1 ptid
+# application/vnd.pwg-multiplexed
+# application/vnd.pwg-xhtml-print+xml
+# application/vnd.qualcomm.brew-app-res
+application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
+# application/vnd.radisys.moml+xml
+# application/vnd.radisys.msml+xml
+# application/vnd.radisys.msml-audit+xml
+# application/vnd.radisys.msml-audit-conf+xml
+# application/vnd.radisys.msml-audit-conn+xml
+# application/vnd.radisys.msml-audit-dialog+xml
+# application/vnd.radisys.msml-audit-stream+xml
+# application/vnd.radisys.msml-conf+xml
+# application/vnd.radisys.msml-dialog+xml
+# application/vnd.radisys.msml-dialog-base+xml
+# application/vnd.radisys.msml-dialog-fax-detect+xml
+# application/vnd.radisys.msml-dialog-fax-sendrecv+xml
+# application/vnd.radisys.msml-dialog-group+xml
+# application/vnd.radisys.msml-dialog-speech+xml
+# application/vnd.radisys.msml-dialog-transform+xml
+# application/vnd.rainstor.data
+# application/vnd.rapid
+application/vnd.realvnc.bed bed
+application/vnd.recordare.musicxml mxl
+application/vnd.recordare.musicxml+xml musicxml
+# application/vnd.renlearn.rlprint
+application/vnd.rig.cryptonote cryptonote
+application/vnd.rim.cod cod
+application/vnd.rn-realmedia rm
+application/vnd.rn-realmedia-vbr rmvb
+application/vnd.route66.link66+xml link66
+# application/vnd.rs-274x
+# application/vnd.ruckus.download
+# application/vnd.s3sms
+application/vnd.sailingtracker.track st
+# application/vnd.sbm.cid
+# application/vnd.sbm.mid2
+# application/vnd.scribus
+# application/vnd.sealed.3df
+# application/vnd.sealed.csf
+# application/vnd.sealed.doc
+# application/vnd.sealed.eml
+# application/vnd.sealed.mht
+# application/vnd.sealed.net
+# application/vnd.sealed.ppt
+# application/vnd.sealed.tiff
+# application/vnd.sealed.xls
+# application/vnd.sealedmedia.softseal.html
+# application/vnd.sealedmedia.softseal.pdf
+application/vnd.seemail see
+application/vnd.sema sema
+application/vnd.semd semd
+application/vnd.semf semf
+application/vnd.shana.informed.formdata ifm
+application/vnd.shana.informed.formtemplate itp
+application/vnd.shana.informed.interchange iif
+application/vnd.shana.informed.package ipk
+application/vnd.simtech-mindmapper twd twds
+application/vnd.smaf mmf
+# application/vnd.smart.notebook
+application/vnd.smart.teacher teacher
+# application/vnd.software602.filler.form+xml
+# application/vnd.software602.filler.form-xml-zip
+application/vnd.solent.sdkm+xml sdkm sdkd
+application/vnd.spotfire.dxp dxp
+application/vnd.spotfire.sfs sfs
+# application/vnd.sss-cod
+# application/vnd.sss-dtf
+# application/vnd.sss-ntf
+application/vnd.stardivision.calc sdc
+application/vnd.stardivision.draw sda
+application/vnd.stardivision.impress sdd
+application/vnd.stardivision.math smf
+application/vnd.stardivision.writer sdw vor
+application/vnd.stardivision.writer-global sgl
+application/vnd.stepmania.package smzip
+application/vnd.stepmania.stepchart sm
+# application/vnd.street-stream
+application/vnd.sun.xml.calc sxc
+application/vnd.sun.xml.calc.template stc
+application/vnd.sun.xml.draw sxd
+application/vnd.sun.xml.draw.template std
+application/vnd.sun.xml.impress sxi
+application/vnd.sun.xml.impress.template sti
+application/vnd.sun.xml.math sxm
+application/vnd.sun.xml.writer sxw
+application/vnd.sun.xml.writer.global sxg
+application/vnd.sun.xml.writer.template stw
+# application/vnd.sun.wadl+xml
+application/vnd.sus-calendar sus susp
+application/vnd.svd svd
+# application/vnd.swiftview-ics
+application/vnd.symbian.install sis sisx
+application/vnd.syncml+xml xsm
+application/vnd.syncml.dm+wbxml bdm
+application/vnd.syncml.dm+xml xdm
+# application/vnd.syncml.dm.notification
+# application/vnd.syncml.ds.notification
+application/vnd.tao.intent-module-archive tao
+application/vnd.tcpdump.pcap pcap cap dmp
+application/vnd.tmobile-livetv tmo
+application/vnd.trid.tpt tpt
+application/vnd.triscape.mxs mxs
+application/vnd.trueapp tra
+# application/vnd.truedoc
+# application/vnd.ubisoft.webplayer
+application/vnd.ufdl ufd ufdl
+application/vnd.uiq.theme utz
+application/vnd.umajin umj
+application/vnd.unity unityweb
+application/vnd.uoml+xml uoml
+# application/vnd.uplanet.alert
+# application/vnd.uplanet.alert-wbxml
+# application/vnd.uplanet.bearer-choice
+# application/vnd.uplanet.bearer-choice-wbxml
+# application/vnd.uplanet.cacheop
+# application/vnd.uplanet.cacheop-wbxml
+# application/vnd.uplanet.channel
+# application/vnd.uplanet.channel-wbxml
+# application/vnd.uplanet.list
+# application/vnd.uplanet.list-wbxml
+# application/vnd.uplanet.listcmd
+# application/vnd.uplanet.listcmd-wbxml
+# application/vnd.uplanet.signal
+application/vnd.vcx vcx
+# application/vnd.vd-study
+# application/vnd.vectorworks
+# application/vnd.verimatrix.vcas
+# application/vnd.vidsoft.vidconference
+application/vnd.visio vsd vst vss vsw
+application/vnd.visionary vis
+# application/vnd.vividence.scriptfile
+application/vnd.vsf vsf
+# application/vnd.wap.sic
+# application/vnd.wap.slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo wtb
+# application/vnd.wfa.wsc
+# application/vnd.wmc
+# application/vnd.wmf.bootstrap
+# application/vnd.wolfram.mathematica
+# application/vnd.wolfram.mathematica.package
+application/vnd.wolfram.player nbp
+application/vnd.wordperfect wpd
+application/vnd.wqd wqd
+# application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf stf
+# application/vnd.wv.csp+wbxml
+# application/vnd.wv.csp+xml
+# application/vnd.wv.ssp+xml
+application/vnd.xara xar
+application/vnd.xfdl xfdl
+# application/vnd.xfdl.webform
+# application/vnd.xmi+xml
+# application/vnd.xmpie.cpkg
+# application/vnd.xmpie.dpkg
+# application/vnd.xmpie.plan
+# application/vnd.xmpie.ppkg
+# application/vnd.xmpie.xlim
+application/vnd.yamaha.hv-dic hvd
+application/vnd.yamaha.hv-script hvs
+application/vnd.yamaha.hv-voice hvp
+application/vnd.yamaha.openscoreformat osf
+application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
+# application/vnd.yamaha.remote-setup
+application/vnd.yamaha.smaf-audio saf
+application/vnd.yamaha.smaf-phrase spf
+# application/vnd.yamaha.through-ngn
+# application/vnd.yamaha.tunnel-udpencap
+application/vnd.yellowriver-custom-menu cmp
+application/vnd.zul zir zirz
+application/vnd.zzazz.deck+xml zaz
+application/voicexml+xml vxml
+# application/vq-rtcpxr
+# application/watcherinfo+xml
+# application/whoispp-query
+# application/whoispp-response
+application/widget wgt
+application/winhlp hlp
+# application/wita
+# application/wordperfect5.1
+application/wsdl+xml wsdl
+application/wspolicy+xml wspolicy
+application/x-7z-compressed 7z
+application/x-abiword abw
+application/x-ace-compressed ace
+# application/x-amf
+application/x-apple-diskimage dmg
+application/x-authorware-bin aab x32 u32 vox
+application/x-authorware-map aam
+application/x-authorware-seg aas
+application/x-bcpio bcpio
+application/x-bittorrent torrent
+application/x-blorb blb blorb
+application/x-bzip bz
+application/x-bzip2 bz2 boz
+application/x-cbr cbr cba cbt cbz cb7
+application/x-cdlink vcd
+application/x-cfs-compressed cfs
+application/x-chat chat
+application/x-chess-pgn pgn
+application/x-conference nsc
+# application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-debian-package deb udeb
+application/x-dgc-compressed dgc
+application/x-director dir dcr dxr cst cct cxt w3d fgd swa
+application/x-doom wad
+application/x-dtbncx+xml ncx
+application/x-dtbook+xml dtb
+application/x-dtbresource+xml res
+application/x-dvi dvi
+application/x-envoy evy
+application/x-eva eva
+application/x-font-bdf bdf
+# application/x-font-dos
+# application/x-font-framemaker
+application/x-font-ghostscript gsf
+# application/x-font-libgrx
+application/x-font-linux-psf psf
+application/x-font-otf otf
+application/x-font-pcf pcf
+application/x-font-snf snf
+# application/x-font-speedo
+# application/x-font-sunos-news
+application/x-font-ttf ttf ttc
+application/x-font-type1 pfa pfb pfm afm
+application/x-font-woff woff
+# application/x-font-vfont
+application/x-freearc arc
+application/x-futuresplash spl
+application/x-gca-compressed gca
+application/x-glulx ulx
+application/x-gnumeric gnumeric
+application/x-gramps-xml gramps
+application/x-gtar gtar
+# application/x-gzip
+application/x-hdf hdf
+application/x-install-instructions install
+application/x-iso9660-image iso
+application/x-java-jnlp-file jnlp
+application/x-latex latex
+application/x-lzh-compressed lzh lha
+application/x-mie mie
+application/x-mobipocket-ebook prc mobi
+application/x-ms-application application
+application/x-ms-shortcut lnk
+application/x-ms-wmd wmd
+application/x-ms-wmz wmz
+application/x-ms-xbap xbap
+application/x-msaccess mdb
+application/x-msbinder obd
+application/x-mscardfile crd
+application/x-msclip clp
+application/x-msdownload exe dll com bat msi
+application/x-msmediaview mvb m13 m14
+application/x-msmetafile wmf wmz emf emz
+application/x-msmoney mny
+application/x-mspublisher pub
+application/x-msschedule scd
+application/x-msterminal trm
+application/x-mswrite wri
+application/x-netcdf nc cdf
+application/x-nzb nzb
+application/x-pkcs12 p12 pfx
+application/x-pkcs7-certificates p7b spc
+application/x-pkcs7-certreqresp p7r
+application/x-rar-compressed rar
+application/x-research-info-systems ris
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-silverlight-app xap
+application/x-sql sql
+application/x-stuffit sit
+application/x-stuffitx sitx
+application/x-subrip srt
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-t3vm-image t3
+application/x-tads gam
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-tex-tfm tfm
+application/x-texinfo texinfo texi
+application/x-tgif obj
+application/x-ustar ustar
+application/x-wais-source src
+application/x-x509-ca-cert der crt
+application/x-xfig fig
+application/x-xliff+xml xlf
+application/x-xpinstall xpi
+application/x-xz xz
+application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8
+# application/x400-bp
+application/xaml+xml xaml
+# application/xcap-att+xml
+# application/xcap-caps+xml
+application/xcap-diff+xml xdf
+# application/xcap-el+xml
+# application/xcap-error+xml
+# application/xcap-ns+xml
+# application/xcon-conference-info-diff+xml
+# application/xcon-conference-info+xml
+application/xenc+xml xenc
+application/xhtml+xml xhtml xht
+# application/xhtml-voice+xml
+application/xml xml xsl
+application/xml-dtd dtd
+# application/xml-external-parsed-entity
+# application/xmpp+xml
+application/xop+xml xop
+application/xproc+xml xpl
+application/xslt+xml xslt
+application/xspf+xml xspf
+application/xv+xml mxml xhvml xvml xvm
+application/yang yang
+application/yin+xml yin
+application/zip zip
+# audio/1d-interleaved-parityfec
+# audio/32kadpcm
+# audio/3gpp
+# audio/3gpp2
+# audio/ac3
+audio/adpcm adp
+# audio/amr
+# audio/amr-wb
+# audio/amr-wb+
+# audio/asc
+# audio/atrac-advanced-lossless
+# audio/atrac-x
+# audio/atrac3
+audio/basic au snd
+# audio/bv16
+# audio/bv32
+# audio/clearmode
+# audio/cn
+# audio/dat12
+# audio/dls
+# audio/dsr-es201108
+# audio/dsr-es202050
+# audio/dsr-es202211
+# audio/dsr-es202212
+# audio/dv
+# audio/dvi4
+# audio/eac3
+# audio/evrc
+# audio/evrc-qcp
+# audio/evrc0
+# audio/evrc1
+# audio/evrcb
+# audio/evrcb0
+# audio/evrcb1
+# audio/evrcwb
+# audio/evrcwb0
+# audio/evrcwb1
+# audio/example
+# audio/fwdred
+# audio/g719
+# audio/g722
+# audio/g7221
+# audio/g723
+# audio/g726-16
+# audio/g726-24
+# audio/g726-32
+# audio/g726-40
+# audio/g728
+# audio/g729
+# audio/g7291
+# audio/g729d
+# audio/g729e
+# audio/gsm
+# audio/gsm-efr
+# audio/gsm-hr-08
+# audio/ilbc
+# audio/ip-mr_v2.5
+# audio/isac
+# audio/l16
+# audio/l20
+# audio/l24
+# audio/l8
+# audio/lpc
+audio/midi mid midi kar rmi
+# audio/mobile-xmf
+audio/mp4 mp4a
+# audio/mp4a-latm
+# audio/mpa
+# audio/mpa-robust
+audio/mpeg mpga mp2 mp2a mp3 m2a m3a
+# audio/mpeg4-generic
+# audio/musepack
+audio/ogg oga ogg spx
+# audio/opus
+# audio/parityfec
+# audio/pcma
+# audio/pcma-wb
+# audio/pcmu-wb
+# audio/pcmu
+# audio/prs.sid
+# audio/qcelp
+# audio/red
+# audio/rtp-enc-aescm128
+# audio/rtp-midi
+# audio/rtx
+audio/s3m s3m
+audio/silk sil
+# audio/smv
+# audio/smv0
+# audio/smv-qcp
+# audio/sp-midi
+# audio/speex
+# audio/t140c
+# audio/t38
+# audio/telephone-event
+# audio/tone
+# audio/uemclip
+# audio/ulpfec
+# audio/vdvi
+# audio/vmr-wb
+# audio/vnd.3gpp.iufp
+# audio/vnd.4sb
+# audio/vnd.audiokoz
+# audio/vnd.celp
+# audio/vnd.cisco.nse
+# audio/vnd.cmles.radio-events
+# audio/vnd.cns.anp1
+# audio/vnd.cns.inf1
+audio/vnd.dece.audio uva uvva
+audio/vnd.digital-winds eol
+# audio/vnd.dlna.adts
+# audio/vnd.dolby.heaac.1
+# audio/vnd.dolby.heaac.2
+# audio/vnd.dolby.mlp
+# audio/vnd.dolby.mps
+# audio/vnd.dolby.pl2
+# audio/vnd.dolby.pl2x
+# audio/vnd.dolby.pl2z
+# audio/vnd.dolby.pulse.1
+audio/vnd.dra dra
+audio/vnd.dts dts
+audio/vnd.dts.hd dtshd
+# audio/vnd.dvb.file
+# audio/vnd.everad.plj
+# audio/vnd.hns.audio
+audio/vnd.lucent.voice lvp
+audio/vnd.ms-playready.media.pya pya
+# audio/vnd.nokia.mobile-xmf
+# audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800 ecelp4800
+audio/vnd.nuera.ecelp7470 ecelp7470
+audio/vnd.nuera.ecelp9600 ecelp9600
+# audio/vnd.octel.sbc
+# audio/vnd.qcelp
+# audio/vnd.rhetorex.32kadpcm
+audio/vnd.rip rip
+# audio/vnd.sealedmedia.softseal.mpeg
+# audio/vnd.vmx.cvsd
+# audio/vorbis
+# audio/vorbis-config
+audio/webm weba
+audio/x-aac aac
+audio/x-aiff aif aiff aifc
+audio/x-caf caf
+audio/x-flac flac
+audio/x-matroska mka
+audio/x-mpegurl m3u
+audio/x-ms-wax wax
+audio/x-ms-wma wma
+audio/x-pn-realaudio ram ra
+audio/x-pn-realaudio-plugin rmp
+# audio/x-tta
+audio/x-wav wav
+audio/xm xm
+chemical/x-cdx cdx
+chemical/x-cif cif
+chemical/x-cmdf cmdf
+chemical/x-cml cml
+chemical/x-csml csml
+# chemical/x-pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm cgm
+# image/example
+# image/fits
+image/g3fax g3
+image/gif gif
+image/ief ief
+# image/jp2
+image/jpeg jpeg jpg jpe
+# image/jpm
+# image/jpx
+image/ktx ktx
+# image/naplps
+image/png png
+image/prs.btif btif
+# image/prs.pti
+image/sgi sgi
+image/svg+xml svg svgz
+# image/t38
+image/tiff tiff tif
+# image/tiff-fx
+image/vnd.adobe.photoshop psd
+# image/vnd.cns.inf2
+image/vnd.dece.graphic uvi uvvi uvg uvvg
+image/vnd.dvb.subtitle sub
+image/vnd.djvu djvu djv
+image/vnd.dwg dwg
+image/vnd.dxf dxf
+image/vnd.fastbidsheet fbs
+image/vnd.fpx fpx
+image/vnd.fst fst
+image/vnd.fujixerox.edmics-mmr mmr
+image/vnd.fujixerox.edmics-rlc rlc
+# image/vnd.globalgraphics.pgb
+# image/vnd.microsoft.icon
+# image/vnd.mix
+image/vnd.ms-modi mdi
+image/vnd.ms-photo wdp
+image/vnd.net-fpx npx
+# image/vnd.radiance
+# image/vnd.sealed.png
+# image/vnd.sealedmedia.softseal.gif
+# image/vnd.sealedmedia.softseal.jpg
+# image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff xif
+image/webp webp
+image/x-3ds 3ds
+image/x-cmu-raster ras
+image/x-cmx cmx
+image/x-freehand fh fhc fh4 fh5 fh7
+image/x-icon ico
+image/x-mrsid-image sid
+image/x-pcx pcx
+image/x-pict pic pct
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-tga tga
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+# message/cpim
+# message/delivery-status
+# message/disposition-notification
+# message/example
+# message/external-body
+# message/feedback-report
+# message/global
+# message/global-delivery-status
+# message/global-disposition-notification
+# message/global-headers
+# message/http
+# message/imdn+xml
+# message/news
+# message/partial
+message/rfc822 eml mime
+# message/s-http
+# message/sip
+# message/sipfrag
+# message/tracking-status
+# message/vnd.si.simp
+# model/example
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.collada+xml dae
+model/vnd.dwf dwf
+# model/vnd.flatland.3dml
+model/vnd.gdl gdl
+# model/vnd.gs-gdl
+# model/vnd.gs.gdl
+model/vnd.gtw gtw
+# model/vnd.moml+xml
+model/vnd.mts mts
+# model/vnd.parasolid.transmit.binary
+# model/vnd.parasolid.transmit.text
+model/vnd.vtu vtu
+model/vrml wrl vrml
+model/x3d+binary x3db x3dbz
+model/x3d+vrml x3dv x3dvz
+model/x3d+xml x3d x3dz
+# multipart/alternative
+# multipart/appledouble
+# multipart/byteranges
+# multipart/digest
+# multipart/encrypted
+# multipart/example
+# multipart/form-data
+# multipart/header-set
+# multipart/mixed
+# multipart/parallel
+# multipart/related
+# multipart/report
+# multipart/signed
+# multipart/voice-message
+# text/1d-interleaved-parityfec
+text/cache-manifest appcache
+text/calendar ics ifb
+text/css css
+text/csv csv
+# text/directory
+# text/dns
+# text/ecmascript
+# text/enriched
+# text/example
+# text/fwdred
+text/html html htm
+# text/javascript
+text/n3 n3
+# text/parityfec
+text/plain txt text conf def list log in
+# text/prs.fallenstein.rst
+text/prs.lines.tag dsc
+# text/vnd.radisys.msml-basic-layout
+# text/red
+# text/rfc822-headers
+text/richtext rtx
+# text/rtf
+# text/rtp-enc-aescm128
+# text/rtx
+text/sgml sgml sgm
+# text/t140
+text/tab-separated-values tsv
+text/troff t tr roff man me ms
+text/turtle ttl
+# text/ulpfec
+text/uri-list uri uris urls
+text/vcard vcard
+# text/vnd.abc
+text/vnd.curl curl
+text/vnd.curl.dcurl dcurl
+text/vnd.curl.scurl scurl
+text/vnd.curl.mcurl mcurl
+# text/vnd.dmclientscript
+text/vnd.dvb.subtitle sub
+# text/vnd.esmertec.theme-descriptor
+text/vnd.fly fly
+text/vnd.fmi.flexstor flx
+text/vnd.graphviz gv
+text/vnd.in3d.3dml 3dml
+text/vnd.in3d.spot spot
+# text/vnd.iptc.newsml
+# text/vnd.iptc.nitf
+# text/vnd.latex-z
+# text/vnd.motorola.reflex
+# text/vnd.ms-mediapackage
+# text/vnd.net2phone.commcenter.command
+# text/vnd.si.uricatalogue
+text/vnd.sun.j2me.app-descriptor jad
+# text/vnd.trolltech.linguist
+# text/vnd.wap.si
+# text/vnd.wap.sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-asm s asm
+text/x-c c cc cxx cpp h hh dic
+text/x-fortran f for f77 f90
+text/x-java-source java
+text/x-opml opml
+text/x-pascal p pas
+text/x-nfo nfo
+text/x-setext etx
+text/x-sfv sfv
+text/x-uuencode uu
+text/x-vcalendar vcs
+text/x-vcard vcf
+# text/xml
+# text/xml-external-parsed-entity
+# video/1d-interleaved-parityfec
+video/3gpp 3gp
+# video/3gpp-tt
+video/3gpp2 3g2
+# video/bmpeg
+# video/bt656
+# video/celb
+# video/dv
+# video/example
+video/h261 h261
+video/h263 h263
+# video/h263-1998
+# video/h263-2000
+video/h264 h264
+# video/h264-rcdo
+# video/h264-svc
+video/jpeg jpgv
+# video/jpeg2000
+video/jpm jpm jpgm
+video/mj2 mj2 mjp2
+# video/mp1s
+# video/mp2p
+# video/mp2t
+video/mp4 mp4 mp4v mpg4
+# video/mp4v-es
+video/mpeg mpeg mpg mpe m1v m2v
+# video/mpeg4-generic
+# video/mpv
+# video/nv
+video/ogg ogv
+# video/parityfec
+# video/pointer
+video/quicktime qt mov
+# video/raw
+# video/rtp-enc-aescm128
+# video/rtx
+# video/smpte292m
+# video/ulpfec
+# video/vc1
+# video/vnd.cctv
+video/vnd.dece.hd uvh uvvh
+video/vnd.dece.mobile uvm uvvm
+# video/vnd.dece.mp4
+video/vnd.dece.pd uvp uvvp
+video/vnd.dece.sd uvs uvvs
+video/vnd.dece.video uvv uvvv
+# video/vnd.directv.mpeg
+# video/vnd.directv.mpeg-tts
+# video/vnd.dlna.mpeg-tts
+video/vnd.dvb.file dvb
+video/vnd.fvt fvt
+# video/vnd.hns.video
+# video/vnd.iptvforum.1dparityfec-1010
+# video/vnd.iptvforum.1dparityfec-2005
+# video/vnd.iptvforum.2dparityfec-1010
+# video/vnd.iptvforum.2dparityfec-2005
+# video/vnd.iptvforum.ttsavc
+# video/vnd.iptvforum.ttsmpeg2
+# video/vnd.motorola.video
+# video/vnd.motorola.videop
+video/vnd.mpegurl mxu m4u
+video/vnd.ms-playready.media.pyv pyv
+# video/vnd.nokia.interleaved-multimedia
+# video/vnd.nokia.videovoip
+# video/vnd.objectvideo
+# video/vnd.sealed.mpeg1
+# video/vnd.sealed.mpeg4
+# video/vnd.sealed.swf
+# video/vnd.sealedmedia.softseal.mov
+video/vnd.uvvu.mp4 uvu uvvu
+video/vnd.vivo viv
+video/webm webm
+video/x-f4v f4v
+video/x-fli fli
+video/x-flv flv
+video/x-m4v m4v
+video/x-matroska mkv mk3d mks
+video/x-mng mng
+video/x-ms-asf asf asx
+video/x-ms-vob vob
+video/x-ms-wm wm
+video/x-ms-wmv wmv
+video/x-ms-wmx wmx
+video/x-ms-wvx wvx
+video/x-msvideo avi
+video/x-sgi-movie movie
+video/x-smv smv
+x-conference/x-cooltalk ice
diff --git a/test/modules/http2/conf/test.conf b/test/modules/http2/conf/test.conf
new file mode 100644
index 00000000000..7534af6c870
--- /dev/null
+++ b/test/modules/http2/conf/test.conf
@@ -0,0 +1 @@
+# empty placeholder for test specific configurations
diff --git a/test/modules/http2/config.ini.in b/test/modules/http2/config.ini.in
new file mode 100644
index 00000000000..3135a7ec815
--- /dev/null
+++ b/test/modules/http2/config.ini.in
@@ -0,0 +1,29 @@
+[global]
+curl_bin = curl
+nghttp = nghttp
+h2load = h2load
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+
+apr_bindir = @APR_BINDIR@
+apxs = @bindir@/apxs
+apachectl = @sbindir@/apachectl
+dso_modules = @DSO_MODULES@
+
+[httpd]
+version = @HTTPD_VERSION@
+name = @progname@
+
+[test]
+http_port = 40001
+https_port = 40002
+http_tld = tests.httpd.apache.org
+test_dir = @abs_srcdir@
+test_src_dir = @abs_srcdir@
+server_dir = @abs_srcdir@/gen/apache
+gen_dir = @abs_srcdir@/gen
diff --git a/test/modules/http2/conftest.py b/test/modules/http2/conftest.py
new file mode 100644
index 00000000000..2b8bb057f28
--- /dev/null
+++ b/test/modules/http2/conftest.py
@@ -0,0 +1,52 @@
+import logging
+import os
+
+import pytest
+
+from h2_certs import CertificateSpec, H2TestCA
+from h2_env import H2TestEnv
+
+
+class Dummy:
+ pass
+
+
+def pytest_report_header(config, startdir):
+ env = H2TestEnv()
+ return "mod_h2 [apache: {aversion}({prefix}), mpm: {mpm}]".format(
+ prefix=env.prefix,
+ aversion=env.get_httpd_version(),
+ mpm=env.mpm_type
+ )
+
+
+@pytest.fixture(scope="session")
+def env(pytestconfig) -> H2TestEnv:
+ level = logging.INFO
+ console = logging.StreamHandler()
+ console.setLevel(level)
+ console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
+ logging.getLogger('').addHandler(console)
+ logging.getLogger('').setLevel(level=level)
+ env = H2TestEnv(pytestconfig=pytestconfig)
+ env.apache_error_log_clear()
+ cert_specs = [
+ CertificateSpec(domains=env.domains, key_type='rsa4096'),
+ CertificateSpec(domains=env.domains_noh2, key_type='rsa2048'),
+ ]
+ ca = H2TestCA.create_root(name=env.http_tld,
+ store_dir=os.path.join(env.server_dir, 'ca'), key_type="rsa4096")
+ ca.issue_certs(cert_specs)
+ env.set_ca(ca)
+ return env
+
+
+@pytest.fixture(autouse=True, scope="session")
+def _session_scope(env):
+ yield
+ assert env.apache_stop() == 0
+ errors, warnings = env.apache_errors_and_warnings()
+ assert (len(errors), len(warnings)) == (0, 0),\
+ f"apache logged {len(errors)} errors and {len(warnings)} warnings: \n"\
+ "{0}\n{1}\n".format("\n".join(errors), "\n".join(warnings))
+
diff --git a/test/modules/http2/data/nghttp-output-100k-1.txt b/test/modules/http2/data/nghttp-output-100k-1.txt
new file mode 100644
index 00000000000..1889877e6ec
--- /dev/null
+++ b/test/modules/http2/data/nghttp-output-100k-1.txt
@@ -0,0 +1,1153 @@
+execute: /usr/bin/nghttp -v --header=host: cgi.tests.httpd.apache.org:42002 --data=/home/ylavic/src/apache/mod_h2/test/gen/data-100k https://127.0.0.1:42002//echo.py
+stderr: [WARNING] Certificate verification failed: unable to verify the first certificate
+
+stdout: [ 0.001] Connected
+The negotiated protocol: h2
+[ 0.003] send SETTINGS frame
+ (niv=2)
+ [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
+ [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
+[ 0.003] send PRIORITY frame
+ (dep_stream_id=0, weight=201, exclusive=0)
+[ 0.003] send PRIORITY frame
+ (dep_stream_id=0, weight=101, exclusive=0)
+[ 0.003] send PRIORITY frame
+ (dep_stream_id=0, weight=1, exclusive=0)
+[ 0.003] send PRIORITY frame
+ (dep_stream_id=7, weight=1, exclusive=0)
+[ 0.003] send PRIORITY frame
+ (dep_stream_id=3, weight=1, exclusive=0)
+[ 0.003] send HEADERS frame
+ ; END_HEADERS | PRIORITY
+ (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
+ ; Open new stream
+ :method: POST
+ :path: //echo.py
+ :scheme: https
+ :authority: 127.0.0.1:42002
+ accept: */*
+ accept-encoding: gzip, deflate
+ user-agent: nghttp2/1.36.0
+ content-length: 100000
+ host: cgi.tests.httpd.apache.org:42002
+[ 0.003] send DATA frame
+[ 0.003] send DATA frame
+[ 0.003] send DATA frame
+[ 0.003] send DATA frame
+[ 0.006] recv SETTINGS frame
+ (niv=1)
+ [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
+[ 0.006] recv SETTINGS frame
+ ; ACK
+ (niv=0)
+[ 0.006] recv WINDOW_UPDATE frame
+ (window_size_increment=2147418112)
+[ 0.006] send SETTINGS frame
+ ; ACK
+ (niv=0)
+[ 0.007] recv WINDOW_UPDATE frame
+ (window_size_increment=65535)
+[ 0.007] recv WINDOW_UPDATE frame
+ (window_size_increment=65536)
+[ 0.007] send DATA frame
+[ 0.007] send DATA frame
+[ 0.007] send DATA frame
+ ; END_STREAM
+[ 0.023] recv (stream_id=13) :status: 200
+[ 0.023] recv (stream_id=13) date: Wed, 13 Feb 2019 17:42:49 GMT
+[ 0.023] recv (stream_id=13) server: Apache/2.5.1-dev (Unix) OpenSSL/1.1.1a
+[ 0.023] recv (stream_id=13) content-type: application/data
+[ 0.023] recv HEADERS frame
+ ; END_HEADERS
+ (padlen=0)
+ ; First response header
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[ 0.023] recv DATA frame
+12345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901[ 0.023] recv DATA frame
+23456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012[ 0.023] recv DATA frame
+34567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123[ 0.023] recv DATA frame
+45678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234[ 0.024] recv DATA frame
+56789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345[ 0.024] recv DATA frame
+67890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456[ 0.024] recv DATA frame
+78901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567[ 0.024] recv DATA frame
+89012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678[ 0.024] recv DATA frame
+90123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789[ 0.024] recv DATA frame
+01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0[ 0.024] recv DATA frame
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901[ 0.025] recv DATA frame
+2345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678901234567890123456789012[ 0.025] recv DATA frame
+3456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678901234567890123[ 0.025] recv DATA frame
+4567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678901234[ 0.025] recv DATA frame
+5678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345[ 0.025] recv DATA frame
+6789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456[ 0.025] recv DATA frame
+7890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567[ 0.025] recv DATA frame
+8901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678[ 0.025] recv DATA frame
+9012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789[ 0.025] recv DATA frame
+0123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890[ 0.025] recv DATA frame
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01[ 0.025] recv DATA frame
+2345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012[ 0.025] recv DATA frame
+345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123[ 0.025] recv DATA frame
+456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234[ 0.025] recv DATA frame
+567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345[ 0.026] recv DATA frame
+[ 0.026] send WINDOW_UPDATE frame
+ (window_size_increment=33566)
+[ 0.026] send WINDOW_UPDATE frame
+ (window_size_increment=33566)
+678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456[ 0.026] recv DATA frame
+789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567[ 0.026] recv DATA frame
+890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678[ 0.026] recv DATA frame
+901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789[ 0.026] recv DATA frame
+012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890[ 0.026] recv DATA frame
+123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901[ 0.026] recv DATA frame
+234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012[ 0.026] recv DATA frame
+345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123[ 0.026] recv DATA frame
+45678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234[ 0.026] recv DATA frame
+56789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345[ 0.026] recv DATA frame
+67890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456[ 0.026] recv DATA frame
+78901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567[ 0.026] recv DATA frame
+89012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678[ 0.026] recv DATA frame
+90123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789[ 0.026] recv DATA frame
+01234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890[ 0.026] recv DATA frame
+12345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901[ 0.026] recv DATA frame
+23456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012[ 0.027] recv DATA frame
+34567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123[ 0.027] recv DATA frame
+45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234[ 0.027] recv DATA frame
+5678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678901234567890123456789012345[ 0.027] recv DATA frame
+6789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678901234567890123456[ 0.027] recv DATA frame
+7890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678901234567[ 0.027] recv DATA frame
+8901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789012345678[ 0.027] recv DATA frame
+9012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234567890123456789[ 0.027] recv DATA frame
+0123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345678901234[ 0.028] recv DATA frame
+5678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012345[ 0.028] recv DATA frame
+6789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456789012[ 0.028] send WINDOW_UPDATE frame
+ (window_size_increment=33260)
+[ 0.028] send WINDOW_UPDATE frame
+ (window_size_increment=33260)
+3456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567890123456[ 0.028] recv DATA frame
+7890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+01234567[ 0.028] recv DATA frame
+8901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678[ 0.028] recv DATA frame
+
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789[ 0.028] recv DATA frame
+012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890[ 0.028] recv DATA frame
+123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901[ 0.028] recv DATA frame
+234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012[ 0.028] recv DATA frame
+345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123[ 0.028] recv DATA frame
+456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234[ 0.028] recv DATA frame
+567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345[ 0.028] recv DATA frame
+678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456[ 0.029] recv DATA frame
+789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567[ 0.029] recv DATA frame
+890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678[ 0.029] recv DATA frame
+901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+[ 0.029] recv DATA frame
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[ 0.029] recv DATA frame
+12345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901[ 0.029] recv DATA frame
+23456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012[ 0.029] recv DATA frame
+34567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123[ 0.029] recv DATA frame
+45678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234[ 0.029] recv DATA frame
+56789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345[ 0.029] recv DATA frame
+67890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456[ 0.029] recv DATA frame
+78901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567[ 0.029] recv DATA frame
+89012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678[ 0.029] recv DATA frame
+90123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789[ 0.029] recv DATA frame
+01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0[ 0.029] recv DATA frame
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+[ 0.029] recv DATA frame
+ ; END_STREAM
+[ 0.029] send GOAWAY frame
+ (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
+
diff --git a/test/modules/http2/data/nghttp-output-10k-1.txt b/test/modules/http2/data/nghttp-output-10k-1.txt
new file mode 100644
index 00000000000..fe19b46fbbe
--- /dev/null
+++ b/test/modules/http2/data/nghttp-output-10k-1.txt
@@ -0,0 +1,166 @@
+stderr: [WARNING] Certificate verification failed: unable to verify the first certificate
+
+stdout: [ 0.002] Connected
+The negotiated protocol: h2
+[ 0.004] send SETTINGS frame
+ (niv=2)
+ [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
+ [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=0, weight=201, exclusive=0)
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=0, weight=101, exclusive=0)
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=0, weight=1, exclusive=0)
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=7, weight=1, exclusive=0)
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=3, weight=1, exclusive=0)
+[ 0.004] send HEADERS frame
+ ; END_HEADERS | PRIORITY
+ (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
+ ; Open new stream
+ :method: POST
+ :path: //echo.py
+ :scheme: https
+ :authority: 127.0.0.1:42002
+ accept: */*
+ accept-encoding: gzip, deflate
+ user-agent: nghttp2/1.33.0
+ content-length: 10000
+ host: cgi.tests.httpd.apache.org:42002
+[ 0.004] send DATA frame
+ ; END_STREAM
+[ 0.005] recv SETTINGS frame
+ (niv=1)
+ [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
+[ 0.005] recv SETTINGS frame
+ ; ACK
+ (niv=0)
+[ 0.005] recv WINDOW_UPDATE frame
+ (window_size_increment=2147418112)
+[ 0.005] send SETTINGS frame
+ ; ACK
+ (niv=0)
+[ 0.038] recv (stream_id=13) :status: 200
+[ 0.038] recv (stream_id=13) date: Thu, 14 Feb 2019 11:50:20 GMT
+[ 0.038] recv (stream_id=13) server: Apache/2.4.39-dev (Unix) OpenSSL/1.1.1
+[ 0.038] recv (stream_id=13) content-type: application/data
+[ 0.038] recv HEADERS frame
+ ; END_HEADERS
+ (padlen=0)
+ ; First response header
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890[ 0.038] recv DATA frame
+12345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901[ 0.038] recv DATA frame
+23456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123456789012[ 0.038] recv DATA frame
+34567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234567890123[ 0.038] recv DATA frame
+45678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345678901234[ 0.038] recv DATA frame
+56789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+0123456789012345678901234567890123456789012345[ 0.038] recv DATA frame
+67890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567[ 0.038] recv DATA frame
+890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678[ 0.039] recv DATA frame
+901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+[ 0.039] recv DATA frame
+[ 0.039] recv DATA frame
+ ; END_STREAM
+[ 0.039] send GOAWAY frame
+ (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
+
diff --git a/test/modules/http2/data/nghttp-output-1k-1.txt b/test/modules/http2/data/nghttp-output-1k-1.txt
new file mode 100644
index 00000000000..de9964c7ca2
--- /dev/null
+++ b/test/modules/http2/data/nghttp-output-1k-1.txt
@@ -0,0 +1,68 @@
+stderr: [WARNING] Certificate verification failed: unable to verify the first certificate
+
+stdout: [ 0.002] Connected
+The negotiated protocol: h2
+[ 0.004] send SETTINGS frame
+ (niv=2)
+ [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
+ [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=0, weight=201, exclusive=0)
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=0, weight=101, exclusive=0)
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=0, weight=1, exclusive=0)
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=7, weight=1, exclusive=0)
+[ 0.004] send PRIORITY frame
+ (dep_stream_id=3, weight=1, exclusive=0)
+[ 0.004] send HEADERS frame
+ ; END_HEADERS | PRIORITY
+ (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
+ ; Open new stream
+ :method: POST
+ :path: //echo.py
+ :scheme: https
+ :authority: 127.0.0.1:42002
+ accept: */*
+ accept-encoding: gzip, deflate
+ user-agent: nghttp2/1.33.0
+ content-length: 1000
+ host: cgi.tests.httpd.apache.org:42002
+[ 0.004] send DATA frame
+ ; END_STREAM
+[ 0.005] recv SETTINGS frame
+ (niv=1)
+ [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
+[ 0.005] recv SETTINGS frame
+ ; ACK
+ (niv=0)
+[ 0.005] recv WINDOW_UPDATE frame
+ (window_size_increment=2147418112)
+[ 0.005] send SETTINGS frame
+ ; ACK
+ (niv=0)
+[ 0.048] recv (stream_id=13) :status: 200
+[ 0.048] recv (stream_id=13) date: Thu, 14 Feb 2019 11:48:18 GMT
+[ 0.048] recv (stream_id=13) server: Apache/2.4.39-dev (Unix) OpenSSL/1.1.1
+[ 0.048] recv (stream_id=13) content-type: application/data
+[ 0.048] recv HEADERS frame
+ ; END_HEADERS
+ (padlen=0)
+ ; First response header
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+[ 0.048] recv DATA frame
+[ 0.048] recv DATA frame
+ ; END_STREAM
+[ 0.048] send GOAWAY frame
+ (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
+
diff --git a/test/modules/http2/h2_certs.py b/test/modules/http2/h2_certs.py
new file mode 100644
index 00000000000..82c6b5020a4
--- /dev/null
+++ b/test/modules/http2/h2_certs.py
@@ -0,0 +1,444 @@
+import os
+import re
+from datetime import timedelta, datetime
+from typing import List, Any, Optional
+
+from cryptography import x509
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives.asymmetric import ec, rsa
+from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
+from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
+from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption, load_pem_private_key
+from cryptography.x509 import ExtendedKeyUsageOID, NameOID
+
+
+EC_SUPPORTED = {}
+EC_SUPPORTED.update([(curve.name.upper(), curve) for curve in [
+ ec.SECP192R1,
+ ec.SECP224R1,
+ ec.SECP256R1,
+ ec.SECP384R1,
+]])
+
+
+def _private_key(key_type):
+ if isinstance(key_type, str):
+ key_type = key_type.upper()
+ m = re.match(r'^(RSA)?(\d+)$', key_type)
+ if m:
+ key_type = int(m.group(2))
+
+ if isinstance(key_type, int):
+ return rsa.generate_private_key(
+ public_exponent=65537,
+ key_size=key_type,
+ backend=default_backend()
+ )
+ if not isinstance(key_type, ec.EllipticCurve) and key_type in EC_SUPPORTED:
+ key_type = EC_SUPPORTED[key_type]
+ return ec.generate_private_key(
+ curve=key_type,
+ backend=default_backend()
+ )
+
+
+class CertificateSpec:
+
+ def __init__(self, name: str = None, domains: List[str] = None,
+ email: str = None,
+ key_type: str = None, single_file: bool = False,
+ valid_from: timedelta = timedelta(days=-1),
+ valid_to: timedelta = timedelta(days=89),
+ client: bool = False,
+ sub_specs: List['CertificateSpec'] = None):
+ self._name = name
+ self.domains = domains
+ self.client = client
+ self.email = email
+ self.key_type = key_type
+ self.single_file = single_file
+ self.valid_from = valid_from
+ self.valid_to = valid_to
+ self.sub_specs = sub_specs
+
+ @property
+ def name(self) -> Optional[str]:
+ if self._name:
+ return self._name
+ elif self.domains:
+ return self.domains[0]
+ return None
+
+
+class Credentials:
+
+ def __init__(self, name: str, cert: Any, pkey: Any):
+ self._name = name
+ self._cert = cert
+ self._pkey = pkey
+ self._cert_file = None
+ self._pkey_file = None
+ self._store = None
+
+ @property
+ def name(self) -> str:
+ return self._name
+
+ @property
+ def subject(self) -> x509.Name:
+ return self._cert.subject
+
+ @property
+ def key_type(self):
+ if isinstance(self._pkey, RSAPrivateKey):
+ return f"rsa{self._pkey.key_size}"
+ elif isinstance(self._pkey, EllipticCurvePrivateKey):
+ return f"{self._pkey.curve.name}"
+ else:
+ raise Exception(f"unknown key type: {self._pkey}")
+
+ @property
+ def private_key(self) -> Any:
+ return self._pkey
+
+ @property
+ def certificate(self) -> Any:
+ return self._cert
+
+ @property
+ def cert_pem(self) -> bytes:
+ return self._cert.public_bytes(Encoding.PEM)
+
+ @property
+ def pkey_pem(self) -> bytes:
+ return self._pkey.private_bytes(
+ Encoding.PEM,
+ PrivateFormat.TraditionalOpenSSL if self.key_type.startswith('rsa') else PrivateFormat.PKCS8,
+ NoEncryption())
+
+ def set_store(self, store: 'CertStore'):
+ self._store = store
+
+ def set_files(self, cert_file: str, pkey_file: str = None):
+ self._cert_file = cert_file
+ self._pkey_file = pkey_file
+
+ @property
+ def cert_file(self) -> str:
+ return self._cert_file
+
+ @property
+ def pkey_file(self) -> Optional[str]:
+ return self._pkey_file
+
+ def get_first(self, name) -> Optional['Credentials']:
+ creds = self._store.get_credentials_for_name(name) if self._store else []
+ return creds[0] if len(creds) else None
+
+ def get_credentials_for_name(self, name) -> List['Credentials']:
+ return self._store.get_credentials_for_name(name) if self._store else []
+
+ def issue_certs(self, specs: List[CertificateSpec],
+ chain: List['Credentials'] = None) -> List['Credentials']:
+ return [self.issue_cert(spec=spec, chain=chain) for spec in specs]
+
+ def issue_cert(self, spec: CertificateSpec, chain: List['Credentials'] = None) -> 'Credentials':
+ key_type = spec.key_type if spec.key_type else self.key_type
+ creds = self._store.load_credentials(name=spec.name, key_type=key_type, single_file=spec.single_file) \
+ if self._store else None
+ if creds is None:
+ creds = H2TestCA.create_credentials(spec=spec, issuer=self, key_type=key_type,
+ valid_from=spec.valid_from, valid_to=spec.valid_to)
+ if self._store:
+ self._store.save(creds, single_file=spec.single_file)
+
+ if spec.sub_specs:
+ if self._store:
+ sub_store = CertStore(fpath=os.path.join(self._store.path, creds.name))
+ creds.set_store(sub_store)
+ subchain = chain.copy() if chain else []
+ subchain.append(self)
+ creds.issue_certs(spec.sub_specs, chain=subchain)
+ return creds
+
+
+class CertStore:
+
+ def __init__(self, fpath: str):
+ self._store_dir = fpath
+ if not os.path.exists(self._store_dir):
+ os.makedirs(self._store_dir)
+ self._creds_by_name = {}
+
+ @property
+ def path(self) -> str:
+ return self._store_dir
+
+ def save(self, creds: Credentials, name: str = None,
+ chain: List[Credentials] = None,
+ single_file: bool = False) -> None:
+ name = name if name is not None else creds.name
+ cert_file = self.get_cert_file(name=name, key_type=creds.key_type)
+ pkey_file = self.get_pkey_file(name=name, key_type=creds.key_type)
+ if single_file:
+ pkey_file = None
+ with open(cert_file, "wb") as fd:
+ fd.write(creds.cert_pem)
+ if chain:
+ for c in chain:
+ fd.write(c.cert_pem)
+ if pkey_file is None:
+ fd.write(creds.pkey_pem)
+ if pkey_file is not None:
+ with open(pkey_file, "wb") as fd:
+ fd.write(creds.pkey_pem)
+ creds.set_files(cert_file, pkey_file)
+ self._add_credentials(name, creds)
+
+ def _add_credentials(self, name: str, creds: Credentials):
+ if name not in self._creds_by_name:
+ self._creds_by_name[name] = []
+ self._creds_by_name[name].append(creds)
+
+ def get_credentials_for_name(self, name) -> List[Credentials]:
+ return self._creds_by_name[name] if name in self._creds_by_name else []
+
+ def get_cert_file(self, name: str, key_type=None) -> str:
+ key_infix = ".{0}".format(key_type) if key_type is not None else ""
+ return os.path.join(self._store_dir, f'{name}{key_infix}.cert.pem')
+
+ def get_pkey_file(self, name: str, key_type=None) -> str:
+ key_infix = ".{0}".format(key_type) if key_type is not None else ""
+ return os.path.join(self._store_dir, f'{name}{key_infix}.pkey.pem')
+
+ def load_pem_cert(self, fpath: str) -> x509.Certificate:
+ with open(fpath) as fd:
+ return x509.load_pem_x509_certificate("".join(fd.readlines()).encode())
+
+ def load_pem_pkey(self, fpath: str):
+ with open(fpath) as fd:
+ return load_pem_private_key("".join(fd.readlines()).encode(), password=None)
+
+ def load_credentials(self, name: str, key_type=None, single_file: bool = False):
+ cert_file = self.get_cert_file(name=name, key_type=key_type)
+ pkey_file = cert_file if single_file else self.get_pkey_file(name=name, key_type=key_type)
+ if os.path.isfile(cert_file) and os.path.isfile(pkey_file):
+ cert = self.load_pem_cert(cert_file)
+ pkey = self.load_pem_pkey(pkey_file)
+ creds = Credentials(name=name, cert=cert, pkey=pkey)
+ creds.set_store(self)
+ creds.set_files(cert_file, pkey_file)
+ self._add_credentials(name, creds)
+ return creds
+ return None
+
+
+class H2TestCA:
+
+ @classmethod
+ def create_root(cls, name: str, store_dir: str, key_type: str = "rsa2048") -> Credentials:
+ store = CertStore(fpath=store_dir)
+ creds = store.load_credentials(name="ca", key_type=key_type)
+ if creds is None:
+ creds = H2TestCA._make_ca_credentials(name=name, key_type=key_type)
+ store.save(creds, name="ca")
+ creds.set_store(store)
+ return creds
+
+ @staticmethod
+ def create_credentials(spec: CertificateSpec, issuer: Credentials, key_type: Any,
+ valid_from: timedelta = timedelta(days=-1),
+ valid_to: timedelta = timedelta(days=89),
+ ) -> Credentials:
+ """Create a certificate signed by this CA for the given domains.
+ :returns: the certificate and private key PEM file paths
+ """
+ if spec.domains and len(spec.domains):
+ creds = H2TestCA._make_server_credentials(name=spec.name, domains=spec.domains,
+ issuer=issuer, valid_from=valid_from,
+ valid_to=valid_to, key_type=key_type)
+ elif spec.client:
+ creds = H2TestCA._make_client_credentials(name=spec.name, issuer=issuer,
+ email=spec.email, valid_from=valid_from,
+ valid_to=valid_to, key_type=key_type)
+ elif spec.name:
+ creds = H2TestCA._make_ca_credentials(name=spec.name, issuer=issuer,
+ valid_from=valid_from, valid_to=valid_to,
+ key_type=key_type)
+ else:
+ raise Exception(f"unrecognized certificate specification: {spec}")
+ return creds
+
+ @staticmethod
+ def _make_x509_name(org_name: str = None, common_name: str = None, parent: x509.Name = None) -> x509.Name:
+ name_pieces = []
+ if org_name:
+ oid = NameOID.ORGANIZATIONAL_UNIT_NAME if parent else NameOID.ORGANIZATION_NAME
+ name_pieces.append(x509.NameAttribute(oid, org_name))
+ elif common_name:
+ name_pieces.append(x509.NameAttribute(NameOID.COMMON_NAME, common_name))
+ if parent:
+ name_pieces.extend([rdn for rdn in parent])
+ return x509.Name(name_pieces)
+
+ @staticmethod
+ def _make_csr(
+ subject: x509.Name,
+ pkey: Any,
+ issuer_subject: Optional[Credentials],
+ valid_from_delta: timedelta = None,
+ valid_until_delta: timedelta = None
+ ):
+ pubkey = pkey.public_key()
+ issuer_subject = issuer_subject if issuer_subject is not None else subject
+
+ valid_from = datetime.now()
+ if valid_until_delta is not None:
+ valid_from += valid_from_delta
+ valid_until = datetime.now()
+ if valid_until_delta is not None:
+ valid_until += valid_until_delta
+
+ return (
+ x509.CertificateBuilder()
+ .subject_name(subject)
+ .issuer_name(issuer_subject)
+ .public_key(pubkey)
+ .not_valid_before(valid_from)
+ .not_valid_after(valid_until)
+ .serial_number(x509.random_serial_number())
+ .add_extension(
+ x509.SubjectKeyIdentifier.from_public_key(pubkey),
+ critical=False,
+ )
+ )
+
+ @staticmethod
+ def _add_ca_usages(csr: Any) -> Any:
+ return csr.add_extension(
+ x509.BasicConstraints(ca=True, path_length=9),
+ critical=True,
+ ).add_extension(
+ x509.KeyUsage(
+ digital_signature=True,
+ content_commitment=False,
+ key_encipherment=False,
+ data_encipherment=False,
+ key_agreement=False,
+ key_cert_sign=True,
+ crl_sign=True,
+ encipher_only=False,
+ decipher_only=False),
+ critical=True
+ ).add_extension(
+ x509.ExtendedKeyUsage([
+ ExtendedKeyUsageOID.CLIENT_AUTH,
+ ExtendedKeyUsageOID.SERVER_AUTH,
+ ExtendedKeyUsageOID.CODE_SIGNING,
+ ]),
+ critical=True
+ )
+
+ @staticmethod
+ def _add_leaf_usages(csr: Any, domains: List[str], issuer: Credentials) -> Any:
+ return csr.add_extension(
+ x509.BasicConstraints(ca=False, path_length=None),
+ critical=True,
+ ).add_extension(
+ x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
+ issuer.certificate.extensions.get_extension_for_class(
+ x509.SubjectKeyIdentifier).value),
+ critical=False
+ ).add_extension(
+ x509.SubjectAlternativeName([x509.DNSName(domain) for domain in domains]),
+ critical=True,
+ ).add_extension(
+ x509.ExtendedKeyUsage([
+ ExtendedKeyUsageOID.SERVER_AUTH,
+ ]),
+ critical=True
+ )
+
+ @staticmethod
+ def _add_client_usages(csr: Any, issuer: Credentials, rfc82name: str = None) -> Any:
+ cert = csr.add_extension(
+ x509.BasicConstraints(ca=False, path_length=None),
+ critical=True,
+ ).add_extension(
+ x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
+ issuer.certificate.extensions.get_extension_for_class(
+ x509.SubjectKeyIdentifier).value),
+ critical=False
+ )
+ if rfc82name:
+ cert.add_extension(
+ x509.SubjectAlternativeName([x509.RFC822Name(rfc82name)]),
+ critical=True,
+ )
+ cert.add_extension(
+ x509.ExtendedKeyUsage([
+ ExtendedKeyUsageOID.CLIENT_AUTH,
+ ]),
+ critical=True
+ )
+ return cert
+
+ @staticmethod
+ def _make_ca_credentials(name, key_type: Any,
+ issuer: Credentials = None,
+ valid_from: timedelta = timedelta(days=-1),
+ valid_to: timedelta = timedelta(days=89),
+ ) -> Credentials:
+ pkey = _private_key(key_type=key_type)
+ if issuer is not None:
+ issuer_subject = issuer.certificate.subject
+ issuer_key = issuer.private_key
+ else:
+ issuer_subject = None
+ issuer_key = pkey
+ subject = H2TestCA._make_x509_name(org_name=name, parent=issuer.subject if issuer else None)
+ csr = H2TestCA._make_csr(subject=subject,
+ issuer_subject=issuer_subject, pkey=pkey,
+ valid_from_delta=valid_from, valid_until_delta=valid_to)
+ csr = H2TestCA._add_ca_usages(csr)
+ cert = csr.sign(private_key=issuer_key,
+ algorithm=hashes.SHA256(),
+ backend=default_backend())
+ return Credentials(name=name, cert=cert, pkey=pkey)
+
+ @staticmethod
+ def _make_server_credentials(name: str, domains: List[str], issuer: Credentials,
+ key_type: Any,
+ valid_from: timedelta = timedelta(days=-1),
+ valid_to: timedelta = timedelta(days=89),
+ ) -> Credentials:
+ name = name
+ pkey = _private_key(key_type=key_type)
+ subject = H2TestCA._make_x509_name(common_name=name, parent=issuer.subject)
+ csr = H2TestCA._make_csr(subject=subject,
+ issuer_subject=issuer.certificate.subject, pkey=pkey,
+ valid_from_delta=valid_from, valid_until_delta=valid_to)
+ csr = H2TestCA._add_leaf_usages(csr, domains=domains, issuer=issuer)
+ cert = csr.sign(private_key=issuer.private_key,
+ algorithm=hashes.SHA256(),
+ backend=default_backend())
+ return Credentials(name=name, cert=cert, pkey=pkey)
+
+ @staticmethod
+ def _make_client_credentials(name: str,
+ issuer: Credentials, email: Optional[str],
+ key_type: Any,
+ valid_from: timedelta = timedelta(days=-1),
+ valid_to: timedelta = timedelta(days=89),
+ ) -> Credentials:
+ pkey = _private_key(key_type=key_type)
+ subject = H2TestCA._make_x509_name(common_name=name, parent=issuer.subject)
+ csr = H2TestCA._make_csr(subject=subject,
+ issuer_subject=issuer.certificate.subject, pkey=pkey,
+ valid_from_delta=valid_from, valid_until_delta=valid_to)
+ csr = H2TestCA._add_client_usages(csr, issuer=issuer, rfc82name=email)
+ cert = csr.sign(private_key=issuer.private_key,
+ algorithm=hashes.SHA256(),
+ backend=default_backend())
+ return Credentials(name=name, cert=cert, pkey=pkey)
diff --git a/test/modules/http2/h2_conf.py b/test/modules/http2/h2_conf.py
new file mode 100644
index 00000000000..743ccc8c43c
--- /dev/null
+++ b/test/modules/http2/h2_conf.py
@@ -0,0 +1,147 @@
+import os
+
+
+class HttpdConf(object):
+
+ def __init__(self, env, path=None):
+ self.env = env
+ self._lines = []
+ self._has_ssl_vhost = False
+
+ def install(self):
+ if not self._has_ssl_vhost:
+ self.add_vhost_test1()
+ self.env.install_test_conf(self._lines)
+
+ def add(self, line):
+ if isinstance(line, list):
+ self._lines.extend(line)
+ else:
+ self._lines.append(line)
+ return self
+
+ def add_vhost(self, port, name, aliases=None, doc_root="htdocs", with_ssl=True):
+ self.start_vhost(port, name, aliases, doc_root, with_ssl)
+ self.end_vhost()
+ return self
+
+ def start_vhost(self, port, name, aliases=None, doc_root="htdocs", with_ssl=True):
+ server_domain = f"{name}.{self.env.http_tld}"
+ lines = [
+ f"",
+ f" ServerName {server_domain}"
+ ]
+ if aliases:
+ lines.extend([
+ f" ServerAlias {alias}.{self.env.http_tld}" for alias in aliases])
+ lines.append(f" DocumentRoot {doc_root}")
+ if with_ssl:
+ self._has_ssl_vhost = True
+ lines.append(" SSLEngine on")
+ for cred in self.env.get_credentials_for_name(server_domain):
+ lines.extend([
+ f"SSLCertificateFile {cred.cert_file}",
+ f"SSLCertificateKeyFile {cred.pkey_file}",
+ ])
+ return self.add(lines)
+
+ def end_vhost(self):
+ self.add("")
+ return self
+
+ def add_proxies(self, host, proxy_self=False, h2proxy_self=False):
+ if proxy_self or h2proxy_self:
+ self.add(" ProxyPreserveHost on")
+ if proxy_self:
+ self.add(f"""
+ ProxyPass /proxy/ http://127.0.0.1:{self.env.http_port}/
+ ProxyPassReverse /proxy/ http://{host}.{self.env.http_tld}:{self.env.http_port}/
+ """)
+ if h2proxy_self:
+ self.add(f"""
+ ProxyPass /h2proxy/ h2://127.0.0.1:{self.env.https_port}/
+ ProxyPassReverse /h2proxy/ https://{host}.{self.env.http_tld}:self.env.https_port/
+ """)
+ return self
+
+ def add_vhost_test1(self, proxy_self=False, h2proxy_self=False, extras=None):
+ domain = f"test1.{self.env.http_tld}"
+ if extras and 'base' in extras:
+ self.add(extras['base'])
+ self.start_vhost(
+ self.env.http_port, "test1", aliases=["www1"], doc_root="htdocs/test1", with_ssl=False
+ ).add(
+ " Protocols h2c http/1.1"
+ ).end_vhost()
+ self.start_vhost(
+ self.env.https_port, "test1", aliases=["www1"], doc_root="htdocs/test1", with_ssl=True)
+ self.add(f"""
+ Protocols h2 http/1.1
+
+ Options +Indexes
+ HeaderName /006/header.html
+
+ {extras[domain] if extras and domain in extras else ""}
+ """)
+ self.add_proxies("test1", proxy_self, h2proxy_self)
+ self.end_vhost()
+ return self
+
+ def add_vhost_test2(self):
+ self.start_vhost(self.env.http_port, "test2", aliases=["www2"], doc_root="htdocs/test2", with_ssl=False)
+ self.add(" Protocols http/1.1 h2c")
+ self.end_vhost()
+ self.start_vhost(self.env.https_port, "test2", aliases=["www2"], doc_root="htdocs/test2", with_ssl=True)
+ self.add("""
+ Protocols http/1.1 h2
+
+ Options +Indexes
+ HeaderName /006/header.html
+ """)
+ self.end_vhost()
+ return self
+
+ def add_vhost_cgi(self, proxy_self=False, h2proxy_self=False):
+ if proxy_self:
+ self.add_proxy_setup()
+ if h2proxy_self:
+ self.add(" SSLProxyEngine on")
+ self.add(" SSLProxyCheckPeerName off")
+ self.start_vhost(self.env.https_port, "cgi", aliases=["cgi-alias"], doc_root="htdocs/cgi", with_ssl=True)
+ self.add("""
+ Protocols h2 http/1.1
+ SSLOptions +StdEnvVars
+ AddHandler cgi-script .py
+
+ SetHandler http2-status
+ """)
+ self.add_proxies("cgi", proxy_self, h2proxy_self)
+ self.add(" ")
+ self.add(" SetHandler h2test-echo")
+ self.add(" ")
+ self.end_vhost()
+ self.start_vhost(self.env.http_port, "cgi", aliases=["cgi-alias"], doc_root="htdocs/cgi", with_ssl=False)
+ self.add(" AddHandler cgi-script .py")
+ self.end_vhost()
+ self.add(" LogLevel proxy:info")
+ self.add(" LogLevel proxy_http:info")
+ return self
+
+ def add_vhost_noh2(self):
+ self.start_vhost(self.env.https_port, "noh2", aliases=["noh2-alias"], doc_root="htdocs/noh2", with_ssl=True)
+ self.add(f"""
+ Protocols http/1.1
+ SSLOptions +StdEnvVars""")
+ self.end_vhost()
+ self.start_vhost(self.env.http_port, "noh2", aliases=["noh2-alias"], doc_root="htdocs/noh2", with_ssl=False)
+ self.add(" Protocols http/1.1")
+ self.add(" SSLOptions +StdEnvVars")
+ self.end_vhost()
+ return self
+
+ def add_proxy_setup(self):
+ self.add("ProxyStatus on")
+ self.add("ProxyTimeout 5")
+ self.add("SSLProxyEngine on")
+ self.add("SSLProxyVerify none")
+ return self
diff --git a/test/modules/http2/h2_env.py b/test/modules/http2/h2_env.py
new file mode 100644
index 00000000000..ba0c870c67b
--- /dev/null
+++ b/test/modules/http2/h2_env.py
@@ -0,0 +1,608 @@
+import inspect
+import logging
+import re
+import os
+import shutil
+import stat
+import subprocess
+import sys
+import time
+from datetime import datetime, timedelta
+from string import Template
+from typing import List
+
+import requests
+
+from configparser import ConfigParser, ExtendedInterpolation
+from urllib.parse import urlparse
+
+from h2_certs import Credentials
+from h2_nghttp import Nghttp
+from h2_result import ExecResult
+
+
+log = logging.getLogger(__name__)
+
+
+class Dummy:
+ pass
+
+
+class H2TestSetup:
+
+ # the modules we want to load
+ MODULES = [
+ "log_config",
+ "logio",
+ "unixd",
+ "version",
+ "watchdog",
+ "authn_core",
+ "authz_host",
+ "authz_groupfile",
+ "authz_user",
+ "authz_core",
+ "access_compat",
+ "auth_basic",
+ "cache",
+ "cache_disk",
+ "cache_socache",
+ "socache_shmcb",
+ "dumpio",
+ "reqtimeout",
+ "filter",
+ "mime",
+ "env",
+ "headers",
+ "setenvif",
+ "slotmem_shm",
+ "ssl",
+ "status",
+ "autoindex",
+ "cgid",
+ "dir",
+ "alias",
+ "rewrite",
+ "deflate",
+ "proxy",
+ "proxy_http",
+ "proxy_balancer",
+ "proxy_hcheck",
+ ]
+
+ def __init__(self, env: 'H2TestEnv'):
+ self.env = env
+
+ def make(self):
+ self._make_dirs()
+ self._make_conf()
+ self._make_htdocs()
+ self._make_h2test()
+ self._make_modules_conf()
+
+ def _make_dirs(self):
+ if os.path.exists(self.env.gen_dir):
+ shutil.rmtree(self.env.gen_dir)
+ os.makedirs(self.env.gen_dir)
+ if not os.path.exists(self.env.server_logs_dir):
+ os.makedirs(self.env.server_logs_dir)
+
+ def _make_conf(self):
+ conf_src_dir = os.path.join(self.env.test_dir, 'conf')
+ conf_dest_dir = os.path.join(self.env.server_dir, 'conf')
+ if not os.path.exists(conf_dest_dir):
+ os.makedirs(conf_dest_dir)
+ for name in os.listdir(conf_src_dir):
+ src_path = os.path.join(conf_src_dir, name)
+ m = re.match(r'(.+).template', name)
+ if m:
+ self._make_template(src_path, os.path.join(conf_dest_dir, m.group(1)))
+ elif os.path.isfile(src_path):
+ shutil.copy(src_path, os.path.join(conf_dest_dir, name))
+
+ def _make_template(self, src, dest):
+ var_map = dict()
+ for name, value in self.env.__class__.__dict__.items():
+ if isinstance(value, property):
+ var_map[name] = value.fget(self.env)
+ t = Template(''.join(open(src).readlines()))
+ with open(dest, 'w') as fd:
+ fd.write(t.substitute(var_map))
+
+ def _make_htdocs(self):
+ if not os.path.exists(self.env.server_docs_dir):
+ os.makedirs(self.env.server_docs_dir)
+ shutil.copytree(os.path.join(self.env.test_dir, 'htdocs'),
+ os.path.join(self.env.server_dir, 'htdocs'),
+ dirs_exist_ok=True)
+ cgi_dir = os.path.join(self.env.server_dir, 'htdocs/cgi')
+ for name in os.listdir(cgi_dir):
+ if re.match(r'.+\.py', name):
+ cgi_file = os.path.join(cgi_dir, name)
+ st = os.stat(cgi_file)
+ os.chmod(cgi_file, st.st_mode | stat.S_IEXEC)
+
+ def _make_h2test(self):
+ subprocess.run([self.env.apxs, '-c', 'mod_h2test.c'],
+ capture_output=True, check=True,
+ cwd=os.path.join(self.env.test_dir, 'mod_h2test'))
+
+ def _make_modules_conf(self):
+ modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf')
+ with open(modules_conf, 'w') as fd:
+ # issue load directives for all modules we want that are shared
+ for m in self.MODULES:
+ mod_path = os.path.join(self.env.libexec_dir, f"mod_{m}.so")
+ if os.path.isfile(mod_path):
+ fd.write(f"LoadModule {m}_module \"{mod_path}\"\n")
+ for m in ["http2", "proxy_http2"]:
+ fd.write(f"LoadModule {m}_module \"{self.env.libexec_dir}/mod_{m}.so\"\n")
+ # load our test module which is not installed
+ fd.write(f"LoadModule h2test_module \"{self.env.test_dir}/mod_h2test/.libs/mod_h2test.so\"\n")
+
+
+class H2TestEnv:
+
+ def __init__(self, pytestconfig=None):
+ our_dir = os.path.dirname(inspect.getfile(Dummy))
+ self.config = ConfigParser(interpolation=ExtendedInterpolation())
+ self.config.read(os.path.join(our_dir, 'config.ini'))
+
+ self._apxs = self.config.get('global', 'apxs')
+ self._prefix = self.config.get('global', 'prefix')
+ self._apachectl = self.config.get('global', 'apachectl')
+ self._libexec_dir = self.get_apxs_var('LIBEXECDIR')
+
+ self._curl = self.config.get('global', 'curl_bin')
+ self._nghttp = self.config.get('global', 'nghttp')
+ self._h2load = self.config.get('global', 'h2load')
+ self._ca = None
+
+ self._http_port = int(self.config.get('test', 'http_port'))
+ self._https_port = int(self.config.get('test', 'https_port'))
+ self._http_tld = self.config.get('test', 'http_tld')
+ self._test_dir = self.config.get('test', 'test_dir')
+ self._test_src_dir = self.config.get('test', 'test_src_dir')
+ self._gen_dir = self.config.get('test', 'gen_dir')
+ self._server_dir = os.path.join(self._gen_dir, 'apache')
+ self._server_conf_dir = os.path.join(self._server_dir, "conf")
+ self._server_docs_dir = os.path.join(self._server_dir, "htdocs")
+ self._server_logs_dir = os.path.join(self.server_dir, "logs")
+ self._server_error_log = os.path.join(self._server_logs_dir, "error_log")
+
+ self._dso_modules = self.config.get('global', 'dso_modules').split(' ')
+ self._domains = [
+ f"test1.{self._http_tld}",
+ f"test2.{self._http_tld}",
+ f"test3.{self._http_tld}",
+ f"cgi.{self._http_tld}",
+ f"push.{self._http_tld}",
+ f"hints.{self._http_tld}",
+ f"ssl.{self._http_tld}",
+ f"pad0.{self._http_tld}",
+ f"pad1.{self._http_tld}",
+ f"pad2.{self._http_tld}",
+ f"pad3.{self._http_tld}",
+ f"pad8.{self._http_tld}",
+ ]
+ self._domains_noh2 = [
+ f"noh2.{self._http_tld}",
+ ]
+ self._mpm_type = os.environ['MPM'] if 'MPM' in os.environ else 'event'
+
+ self._httpd_addr = "127.0.0.1"
+ self._http_base = f"http://{self._httpd_addr}:{self.http_port}"
+ self._https_base = f"https://{self._httpd_addr}:{self.https_port}"
+
+ self._test_conf = os.path.join(self._server_conf_dir, "test.conf")
+ self._httpd_base_conf = f"""
+ LoadModule mpm_{self.mpm_type}_module \"{self.libexec_dir}/mod_mpm_{self.mpm_type}.so\"
+ H2MinWorkers 1
+ H2MaxWorkers 64
+ SSLSessionCache "shmcb:ssl_gcache_data(32000)"
+ """
+ py_verbosity = pytestconfig.option.verbose if pytestconfig is not None else 0
+ if py_verbosity >= 2:
+ self._httpd_base_conf += f"""
+ LogLevel http2:trace2 proxy_http2:info
+ LogLevel core:trace5 mpm_{self.mpm_type}:trace5
+ """
+ if py_verbosity >= 1:
+ self._httpd_base_conf += "LogLevel http2:debug proxy_http2:debug"
+ else:
+ self._httpd_base_conf += "LogLevel http2:info proxy_http2:info"
+
+ self._verify_certs = False
+ self._setup = H2TestSetup(env=self)
+ self._setup.make()
+
+ @property
+ def apxs(self) -> str:
+ return self._apxs
+
+ @property
+ def prefix(self) -> str:
+ return self._prefix
+
+ @property
+ def mpm_type(self) -> str:
+ return self._mpm_type
+
+ @property
+ def http_port(self) -> int:
+ return self._http_port
+
+ @property
+ def https_port(self) -> int:
+ return self._https_port
+
+ @property
+ def http_tld(self) -> str:
+ return self._http_tld
+
+ @property
+ def domain_test1(self) -> str:
+ return self._domains[0]
+
+ @property
+ def domains(self) -> List[str]:
+ return self._domains
+
+ @property
+ def domains_noh2(self) -> List[str]:
+ return self._domains_noh2
+
+ @property
+ def http_base_url(self) -> str:
+ return self._http_base
+
+ @property
+ def https_base_url(self) -> str:
+ return self._https_base
+
+ @property
+ def gen_dir(self) -> str:
+ return self._gen_dir
+
+ @property
+ def test_dir(self) -> str:
+ return self._test_dir
+
+ @property
+ def test_src_dir(self) -> str:
+ return self._test_src_dir
+
+ @property
+ def server_dir(self) -> str:
+ return self._server_dir
+
+ @property
+ def server_logs_dir(self) -> str:
+ return self._server_logs_dir
+
+ @property
+ def libexec_dir(self) -> str:
+ return self._libexec_dir
+
+ @property
+ def dso_modules(self) -> List[str]:
+ return self._dso_modules
+
+ @property
+ def server_conf_dir(self) -> str:
+ return self._server_conf_dir
+
+ @property
+ def server_docs_dir(self) -> str:
+ return self._server_docs_dir
+
+ @property
+ def httpd_base_conf(self) -> str:
+ return self._httpd_base_conf
+
+ @property
+ def h2load(self) -> str:
+ return self._h2load
+
+ @property
+ def ca(self) -> Credentials:
+ return self._ca
+
+ def set_ca(self, ca: Credentials):
+ self._ca = ca
+
+ def get_credentials_for_name(self, dns_name) -> List['Credentials']:
+ for domains in [self._domains, self._domains_noh2]:
+ if dns_name in domains:
+ return self.ca.get_credentials_for_name(domains[0])
+ return []
+
+ def has_h2load(self):
+ return self._h2load != ""
+
+ def has_nghttp(self):
+ return self._nghttp != ""
+
+ def has_nghttp_get_assets(self):
+ if not self.has_nghttp():
+ return False
+ args = [self._nghttp, "-a"]
+ p = subprocess.run(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ rv = p.returncode
+ if rv != 0:
+ return False
+ return p.stderr == ""
+
+ def get_apxs_var(self, name: str) -> str:
+ p = subprocess.run([self._apxs, "-q", name], capture_output=True, text=True)
+ if p.returncode != 0:
+ return ""
+ return p.stdout.strip()
+
+ def get_httpd_version(self) -> str:
+ return self.get_apxs_var("HTTPD_VERSION")
+
+ def mkpath(self, path):
+ if not os.path.exists(path):
+ return os.makedirs(path)
+
+ def test_src(self, path):
+ return os.path.join(self._test_src_dir, path)
+
+ def run(self, args) -> ExecResult:
+ log.debug("execute: %s", " ".join(args))
+ start = datetime.now()
+ p = subprocess.run(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ return ExecResult(exit_code=p.returncode, stdout=p.stdout, stderr=p.stderr,
+ duration=datetime.now() - start)
+
+ def mkurl(self, scheme, hostname, path='/'):
+ port = self.https_port if scheme == 'https' else self.http_port
+ return "%s://%s.%s:%s%s" % (scheme, hostname, self.http_tld, port, path)
+
+ def install_test_conf(self, conf: List[str]):
+ with open(self._test_conf, 'w') as fd:
+ fd.write(f"{self.httpd_base_conf}\n")
+ for line in conf:
+ fd.write(f"{line}\n")
+
+ def is_live(self, url, timeout: timedelta = None):
+ s = requests.Session()
+ if not timeout:
+ timeout = timedelta(seconds=10)
+ try_until = datetime.now() + timeout
+ log.debug("checking reachability of %s", url)
+ while datetime.now() < try_until:
+ try:
+ req = requests.Request('HEAD', url).prepare()
+ s.send(req, verify=self._verify_certs, timeout=timeout.total_seconds())
+ return True
+ except IOError:
+ log.debug("connect error: %s", sys.exc_info()[0])
+ time.sleep(.2)
+ except:
+ log.warning("Unexpected error: %s", sys.exc_info()[0])
+ time.sleep(.2)
+ log.debug(f"Unable to contact '{url}' after {timeout} sec")
+ return False
+
+ def is_dead(self, url, timeout: timedelta = None):
+ s = requests.Session()
+ if not timeout:
+ timeout = timedelta(seconds=10)
+ try_until = datetime.now() + timeout
+ log.debug("checking reachability of %s", url)
+ while datetime.now() < try_until:
+ try:
+ req = requests.Request('HEAD', url).prepare()
+ s.send(req, verify=self._verify_certs, timeout=int(timeout.total_seconds()))
+ time.sleep(.2)
+ except IOError as ex:
+ return True
+ log.debug("Server still responding after %d sec", timeout)
+ return False
+
+ def _run_apachectl(self, cmd):
+ args = [self._apachectl,
+ "-d", self.server_dir,
+ "-f", os.path.join(self._server_dir, 'conf/httpd.conf'),
+ "-k", cmd]
+ log.debug("execute: %s", " ".join(args))
+ p = subprocess.run(args, capture_output=True, text=True)
+ rv = p.returncode
+ if rv != 0:
+ log.warning(f"exit {rv}, stdout: {p.stdout}, stderr: {p.stderr}")
+ return rv
+
+ def apache_reload(self):
+ rv = self._run_apachectl("graceful")
+ if rv == 0:
+ timeout = timedelta(seconds=10)
+ rv = 0 if self.is_live(self._http_base, timeout=timeout) else -1
+ return rv
+
+ def apache_restart(self):
+ rv = self.apache_stop()
+ rv = self._run_apachectl("start")
+ if rv == 0:
+ timeout = timedelta(seconds=10)
+ rv = 0 if self.is_live(self._http_base, timeout=timeout) else -1
+ return rv
+
+ def apache_stop(self):
+ rv = self._run_apachectl("stop")
+ if rv == 0:
+ timeout = timedelta(seconds=10)
+ rv = 0 if self.is_dead(self._http_base, timeout=timeout) else -1
+ log.debug("waited for a apache.is_dead, rv=%d", rv)
+ return rv
+
+ def apache_error_log_clear(self):
+ if os.path.isfile(self._server_error_log):
+ os.remove(self._server_error_log)
+
+ RE_APLOGNO = re.compile(r'.*\[(?P[^:]+):(error|warn)].* (?PAH\d+): .+')
+ RE_SSL_LIB_ERR = re.compile(r'.*\[ssl:error].* SSL Library Error: error:(?P\S+):.+')
+ RE_ERRLOG_ERROR = re.compile(r'.*\[(?P[^:]+):error].*')
+ RE_ERRLOG_WARN = re.compile(r'.*\[(?P[^:]+):warn].*')
+
+ def apache_errors_and_warnings(self):
+ errors = []
+ warnings = []
+
+ if os.path.isfile(self._server_error_log):
+ for line in open(self._server_error_log):
+ m = self.RE_APLOGNO.match(line)
+ if m and m.group('aplogno') in [
+ 'AH02032',
+ 'AH01276',
+ 'AH01630',
+ 'AH00135',
+ 'AH02261', # Re-negotiation handshake failed (our test_101
+ ]:
+ # we know these happen normally in our tests
+ continue
+ m = self.RE_SSL_LIB_ERR.match(line)
+ if m and m.group('errno') in [
+ '1417A0C1', # cipher suite mismatch, test_101
+ '1417C0C7', # client cert not accepted, test_101
+ ]:
+ # we know these happen normally in our tests
+ continue
+ m = self.RE_ERRLOG_ERROR.match(line)
+ if m and m.group('module') not in ['cgid']:
+ errors.append(line)
+ continue
+ m = self.RE_ERRLOG_WARN.match(line)
+ if m:
+ warnings.append(line)
+ continue
+ return errors, warnings
+
+ def curl_complete_args(self, urls, timeout, options):
+ if not isinstance(urls, list):
+ urls = [urls]
+ u = urlparse(urls[0])
+ assert u.hostname, f"hostname not in url: {urls[0]}"
+ assert u.port, f"port not in url: {urls[0]}"
+ headerfile = ("%s/curl.headers" % self.gen_dir)
+ if os.path.isfile(headerfile):
+ os.remove(headerfile)
+
+ args = [
+ self._curl,
+ "--cacert", self.ca.cert_file,
+ "-s", "-D", headerfile,
+ "--resolve", ("%s:%s:%s" % (u.hostname, u.port, self._httpd_addr)),
+ "--connect-timeout", ("%d" % timeout)
+ ]
+ if options:
+ args.extend(options)
+ args += urls
+ return args, headerfile
+
+ def curl_raw(self, urls, timeout, options):
+ args, headerfile = self.curl_complete_args(urls, timeout, options)
+ r = self.run(args)
+ if r.exit_code == 0:
+ lines = open(headerfile).readlines()
+ exp_stat = True
+ header = {}
+ for line in lines:
+ if exp_stat:
+ log.debug("reading 1st response line: %s", line)
+ m = re.match(r'^(\S+) (\d+) (.*)$', line)
+ assert m
+ r.add_response({
+ "protocol": m.group(1),
+ "status": int(m.group(2)),
+ "description": m.group(3),
+ "body": r.outraw
+ })
+ exp_stat = False
+ header = {}
+ elif re.match(r'^$', line):
+ exp_stat = True
+ else:
+ log.debug("reading header line: %s", line)
+ m = re.match(r'^([^:]+):\s*(.*)$', line)
+ assert m
+ header[m.group(1).lower()] = m.group(2)
+ r.response["header"] = header
+ if r.json:
+ r.response["json"] = r.json
+ return r
+
+ def curl_get(self, url, timeout=5, options=None):
+ return self.curl_raw([url], timeout=timeout, options=options)
+
+ def curl_upload(self, url, fpath, timeout=5, options=None):
+ if not options:
+ options = []
+ options.extend([
+ "--form", ("file=@%s" % fpath)
+ ])
+ return self.curl_raw([url], timeout, options)
+
+ def curl_post_data(self, url, data="", timeout=5, options=None):
+ if not options:
+ options = []
+ options.extend(["--data", "%s" % data])
+ return self.curl_raw(url, timeout, options)
+
+ def curl_post_value(self, url, key, value, timeout=5, options=None):
+ if not options:
+ options = []
+ options.extend(["--form", "{0}={1}".format(key, value)])
+ return self.curl_raw(url, timeout, options)
+
+ def curl_protocol_version(self, url, timeout=5, options=None):
+ if not options:
+ options = []
+ options.extend(["-w", "%{http_version}\n", "-o", "/dev/null"])
+ r = self.curl_raw(url, timeout=timeout, options=options)
+ if r.exit_code == 0 and r.response:
+ return r.response["body"].decode('utf-8').rstrip()
+ return -1
+
+ def nghttp(self):
+ return Nghttp(self._nghttp, connect_addr=self._httpd_addr, tmp_dir=self.gen_dir)
+
+ def h2load_status(self, run: ExecResult):
+ stats = {}
+ m = re.search(
+ r'requests: (\d+) total, (\d+) started, (\d+) done, (\d+) succeeded'
+ r', (\d+) failed, (\d+) errored, (\d+) timeout', run.stdout)
+ if m:
+ stats["requests"] = {
+ "total": int(m.group(1)),
+ "started": int(m.group(2)),
+ "done": int(m.group(3)),
+ "succeeded": int(m.group(4))
+ }
+ m = re.search(r'status codes: (\d+) 2xx, (\d+) 3xx, (\d+) 4xx, (\d+) 5xx',
+ run.stdout)
+ if m:
+ stats["status"] = {
+ "2xx": int(m.group(1)),
+ "3xx": int(m.group(2)),
+ "4xx": int(m.group(3)),
+ "5xx": int(m.group(4))
+ }
+ run.add_results({"h2load": stats})
+ return run
+
+ def setup_data_1k_1m(self):
+ s100 = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n"
+ with open(os.path.join(self.gen_dir, "data-1k"), 'w') as f:
+ for i in range(10):
+ f.write(s100)
+ with open(os.path.join(self.gen_dir, "data-10k"), 'w') as f:
+ for i in range(100):
+ f.write(s100)
+ with open(os.path.join(self.gen_dir, "data-100k"), 'w') as f:
+ for i in range(1000):
+ f.write(s100)
+ with open(os.path.join(self.gen_dir, "data-1m"), 'w') as f:
+ for i in range(10000):
+ f.write(s100)
diff --git a/test/modules/http2/h2_nghttp.py b/test/modules/http2/h2_nghttp.py
new file mode 100644
index 00000000000..d06798e868e
--- /dev/null
+++ b/test/modules/http2/h2_nghttp.py
@@ -0,0 +1,288 @@
+import re
+import os
+import subprocess
+from datetime import datetime
+from typing import Dict
+
+from urllib.parse import urlparse
+
+from h2_result import ExecResult
+
+
+def _get_path(x):
+ return x["path"]
+
+
+class Nghttp:
+
+ def __init__(self, path, connect_addr=None, tmp_dir="/tmp"):
+ self.NGHTTP = path
+ self.CONNECT_ADDR = connect_addr
+ self.TMP_DIR = tmp_dir
+
+ @staticmethod
+ def get_stream(streams, sid):
+ sid = int(sid)
+ if sid not in streams:
+ streams[sid] = {
+ "id": sid,
+ "header": {},
+ "request": {
+ "id": sid,
+ "body": b''
+ },
+ "response": {
+ "id": sid,
+ "body": b''
+ },
+ "paddings": [],
+ "promises": []
+ }
+ return streams[sid] if sid in streams else None
+
+ def run(self, urls, timeout, options):
+ return self._baserun(urls, timeout, options)
+
+ def complete_args(self, url, _timeout, options: [str]) -> [str]:
+ if not isinstance(url, list):
+ url = [url]
+ u = urlparse(url[0])
+ args = [self.NGHTTP]
+ if self.CONNECT_ADDR:
+ connect_host = self.CONNECT_ADDR
+ args.append("--header=host: %s:%s" % (u.hostname, u.port))
+ else:
+ connect_host = u.hostname
+ if options:
+ args.extend(options)
+ for xurl in url:
+ xu = urlparse(xurl)
+ nurl = "%s://%s:%s/%s" % (u.scheme, connect_host, xu.port, xu.path)
+ if xu.query:
+ nurl = "%s?%s" % (nurl, xu.query)
+ args.append(nurl)
+ return args
+
+ def _baserun(self, url, timeout, options):
+ return self._run(self.complete_args(url, timeout, options))
+
+ def parse_output(self, btext) -> Dict:
+ # getting meta data and response body out of nghttp's output
+ # is a bit tricky. Without '-v' we just get the body. With '-v' meta
+ # data and timings in both directions are listed.
+ # We rely on response :status: to be unique and on
+ # response body not starting with space.
+ # Something not good enough for general purpose, but for these tests.
+ output = {}
+ body = ''
+ streams = {}
+ skip_indents = True
+ # chunk output into lines. nghttp mixes text
+ # meta output with bytes from the response body.
+ lines = [l.decode() for l in btext.split(b'\n')]
+ for lidx, l in enumerate(lines):
+ if len(l) == 0:
+ body += '\n'
+ continue
+ m = re.match(r'\[.*] recv \(stream_id=(\d+)\) (\S+): (\S*)', l)
+ if m:
+ s = self.get_stream(streams, m.group(1))
+ hname = m.group(2)
+ hval = m.group(3)
+ print("stream %d header %s: %s" % (s["id"], hname, hval))
+ header = s["header"]
+ if hname in header:
+ header[hname] += ", %s" % hval
+ else:
+ header[hname] = hval
+ body = ''
+ continue
+
+ m = re.match(r'\[.*] recv HEADERS frame <.* stream_id=(\d+)>', l)
+ if m:
+ s = self.get_stream(streams, m.group(1))
+ if s:
+ print("stream %d: recv %d header" % (s["id"], len(s["header"])))
+ response = s["response"]
+ hkey = "header"
+ if "header" in response:
+ h = response["header"]
+ if ":status" in h and int(h[":status"]) >= 200:
+ hkey = "trailer"
+ else:
+ prev = {
+ "header": h
+ }
+ if "previous" in response:
+ prev["previous"] = response["previous"]
+ response["previous"] = prev
+ response[hkey] = s["header"]
+ s["header"] = {}
+ body = ''
+ continue
+
+ m = re.match(r'(.*)\[.*] recv DATA frame ', l)
+ if m:
+ s = self.get_stream(streams, m.group(3))
+ body += m.group(1)
+ blen = int(m.group(2))
+ if s:
+ print("stream %d: %d DATA bytes added" % (s["id"], blen))
+ padlen = 0
+ if len(lines) > lidx + 2:
+ mpad = re.match(r' +\(padlen=(\d+)\)', lines[lidx+2])
+ if mpad:
+ padlen = int(mpad.group(1))
+ s["paddings"].append(padlen)
+ blen -= padlen
+ s["response"]["body"] += body[-blen:].encode()
+ body = ''
+ skip_indents = True
+ continue
+
+ m = re.match(r'\[.*] recv PUSH_PROMISE frame <.* stream_id=(\d+)>', l)
+ if m:
+ s = self.get_stream(streams, m.group(1))
+ if s:
+ # headers we have are request headers for the PUSHed stream
+ # these have been received on the originating stream, the promised
+ # stream id it mentioned in the following lines
+ print("stream %d: %d PUSH_PROMISE header" % (s["id"], len(s["header"])))
+ if len(lines) > lidx+2:
+ m2 = re.match(r'\s+\(.*promised_stream_id=(\d+)\)', lines[lidx+2])
+ if m2:
+ s2 = self.get_stream(streams, m2.group(1))
+ s2["request"]["header"] = s["header"]
+ s["promises"].append(s2)
+ s["header"] = {}
+ continue
+
+ m = re.match(r'(.*)\[.*] recv (\S+) frame ', l)
+ if m:
+ print("recv frame %s on stream %s" % (m.group(2), m.group(4)))
+ body += m.group(1)
+ skip_indents = True
+ continue
+
+ m = re.match(r'(.*)\[.*] send (\S+) frame ', l)
+ if m:
+ print("send frame %s on stream %s" % (m.group(2), m.group(4)))
+ body += m.group(1)
+ skip_indents = True
+ continue
+
+ if skip_indents and l.startswith(' '):
+ continue
+
+ if '[' != l[0]:
+ skip_indents = None
+ body += l + '\n'
+
+ # the main request is done on the lowest odd numbered id
+ main_stream = 99999999999
+ for sid in streams:
+ s = streams[sid]
+ if ":status" in s["response"]["header"]:
+ s["response"]["status"] = int(s["response"]["header"][":status"])
+ if (sid % 2) == 1 and sid < main_stream:
+ main_stream = sid
+
+ output["streams"] = streams
+ if main_stream in streams:
+ output["response"] = streams[main_stream]["response"]
+ output["paddings"] = streams[main_stream]["paddings"]
+ return output
+
+ def _raw(self, url, timeout, options):
+ args = ["-v"]
+ if options:
+ args.extend(options)
+ r = self._baserun(url, timeout, args)
+ if 0 == r.exit_code:
+ r.add_results(self.parse_output(r.outraw))
+ return r
+
+ def get(self, url, timeout=5, options=None):
+ return self._raw(url, timeout, options)
+
+ def assets(self, url, timeout=5, options=None):
+ if not options:
+ options = []
+ options.extend(["-ans"])
+ r = self._baserun(url, timeout, options)
+ assets = []
+ if 0 == r.exit_code:
+ lines = re.findall(r'[^\n]*\n', r.stdout, re.MULTILINE)
+ for lidx, l in enumerate(lines):
+ m = re.match(r'\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+/(.*)', l)
+ if m:
+ assets.append({
+ "path": m.group(7),
+ "status": int(m.group(5)),
+ "size": m.group(6)
+ })
+ assets.sort(key=_get_path)
+ r.add_assets(assets)
+ return r
+
+ def post_data(self, url, data, timeout=5, options=None):
+ reqbody = ("%s/nghttp.req.body" % self.TMP_DIR)
+ with open(reqbody, 'wb') as f:
+ f.write(data.encode('utf-8'))
+ if not options:
+ options = []
+ options.extend(["--data=%s" % reqbody])
+ return self._raw(url, timeout, options)
+
+ def post_name(self, url, name, timeout=5, options=None):
+ reqbody = ("%s/nghttp.req.body" % self.TMP_DIR)
+ with open(reqbody, 'w') as f:
+ f.write("--DSAJKcd9876\n")
+ f.write("Content-Disposition: form-data; name=\"value\"; filename=\"xxxxx\"\n")
+ f.write("Content-Type: text/plain\n")
+ f.write("\n%s\n" % name)
+ f.write("--DSAJKcd9876\n")
+ if not options:
+ options = []
+ options.extend(["--data=%s" % reqbody])
+ return self._raw(url, timeout, options)
+
+ def upload(self, url, fpath, timeout=5, options=None):
+ if not options:
+ options = []
+ options.extend(["--data=%s" % fpath])
+ return self._raw(url, timeout, options)
+
+ def upload_file(self, url, fpath, timeout=5, options=None):
+ fname = os.path.basename(fpath)
+ reqbody = ("%s/nghttp.req.body" % self.TMP_DIR)
+ with open(fpath, 'rb') as fin:
+ with open(reqbody, 'wb') as f:
+ f.write(("""--DSAJKcd9876
+Content-Disposition: form-data; name="xxx"; filename="xxxxx"
+Content-Type: text/plain
+
+testing mod_h2
+--DSAJKcd9876
+Content-Disposition: form-data; name="file"; filename="%s"
+Content-Type: application/octet-stream
+Content-Transfer-Encoding: binary
+
+""" % fname).encode('utf-8'))
+ f.write(fin.read())
+ f.write("""
+--DSAJKcd9876""".encode('utf-8'))
+ if not options:
+ options = []
+ options.extend([
+ "--data=%s" % reqbody,
+ "--expect-continue",
+ "-HContent-Type: multipart/form-data; boundary=DSAJKcd9876"])
+ return self._raw(url, timeout, options)
+
+ def _run(self, args) -> ExecResult:
+ print(("execute: %s" % " ".join(args)))
+ start = datetime.now()
+ p = subprocess.run(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ return ExecResult(exit_code=p.returncode, stdout=p.stdout, stderr=p.stderr,
+ duration=datetime.now() - start)
diff --git a/test/modules/http2/h2_result.py b/test/modules/http2/h2_result.py
new file mode 100644
index 00000000000..06fc9e53004
--- /dev/null
+++ b/test/modules/http2/h2_result.py
@@ -0,0 +1,71 @@
+import json
+from datetime import timedelta
+from typing import Optional, Dict, List
+
+
+class ExecResult:
+
+ def __init__(self, exit_code: int, stdout: bytes, stderr: bytes = None, duration: timedelta = None):
+ self._exit_code = exit_code
+ self._raw = stdout if stdout else b''
+ self._stdout = stdout.decode() if stdout is not None else ""
+ self._stderr = stderr.decode() if stderr is not None else ""
+ self._duration = duration if duration is not None else timedelta()
+ self._response = None
+ self._results = {}
+ self._assets = []
+ # noinspection PyBroadException
+ try:
+ self._json_out = json.loads(self._stdout)
+ except:
+ self._json_out = None
+
+ @property
+ def exit_code(self) -> int:
+ return self._exit_code
+
+ @property
+ def outraw(self) -> bytes:
+ return self._raw
+
+ @property
+ def stdout(self) -> str:
+ return self._stdout
+
+ @property
+ def json(self) -> Optional[Dict]:
+ """Output as JSON dictionary or None if not parseable."""
+ return self._json_out
+
+ @property
+ def stderr(self) -> str:
+ return self._stderr
+
+ @property
+ def duration(self) -> timedelta:
+ return self._duration
+
+ @property
+ def response(self) -> Optional[Dict]:
+ return self._response
+
+ @property
+ def results(self) -> Dict:
+ return self._results
+
+ @property
+ def assets(self) -> List:
+ return self._assets
+
+ def add_response(self, resp: Dict):
+ if self._response:
+ resp['previous'] = self._response
+ self._response = resp
+
+ def add_results(self, results: Dict):
+ self._results.update(results)
+ if 'response' in results:
+ self.add_response(results['response'])
+
+ def add_assets(self, assets: List):
+ self._assets.extend(assets)
diff --git a/test/modules/http2/htdocs/alive.json b/test/modules/http2/htdocs/alive.json
new file mode 100644
index 00000000000..2239ee2ee7b
--- /dev/null
+++ b/test/modules/http2/htdocs/alive.json
@@ -0,0 +1,4 @@
+{
+ "host" : "generic",
+ "alive" : true
+}
diff --git a/test/modules/http2/htdocs/cgi/echo.py b/test/modules/http2/htdocs/cgi/echo.py
new file mode 100644
index 00000000000..5ffe6ed8230
--- /dev/null
+++ b/test/modules/http2/htdocs/cgi/echo.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+import sys, cgi, os
+
+status = '200 Ok'
+
+content = ''
+for line in sys.stdin:
+ content += line
+
+# Just echo what we get
+print("Status: 200")
+print("Content-Type: application/data\n")
+sys.stdout.write(content)
+
diff --git a/test/modules/http2/htdocs/cgi/echohd.py b/test/modules/http2/htdocs/cgi/echohd.py
new file mode 100644
index 00000000000..371ae8b0f7a
--- /dev/null
+++ b/test/modules/http2/htdocs/cgi/echohd.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+import cgi, os
+import cgitb; cgitb.enable()
+
+status = '200 Ok'
+
+form = cgi.FieldStorage()
+name = form.getvalue('name')
+
+if name:
+ print("Status: 200")
+ print("""\
+Content-Type: text/plain\n""")
+ print("""%s: %s""" % (name, os.environ['HTTP_'+name]))
+else:
+ print("Status: 400 Parameter Missing")
+ print("""\
+Content-Type: text/html\n
+
+No name was specified
+""")
+
+
diff --git a/test/modules/http2/htdocs/cgi/env.py b/test/modules/http2/htdocs/cgi/env.py
new file mode 100644
index 00000000000..5c9c0b1adbc
--- /dev/null
+++ b/test/modules/http2/htdocs/cgi/env.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+import cgi, os
+import cgitb; cgitb.enable()
+
+status = '200 Ok'
+
+try:
+ form = cgi.FieldStorage()
+ input = form['name']
+
+ # Test if the file was uploaded
+ if input.value is not None:
+ val = os.environ[input.value] if input.value in os.environ else ""
+ print("Status: 200")
+ print("""\
+Content-Type: text/plain\n""")
+ print("{0}={1}".format(input.value, val))
+
+ else:
+ print("Status: 400 Parameter Missing")
+ print("""\
+Content-Type: text/html\n
+
+ No name was specified: %s
+ """ % (count.value))
+
+except KeyError:
+ print("Status: 200 Ok")
+ print("""\
+Content-Type: text/html\n
+
+ Echo
+ """)
+ pass
+
+
+
diff --git a/test/modules/http2/htdocs/cgi/files/empty.txt b/test/modules/http2/htdocs/cgi/files/empty.txt
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/test/modules/http2/htdocs/cgi/hecho.py b/test/modules/http2/htdocs/cgi/hecho.py
new file mode 100644
index 00000000000..5c1f79a3027
--- /dev/null
+++ b/test/modules/http2/htdocs/cgi/hecho.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+import cgi, os
+import cgitb; cgitb.enable()
+
+status = '200 Ok'
+
+try:
+ form = cgi.FieldStorage()
+
+ # A nested FieldStorage instance holds the file
+ name = form['name'].value
+ value = ''
+
+ try:
+ value = form['value'].value
+ except KeyError:
+ value = os.environ.get("HTTP_"+name, "unset")
+
+ # Test if a value was given
+ if name:
+ print("Status: 200")
+ print("%s: %s" % (name, value,))
+ print ("""\
+Content-Type: text/plain\n""")
+
+ else:
+ print("Status: 400 Parameter Missing")
+ print("""\
+Content-Type: text/html\n
+
+ No name and value was specified: %s %s
+ """ % (name, value))
+
+except KeyError:
+ print("Status: 200 Ok")
+ print("""\
+Content-Type: text/html\n
+
+ Echo
+ """)
+ pass
+
+
diff --git a/test/modules/http2/htdocs/cgi/hello.py b/test/modules/http2/htdocs/cgi/hello.py
new file mode 100644
index 00000000000..191acb2fedd
--- /dev/null
+++ b/test/modules/http2/htdocs/cgi/hello.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import os
+
+print("Content-Type: application/json")
+print()
+print("{")
+print(" \"https\" : \"%s\"," % (os.getenv('HTTPS', '')))
+print(" \"host\" : \"%s\"," % (os.getenv('SERVER_NAME', '')))
+print(" \"protocol\" : \"%s\"," % (os.getenv('SERVER_PROTOCOL', '')))
+print(" \"ssl_protocol\" : \"%s\"," % (os.getenv('SSL_PROTOCOL', '')))
+print(" \"h2\" : \"%s\"," % (os.getenv('HTTP2', '')))
+print(" \"h2push\" : \"%s\"" % (os.getenv('H2PUSH', '')))
+print("}")
+
diff --git a/test/modules/http2/htdocs/cgi/mnot164.py b/test/modules/http2/htdocs/cgi/mnot164.py
new file mode 100644
index 00000000000..949b0f195b0
--- /dev/null
+++ b/test/modules/http2/htdocs/cgi/mnot164.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python3
+
+import cgi
+import cgitb; cgitb.enable()
+import os
+import sys
+
+try:
+ form = cgi.FieldStorage()
+ count = form['count'].value
+ text = form['text'].value
+except KeyError:
+ text="a"
+ count=77784
+
+
+print("Status: 200 OK")
+print("Content-Type: text/html")
+print()
+sys.stdout.write(text*int(count))
+
diff --git a/test/modules/http2/htdocs/cgi/necho.py b/test/modules/http2/htdocs/cgi/necho.py
new file mode 100644
index 00000000000..b9249b8969c
--- /dev/null
+++ b/test/modules/http2/htdocs/cgi/necho.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+import cgi, os
+import time
+import cgitb; cgitb.enable()
+
+status = '200 Ok'
+
+try:
+ form = cgi.FieldStorage()
+ count = form['count']
+ text = form['text']
+
+ waitsec = float(form['wait1'].value) if 'wait1' in form else 0.0
+ if waitsec > 0:
+ time.sleep(waitsec)
+
+ if int(count.value):
+ print("Status: 200")
+ print("""\
+Content-Type: text/plain\n""")
+
+ waitsec = float(form['wait2'].value) if 'wait2' in form else 0.0
+ if waitsec > 0:
+ time.sleep(waitsec)
+
+ i = 0;
+ for i in range(0, int(count.value)):
+ print("%s" % (text.value))
+
+ waitsec = float(form['wait3'].value) if 'wait3' in form else 0.0
+ if waitsec > 0:
+ time.sleep(waitsec)
+
+ else:
+ print("Status: 400 Parameter Missing")
+ print("""\
+Content-Type: text/html\n
+
+ No count was specified: %s
+ """ % (count.value))
+
+except KeyError:
+ print("Status: 200 Ok")
+ print("""\
+Content-Type: text/html\n
+
+ Echo
+ """)
+ pass
+
+
diff --git a/test/modules/http2/htdocs/cgi/upload.py b/test/modules/http2/htdocs/cgi/upload.py
new file mode 100644
index 00000000000..2c8d63aa108
--- /dev/null
+++ b/test/modules/http2/htdocs/cgi/upload.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+import cgi, os
+import cgitb
+cgitb.enable()
+
+status = '200 Ok'
+
+try: # Windows needs stdio set for binary mode.
+ import msvcrt
+ msvcrt.setmode (0, os.O_BINARY) # stdin = 0
+ msvcrt.setmode (1, os.O_BINARY) # stdout = 1
+except ImportError:
+ pass
+
+form = cgi.FieldStorage()
+
+# Test if the file was uploaded
+if 'file' in form:
+ fileitem = form['file']
+ # strip leading path from file name to avoid directory traversal attacks
+ fn = os.path.basename(fileitem.filename)
+ f = open(('%s/files/%s' % (os.environ["DOCUMENT_ROOT"], fn)), 'wb');
+ f.write(fileitem.file.read())
+ f.close()
+ message = "The file %s was uploaded successfully" % (fn)
+ print("Status: 201 Created")
+ print("Content-Type: text/html")
+ print("Location: %s://%s/files/%s" % (os.environ["REQUEST_SCHEME"], os.environ["HTTP_HOST"], fn))
+ print("")
+ print("%s
" % (message))
+
+elif 'remove' in form:
+ remove = form['remove'].value
+ try:
+ fn = os.path.basename(remove)
+ os.remove('./files/' + fn)
+ message = 'The file "' + fn + '" was removed successfully'
+ except OSError as e:
+ message = 'Error removing ' + fn + ': ' + e.strerror
+ status = '404 File Not Found'
+ print("Status: %s" % (status))
+ print("""
+Content-Type: text/html
+
+
+%s
+""" % (message))
+
+else:
+ message = '''\
+ Upload File
+ '''
+ print("Status: %s" % (status))
+ print("""\
+Content-Type: text/html
+
+
+%s
+""" % (message))
+
diff --git a/test/modules/http2/htdocs/forbidden.html b/test/modules/http2/htdocs/forbidden.html
new file mode 100644
index 00000000000..e186310c739
--- /dev/null
+++ b/test/modules/http2/htdocs/forbidden.html
@@ -0,0 +1,11 @@
+
+
+ 403 - Forbidden
+
+
+ 403 - Forbidden
+
+ An example of an error document.
+
+
+
diff --git a/test/modules/http2/htdocs/index.html b/test/modules/http2/htdocs/index.html
new file mode 100644
index 00000000000..3c076261440
--- /dev/null
+++ b/test/modules/http2/htdocs/index.html
@@ -0,0 +1,9 @@
+
+
+ mod_h2 test site generic
+
+
+ mod_h2 test site generic
+
+
+
diff --git a/test/modules/http2/htdocs/noh2/alive.json b/test/modules/http2/htdocs/noh2/alive.json
new file mode 100644
index 00000000000..7b54893ee5f
--- /dev/null
+++ b/test/modules/http2/htdocs/noh2/alive.json
@@ -0,0 +1,5 @@
+{
+ "host" : "noh2",
+ "alive" : true
+}
+
diff --git a/test/modules/http2/htdocs/noh2/index.html b/test/modules/http2/htdocs/noh2/index.html
new file mode 100644
index 00000000000..696068e9dc2
--- /dev/null
+++ b/test/modules/http2/htdocs/noh2/index.html
@@ -0,0 +1,9 @@
+
+
+ mod_h2 test site noh2
+
+
+ mod_h2 test site noh2
+
+
+
diff --git a/test/modules/http2/htdocs/test1/001.html b/test/modules/http2/htdocs/test1/001.html
new file mode 100644
index 00000000000..184952d28c5
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/001.html
@@ -0,0 +1,10 @@
+
+
+
+ HTML/2.0 Test File: 001
+
+
+ HTML/2.0 Test File: 001
+ This file only contains a simple HTML structure with plain text.
+
+
diff --git a/test/modules/http2/htdocs/test1/002.jpg b/test/modules/http2/htdocs/test1/002.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3feefb070a78be4b79512578c62768d01f8145bf
GIT binary patch
literal 90364
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
+
+
+ HTML/2.0 Test File: 003
+
+
+ HTML/2.0 Test File: 003
+ This is a text HTML file with a big image:
+ 
+
+
diff --git a/test/modules/http2/htdocs/test1/003/003_img.jpg b/test/modules/http2/htdocs/test1/003/003_img.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3feefb070a78be4b79512578c62768d01f8145bf
GIT binary patch
literal 90364
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