From: Stefan Eissing
Date: Thu, 23 Sep 2021 09:53:01 +0000 (+0000)
Subject: * merging test/modules from trunk
X-Git-Tag: candidate-2.4.50-rc1~35
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1430e0a292679a86e5a100ebf7cfd0a21dc43dfb;p=thirdparty%2Fapache%2Fhttpd.git
* 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
---
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 00000000000..3feefb070a7
Binary files /dev/null and b/test/modules/http2/htdocs/test1/002.jpg differ
diff --git a/test/modules/http2/htdocs/test1/003.html b/test/modules/http2/htdocs/test1/003.html
new file mode 100644
index 00000000000..d5b08c52bb1
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/003.html
@@ -0,0 +1,11 @@
+
+
+
+ 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 00000000000..3feefb070a7
Binary files /dev/null and b/test/modules/http2/htdocs/test1/003/003_img.jpg differ
diff --git a/test/modules/http2/htdocs/test1/004.html b/test/modules/http2/htdocs/test1/004.html
new file mode 100644
index 00000000000..768cb825b43
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/004.html
@@ -0,0 +1,23 @@
+
+
+ HTML/2.0 Test File: 004
+
+
+
HTML/2.0 Test File: 004
+ This file contains plain text with a bunch of images.
+
+
+
+
+
+
+
+
+
+
+
+
+ This page is developed using this template:HTTP/2 demo server
+
+
+
\ No newline at end of file
diff --git a/test/modules/http2/htdocs/test1/004/gophertiles.jpg b/test/modules/http2/htdocs/test1/004/gophertiles.jpg
new file mode 100644
index 00000000000..e45ac3b02bb
Binary files /dev/null and b/test/modules/http2/htdocs/test1/004/gophertiles.jpg differ
diff --git a/test/modules/http2/htdocs/test1/006.html b/test/modules/http2/htdocs/test1/006.html
new file mode 100644
index 00000000000..6b730255a14
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/006.html
@@ -0,0 +1,23 @@
+
+
+
+ HTML/2.0 Test File: 006
+
+
+
+
+ HTML/2.0 Test File: 006
+ This page contains:
+
+ HTML
+ CSS
+ JavaScript
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/modules/http2/htdocs/test1/006/006.css b/test/modules/http2/htdocs/test1/006/006.css
new file mode 100644
index 00000000000..de6aa5fd180
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/006/006.css
@@ -0,0 +1,21 @@
+@CHARSET "ISO-8859-1";
+body{
+ background:HoneyDew;
+}
+p{
+color:#0000FF;
+text-align:left;
+}
+
+h1{
+color:#FF0000;
+text-align:center;
+}
+
+.listTitle{
+ font-size:large;
+}
+
+.listElements{
+ color:#3366FF
+}
\ No newline at end of file
diff --git a/test/modules/http2/htdocs/test1/006/006.js b/test/modules/http2/htdocs/test1/006/006.js
new file mode 100644
index 00000000000..b450067b530
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/006/006.js
@@ -0,0 +1,31 @@
+/**
+ * JavaScript Functions File
+ */
+function returnDate()
+{
+ var currentDate;
+ currentDate=new Date();
+ var dateString=(currentDate.getMonth()+1)+'/'+currentDate.getDate()+'/'+currentDate.getFullYear();
+ return dateString;
+}
+
+function returnHour()
+{
+ var currentDate;
+ currentDate=new Date();
+ var hourString=currentDate.getHours()+':'+currentDate.getMinutes()+':'+currentDate.getSeconds();
+ return hourString;
+}
+
+function javaScriptMessage(){
+ return 'This section is generated under JavaScript: ';
+}
+
+function mainJavascript(){
+ document.write(javaScriptMessage())
+ document.write('');
+ document.write('Current date (dd/mm/yyyy): ' + returnDate());
+ document.write(' ');
+ document.write(' Current time (hh:mm:ss): '+returnHour());
+ document.write(' ');
+}
\ No newline at end of file
diff --git a/test/modules/http2/htdocs/test1/006/header.html b/test/modules/http2/htdocs/test1/006/header.html
new file mode 100644
index 00000000000..bace20ee88b
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/006/header.html
@@ -0,0 +1 @@
+My Header Title
diff --git a/test/modules/http2/htdocs/test1/007.html b/test/modules/http2/htdocs/test1/007.html
new file mode 100644
index 00000000000..4db93e4c5a7
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/007.html
@@ -0,0 +1,21 @@
+
+
+
+
+HTML/2.0 Test File: 007
+
+
+ HTML/2.0 Test File: 007
+ This page is used to send data from the client to the server:
+
+
+
+
\ No newline at end of file
diff --git a/test/modules/http2/htdocs/test1/007/007.py b/test/modules/http2/htdocs/test1/007/007.py
new file mode 100644
index 00000000000..02b5466f96a
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/007/007.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import cgi, sys
+import cgitb; cgitb.enable()
+
+print "Content-Type: text/html;charset=UTF-8"
+print
+
+print """\
+
+ HTML/2.0 Test File: 007 (received data)
+ HTML/2.0 Test File: 007 """
+
+# alternative output: parsed form params <-> plain POST body
+parseContent = True # <-> False
+
+if parseContent:
+ print 'Data processed: '
+ form = cgi.FieldStorage()
+ for name in form:
+ print '', name, ': ', form[name].value, ' '
+ print ' '
+else:
+ print 'POST data output: '
+ data = sys.stdin.read()
+ print data
+ print ' '
+
+print ''
\ No newline at end of file
diff --git a/test/modules/http2/htdocs/test1/009.py b/test/modules/http2/htdocs/test1/009.py
new file mode 100644
index 00000000000..8fd9095af3b
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/009.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import cgi, sys, time
+import cgitb; cgitb.enable()
+
+print "Content-Type: text/html;charset=UTF-8"
+print
+
+print """\
+
+ HTML/2.0 Test File: 009 (server time)
+ HTML/2.0 Test File: 009
+ 60 seconds of server time, one by one.
"""
+
+for i in range(60):
+ s = time.strftime("%Y-%m-%d %H:%M:%S")
+ print "", s, "
"
+ sys.stdout.flush()
+ time.sleep(1)
+
+print "done.
"
\ No newline at end of file
diff --git a/test/modules/http2/htdocs/test1/alive.json b/test/modules/http2/htdocs/test1/alive.json
new file mode 100644
index 00000000000..93e7f959725
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/alive.json
@@ -0,0 +1,5 @@
+{
+ "host" : "test1",
+ "alive" : true
+}
+
diff --git a/test/modules/http2/htdocs/test1/apache.org-files/ant.jpg b/test/modules/http2/htdocs/test1/apache.org-files/ant.jpg
new file mode 100644
index 00000000000..2ebd7ad7172
Binary files /dev/null and b/test/modules/http2/htdocs/test1/apache.org-files/ant.jpg differ
diff --git a/test/modules/http2/htdocs/test1/apache.org-files/asf_logo.png b/test/modules/http2/htdocs/test1/apache.org-files/asf_logo.png
new file mode 100644
index 00000000000..07c0113c7bf
Binary files /dev/null and b/test/modules/http2/htdocs/test1/apache.org-files/asf_logo.png differ
diff --git a/test/modules/http2/htdocs/test1/apache.org-files/async-ads.js b/test/modules/http2/htdocs/test1/apache.org-files/async-ads.js
new file mode 100644
index 00000000000..eee04abfaf9
--- /dev/null
+++ b/test/modules/http2/htdocs/test1/apache.org-files/async-ads.js
@@ -0,0 +1,278 @@
+if(!window['googleNDT_']){window['googleNDT_']=(new Date()).getTime();}(function() {window.googleAltLoader=4;var version_='3.0';var hash_='1ac79f060b1e0868a225f2a9999fbf89c251fdf3';var module_='ads';var packages_='search';var googleApisBase_='//ajax.googleapis.com/ajax';var serviceBase_='//cse.google.com/uds';var serviceHost_='cse.google.com';var k;var aa=this,ba=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if("function"==b&&"undefined"==typeof a.call)return"object";return b},ca=function(a){return null!=a},da=function(a){return"string"==typeof a},ea=function(a,b,c){return a.call.apply(a.bind,arguments)},fa=function(a,b,c){if(!a)throw Error();if(2this.Mf&&(Mb("Tried to set int value to a number too large ( "+a+" = "+b+")","sIGVV"),c=this.Mf);0>c&&(Mb("Tried to set int value to a number too small ( "+a+" = "+b+")","sIGVV"),c=0);return c};k.Ga=m(x.prototype.Ga,"fssiGVV");k.Db=function(){return this.value||0};k.Db=m(x.prototype.Db,"fssiTB");k.Ub=function(a){return a};k.Ub=m(x.prototype.Ub,"fssiPFB");
+k.Ra=function(){return this.value+""};k.Ra=m(x.prototype.Ra,"fssiTES");k.Oa=function(a){return parseInt(a,10)};k.Oa=m(x.prototype.Oa,"fssiPES");var Ib=function(){this.lb=this.value=null;this.U=!1},Ib=m(Ib,"fsES");k=Ib.prototype;k.Td=2;k.Ga=function(a,b){return b=b?b.toString():""};k.Ga=m(Ib.prototype.Ga,"fsesGVV");k.Ra=function(){return this.value?encodeURIComponent(this.value):""};k.Ra=m(Ib.prototype.Ra,"fsesTES");k.Oa=function(a){return decodeURIComponent(a)};k.Oa=m(Ib.prototype.Oa,"fsesPES");
+var Lb=[Jb,x,Ib],Nb=function(a){null==Hb&&Kb();return Hb.Qa(a)},Nb=m(Nb,"fsSC"),Pb=function(a,b){null==Hb&&Kb();null==t&&(t={},Ob());a.Ua=b;t[a.sessionId]=a},Pb=m(Pb,"fsLFC"),Ob=function(){window.setInterval(Qb,500);Hb.Ha()},Ob=m(Ob,"fsIL"),Qb=function(){for(var a in t)if(t.hasOwnProperty(a)){var b=t[a];b.Rb()||(b.Ua=null,delete t[a])}},Qb=m(Qb,"fsCDI"),Kb=function(){A.Oe();Hb=A.af?A:ra()?z:B},Kb=m(Kb,"fsLT"),z={Jf:"exists",Qa:function(a){if(!a.U)return!0;for(var b in a.state)if(a.state.hasOwnProperty(b)){var c=
+a.state[b];if(c.U&&c.Db){var d=c.Tc,e=c.Db(),f=b+":";z.Md(f+z.Jf);for(var g=0,h=1;g")&&(a=a.replace(ac,">"));-1!=a.indexOf('"')&&(a=a.replace(bc,"""));-1!=a.indexOf("'")&&(a=a.replace(cc,"'"));-1!=a.indexOf("\x00")&&(a=a.replace(dc,""));return a},Zb=/&/g,$b=//g,bc=/"/g,cc=/'/g,dc=/\x00/g,Yb=/[\x00&<>"']/,
+fc=function(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^ia()).toString(36)},gc=function(a,b){return ab?1:0};var hc=Array.prototype.filter?function(a,b,c){return Array.prototype.filter.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=[],f=0,g=da(a)?a.split(""):a,h=0;h]*>|&[^;]+;/g,kc=function(a,b){return b?a.replace(jc,""):a},lc=RegExp("[A-Za-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u0300-\u0590\u0800-\u1fff\u200e\u2c00-\ufb1c\ufe00-\ufe6f\ufefd-\uffff]"),mc=RegExp("^[^A-Za-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u0300-\u0590\u0800-\u1fff\u200e\u2c00-\ufb1c\ufe00-\ufe6f\ufefd-\uffff]*[\u0591-\u06ef\u06fa-\u07ff\u200f\ufb1d-\ufdff\ufe70-\ufefc]"),nc=/^http:\/\/.*/,oc=/\s+/,pc=/[\d\u06f0-\u06f9]/;var rc=function(){this.Kj="";this.$h=qc},qc={};var tc=function(){this.df="";this.ai=sc};tc.prototype.ve=function(){return 1};var uc=function(a){return a instanceof tc&&a.constructor===tc&&a.ai===sc?a.df:"type_error:SafeUrl"},sc={};var wc=function(){this.Lj="";this.bi=vc};wc.prototype.ve=function(){return 1};var xc=function(a){return a instanceof wc&&a.constructor===wc&&a.bi===vc?a.Lj:"type_error:TrustedResourceUrl"},vc={};var zc=function(){this.df="";this.Zh=yc;this.Ii=null};zc.prototype.ve=function(){return this.Ii};var yc={};var Ac=function(){return null},Bc=function(a){var b=arguments,c=b.length;return function(){for(var a,e=0;eparseFloat(a))?String(b):a}(),Qc={},Rc=function(a){var b;if(!(b=Qc[a])){b=0;for(var c=Xb(String(Pc)).split("."),d=Xb(String(a)).split("."),e=Math.max(c.length,d.length),f=0;0==b&&f"+b,d.removeChild(d.firstChild)):d.innerHTML=b;if(1==d.childNodes.length)d=d.removeChild(d.firstChild);else{for(c=c.createDocumentFragment();d.firstChild;)c.appendChild(d.firstChild);d=c}return d};Xc.prototype.appendChild=function(a,b){a.appendChild(b)};
+Xc.prototype.contains=function(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a};E&&Rc(8);var ad={},bd={},cd={},dd={},ed={},fd={},gd=function(){throw Error("Do not instantiate directly");};gd.prototype.Ba=null;gd.prototype.toString=function(){return this.content};var hd=function(){gd.call(this)};ja(hd,gd);var id=function(a,b){return null!=a&&a.Ya===b},jd=function(a){if(null!=a)switch(a.Ba){case 1:return 1;case -1:return-1;case 0:return 0}return null},kd=function(){gd.call(this)};ja(kd,gd);kd.prototype.Ya=ad;var G=function(a){return null!=a&&a.Ya===ad?a:a instanceof zc?F(a instanceof zc&&a.constructor===zc&&a.Zh===yc?a.df:"type_error:SafeHtml",a.ve()):F(ec(String(String(a))),jd(a))},ld=function(){gd.call(this)};ja(ld,gd);ld.prototype.Ya={};ld.prototype.Ba=1;var md=function(){gd.call(this)};ja(md,gd);
+md.prototype.Ya=bd;md.prototype.Ba=1;var nd=function(){gd.call(this)};ja(nd,gd);nd.prototype.Ya=cd;nd.prototype.Ba=1;var od=function(){gd.call(this)};ja(od,gd);od.prototype.Ya=dd;od.prototype.Ba=1;var pd=function(){gd.call(this)};ja(pd,gd);pd.prototype.Ya=ed;pd.prototype.Ba=1;var qd=function(a,b){this.content=String(a);this.Ba=null!=b?b:null};ja(qd,hd);qd.prototype.Ya=fd;
+var rd=function(a){function b(a){this.content=a}b.prototype=a.prototype;return function(a){return new b(String(a))}},F=function(a){function b(a){this.content=a}b.prototype=a.prototype;return function(a,d){var e=new b(String(a));void 0!==d&&(e.Ba=d);return e}}(kd);rd(ld);var sd=rd(md);rd(nd);
+var td=rd(od),ud=rd(pd),vd=function(a,b){function c(){}c.prototype=a;var d=new c,e;for(e in b)d[e]=b[e];return d},wd=function(a){function b(a){this.content=a}b.prototype=a.prototype;return function(a){return(a=String(a))?new b(a):""}},xd=function(a){return(a=String(a))?new qd(a,void 0):""},I=function(a){function b(a){this.content=a}b.prototype=a.prototype;return function(a,d){var e=String(a);if(!e)return"";e=new b(e);void 0!==d&&(e.Ba=d);return e}}(kd);wd(ld);wd(nd);wd(md);wd(od);
+var yd=wd(pd),K=function(a){return G(a)},zd=function(a){return a.replace(/<\//g,"<\\/").replace(/\]\]>/g,"]]\\>")},M=function(a){return id(a,ad)?(a=String(a.content).replace(Ad,"").replace(Bd,"<"),String(a).replace(Cd,Dd)):ec(String(a))},Fd=function(a){if(id(a,dd))return a.content.replace(/([^"'\s])$/,"$1 ");a=String(a);a=Ed.test(a)?a:"zSoyz";return a},Id=function(a){return String(a).replace(Gd,Hd)},O=function(a){if(id(a,bd)||id(a,cd))return String(a).replace(Gd,Hd);a instanceof tc?a=Id(uc(a)):
+a instanceof wc?a=Id(xc(a)):(a=String(a),a=Jd.test(a)?a.replace(Gd,Hd):"#zSoyz");return a},Ld=function(a){if(id(a,bd)||id(a,cd))return String(a).replace(Gd,Hd);a instanceof tc?a=Id(uc(a)):a instanceof wc?a=Id(xc(a)):(a=String(a),a=Kd.test(a)?a.replace(Gd,Hd):"about:invalid#zSoyz");return a},P=function(a){if(id(a,ed))return zd(a.content);null==a?a="":a instanceof rc?(a=a instanceof rc&&a.constructor===rc&&a.$h===qc?a.Kj:"type_error:SafeStyle",a=zd(a)):(a=String(a),a=Md.test(a)?a:"zSoyz");return a},
+Q=function(a){return id(a,fd)?"zSoyz":a},Nd=function(a){var b=jd(a);if(null==b){var c=b=0,d=!1;a=kc(a+"",id(a,ad)).split(oc);for(var e=0;e":">","`":"`","\u0085":"
",
+"\u00a0":" ","\u2028":"
","\u2029":"
"},Dd=function(a){return Od[a]},Pd={"\x00":"%00","\u0001":"%01","\u0002":"%02","\u0003":"%03","\u0004":"%04","\u0005":"%05","\u0006":"%06","\u0007":"%07","\b":"%08","\t":"%09","\n":"%0A","\x0B":"%0B","\f":"%0C","\r":"%0D","\u000e":"%0E","\u000f":"%0F","\u0010":"%10","\u0011":"%11","\u0012":"%12","\u0013":"%13","\u0014":"%14","\u0015":"%15","\u0016":"%16","\u0017":"%17","\u0018":"%18","\u0019":"%19","\u001a":"%1A","\u001b":"%1B","\u001c":"%1C",
+"\u001d":"%1D","\u001e":"%1E","\u001f":"%1F"," ":"%20",'"':"%22","'":"%27","(":"%28",")":"%29","<":"%3C",">":"%3E","\\":"%5C","{":"%7B","}":"%7D","\u007f":"%7F","\u0085":"%C2%85","\u00a0":"%C2%A0","\u2028":"%E2%80%A8","\u2029":"%E2%80%A9","\uff01":"%EF%BC%81","\uff03":"%EF%BC%83","\uff04":"%EF%BC%84","\uff06":"%EF%BC%86","\uff07":"%EF%BC%87","\uff08":"%EF%BC%88","\uff09":"%EF%BC%89","\uff0a":"%EF%BC%8A","\uff0b":"%EF%BC%8B","\uff0c":"%EF%BC%8C","\uff0f":"%EF%BC%8F","\uff1a":"%EF%BC%9A","\uff1b":"%EF%BC%9B",
+"\uff1d":"%EF%BC%9D","\uff1f":"%EF%BC%9F","\uff20":"%EF%BC%A0","\uff3b":"%EF%BC%BB","\uff3d":"%EF%BC%BD"},Hd=function(a){return Pd[a]},Cd=/[\x00\x22\x27\x3c\x3e]/g,Gd=/[\x00- \x22\x27-\x29\x3c\x3e\\\x7b\x7d\x7f\x85\xa0\u2028\u2029\uff01\uff03\uff04\uff06-\uff0c\uff0f\uff1a\uff1b\uff1d\uff1f\uff20\uff3b\uff3d]/g,Md=/^(?!-*(?:expression|(?:moz-)?binding))(?:[.#]?-?(?:[_a-z0-9-]+)(?:-[_a-z0-9-]+)*-?|-?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[a-z]{1,2}|%)?|!important|)$/i,Jd=/^(?![^#?]*\/(?:\.|%2E){2}(?:[\/?#]|$))(?:(?:https?|mailto):|[^&:\/?#]*(?:[\/?#]|$))/i,
+Kd=/^[^&:\/?#]*(?:[\/?#]|$)|^https?:|^data:image\/[a-z0-9+]+;base64,[a-z0-9+\/]+=*$|^blob:/i,Ed=/^(?!on|src|(?:style|action|archive|background|cite|classid|codebase|data|dsync|href|longdesc|usemap)\s*$)(?:[a-z0-9_$:-]*)$/i,Ad=/<(?:!|\/?([a-zA-Z][a-zA-Z0-9:\-]*))(?:[^>'"]|"[^"]*"|'[^']*')*>/g,Bd=/"+G(a.content)+"")};if(window.IS_GOOGLE_AFS_IFRAME_){var Td=1,R=function(){return"e"+Td++},Ud=function(a){this.Cb=a};Ud.prototype.j=function(){return this.Cb};var S=new Ud("");S.G=function(){return[]}};if(window.IS_GOOGLE_AFS_IFRAME_)var Vd=function(a,b,c,d,e,f,g,h,l,r,u,y,C,H,J){this.eb=a;this.za=b;this.xi=c;this.Jb=d;this.me=e;this.Te=f;this.yb=g;this.xk=h;this.f=l;this.A=r;this.yj=u;this.bk=y;this.Y=C;this.ac=H;this.xg=!1;this.sg=J};var Wd=function(a,b){if(a.classList)return a.classList.contains(b);for(var c=a.className.split(" "),d=0;d"+
+a+" ";var c;try{c=b.firstChild.firstChild.firstChild}catch(d){return null}return 1==c.nodeType&&"tr"==c.tagName.toLowerCase()?c:null},be=function(a){var b=a.parentNode,c=a.nextSibling,d=document.createElement("div");d.appendChild(a);b&&(c?b.insertBefore(d,c):b.appendChild(d));return d};var U=function(a,b,c){if(a.addEventListener)a.addEventListener(b,c,!1);else if(a.attachEvent)a.attachEvent("on"+b,c);else{var d=a["on"+b];a["on"+b]=null!=d?Bc(c,d):c}},ce=function(a,b){U(a,"mousedown",b);U(a,"mousedown",function(a,b,e){var f=!1;return function(){f||(a.removeEventListener?a.removeEventListener(b,e,!1):a.detachEvent&&a.detachEvent("on"+b,e),f=!0)}}(a,"mousedown",b))};var de=function(a){de[" "](a);return a};de[" "]=function(){};E&&Rc("9");!Mc||Rc("528");Lc&&Rc("1.9b")||E&&Rc("8")||Jc&&Rc("9.5")||Mc&&Rc("528");Lc&&!Rc("8")||E&&Rc("9");var ee=function(a,b,c,d,e,f,g,h){this.Rc=a;this.Ef=b;this.Cf=c;this.Ff=d;this.Df=e;this.Gf=f;this.Rd=g;this.Hf=h};ee.prototype.clone=function(){return new ee(this.Rc,this.Ef,this.Cf,this.Ff,this.Df,this.Gf,this.Rd,this.Hf)};
+var fe=function(a,b){if(0==b)return a.Rc;if(1==b)return a.Rd;var c=Cc(a.Rc,a.Cf,b),d=Cc(a.Cf,a.Df,b),e=Cc(a.Df,a.Rd,b),c=Cc(c,d,b),d=Cc(d,e,b);return Cc(c,d,b)},he=function(a){var b=ge,c=(a-b.Rc)/(b.Rd-b.Rc);if(0>=c)return 0;if(1<=c)return 1;for(var d=0,e=1,f=0;8>f;f++){var g=fe(b,c),h=(fe(b,c+1E-6)-g)/1E-6;if(1E-6>Math.abs(g-a))return c;if(1E-6>Math.abs(h))break;else gf;f++)g Nd(a.text),f:a.f}))},ne=function(a){return F(0 '+G(a.text)+""+(a.f?"":""):"")};var qe=function(a){return F('"+K(oe(a))+" ")},re=function(a){return F('"+(a.Zi?"":''+K(oe(a))+" "))},se=function(a){return F('"+K(ne({text:a.text,Ia:!1,f:a.f}))+" ")},te=function(a){var b=F,c;c=a.wh;var d=a.xh;a=a.f;var e="";if(d&&0'+G(c)+"")},ue=function(a){return F('"+te(a)+" ")},ve=function(a){return F(""+
+G(a.Ka)+"
"+G(a.La)+" "+G(a.Ad))},we=function(a){return F(""+G(a.Ka)+"
"+G(a.La))},xe=function(a){var b,c="",d=b=a.eb,e=typeof d;switch("object"==e&&null!=d||"function"==e?b.toString():b){case 1:c+="oneLine";break;case 2:c+="twoLine";break;case 3:c+="threeLine"}c=xd(c);a=""+('"+G(a.content)+"
");return F(a)};var ye=function(a){var b=Yc(a),c=new Vc(0,0),d;d=b?Yc(b):document;var e;(e=!E||9<=Uc)||(e="CSS1Compat"==Zc(d).qc.compatMode);if(a==(e?d.documentElement:d.body))return c;var f;a:{try{f=a.getBoundingClientRect()}catch(g){f={left:0,top:0,right:0,bottom:0};break a}E&&a.ownerDocument.body&&(a=a.ownerDocument,f.left-=a.documentElement.clientLeft+a.body.clientLeft,f.top-=a.documentElement.clientTop+a.body.clientTop)}a=Zc(b).qc;b=a.scrollingElement?a.scrollingElement:Mc||"CSS1Compat"!=a.compatMode?a.body||
+a.documentElement:a.documentElement;a=a.parentWindow||a.defaultView;b=E&&Rc("10")&&a.pageYOffset!=b.scrollTop?new Vc(b.scrollLeft,b.scrollTop):new Vc(a.pageXOffset||b.scrollLeft,a.pageYOffset||b.scrollTop);c.x=f.left+b.x;c.y=f.top+b.y;return c};var ze=function(a){return F(""+G(a.text)+" ")};if(window.IS_GOOGLE_AFS_IFRAME_){var Ae=function(a,b){this.ki=a;this.D=b||ze};Ae.prototype.j=function(){return this.D({text:this.ki,ca:null})}};var Be=function(a){var b="";a=a.elements;for(var c=a.length,d=0;d';a=a.Jc;for(var c=a.length,d=0;d")};if(window.IS_GOOGLE_AFS_IFRAME_){var Ee=function(a,b){this.F=R();this.qb=a;this.D=b||De};Ee.prototype.j=function(){for(var a=[],b=0;b^<]*>/g,"")},Le=function(a){var b=a.offsetWidth;if(!Ge())return b;var c=document.defaultView||{};c&&c.getComputedStyle?(a=c.getComputedStyle(a,!1),b-=He(a.getPropertyValue("padding-left"))+He(a.getPropertyValue("padding-right"))):(a=a.currentStyle,b-=He(a.paddingLeft)+He(a.paddingRight));return b},Me=function(a){var b=a.cloneNode(!0);b.style.visibility="hidden";b.style.position="absolute";if(ra()){var c=a.ownerDocument.createElement("div");
+c.style.visibility="hidden";c.style.position="relative";c.style.width="9999px";c.appendChild(b);a.parentNode.appendChild(c)}else b.style.top="0",b.style.whiteSpace="nowrap",a.parentNode.appendChild(b);a=new Wc(b.offsetWidth,b.offsetHeight);ra()?c.parentNode.removeChild(c):b.parentNode.removeChild(b);return a},Ne=function(){var a=document.createElement("div");a.innerHTML=" ";return"http://www.w3.org/2000/svg"==(a.firstChild&&a.firstChild.namespaceURI)};var Oe=/([?|&]{1}nm=)([\d]{1,})/,Pe=/(\?|&)clkt=-?[\d]*/g,Qe=/[&\?]nb=\d/,Re=/(\?|&)nx=-?[\d]+/g,Se=/(\?|&)ny=-?[\d]+/g,Ue=function(a){return function(){for(var b=0;ba.length+b.length&&(a+=b+encodeURIComponent(c),1950'),c=a.Jc,d=c.length,e=0;e'+G(f)+"");b+=""}return F(b)},lf=function(a){var b=F;if("jfkButton"==a.Y){var c=a.ij,d=a.text;a=F(K(Sd({href:a.url,A:a.A,qa:"grayJfkButton",content:I((c?' ':
+"")+''+G(d)+" ")})))}else a='";return b(a)};var mf=function(a){var b=a.rb?"right":"left";a=""+('");return F(a)},nf=function(a){var b=a.rb?"right":"left";return a=""+('")},of=function(a){var b=
+a.f?"right":"left";a=""+('");return F(a)};if(window.IS_GOOGLE_AFS_IFRAME_){var pf=function(a,b,c,d,e,f,g,h){this.F=R();this.va=a;this.aj=b;this.jj=c;this.Cb=d;this.ui=e;this.I=f;this.W=g;this.D=h||lf};pf.prototype.j=function(){return this.D({uid:this.F,url:this.va,zg:this.aj,ij:this.jj,text:this.Cb,Y:this.ui,f:this.I,A:this.W})};var qf=function(a,b,c,d,e){"svgIcon"==c&&(c=Ne()?c+"Ctc":"pngIcon");return new pf(a,(window._googCsaAlwaysHttps?"https:":"")+"//www.google.com/images/afs/mobile/button_ctc.png",(window._googCsaAlwaysHttps?"https:":
+"")+"//www.google.com/images/afs/mobile/gray_phone_icon.png",b,c,d,e,void 0)},rf=function(a,b,c,d,e){"svgIcon"==c&&(c=Ne()?c+"Ctd":"pngIcon");return new pf(a,(window._googCsaAlwaysHttps?"https:":"")+"//www.google.com/images/afs/mobile/"+(c?"ctd_get_app.png":"ctd-dl-icon.png"),"",b,c,e,d,void 0)},sf=function(a,b){var c=[];a.ctc&&c.push(qf(a.ctc.u,a.ctc.bt,b.Y,b.f,b.A));a.ctd&&c.push(rf(a.u,a.ctd.ps,b.Y,b.f,b.A));!(1<=c.length)||b.Y||a.ctc&&a.ctc.coa||a.ctd||c.push(new pf(a.u,(window._googCsaAlwaysHttps?
+"https:":"")+"//www.google.com/images/afs/mobile/button_visit_site.png","",b.xk,"",b.f,b.A,void 0));return c},tf=function(a,b,c,d){this.Nc=a;this.jc=b;this.o=c;this.D=d||of};tf.prototype.j=function(){var a={Da:this.jc.j(),Ea:this.Nc.j(),Z:this.o.ac?60:78,Li:"jfkButton"==this.o.Y?"top":"middle",ga:12,borderColor:"jfkButton"==this.o.Y||this.o.ac?"":"#DDDDDD",f:this.o.f};return this.D(a)};tf.prototype.M=function(a,b){this.Nc.M&&this.Nc.M(a,b);this.jc.M&&this.jc.M(a,b)};tf.prototype.G=function(a){var b=
+[];this.Nc.G&&(b=b.concat(this.Nc.G(a)));this.jc.G&&(b=b.concat(this.jc.G(a)));return b};var uf=function(a,b,c){b=sf(b,c);return 1==b.length?new tf(a,b[0],c,void 0):a},vf=function(a,b){var c=sf(a,b);return 1a?b=0:.8a&&(.2>=c&&(g.style.paddingBottom="3px"),.95<=c?g.style.paddingBottom="1px":.85<=c&&(g.style.paddingBottom="2px"));g&&1==c&&(g.style.paddingBottom="");if(window.onresize)window.onresize();f.style.opacity=b},l=function(a){var b=2*(.5-a);.5 a&&(c=1);f.style.height=e*c+"px";f.style.opacity=b;if(window.onresize)window.onresize()},r=new ke(350);return function(){r.$a||(Wd(b,"collapsed")?(r.Gb=h,Xd(b,"collapsed"),d&&Xd(d,"collapsed")):(r.Gb=l,Yd(b,
+"collapsed"),d&&Yd(d,"collapsed")),le(r))}};var Af=function(a){return F(''+G(a.Ka)+"
"+yf({content:I('
'+(!a.J||!a.O||a.$&&a.V?"":zf({J:a.J,O:a.O,xd:!0}))+G(a.La)+'
'+G(a.Ad)+"
"),f:a.f,$:a.$,V:a.V,sa:a.sa,ra:a.ra,Z:a.$&&a.V?45:0,ga:0,rb:a.f,J:a.J,O:a.O})+"
")},Bf=function(a){return F(''+G(a.Ka)+"
"+yf({content:I('
'+
+(!a.J||!a.O||a.$&&a.V?"":zf({J:a.J,O:a.O,xd:!0}))+'
'+G(a.La)+"
"),f:a.f,$:a.$,V:a.V,sa:a.sa,ra:a.ra,Z:a.$&&a.V?45:0,ga:0,rb:a.f,J:a.J,O:a.O})+"
")},Cf=function(a){return F(""+(a.$&&a.V?'
':"")+G(a.nj)+(a.J&&a.O?" "+zf({J:a.J,O:a.O,xd:!0}):"")+G(a.oj)+"
")},yf=function(a){return F(K(mf({Da:I(""+
+(a.$&&a.V?''+(a.J&&a.O?zf({J:a.J,O:a.O,xd:!1}):"")+"
":"")),Ea:I(""+G(a.content)),Z:a.Z,ga:a.ga,rb:a.f})))},zf=function(a){return F('")};var Df=function(a){return F(' ')},Ef=function(a){return F('')};if(window.IS_GOOGLE_AFS_IFRAME_){var Gf=function(a){return a.adIconUrl&&"title-right"==a.adIconLocation?new Ff(a.adIconUrl,a.img?Df:Ef):S},Ff=function(a,b){this.ek=a;this.D=b};Ff.prototype.j=function(){return this.D({ya:this.ek})}};var Hf=function(a){return F((a.Ng?F(' '):"")+''+K(pe({text:a.Hd,f:a.f}))+"
")};if(window.IS_GOOGLE_AFS_IFRAME_){var If=function(a,b,c){this.Ic=a;this.I=b;this.D=c||Hf};If.prototype.j=function(){return this.D({Hd:this.Ic,f:this.I,Ng:!0})}};var Kf=function(a){return""+Jf({text:a.text.c,Ia:a.text.rtl,f:a.f})},Jf=function(a){return''+Q(a.text)+" "+(a.f?"":"")};var Lf=function(a){return F(a.Ne?""+K(pe({text:a.Ne,f:a.f}))+"
":"")};if(window.IS_GOOGLE_AFS_IFRAME_){var Mf=function(a,b,c){this.F=R();this.Cb=a;this.I=b;this.D=c||Lf};Mf.prototype.j=function(){return this.D({uid:this.F,Ne:this.Cb,f:this.I})};var Nf=function(a,b){return a.location?new Mf(a.location,b.f):S}};if(window.IS_GOOGLE_AFS_IFRAME_){var Pf=function(a,b,c,d){this.F=R();this.xa=a;this.Ce=b;this.zk=c;this.D=d||Of};Pf.prototype.j=function(){return this.D({uid:this.F,Gd:this.xa,tb:this.Ce,Hh:this.zk})};var Qf=function(a,b){var c=a.gt&&"oh"==a.gt.r&&a.gt.t?a.gt.t:null;return a.oh&&0 ",c=a.$e,d=c.length,e=0;e"}return F(b)};if(window.IS_GOOGLE_AFS_IFRAME_){var Sf=function(a,b,c,d){this.F=R();this.jk=a;this.W=b;this.I=c;this.D=d||Rf};Sf.prototype.j=function(){return this.D({uid:this.F,$e:this.jk,A:this.W,f:this.I})};var Uf=function(a,b){return a.plus_ones?new Sf(Tf(a),b.A,b.f):S},Tf=function(a){var b=[];if(a.plus_ones)for(var c=0,d=a.plus_ones.length;c ('+K(Sd({href:a.Mc.u,content:Math.round(10*a.Mc.r)/10,A:a.A,qa:"sr-gt sr-gl"}))+") ":"")},Xf=function(a){for(var b='',c=a.ik,d=c.length,e=0;e
':"LINK_START"==f?'":"LINK_END"==f?" ":"NUM_START"==f?'':"NUM_END"==
+f?" ":K(pe({text:f,f:a.f})));return F(b+" ")},Vf=function(a){return F(' ')};if(window.IS_GOOGLE_AFS_IFRAME_){var Yf=function(a,b,c,d,e,f){this.F=R();this.Cb=a;this.W=b;this.Pa=c;this.va=d;this.I=e;this.D=f||Xf};Yf.prototype.j=function(){return this.D({uid:this.F,ik:this.Cb,A:this.W,r:this.Pa,vk:this.va,f:this.I})};var Zf=function(a,b){if(a.ctd&&a.ctd.r&&a.ctd.nr&&b.ac){var c=a.ctd.r;return new Yf(["NUM_START",c,"NUM_END","RATING"," ","("+a.ctd.nr+")"],!1,c,"",b.f)}return a.sr&&a.sr.nt&&a.sr.r&&a.sr.u?new Yf(a.sr.nt,b.A,a.sr.r,a.sr.u,b.f):S}};var ag=function(a){var b="";if(a.qf&&0'),c=a.qf,d=c.length,e=0;e";c=a.ck;d=c.length;for(e=0;e ";if(a.Te&&a.na&&0';c=a.na;d=c.length;for(e=0;e"}}return F(b)},
+$f=function(a){return F("")},bg=function(a){for(var b='',c=a.na,d=c.length,e=0;e");return F(b+" ")},cg=function(a){return F(''+bg({na:a.na,A:a.A,ig:2,pf:a.qh})+'
'+bg({na:a.na.slice(0,3),A:a.A,ig:1,pf:a.nh})+"
")},dg=function(a){return F(''+cg({uid:a.uid,na:a.na,A:a.A,qh:"sitelinksTruncatedWide",nh:"sitelinksTruncatedNarrow",Ih:"nonSfblSitelinksWrapper"})+
+"
")};if(window.IS_GOOGLE_AFS_IFRAME_){var eg=function(a,b,c,d,e){this.F=R();this.$b=a;this.W=b;this.Qj=c;this.I=d;this.D=e||ag};eg.prototype.j=function(){for(var a=[],b=[],c=0;c',c=a.be,d=c.length,e=0;e'+(0!=e?"· ":"")+K(pe({text:c[e],f:a.f}))+"";b+=""}return F(b)};if(window.IS_GOOGLE_AFS_IFRAME_){var jg=function(a,b,c){this.vi=a;this.I=b;this.D=c||ig};jg.prototype.j=function(){return this.D({be:this.vi,f:this.I})};var kg=function(a,b){return a.cos&&0d&&(c=c.substring(0,d-3)+"...");a.nodeValue=c;return!1}c=a.textContent||a.innerText;if(!c||c.length<=(b?0:4))return a.parentNode.removeChild(a),!0;for(c=lg(a.lastChild,b);c;)c=lg(a.lastChild,c);return!1},mg=function(a,b){if(!(0>=b)){for(var c=a.innerHTML.length;0b;c--)for(var d=a,e=lg(d.lastChild,!1);e;)e=lg(d.lastChild,
+e);a.offsetHeight>b&&(a.innerHTML="")}},ng=function(a,b){var c=a.style.whiteSpace,d=a.style.wordWrap;a.style.whiteSpace="nowrap";a.style.wordWrap="normal";var e=a.offsetHeight;a.style.whiteSpace=c;a.style.wordWrap=d;mg(a,e*b+b)},og=function(a,b,c,d,e){var f=a.offsetHeight;if(!(f<=b)){var g=be(a);a=be(g);g.style.overflow="hidden";g.style.position="relative";var h=document.createElement("div");try{h.style.backgroundImage="linear-gradient(to bottom, rgba(255,255,255,0), #ffffff)"}catch(L){}h.style.height=
+"30px";h.style.position="absolute";h.style.bottom=0;h.style.width="100%";h.style.pointerEvents="none";g.appendChild(h);var l=document.createElement("div");l.innerHTML=c;l.className="expander";l.style.textAlign="center";l.style.color=e;l.style.cursor="pointer";l.style.fontSize="11px";a.appendChild(l);var r=b-l.offsetHeight;g.style.height=r+"px";var u=f-r,y=document.getElementById("adBlock"),C=function(a){var b=y?y.offsetHeight:null;g.style.height=r+a*u+"px";.8<=a&&(l.innerHTML=d,h.style.background=
+"");y&&b&&y.offsetHeight>b&&(y&&.2>=a&&(y.style.paddingBottom="4px"),y&&.98<=a?y.style.paddingBottom="1px":y&&.97<=a?y.style.paddingBottom="2px":y&&.96<=a&&(y.style.paddingBottom="3px"));y&&1==a&&(y.style.paddingBottom="");if(window.onresize)window.onresize()},H=function(a){g.style.height=f-a*u+"px";if(.2>=a)try{h.style.backgroundImage="linear-gradient(to bottom, rgba(255,255,255,0), #ffffff)"}catch(b){}.8<=a&&(l.innerHTML=c);if(window.onresize)window.onresize()},J=new ke(400);U(l,"click",function(){J.$a||
+l.innerHTML!=c?J.$a||(J.Gb=H,le(J)):(J.Gb=C,le(J))})}};if(window.IS_GOOGLE_AFS_IFRAME_){var pg=function(a,b,c){ng(T(a.document,b),2);U(a,"resize",function(){var d=T(a.document,b);d.innerHTML=c;ng(d,2)})},qg=function(a,b,c,d,e,f,g,h,l,r,u,y,C,H){this.F=R();this.P=a;this.T=b;this.ob=R();this.R=c;this.zc=d;this.vb=e;this.oa=f;this.vc=g;this.Dc=h;this.Cc=l;this.Ac=r;this.Pa=u;this.zb=y;this.I=C;this.fa=H||Af;this.Fb=R();this.Ca=R()};qg.prototype.j=function(){var a=Be({elements:[this.oa.j(),this.R.j()]}),b=Be({elements:[this.P.j(),this.vb.j()]}),c=this.zc?
+a:this.T.j(),d=this.zc?this.T.j():a,a=this.fa({Ka:b,La:c,Ad:d,Eb:this.F,oc:this.ob,$:this.vc,V:this.Dc,sa:this.Cc,ra:this.Ac,J:this.Pa,O:this.zb,Lc:!1,f:this.I}),b=this.fa({Ka:b,La:c,Ad:d,Eb:this.Fb,oc:this.Ca,J:this.Pa,O:this.zb,Lc:!0,f:this.I});return Be({elements:[a,b]})};qg.prototype.M=function(a){var b=T(a.document,this.ob).innerHTML;pg(a,this.ob,b);this.Ca&&(b=T(a.document,this.Ca).innerHTML,pg(a,this.Ca,b));this.Fb&&U(a,"resize",wf(a,this.F,this.Fb))};qg.prototype.G=function(a){return this.P.G(a).concat(this.R.G(a))};
+var rg=function(a,b,c,d,e,f,g,h,l,r,u,y,C){this.F=R();this.P=a;this.T=b;this.ob=R();this.R=c;this.vb=d;this.oa=e;this.vc=f;this.Dc=g;this.Cc=h;this.Ac=l;this.Pa=r;this.zb=u;this.I=y;this.fa=C||Bf;this.Fb=R();this.Ca=R()};rg.prototype.j=function(){var a=Be({elements:[this.P.j(),this.vb.j()]}),b=Be({elements:[this.oa.j()," ",this.R.j()," ",this.T.j()]}),c=this.fa({Ka:a,La:b,Eb:this.F,oc:this.ob,$:this.vc,V:this.Dc,sa:this.Cc,ra:this.Ac,J:this.Pa,O:this.zb,Lc:!1,f:this.I}),a=this.fa({Ka:a,La:b,Eb:this.Fb,
+oc:this.Ca,J:this.Pa,O:this.zb,Lc:!0,f:this.I});return Be({elements:[c,a]})};rg.prototype.M=function(a){var b=T(a.document,this.ob).innerHTML;pg(a,this.ob,b);this.Ca&&(b=T(a.document,this.Ca).innerHTML,pg(a,this.Ca,b));this.Fb&&U(a,"resize",wf(a,this.F,this.Fb))};rg.prototype.G=function(a){return this.P.G(a).concat(this.R.G(a))};var sg=function(a,b,c,d,e,f,g,h,l,r,u){this.P=a;this.T=b;this.R=c;this.oa=d;this.vc=e;this.Dc=f;this.Cc=g;this.Ac=h;this.Pa=l;this.zb=r;this.fa=u||Cf};sg.prototype.j=function(){var a=
+Be({elements:[this.oa.j()," ",this.P.j()," "]}),b=Be({elements:[" ",this.T.j()," ",this.R.j()]});return this.fa({nj:a,oj:b,$:this.vc,V:this.Dc,sa:this.Cc,ra:this.Ac,J:this.Pa,O:this.zb})};sg.prototype.G=function(a){return this.P.G(a).concat(this.R.G(a))}};if(window.IS_GOOGLE_AFS_IFRAME_){var yg=function(a,b,c,d,e){this.F=R();this.gc=a;this.caps_=b;this.o=c;this.D=e||tg;d=[];c.Y&&1!=c.eb&&(e=df(a,c),e=new Ee([e,Gf(a)]),d.push(new af(e,a,c)));e=c.Y&&1!=c.eb?S:df(a,c);var f=c.Y&&1!=c.eb?S:Gf(a),g=jf(a,c),h=gf(a,c);if(a.ctd){var l=a.ctd.iu;if(l)var r=a.ctd.ih>a.ctd.iw?"height":"width",u=a.u,y=a.ctd.ir;else y=u=r=void 0;var C=a.ctd.r,H=a.ctd.nr;switch(c.eb){case 1:e=new sg(e,h,g,c.yb,l,r,u,y,C,H);break;case 2:e=new rg(e,h,g,f,c.yb,l,r,u,y,C,H,c.f);break;
+default:e=new qg(e,h,g,c.me,f,c.yb,l,r,u,y,C,H,c.f)}}else switch(c.eb){case 1:e=new ug(e,h,g,c.yb);break;case 2:e=new vg(e,h,g,f,c.yb);break;default:e=new wg(e,h,g,a.pn?new If(a.pn,c.f):S,c.me,f,c.yb)}e=new af(e,a,c);b=xg(a,b,c);c.Y?(b=new Ee([e].concat(b)),d.push(uf(b,a,c))):(d.push(uf(e,a,c)),d=d.concat(b));this.$c=new Ee(d);this.Wf=R()};yg.prototype.j=function(){var a={uid:this.F,B:this.gc,A:this.o.A,fi:this.$c.j(),Jb:this.o.za||this.o.Jb,Vf:this.Wf,kk:null,jh:null};return this.D(a)};yg.prototype.M=
+function(a,b){var c=this.$c.G(a.document),d=document.getElementById(this.Wf);d&&c.push(new Ze(d,"&nb=18"));for(d=T(a.document,this.F);null!=d&&!Wd(d,"a_");)d=d.parentElement;d&&$e(c,d,T(a.document,"adBlock"),b);this.$c.M&&this.$c.M(a,b)};var wg=function(a,b,c,d,e,f,g,h){this.P=a;this.T=b;this.R=c;this.Ic=d;this.zc=e;this.vb=f;this.oa=g;this.fa=h||ve};wg.prototype.j=function(){var a=Be({elements:[this.oa.j(),this.R.j(),this.Ic.j()]});return this.fa({Ka:Be({elements:[this.P.j(),this.vb.j()]}),La:this.zc?
+a:this.T.j(),Ad:this.zc?this.T.j():a})};wg.prototype.G=function(a){return this.P.G(a).concat(this.R.G(a).concat(this.T.G(a)))};var vg=function(a,b,c,d,e,f){this.P=a;this.T=b;this.R=c;this.vb=d;this.oa=e;this.fa=f||we};vg.prototype.j=function(){var a=Be({elements:[this.P.j(),this.vb.j()]}),b=Be({elements:[this.oa.j(),this.R.j(),this.T.j()]});return this.fa({Ka:a,La:b})};vg.prototype.G=function(a){return this.P.G(a).concat(this.R.G(a).concat(this.T.G(a)))};var ug=function(a,b,c,d){this.P=a;this.T=b;
+this.R=c;this.oa=d};ug.prototype.j=function(){return Be({elements:[this.oa.j(),this.P.j(),this.T.j(),F(""),this.R.j()]})};ug.prototype.G=function(a){return this.P.G(a).concat(this.R.G(a).concat(this.T.G(a)))}};var zg=function(a,b,c,d,e){this.gg=a;this.tg=b;this.hh=c;this.Oj=d;this.Nj=e||""};zg.prototype.$j=function(a){var b=new $a("https:"+Ka()+"/afs/gen_204");n(b,"client",this.gg);n(b,"zx",this.tg());n(b,"aqid",this.Nj);n(b,"action",a);this.hh(ab(b))};var Ag={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",
+darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",
+ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",
+lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",
+moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",
+seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};var Fg=function(a){var b={};a=String(a);var c="#"==a.charAt(0)?a:"#"+a;if(Bg.test(c))return b.ud=Cg(c),b.type="hex",b;a:{var d=a.match(Dg);if(d){var c=Number(d[1]),e=Number(d[2]),d=Number(d[3]);if(0<=c&&255>=c&&0<=e&&255>=e&&0<=d&&255>=d){c=[c,e,d];break a}}c=[]}if(c.length)return b.ud=Eg(c[0],c[1],c[2]),b.type="rgb",b;if(Ag&&(c=Ag[a.toLowerCase()]))return b.ud=c,b.type="named",b;throw Error(a+" is not a valid color string");},Gg=/#(.)(.)(.)/,Cg=function(a){if(!Bg.test(a))throw Error("'"+a+"' is not a valid hex color");
+4==a.length&&(a=a.replace(Gg,"#$1$1$2$2$3$3"));return a.toLowerCase()},Eg=function(a,b,c){a=Number(a);b=Number(b);c=Number(c);if(isNaN(a)||0>a||255b||255c||255'+Q(a[d])+"";return b};var Ng=function(a){return F(a.B.adIconUrl&&"ad-left"==a.B.adIconLocation&&a.B.img?(a.kc?'':"")+' '+(a.kc?" ":""):"")},Og=function(a){return F(a.B.adIconUrl&&"ad-left"==a.B.adIconLocation&&!a.B.img?'':"")};var Qg=function(a){var b=F,c='',d;if(a.B.adIconUrl&&"ad-left"==a.B.adIconLocation&&a.B.img&&a.B.adIconWidth){d=I(""+K(Ng({B:a.B,kc:a.Jb,A:a.A,Kg:a.Bk})));var e=I(""+Pg(a)),f=a.B.adIconSpacingAfter?a.B.adIconSpacingAfter:12,g=a.f?"right":"left";d=""+('
");d=F(d);d=G(d)}else d=Pg(a);c=c+d+"
";d=a.expansion;d=F(d&&""!=d?'
'+G(d)+"
":"");return b(c+d+(a.ii?F('
"):"")+"
")},Pg=function(a){return F(G(a.li)+G(a.tk)+(a.Fg&&a.V?K(yf({content:a.eg,f:a.f,$:a.Fg,V:a.V,sa:a.sa,ra:a.ra,Z:45,ga:12,rb:a.f})):''+G(a.eg)+"
"))};if(window.IS_GOOGLE_AFS_IFRAME_){var Rg=function(a,b,c,d){this.gc=a;this.F=R();this.lj=R();var e=df(a,c),e=new Ee([e,Gf(a)]);this.Ah=new af(e,a,c);var f=jf(a,c),g=Zf(a,c),e=gf(a,c),f=new Ee([f,g],Ce),e=c.me?new Ee([f,e]):new Ee([e,f]),e=new Ee([new af(e,a,c),kg(a,c)]);this.fg=uf(e,a,c);this.qg=new Ee(xg(a,b,c));this.gj=!c.xg;c.xg=!0;this.o=c;this.Wi=a.ctc||a.ctd;this.Mg="collapse"==c.ac;a.ctd&&(this.Di=a.ctd.iu,this.Fi=a.ctd.ih>a.ctd.iw?"height":"width",this.Ei=a.u,this.fj=a.ctd.ir);this.D=d||Qg};
+Rg.prototype.j=function(){var a={tk:this.Ah.j(),li:this.o.yb.j(),eg:this.fg.j(),expansion:this.qg.j(),Eb:this.F,f:this.o.f,Fg:this.Di,V:this.Fi,sa:this.Ei,ra:this.fj,B:this.gc,Jb:this.o.za||this.o.Jb,A:this.o.A,Vf:this.lj,ii:this.Mg,Fh:Ne()};return this.D(a)};Rg.prototype.M=function(a,b){this.Ah.M(a,b);this.fg.M(a,b);this.qg.M(a,b);var c=T(a.document,this.F),d=c.parentNode;this.Wi||Yd(c,"n_");var e=Zd(c,"a","e_");0'+(a.gd?'':"")+G(a.$d)+(a.gd?" ":"")+"":"")},Vg=function(a){return""+(a.Bc?''+Q(a.Bc)+" ":"")};var tg=function(a){var b=(a.jh?"":Og(a))+''+(a.jh?"":Ng({B:a.B,kc:a.Jb,A:a.A,Kg:a.Vf}))+'
',c;c=a.kk?F('
"):"";return b+c+Q(a.fi)+"
"+F(a.B.adIconUrl&&"ad-left"==a.B.adIconLocation&&!a.B.img?'
':
+"")};var Wg=function(a){return F(a.text?''+G(a.text)+"
":"")};var Xg=function(a){var b="";if(a.Kd&&0',c=a.Kd,d=c.length,e=0;e'+K(pe(f))+" - "+(f.rh?'"+K(pe({text:f.source,f:f.f}))+" ":K(pe({text:f.source,f:f.f})))+"":""),b=b+f;b+=""}else a.tb&&(b+=K(Wg({text:a.tb})));return F(b)};if(window.IS_GOOGLE_AFS_IFRAME_){var Yg=function(a,b,c,d){this.F=R();this.Tj=a;this.Ce=b;this.I=c;this.D=d||Xg};Yg.prototype.j=function(){return this.D({uid:this.F,Kd:this.Tj,tb:this.Ce,f:this.I})};var Zg=function(a,b){var c=a.gt&&"ar"==a.gt.r&&a.gt.t?a.gt.t:null;return a.ar&&0'+(a.Hh?' ':"");a=a.Gd;for(var c=a.length,d=0;d'+(0!=d?"· ":"")+''+G(a[d].t)+" ";b+=""}else a.tb&&(b+=K(Wg({text:a.tb})));return F(b)};if(window.IS_GOOGLE_AFS_IFRAME_)var xg=function(a,b,c){return b.isHighendMobile?c.ac?[Nf(a,c),hg(a,c)]:b.reviewUnderSellerRating?[kg(a,c),hg(a,c),Zf(a,c),Zg(a,c),Uf(a,c),Nf(a,c),Qf(a,c),vf(a,c)]:[kg(a,c),Zg(a,c),hg(a,c),Zf(a,c),Uf(a,c),Nf(a,c),Qf(a,c),vf(a,c)]:b.reviewUnderSellerRating?[kg(a,c),Uf(a,c),Nf(a,c),hg(a,c),Zf(a,c),Zg(a,c),Qf(a,c)]:[kg(a,c),Zg(a,c),Uf(a,c),Nf(a,c),hg(a,c),Zf(a,c),Qf(a,c)]},ch=function(a,b,c,d,e){var f=Rb(d),g=Sb(d),h=f("type")||"ads",l=a.linkColorSchemeVisUrlLinkColor||
+"#008000",r=a.linkColorSchemeTitleLinkColor||"#0000CC";a.isHighendMobile&&a.mobileUiFormat?(l="#006621",r="#1a0dab"):$g(d,a)&&(r=l="#4272db");var l=f("colorDomainLink",l),r=f("colorTitleLink",r),u=e.adBadgeColor||l,y="0.85em",C=f("fontSizeDomainLink");C&&(y=.85*C+"px");var H;H=(H=d.width)&&"auto"!=H?H:"100%";var J={Qb:!1,Ud:null,ae:null};if(d.verticalSpacing){var L=d.verticalSpacing/2;J.Qb=!0;J.Ud=Math.floor(L);J.ae=Math.ceil(L)}var L=(L=f("colorAdSeparator"))?L:a.isHighendMobile||a.isTablet?"#E6E6E6":
+null,ua=f("colorAdBackground"),ka=f("colorAdBorder"),la=f("colorText"),qa=f("colorBackground"),eb=f("colorBorder"),sb=f("colorAttribution"),fb=f("colorPlusOnes"),qk=f("colorKeyword"),rk=f("colorLocation"),sk=f("colorAnnotation"),Qa;Qa=[[0,0,0],[255,255,255]];if(l){var Sc;Sc=Cg(l);Qa=Kg([parseInt(Sc.substr(1,2),16),parseInt(Sc.substr(3,2),16),parseInt(Sc.substr(5,2),16)],Qa);Qa=Eg(Qa[0],Qa[1],Qa[2])}else Qa=null;a={C:a,ti:H,Ta:J,fc:L,Va:ua,S:ka,da:la,mb:r,Mb:l,Lb:qa,Aa:eb,Kb:sb,hd:fb,hg:qk,Wa:rk,N:sk,
+yi:u,zi:Qa,fontFamily:f("fontFamily"),qe:f("fontFamilyAttribution"),sb:f("fontSizeTitle"),wa:f("fontSizeDescription"),rc:C,Pb:f("fontSizeAttribution"),qd:f("fontSizePlusOnes"),od:f("fontSizeLocation"),K:f("fontSizeAnnotation"),Ni:y,mk:f("titleBold"),sk:e.titleInlineBlock,Uj:f("rolloverLinkBold"),fh:f("rolloverLinkColor"),eh:f("rolloverLinkBackgroundColor"),Vj:f("rolloverLinkUnderline"),dh:f("rolloverAdBackgroundColor"),Pg:f("noTitleUnderline"),zh:ah(a),Xc:g("adBorderSelections","left"),cc:g("adBorderSelections",
+"right"),Yc:g("adBorderSelections","top"),Wc:g("adBorderSelections","bottom"),pi:g("borderSelections","left"),ag:g("borderSelections","right"),ri:g("borderSelections","top"),oi:g("borderSelections","bottom"),za:Tb(d,a),Tb:f("lineHeightTitle"),aa:f("lineHeightDescription"),ab:f("lineHeightDomainLink"),Zf:f("attributionSpacingBelow"),hj:$g(d,a),De:e.hasButtonRight};f("adIconUrl")?(a.Ib=f("adIconWidth"),a.kb=f("adIconHeight"),a.Hb=f("adIconLocation"),a.dc=f("adIconSpacingAbove"),a.ec=f("adIconSpacingBefore"),
+a.Uf=f("adIconSpacingAfter"),a.ad=f("adIconSpacingBelow"),a.Vd=!0):f("adIconPageUrl")&&(a.Ib=f("adIconPageWidth"),a.kb=f("adIconPageHeight"),a.Hb=f("adIconPageLocation"),a.dc=f("adIconPageSpacingAbove"),a.ec=f("adIconPageSpacingBefore"),a.Uf=f("adIconPageSpacingAfter"),a.Vd=!1);"relatedsearch"==h&&(a.type="relatedsearch",a.Nb=f("columnSpacing"),a.vd=f("horizontalFlow"),a.ub=f("horizontalAlignment"));var v,h=a.C.isRtl?"right":"left";d=a.C.isRtl?"left":"right";f="";e=""),b,c)},dh=function(a,b,c,d,e,f,g,h,l){a="";bh(a,g,h)},bh=function(a,b,c){da(a)||(a=a.toString());ra()?b.populate(a):c.appendChild($c(Zc(),a))};if(window.IS_GOOGLE_AFS_IFRAME_)var eh=/^((https?):)?\/\/afs.googleusercontent.com\//,fh=/^\/\/afs.googleusercontent.com\//,gh=function(a,b,c,d,e,f,g){if(!d||eh.test(b))for(var h=0;ha.which:2>a.button)&&Fa(Eb(b))}))}},nh,oh,mh=!1,kh=function(a){mh=!1;a=a.touches;1==a.length&&(a=a[0],nh=a.clientX,oh=a.clientY,mh=!0)},lh=function(a){a=a.touches[0];
+if(10'+G(a.Og)+" ":'')},wh=function(a){return ud(".sb_ {padding-top: 10px; text-align: right; height: 29px; font-size: 12px; color: #666666; line-height: 29px; margin-bottom: 2px;}.tb_ {padding-right: 10px; height: 100%; display: inline-block;}.lb_ {display: inline-block; text-align: center; border-radius: 2px; background: white; border: 1px solid #f3f3f3; cursor: default; white-space: nowrap; text-decoration: none; color: #444444; font-size: 11px; font-weight: bold; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;}.ub_.lb_ {height: 100%; width: 34px; font-size: inherit; position: relative;}.lb_.s_ {border: 1px solid #dcdcdc; background: #f5f5f5; z-index: 10;}.lb_.s_:active {-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); box-shadow: inset 0 1px 2px rgba(0,0,0,.1); background: #f8f8f8; color: #333;}.lb_.s_:hover {border: 1px solid #c6c6c6; z-index: 20;}.left.lb_ {border-top-right-radius: 0; border-bottom-right-radius: 0;}.right.lb_ {border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: -1px;}.vb_ {margin-top: -3px; vertical-align: middle; filter: alpha(opacity=33); opacity: .333;}.lb_.s_:hover > .vb_ {filter: alpha(opacity=90); opacity: .9;}.lb_.s_ > .vb_ {filter: alpha(opacity=55); opacity: .55;}table {font-size: "+
+P(a.fontSize)+"px; border-collapse: collapse; display: inline-table; white-space: normal; margin-right: 10px; vertical-align: top; border-top: 1px solid #ebebeb;}.qb_ {position: relative; overflow: hidden;}.rb_ {white-space: nowrap; position: relative; left: 0px;}.j_ {color: #777777;}")};if(window.IS_GOOGLE_AFS_IFRAME_){var xh=function(a,b,c,d,e){this.xa=a;this.Fj=b;this.ak=c;this.xj=d;this.nb=0;this.Hc=[];this.D=e;this.Yd=new ke(300);this.Qg=R();this.kf=R();this.Sg=R();this.hf=R();this.jf=R();this.Tg=R()};k=xh.prototype;k.j=function(){return this.D({zj:this.Qg,Yj:this.kf,Dj:this.Sg,Wj:this.hf,Xj:this.jf,Ej:this.Tg,Og:0==this.xa.length?this.xj:""})};k.ug=function(a,b){return a==b?this.ak.replace("%1$d",""+a).replace("%2$d",""+this.xa.length):this.Fj.replace("%1$d",""+a).replace("%2$d",
+""+b).replace("%3$d",""+this.xa.length)};k.Cj=function(a,b){if(0!=this.xa.length){var c=T(a,this.Qg);b-=c.offsetHeight;var d=T(a,this.kf),c=c.offsetWidth,e=a.createElement("table");e.style.width=c+"px";d.appendChild(e);for(var f=0,g=0;gb){var h=e.removeChild(e.lastChild);0==f&&(b=e.offsetHeight);this.Hc.push(this.ug(f+1,g));e=a.createElement("table");e.style.width=c+"px";d.appendChild(e);e.appendChild(h);f=g}this.Hc.push(this.ug(f+
+1,this.xa.length));this.Eh(a)}};k.cg=function(){return 0';c='
'+G(a.title)+"
"+(a.ha?'
'+G(a.ha)+"
":"");c=I(c);b+=(a.xb?K(mf({Da:I('
'),Ea:I(""+G(c)),Z:69,ga:10})):G(c))+'
'+G(a.sh)+"
"+G(a.ah)+"
";return F(b)},zh=
+function(a){for(var b='
';c='
'+G(a.title)+'
'+G(a.ha)+'
'+G(a.sh)+"
"+G(a.ah)+"
";c=I(c);b+=(a.xb?K(mf({Da:I('
'+
+(a.description?'
'+G(a.description)+"
":"")),Ea:I(""+G(c)),Z:224,ga:20})):G(c))+"
";return F(b)};var Bh=function(a){var b;return F(''+Ah(a)+""+K(null==(b=a.ma)?"":b)+' '+G(a.Wb)+" ")},Ah=function(a){return F(''+K(Sd({href:a.Ja,content:a.Ed,A:a.Ma,qa:xd("hb_"),Za:a.Dd}))+"
")},Ch=function(a){var b;return F(''+Ah(a)+""+K(null==(b=a.ma)?"":b)+" "+G(a.Wb)+'
'+
+G(a.ua)+'
'+K(Sd({href:a.Ja,content:"Buy",A:a.Ma,qa:xd("s_ kb_ lb_")}))+" ")},Dh=function(a){return ud(".i_ {border-bottom: 1px solid #ebebeb; vertical-align: middle;}.i_ td {padding: 7px 4px 7px 0;}.gb_ {width: 40%;}.i_ .fb_ {text-align: right; padding: 7px 0; font-weight: bold;}.hb_ {text-decoration: none; color: "+P(a.linkColor)+"; display: block; overflow: hidden; text-overflow: ellipsis;}.hb_:hover {text-decoration: underline;}")},Eh=function(a){var b;a=a||
+{};return F(''+Ah(a)+''+G(a.Wb)+'
'+K(null==(b=a.ua)?"":b)+'
'+K(null==(b=a.ma)?"":b)+"
")},Fh=function(a){return ud(".i_ {border-bottom: 1px solid #ebebeb; vertical-align: middle;}.i_ td {height: 50px; padding-right: 4px;}.gb_ {width: 40%;}.i_ .jb_ {text-align: right; padding-right: 0;}.kb_.lb_ {padding: 0 8px; min-width: 54px; height: 27px; line-height: 27px;}.hb_ {text-decoration: none; color: "+
+P(a.linkColor)+"; display: block; overflow: hidden; text-overflow: ellipsis;}.hb_:hover {text-decoration: underline;}.ib_ {color: #7d7d7d; font-size: 80%;}")};if(window.IS_GOOGLE_AFS_IFRAME_){var Gh=function(a,b){this.bg=a;this.maxHeight=b},Hh=new Gh(10,350),Ih=new Gh(20,700),Jh=function(a,b,c,d,e,f,g,h,l,r,u,y,C){this.Ee=a;this.P=b;this.T=c;this.pe=d;this.pj=e;this.dk=f;this.wj=g+" \u25bc";this.mj=h+" \u25b2";this.re=l;this.We=r;this.gk=y;this.D=C;this.Ab=u;this.Ab.height=Math.min(this.Ab.height,this.re.maxHeight);this.Ab.width=Math.min(this.Ab.width,1E3);this.yh=R();this.kg=R();this.Sf=R();this.Qf=R();this.yg=R()};Jh.prototype.j=function(){return this.D({xb:this.Ee,
+title:this.P,description:this.T,ha:this.pe,sh:this.dk,ah:this.We.j(),si:this.Ab.width,uh:this.gk,Oc:this.yh,Hi:this.kg,Rf:this.Sf,ei:this.Qf,Xi:this.yg})};Jh.prototype.Vi=function(a){return T(a,"adBlock").offsetWidth};Jh.prototype.Mj=function(a){this.uk(a);var b=T(a,this.Sf).offsetHeight,b=b+2*this.re.bg;this.We.Cj(a,this.Ab.height-b);this.We.Zd(a)};Jh.prototype.uk=function(a){var b=T(a,this.yh);ng(b,3);if(b=a.getElementById(this.kg)){var c=Je(T(a,this.Qf)),c=c+2*this.re.bg;Je(T(a,this.yg));og(b,
+this.Ab.height-c-50,this.wj,this.mj,this.pj)}};var Kh=function(a,b,c,d){var e,f,g,h=[],l=null,r=a.lc||"#0651cf";switch(a.id){case 1:case "SMALL_FORMAT":e=Bh;f=vh;g=yh;h.push(Dh({linkColor:r}));h.push(ud(wh({fontSize:12})));h.push(ud("#adBlock {font-family: arial; font-size: 0; width: 300px; background: white;}.h_ {font-size: 18px; font-weight: bold; color: #222222; word-wrap: break-word;}.xa_ {padding: 9px; border: 1px solid #e0e0e0;}.ab_ {max-width: 67px; max-height: 67px; vertical-align: middle;}.za_ {width: 67px; height: 67px; border: 1px solid #eeeeee; text-align: center; line-height: 67px;}.bb_ {padding: 10px 0; font-size: 12px; font-weight: bold; color: #222222;}.cb_ {color: #787878; font-size: 13px;}"));
+d&&(e=Eh,h.push(ud(".i_ .nb_ {padding: 7px 0; width: 46px;}.i_ .fb_ {text-align: left; padding-right: 4px;}.ib_ {color: #7d7d7d; font-size: 90%; font-weight: normal;}")));l=Hh;break;case 3:case "WIDE_FORMAT":e=Ch;f=vh;g=zh;h.push(Fh({linkColor:r}));h.push(ud(wh({fontSize:14})));h.push(ud("#adBlock {font-family: arial; font-size: 0; background: white;}.xa_ {padding: 19px; border: 1px solid #e0e0e0;}.ab_ {max-width: 222px; max-height: 222px; vertical-align: middle;}.za_ {width: 222px; height: 222px; border: 1px solid #eeeeee; text-align: center; line-height: 222px; margin-bottom: 20px;}.eb_ {font-size: 12px; line-height: 18px; color: #222222; word-wrap: break-word;}.db_ {padding-bottom: 20px;}.h_ {font-size: 18px; font-weight: bold; color: #222222; word-wrap: break-word;}.cb_ {color: #7d7d7d; font-size: 13px;}.bb_ {font-size: 14px; font-weight: bold; color: #222222; padding-bottom: 8px;}"));
+l=Ih;break;default:return Na.log({message:"Jackpot block json failed to provide a known format."},"crjc"),null}var u=[];a.offers&&(u=ic(a.offers,function(a){return new uh(a.u,a.m,a.pr,a.s,d&&a.ppu?a.ppu:"",c,e)}));f=new xh(u,b.pt,b.sipt,b.nl,f);return new Jh(a.pd.i,a.pd.t,a.pd.d,d&&a.pd.er?a.pd.er:"",r,b.sl,b.m,b.l,l,f,new Wc(a.mw,a.mh),h,g)}};var Lh=function(a){var b='',c='
'+K(Sd({href:a.Ja,content:a.title,A:a.Ma,qa:xd("oc_"),Za:a.Oc}))+'
',c=c+('
'+G(a.Wb)+"
"+(a.Id?(a.ma?'
'+G(a.ma)+"
":
+"")+(a.ha?'
'+G(a.ha)+"
":"")+(a.ua?'
'+G(a.ua)+"
":""):"")+'
'+K(Sd({href:a.Ja,content:a.Ed,A:a.Ma,qa:xd("sc_"),Za:a.Dd}))+"
"),b=b+K(mf({Da:I("
"+K(Sd({href:a.Ja,content:I('
"),A:a.Ma,qa:xd("lc_"),Za:a.Dg}))+"
"),Ea:I(c),Z:a.Fe,ga:a.xc}));return F(b+"
")},Mh=function(a){return ud(".hc_ {background: white; margin-right: "+
+P(a.yc)+"px; margin-bottom: "+P(a.yc)+"px;"+(a.og?P(Rd({value:yd("1px 2px 1px rgba(0, 0, 0, 0.1)")}))+"border: 1px solid #E0E0E0; box-sizing: border-box; border-radius: 3px;":P(Rd({value:yd("0 2px 1px rgba(0, 0, 0, 0.1), 0 0 1px rgba(0, 0, 0, 0.1)")}))+"border-radius: 2px;")+"width: "+P(a.hi)+"px; height: "+P(a.gi)+"px;"+P(Qd())+"}.ic_ {"+(a.og?"padding: "+P(a.xc-1)+"px;":"padding: "+P(a.xc)+"px;")+"position: relative;}.lc_ {text-decoration: none;}.jc_ {width: "+P(a.Fe)+"px; height: "+P(a.bj)+"px; background-repeat: no-repeat; background-position: center; background-size: contain; cursor: pointer; position: relative;}.mc_ {position: relative; height: "+
+P(a.Bi)+"px;}.oc_ {color: "+P(a.nk)+"; font-size: "+P(a.qk)+"px; text-decoration: none;}.nc_ {width: "+P(a.jd)+"px; word-wrap: break-word;}.mb_ {font-size: "+P(a.Ij)+"px; font-weight: bold; color: "+P(a.Xg)+";}.pc_ {color: "+P(a.Xg)+"; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: "+P(a.jd)+"px;}.sc_ {color: "+P(a.Lg)+"; text-decoration: none;}.rc_ {font-size: "+P(a.tj)+"px; padding-bottom: 2px; color: "+P(a.Lg)+"; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: "+
+P(a.jd)+"px;}.bb_ {font-size: 13px;"+P(Qd())+"text-decoration: none; background-color: #555555; position: absolute; bottom: 1px; left: 1px; padding: 0 3px; color: white; border-radius: 2px;}.qc_ {font-size: 12px; color: #777777; padding-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: "+P(a.jd)+"px;}")};var Nh=function(a){var b=''+K(Sd({href:a.Ja,content:I('
"),A:a.Ma,qa:xd("lc_"),Za:a.Dg}))+'
'+K(Sd({href:a.Ja,content:a.title,A:a.Ma,qa:xd("oc_"),Za:a.Oc}))+'
',b=b+('
'+G(a.Wb)+"
"+(a.Id?(a.ma?'
'+G(a.ma)+"
":"")+(a.ha?'
'+G(a.ha)+"
":"")+(a.ua?'
'+G(a.ua)+"
":""):"")+'
'+K(Sd({href:a.Ja,content:a.Ed,A:a.Ma,qa:xd("sc_"),Za:a.Dd}))+"
");return F(b)},Oh=function(a){return ud(P(Mh(a))+".jc_ {margin-bottom: "+
+P(a.xc)+"px;}")};if(window.IS_GOOGLE_AFS_IFRAME_){var Ph=function(a,b,c,d,e,f,g,h,l,r,u,y,C){this.mi=c;this.Me=d;this.P=a.t;this.Qe=a.m;this.cf=a.pr;this.Ee=a.i;this.Nd=a.s;this.Qd=a.ppu;this.pe=a.er;this.Pj=u;this.Yi=b.h;this.yk=b.w;this.Ie=e;this.Hg=f;this.cj=b.ih;this.Eg=b.iw;this.jg=g;this.Ci=h;this.rk=b.ts;this.uj=b.ms;this.Jj=b.ps;this.pk=b.tc;this.sj=b.mc;this.Hj=b.pc;this.Xe=l;this.Ki=r;this.fk=y;this.D=C;this.Ag=R();this.Cg=R();this.vf=R();this.Cd=R();this.Wg=R()};k=Ph.prototype;k.j=function(){return this.D({Ug:this.Ag,
+$f:this.mi,Ja:this.Me,xb:this.Ee,Dg:this.Cg,title:this.P,Oc:this.vf,Wb:this.cf,Ed:this.Qe,Dd:this.Cd,Vg:this.Wg,Fe:this.Eg,xc:this.Hg,Yg:this.Ai(),Ma:this.Xe,ma:this.Nd,ua:this.Qd,ha:this.pe,Id:this.Pj})};k.Ui=function(){return this.fk({hi:this.yk,gi:this.Yi,yc:this.Ie,xc:this.Hg,bj:this.cj,Fe:this.Eg,Bi:this.jg,jd:this.Ci,qk:this.rk,tj:this.uj,Ij:this.Jj,nk:this.pk,Lg:this.sj,Xg:this.Hj,og:this.Ki})};k.Ai=function(){return hc([this.Qd,this.Nd],ca).join("\n")};k.Bh=function(a){var b=a.document.getElementById(this.Wg);
+b&&mg(a.document.getElementById(this.vf),this.jg-(b.offsetHeight+4));this.ic&&this.ic.Bh(a)};k.Xf=function(a){this.ic&&this.ic.Xf(a)};k.vg=function(a){return T(a,this.Ag)};k.wg=function(a){var b=this.ic?this.ic.wg(a):[];return[new Ze(T(a,this.vf),"&nb=0"),new Ze(T(a,this.Cd),"&nb=1"),new Ze(T(a,this.Cg),"&nb=9")].concat(b)};var Qh=function(a,b,c,d,e,f,g){var h=db(a.u),l=new Wc(b.w,b.h),r=new Wc(b.iw,b.ih),u=Math.floor((l.height-r.height)/2);return new Ph(a,b,c,h,d,u,r.height,l.width-(3*u+r.width),
+e,f,g,Mh,Lh)},Rh=function(a,b,c,d,e,f,g){var h=db(a.u),l=new Wc(b.w,b.h),r=new Wc(b.iw,b.ih),u=Math.floor((l.width-r.width)/2);return new Ph(a,b,c,h,d,u,l.height-(3*u+r.height),r.width,e,f,g,Oh,Nh)}};var Sh=function(a){var b='
';a=a.Sj;for(var c=a.length,d=0;d
")};if(window.IS_GOOGLE_AFS_IFRAME_){var Th=function(a,b,c,d,e,f,g){this.Vb=a;this.kh=b;this.Ie=c;this.ni=d;this.Mi=e;this.ej=f;this.D=g};Th.prototype.j=function(){for(var a=[],b=0;b
"},
+Vh=function(a){for(var b='"};var Wh=function(a){var b,c=0;b='";return F(b)},Xh=function(a){for(var b='',c=a.ads,d=c.length,e=0;e'+G(f.l1)+" "+G(f.l2)+'
");b+="
";return F(b)},Yh=function(a){var b;b='';for(var c=a.ads,d=c.length,e=0;e'+
+G(f.l1)+" "+G(f.l2)+' '+G(f.v)+" "}b+="
";return F(b)},Zh=function(a){for(var b='',c=a.ads,d=c.length,e=0;e -
'+G(f.l1)+" "+G(f.l2)+'
");b+="
";return F(b)},$h=function(a){var b,c=0;b='';for(var d=a.ads,e=d.length,f=0;f
"}b+=" ";return F(b)};if(window.IS_GOOGLE_AFS_IFRAME_)var ai=function(a,b){b=b||130;var c=b+Math.max(1.5*b,160),d=a.document.getElementById("wideSfbl"),e=a.document.getElementById("narrowSfbl");d&&e&&(Ie(a.document.body,!1)Ie(f,!1)){for(g=0;h=c[g];g++)h.style.display="none";for(g=0;h=d[g];g++)h.style.display="block"}else{for(g=0;h=c[g];g++)h.style.display="block";for(g=0;h=d[g];g++)h.style.display="none"}};var bi=function(a){return'"+(a.B.pn?Hf({Hd:a.B.pn,f:a.C.isRtl,Ng:!1})+" ":"")+(a.Gg?''+Wf({Mc:a.B.sr})+"
":"")},ci=function(a){return""+(a.C.disableSellerFirstFavicon?bi({B:a.B,C:a.C,A:a.A,Gg:a.wd}):nf({Da:' ',Ea:""+
+bi({B:a.B,C:a.C,A:a.A,Gg:a.wd}),Z:18,ga:3,rb:a.C.isRtl}))+(a.wd?"":''+Wf({Mc:a.B.sr})+"
")},di=function(a){var b='',c=a.B.l1r,d=a.B.l2r,e=a.C.isRtl,f="";if(d&&d.c)var g=c.rtl||d.rtl,f=f+Jf({Ia:g,f:e,text:Kf({text:c,f:g})+" "+Kf({text:d,f:g})});else f+=Kf({text:c,f:e});b=b+f+"
"+ig({be:a.B.cos,
+f:a.C.isRtl})+Xg({Kd:a.B.ar,tb:a.B.gt&&"ar"==a.B.gt.r?a.B.gt.t:null,f:a.C.isRtl})+Rf({$e:a.B.plus_ones,A:a.A})+Lf({Ne:a.B.location,f:a.C.isRtl})+Of({Gd:a.B.oh,tb:a.B.gt&&"oh"==a.B.gt.r?a.B.gt.t:null,Hh:a.C.offerHighlightWithIcon});a=a.B.sls&&0g?e?(e.style.display="none",c?c.style.display="":e.parentNode.style.display="none"):(d.style.display="none",c||(d.parentNode.style.display="none")):e?(e.style.display="",e.parentNode.style.display="",c&&(c.style.display="none")):(d.style.display="",d.parentNode.style.display="")}},Fi=m(Fi,"aH"),Oi=function(a){var b="master-"+Ai(a);a=Di(b,a);b="";if(a)try{b=
+a.document.documentElement.lang}catch(c){}return b},Oi=m(Oi,"gMIHL"),Pi=function(a,b){try{if(a&&a.document.getElementsByTagName("html")){var c;(c=a.document.getElementsByTagName("html")[0])&&!c.lang&&(c.lang=b)}}catch(d){}},Pi=m(Pi,"sSIHL"),Ri=function(a,b,c){a=a.document.getElementsByTagName("table");for(var d=a.length,e=0;eMe(a).height},Si=m(Si,"iW"),Ti=function(a){for(;0e.length?e.push(h):"sl-right"==h.className&&3>f.length&&f.push(h);for(d=[];0e){c=Le(d)-15;125>c&&(c=125);for(var f=d.getElementsByTagName("div"),g=0,h=0,l;l=f[h];h++)Me(l).width<=c&&3>g?g++:l.style.display="none";g>e?(Wi(d,"visibility","visible"),a.style.display="none"):d.style.display="none"}else d.style.display="none"}},Vi=m(Vi,"uS"),Ui=function(a,b){var c=b.shift();if(c){for(;0<
+b.length;)Ti(b.pop());c[1]&&(Si(c)||(Yd(c[0].firstChild,"l"),Yd(c[1].firstChild,"r"),c[0].innerHTML+=" - "+c[1].innerHTML),c[1].parentNode.removeChild(c[1]),c.pop());a.className="sl-table-ol";c[0].className="sl-left-ol";Si(c[0])&&Ti(c)}},Ui=m(Ui,"hSLS"),Xi=function(a,b){return Le(a)b||"number"==typeof c&&16>c)&&(a=a.document.getElementById("adBlock"))&&""!=a.innerHTML?!0:!1},lj=m(lj,"iCSI"),Ji=function(a,b){for(var c=!1,d=[],e=0;erb)for(a=0;a=f)a=g;else{a=[];for(var h=
+0,l=0;l';e=g.length;for(b=0;b'+K(pe({text:a.t,f:f})),d+='
';c=F(d+"")}else{d=""+('");e=g.length;for(b=0;bf||2<=f&&b":"")+'",l=g.length%f||f,d+='=g.length-l?" lr":"")+'">'+Og({B:a,kc:!1,qj:"_top"})+
+'
'+Ng({B:a,kc:!1,qj:"_top"})+'
";c=d+"
"}return c},uj=m(uj,"cRSN"),gj=function(a,b,c,d,e,f,g,h,l,r,u){if(0>=a.length)return null;var y=Ub(e),C="";c=null;if(u.customAdIcons){var H="https"==window.location.protocol;null!=e.adIconUrl&&0';e=a.ads;f=e.length;for(C=0;C'+nf({Da:""+ci(vd(a,{B:g,wd:!0})),Ea:""+di(vd(a,{B:g})),Z:null==(qa=a.Zj)?130:qa,ga:10,rb:a.C.isRtl})+"
";y+='';
+qa=a.ads;e=qa.length;for(f=0;f
'+ci(vd(a,{B:C,wd:!1}))+'
'+di(vd(a,{B:C,Dk:!0}))+"
";C=y+""}else{c=[];qa=g.ac?Rg:yg;for(y=0;y');bh(u,b,d);bh(C,b,d);return c},
+gj=m(gj,"cAN"),vj=function(a){var b=[{index:a.indexOf("{{NUM_START}}"),Sb:13},{index:a.indexOf("{{NUM_END}}"),Sb:11},{index:a.indexOf("{{LINK_START}}"),Sb:14},{index:a.indexOf("{{LINK_END}}"),Sb:12},{index:a.indexOf("{{RATING}}"),Sb:10}];b.sort(function(a,b){return a.index-b.index});for(var c=[],d=0,e=0;-1==b[e].index;)e++;for(;ee&&b<2*e?e+"px":"100%";if(b!=c){c=b;for(var f in qi)e=Di(f,a),null==e?
+delete qi[f]:Wi(e.document.body,"width",b);setTimeout(ha(Ki,a),10)}},"mWS")},yj=m(yj,"gMWS"),zj=function(a,b,c){var d=!1;b=Ai(b);c.isRtl&&si.Xb("rtl",!0);c.queryId&&si.Zb("qi",c.queryId);c.effectiveAdsWebProperty&&si.Zb("eawp",c.effectiveAdsWebProperty);for(var e={},f=0;fr&&!a&&delete W[u]);c.getNumAds&&si.Xb("aD."+b,!0);si.Xb("r."+b,!!c.isRejected);Nb(si)},zj=m(zj,"pAJ"),Aj=function(a){var b=[],c;for(c in ui){var d=a[c];if(d){for(var e=ui[c],f=0;fthis.zd)return null;for(var b=[],c=0;ca.length?null:this.pb.ja(a[0])};var Jj=function(){};Jj.prototype.ka=function(){return"true, false"};Jj.prototype.X=function(a){return"true"==a||1==a?!0:"false"==a||!1===a?!1:null};Jj.prototype.ja=function(a){a=this.X(a);return null==a?null:a?1:0};var q=new Jj;var X=function(a,b){this.Fc=Math.ceil(a);this.Ec=Math.floor(b)};X.prototype.ka=function(){return this.Fc+" - "+this.Ec};X.prototype.X=function(a){a=parseInt(a,10);return a>=this.Fc&&a<=this.Ec?a:null};X.prototype.ja=function(a){return this.X(a)};var Kj=function(a){this.pb=a};Kj.prototype.ka=function(){return this.pb.ka()+" (one or more, comma separated)"};Kj.prototype.X=function(a){a=Lj(a);for(var b=[],c=0;cc)throw Pa("Cannot request more minTop ads than maxTop.");return e+d+f+a};k.ee=m(Y.prototype.ee,"cAA");k.ge=function(a,
+b){var c=this.ea(a);b&&0Y.Zg?e.fexp+=",37108":10>Y.Zg&&(e.fexp+=",37109"),"top"==a.position&&(e.maxTop=a.number,e.longerHeadlines=
+!1,e.number=null));e.format=this.la?this.ea(e):this.ge(e,b);this.Oi=e.format;e.ads=this.ee(c);e.nocache=[Math.floor(1E3*Math.random()),(new Date).getTime()].join("");e.num="0";e.output=this.Kc.Ae();this.Kc.Ue()?(e.domainName||(e.domainName=window.document.domain),e.domainName=e.domainName.substring(0,Y.Sh)):e.domainName="";e.gcsc&&(e.source=Y.Ph);e.v=Bb(e)?"4":"3";e.adPageId&&(e.pubId=e.propertyCode,e.adPageId=vb(this.Na.adPageId,e.adPageId));da(e.pubId)||(e.pubId=""+e.pubId);0==e.pubId.indexOf("partner-")&&
+(e.pubId=e.pubId.substring(8));e=this.Ld(e);!e.titleBold||!0!==e.titleBold&&1!=e.titleBold?e.titleBold&&delete e.titleBold:e.titleBold=1;Fb(e)&&(!e.maxTop&&!e.minTop||e.hasOwnProperty(Y.ib)||(e[Y.ib]=!0));if(!this.la){a=e[Y.ib]||!1;for(f in d)d.hasOwnProperty(f)&&(a=a||d[f].o[Y.ib]);a&&(e.adlh=Y.Rh)}e.clickToCall&&(e.allwcallad=1);this.Sa(e);return e};k.Af=m(Y.prototype.Af,"vASDO");Y.Pc=function(a,b){var c=parseInt(a,10);return!isNaN(c)&&0<=c?c:b};Y.Pc=m(Y.Pc,"tNNIOD");Y.yd=function(a){a=parseInt(a,
+10);return!isNaN(a)&&0<=a};Y.yd=m(Y.yd,"iNNN");Y.Qh={hc:1,lh:1,oh:1,pa:1};Y.sd=function(a,b){var c=b.H,d=b.g.ja(a);return null!=d&&Y.yd(d)?Y.Qh.hasOwnProperty(c)?d?c.charAt(0)+c.charAt(1).toUpperCase():c:c+d:""};Y.sd=m(Y.sd,"gPFO");k=Y.prototype;k.Ye=function(a){var b=[],c;for(c in a)a.hasOwnProperty(c)&&c in this.Na&&this.Na[c].H&&b.push(Y.sd(a[c],this.Na[c]));return b.join("")};k.Ye=m(Y.prototype.Ye,"oTPP");k.Gc=function(a,b){var c=[],d;for(d in a)!(a.hasOwnProperty(d)&&d in this.Na&&this.Na[d].H)||
+d in b&&b[d]==a[d]||c.push(Y.sd(a[d],this.Na[d]));return c.join("")};k.Gc=m(Y.prototype.Gc,"oTBP");k.je=function(a,b,c){var d=a.v?a.v:"3",e=this.fe(a,b,c),f=Y.de()?"vp1":"";if(0==b.length)return["uv",d,e,f,this.Gc(a,{}),"-"].join("");c.pubId=a.pubId;c=this.Ld(c);var g=this.Ye(c),g=["uv",d,e,f,g].join(""),d=[];d.push(this.Gc(a,c));for(a=0;e=b[a];a++)e.o.slaveNumber&&0!=e.o.slaveNumber&&d.push(this.Gc(e.o,c));return[g,d.join("-")].join("-")};k.je=m(Y.prototype.je,"cUIP");k.fe=function(a,b,c){if(a.colorTitleLink||
+a.colorDomainLink||c.colorTitleLink||c.colorDomainLink)return"cs1";for(a=0;c=b[a];a++)if(c.o.colorTitleLink||c.o.colorDomainLink)return"cs1";return""};k.fe=m(Y.prototype.fe,"cCTPP");Y.de=function(){for(var a=document.getElementsByTagName("meta"),b=0,c;c=a[b];b++)if("viewport"==c.name)return!0;return!1};Y.de=m(Y.de,"cVMT");Y.Bf=function(a){for(var b=["fontSizeTitle","fontSizeDescription","fontSizeDomainLink","fontSizeAttribution"],c=0;ctb?tb:e,e=8>e?8:e;a[d]=e+"px"}}return a};Y.Bf=m(Y.Bf,"vFS");k=Y.prototype;k.ke=function(a,b){var c,d,e=this.Kc.ue();if(e){this.Wd(a,e);var f=2==window.googleAltLoader||4==window.googleAltLoader;d=1==window[Y.Of];3==window.googleAltLoader&&d?n(e,"bsl",9):3==window.googleAltLoader?n(e,"bsl",8):4==window.googleAltLoader&&d?n(e,"bsl",11):4==window.googleAltLoader?n(e,"bsl",10):d?n(e,"bsl",f?7:3):15==b.googleAltLoader?n(e,"bsl",2):f&&n(e,"bsl",6);if(!this.la){f=
+window;d=document;var g=new Date;var h=f||ei;try{c=h.history.length}catch(u){c=0}n(e,"u_his",c);n(e,"u_tz",-g.getTimezoneOffset());n(e,"dt",g.getTime());n(e,"u_w",f.screen.width);n(e,"u_h",f.screen.height);c=oi(!0,f);n(e,"biw",c.width);n(e,"bih",c.height);f.top!=f&&(c=oi(!1,f),n(e,"isw",c.width),n(e,"ish",c.height));d.body?(c=(g=!f.scrollY&&"CSS1Compat"!=d.compatMode)?d.body.scrollWidth:d.body.offsetWidth,d=g?d.body.scrollHeight:d.body.offsetHeight):d=c=-1;n(e,"psw",c);n(e,"psh",d);var l;if(f.top==
+f)l=0;else{f=f.top;try{var r;if(r=!!f&&null!=f.location.href)b:{try{de(f.foo);r=!0;break b}catch(u){}r=!1}l=r}catch(u){l=!1}l=l?1:2}n(e,"frm",l)}n(e,"uio",this.Ch);n(e,"rurl",b.location.href,!0);n(e,Y.Uc.referer,b.document.referrer,!0);a.referrer&&n(e,"optref",a.referrer,!0)}return e};k.ke=m(Y.prototype.ke,"cU");k.Xd=function(a,b,c){var d=a.arg,e=[],f;for(f in a)"arg"!=f&&a.hasOwnProperty(f)&&b.hasOwnProperty(f)&&b[f]&&e.push(a[f]);0\x3c/script>')};k.sf=m(Y.prototype.sf,
+"sAP");k.fd=function(a){this.Xa.style.fontWeight="normal";this.Xa.style.textAlign="center";this.Xa.innerHTML="";this.Xa.appendChild(a)};k.fd=m(Y.prototype.fd,"aI");k.bf=function(){var a={},b;for(b in this.o)this.o.hasOwnProperty(b)&&(a[b]=this.o[b]);a.ads="n0";a[""]="";a.slaveNumber="0";a.role="s";a=zk(this.Na,this.ed,a);Z[a.Fa()]=a;this.hb.splice(0,0,a);a=document.createElement("div");document.body.appendChild(a);a.style.height="0px";a.style.visibility="hidden";this.o.container=a;this.Jg=this.o.preload=
+!0};k.bf=m(Y.prototype.bf,"pM");k.Ke=function(){self.rg=self.rg||(new Date).getTime();return(new Date).getTime()-self.rg>Y.di?!0:!1};k.Ke=m(Y.prototype.Ke,"iTU");k.Ge=function(a,b,c,d,e,f){this.gb=this.cb=this.bb=this.fb=0;this.Kc=b;this.hb=f||null;this.Rg=c||null;this.o=this.Af(a,d,e,f);this.Pi=new zg(this.o.pubId,fc,Ea,Math.random);this.md()||this.la||!document.body||Ak()||this.bf();this.Ch=null==this.Rg?"":this.je(this.o,this.hb,this.Rg);if(this.cd=this.la&&this.Kc.td()||this.ke(this.o,window))if(this.wb=
+this.id=this.sc=this.Fa(),this.cd.ld=this.sc,this.ya=ab(this.cd),!this.la){a=[];b=[];for(c=0;ca.length)throw Pa("No options specified.");return 1function test() {}\x3c/script>");e.close();f.open();f.write("
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Open.
+
+
The Apache Software Foundation
+
+
provides support for the Apache Community of open-source software projects, which provide software products for the public good.
+
+
+
+
Innovation.
+
+
The Apache projects are defined
+
+
by collaborative consensus based processes, an open,
+pragmatic software license and a desire to create high quality software
+that leads the way in its field.
+
+
+
+
Community.
+
+
We consider ourselves
+
+
not simply a group of projects sharing a server, but rather a community of developers and users.
+
+
+
+
+
+
+
+
+
+
Apache Projects
+
The all-volunteer ASF develops, stewards, and incubates more
+than 350 Open Source projects and initiatives that cover a wide range of
+ technologies.
+ From Abdera to Zookeeper, if you are looking for a rewarding
+experience in Open Source and industry leading software, chances are you
+ are going to find it here.
+ Are you powered by Apache?
+
+
+
+
+
Featured Projects
+
+
+
+
+
+
+
+
+
+
+
+
The Apache MRUnit is a Java library that helps developers unit test Apache Hadoop map reduce jobs.
+
Learn More...
+
+
+
+
+
+
+
+
+
+
+
+
Apache Synapse is a simple and highly effective ESB, Web Services intermediary and SOA framework. It can be
+added to your existing network very simply either as a services gateway or as an HTTP proxy. Once Apache
+Synapse is mediating your service requests it can perform many functions including routing,...
+
Learn More...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >> this announcement is available online at
http://s.apache.org/q2L by Ted Liu, event co-organizer
On 24-25 October, The Apache Roadshow 2015 - China in Beijing was successfully concluded.
+It...
+
+
+
+ The Apache Jackrabbit community is pleased to announce the release of
+Apache Jackrabbit Oak 1.3.10 The release is available for download at:
http://jackrabbit.apache.org/downloads.html See the full release notes...
+
+
+
+ The Apache Camel community announces the immediate availability of the
+new patch release Apache Camel 2.14.4. This release contains 18 fixes
+applied in the past few weeks by the community...
+
+
+
+
+
+
+
+
+
Latest Activity
+
+
+
+
+
+
+
+
Apache Blogs
+
+
+
+
+
by Ted Liu, event organizing committee
+member, co-founder of KAIYUANSHE, and Principal Technical
+Evangelist, Open Technology Center, Microsoft China
+
On 24-25 October, The Apache Roadshow 2015 - China in Beijing was...
+
+
+
+
Open Source distributed database
+management system simplifies Big Data application development with new
+features, performance optimizations, and significant storage savings
+
+
Forest Hill, MD —10 November 2015— The Apache Software Foundation...
+
+
+
+
Authors: Bernd Eckenfels, Committer, and Gary Gregory, Vice President of Apache Commons
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Apache Project List
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Copyright © 2015 The Apache Software Foundation, Licensed under the Apache License, Version 2.0 .
+
Apache and the Apache feather logo are trademarks of The Apache Software Foundation.
+
+
+
+
+
+
+
+
+
+
+
+