diff options
author | Axel Ulrich <ulrich.axel@gmail.com> | 2020-05-19 13:20:51 -0400 |
---|---|---|
committer | Rasmus Thomsen <oss@cogitri.dev> | 2020-05-26 20:34:43 +0000 |
commit | 33c2125e094c1367bad0c4bd9760c2db12269267 (patch) | |
tree | 6e5d4e466264c6b756cb43bbf0568b8f7cf610e9 | |
parent | 479a259baa0f66bfeb5d11a0d0d4ce4fa3da9260 (diff) | |
download | alpine_aports-33c2125e094c1367bad0c4bd9760c2db12269267.tar.bz2 alpine_aports-33c2125e094c1367bad0c4bd9760c2db12269267.tar.xz alpine_aports-33c2125e094c1367bad0c4bd9760c2db12269267.zip |
community/h2o: adding check()
-rw-r--r-- | community/h2o/APKBUILD | 28 | ||||
-rw-r--r-- | community/h2o/backslashinterpreationintests.patch | 14 | ||||
-rw-r--r-- | community/h2o/cannotlocatetutilpm.patch | 39 | ||||
-rw-r--r-- | community/h2o/disabletls13intls12tests.patch | 25 | ||||
-rw-r--r-- | community/h2o/increasewaitforserverstartintests.patch | 14 | ||||
-rw-r--r-- | community/h2o/largeheadertest.patch | 19 | ||||
-rw-r--r-- | community/h2o/missingsubmodules.patch | 503 | ||||
-rw-r--r-- | community/h2o/proxysessionresumption.patch | 134 | ||||
-rw-r--r-- | community/h2o/sessiontickettest.patch | 140 | ||||
-rw-r--r-- | community/perl-http-entity-parser/APKBUILD (renamed from testing/perl-http-entity-parser/APKBUILD) | 0 | ||||
-rw-r--r-- | community/perl-http-multipartparser/APKBUILD (renamed from testing/perl-http-multipartparser/APKBUILD) | 0 | ||||
-rw-r--r-- | community/perl-protocol-http2/APKBUILD (renamed from testing/perl-protocol-http2/APKBUILD) | 0 | ||||
-rw-r--r-- | community/perl-www-form-urlencoded/APKBUILD (renamed from testing/perl-www-form-urlencoded/APKBUILD) | 0 |
13 files changed, 912 insertions, 4 deletions
diff --git a/community/h2o/APKBUILD b/community/h2o/APKBUILD index 9be25491d4..c46efaf3c0 100644 --- a/community/h2o/APKBUILD +++ b/community/h2o/APKBUILD | |||
@@ -1,21 +1,30 @@ | |||
1 | # Contributor: Bennett Goble <nivardus@gmail.com> | 1 | # Contributor: Bennett Goble <nivardus@gmail.com> |
2 | # Contributor: Axel Ulrich <ulrich.axel@gmail.com> | ||
2 | # Maintainer: Bennett Goble <nivardus@gmail.com> | 3 | # Maintainer: Bennett Goble <nivardus@gmail.com> |
3 | pkgname=h2o | 4 | pkgname=h2o |
4 | pkgver=2.2.6 | 5 | pkgver=2.2.6 |
5 | pkgrel=4 | 6 | pkgrel=5 |
6 | pkgdesc="An optimized HTTP/1, HTTP/2 server written in C" | 7 | pkgdesc="An optimized HTTP/1, HTTP/2 server written in C" |
7 | url="https://h2o.examp1e.net" | 8 | url="https://h2o.examp1e.net" |
8 | arch="all !s390x" | 9 | arch="all !s390x" |
9 | depends="perl openssl" | 10 | depends="perl openssl" |
10 | license="MIT" | 11 | license="MIT" |
11 | makedepends="cmake ruby-dev bison zlib-dev wslay-dev openssl-dev libuv-dev yaml-dev" | 12 | makedepends="cmake ruby-dev bison zlib-dev wslay-dev openssl-dev libuv-dev yaml-dev" |
12 | options="!check" | 13 | checkdepends="perl-test-harness-utils perl-test-tcp perl-test-simple perl-json perl-path-tiny perl-scope-guard perl-test-exception perl-protocol-http2 perl-test-requires perl-hash-multivalue perl-plack perl-lwp-protocol-https perl-http-headers-fast perl-cookie-baker perl-http-entity-parser perl-starlet perl-fcgi-procmanager perl-cgi perl-fcgi nodejs wget" |
13 | install="$pkgname.pre-install" | 14 | install="$pkgname.pre-install" |
14 | subpackages="$pkgname-dev $pkgname-doc $pkgname-openrc" | 15 | subpackages="$pkgname-dev $pkgname-doc $pkgname-openrc" |
15 | source="$pkgname-$pkgver.tar.gz::https://github.com/h2o/h2o/archive/v$pkgver.tar.gz | 16 | source="$pkgname-$pkgver.tar.gz::https://github.com/h2o/h2o/archive/v$pkgver.tar.gz |
16 | h2o.conf | 17 | h2o.conf |
17 | h2o.initd | 18 | h2o.initd |
18 | h2o.logrotate | 19 | h2o.logrotate |
20 | missingsubmodules.patch | ||
21 | backslashinterpreationintests.patch | ||
22 | disabletls13intls12tests.patch | ||
23 | largeheadertest.patch | ||
24 | proxysessionresumption.patch | ||
25 | sessiontickettest.patch | ||
26 | cannotlocatetutilpm.patch | ||
27 | increasewaitforserverstartintests.patch | ||
19 | " | 28 | " |
20 | 29 | ||
21 | # secfixes: | 30 | # secfixes: |
@@ -32,7 +41,10 @@ build() { | |||
32 | -DCMAKE_INSTALL_PREFIX=/usr \ | 41 | -DCMAKE_INSTALL_PREFIX=/usr \ |
33 | -DWITH_MRUBY=ON | 42 | -DWITH_MRUBY=ON |
34 | make -C build | 43 | make -C build |
35 | make -C build libh2o | 44 | } |
45 | |||
46 | check() { | ||
47 | make -C build check | ||
36 | } | 48 | } |
37 | 49 | ||
38 | package() { | 50 | package() { |
@@ -56,4 +68,12 @@ package() { | |||
56 | sha512sums="f2f28905c01782a0432c9dfdb2f21054e0a4741ac4c5f26802d4b439d0172840aa215aba5dc7c9af62275dcc24de105674a3819384dc38246e43ce3e8263eb20 h2o-2.2.6.tar.gz | 68 | sha512sums="f2f28905c01782a0432c9dfdb2f21054e0a4741ac4c5f26802d4b439d0172840aa215aba5dc7c9af62275dcc24de105674a3819384dc38246e43ce3e8263eb20 h2o-2.2.6.tar.gz |
57 | 444f55c3eaae1f349223036086e45c983ea8be89e793068537ec25488c4065174bc509d0987ddc65a0357cb8acfec272e90d13ea7cdadf9cf112953d857aa574 h2o.conf | 69 | 444f55c3eaae1f349223036086e45c983ea8be89e793068537ec25488c4065174bc509d0987ddc65a0357cb8acfec272e90d13ea7cdadf9cf112953d857aa574 h2o.conf |
58 | e93e66a6b00b1bff94e37489c5fdf99d9d657adc63975ec54be30f8da23dafe7d7389f02a6452ed819efc9d8398aa716782a7fd6d8509621a975ed954b73bef9 h2o.initd | 70 | e93e66a6b00b1bff94e37489c5fdf99d9d657adc63975ec54be30f8da23dafe7d7389f02a6452ed819efc9d8398aa716782a7fd6d8509621a975ed954b73bef9 h2o.initd |
59 | 3d2c9e36c48cbb974d0691e4af8e9eb8f13e3bebb98a30417cdc87e76a4b5cddc4e4f665ebea26b95174287b95d002fdc3363f30ffcf15247fcd0530fe1abfcc h2o.logrotate" | 71 | 3d2c9e36c48cbb974d0691e4af8e9eb8f13e3bebb98a30417cdc87e76a4b5cddc4e4f665ebea26b95174287b95d002fdc3363f30ffcf15247fcd0530fe1abfcc h2o.logrotate |
72 | c03ceeea23a545b948815aeb48872dbac388665f0c79c643e7fa17695580c71260b2227058fe60702d052536e8bdb4d8104d430557ec0c3c4515ed132db7a4a8 missingsubmodules.patch | ||
73 | cd62b93041f2f9407d3aa82c924aa13a3f38330a3557c230c47f30eb3d8bbb90db95cdd2ff1e8248eadcae711c90d0e33caa221ede46015df92c3fe4148a6f21 backslashinterpreationintests.patch | ||
74 | 28c5a3a8f64391f317c90f826a488e513b25ad3e7c5febffc0f3a0323b361e4b2900d9dd5e542754b0083c30f68f270eb3b17a8b23ad3f43e4b28feb260ad9eb disabletls13intls12tests.patch | ||
75 | a8b2edff9da782319682ecbf62b93090eedc5503236a7106d0313429b157ec091ddbeb9b8f9f91567ae712a4f2c082b9ba8f84d890b72b54c161c0c4e1cab0ef largeheadertest.patch | ||
76 | a5df628f200475f5db6eb9d1714e955cd33c2de3081ee5f770929833a4cb9e5030fe338c23bcfb516235c2036c6e6452bb52447da0c3d69e3ea8de8bfa00f420 proxysessionresumption.patch | ||
77 | 9304ea3ebb74eb66f3d8c8facfc8a08366cb35ac8f5ee8090f59202abd13842d4a4565b5cbfcfff3110473a03bb9ff00b0f74311b450113675f0cb6d6b759d90 sessiontickettest.patch | ||
78 | 848b9d20221c2d55b034bd3b9943100fd82f3e32a6032e126868471f9e18f60a9d94bc9024890e4af7ee8ffd6308cc1beb001e3052cb938b14280d331493307b cannotlocatetutilpm.patch | ||
79 | 26c4f34bdcb82cdca00b81e8c3223a1c517f912f433e99ae4a9aa16481db2cd23fc77f65773932f8c6e30cb5e34d5d37e0e7a022518a6a13db75d8e16fee2ab4 increasewaitforserverstartintests.patch" | ||
diff --git a/community/h2o/backslashinterpreationintests.patch b/community/h2o/backslashinterpreationintests.patch new file mode 100644 index 0000000000..c8cb4663c8 --- /dev/null +++ b/community/h2o/backslashinterpreationintests.patch | |||
@@ -0,0 +1,14 @@ | |||
1 | Upstream: Yes | ||
2 | Reason: Without this patch tests fail on shells backslash escapes disabled | ||
3 | Url: https://github.com/h2o/h2o/pull/2331 | ||
4 | --- a/t/50mruby.t | ||
5 | +++ b/t/50mruby.t | ||
6 | @@ -498,7 +498,7 @@ | ||
7 | EOT | ||
8 | my $nc = sub { | ||
9 | my $path = shift; | ||
10 | - my $cmd = "echo 'GET $path HTTP/1.1\\r\\nHost: 127.0.0.1\\r\\n\\r' | nc 127.0.0.1 $server->{port}"; | ||
11 | + my $cmd = "echo 'GET $path HTTP/1.1\r\nHost: 127.0.0.1\r\n\r' | nc 127.0.0.1 $server->{port}"; | ||
12 | (undef, my $r) = run_prog($cmd); | ||
13 | split(/\r\n\r\n/, $r, 2); | ||
14 | }; | ||
diff --git a/community/h2o/cannotlocatetutilpm.patch b/community/h2o/cannotlocatetutilpm.patch new file mode 100644 index 0000000000..2897fcdc08 --- /dev/null +++ b/community/h2o/cannotlocatetutilpm.patch | |||
@@ -0,0 +1,39 @@ | |||
1 | Upstream: Yes | ||
2 | Reason: Without this patch make check fails | ||
3 | Url: https://github.com/h2o/h2o/issues/2167 | ||
4 | --- a/CMakeLists.txt | ||
5 | +++ b/CMakeLists.txt | ||
6 | @@ -386,13 +386,13 @@ | ||
7 | OUTPUT_NAME h2o | ||
8 | VERSION ${LIBRARY_VERSION} | ||
9 | SOVERSION ${LIBRARY_SOVERSION}) | ||
10 | -TARGET_LINK_LIBRARIES(libh2o ${LIBUV_LIBRARIES} ${EXTRA_LIBS}) | ||
11 | +TARGET_LINK_LIBRARIES(libh2o ${WSLAY_LIBRARIES} ${LIBUV_LIBRARIES} ${EXTRA_LIBS}) | ||
12 | SET_TARGET_PROPERTIES(libh2o-evloop PROPERTIES | ||
13 | OUTPUT_NAME h2o-evloop | ||
14 | COMPILE_FLAGS "-DH2O_USE_LIBUV=0" | ||
15 | VERSION ${LIBRARY_VERSION} | ||
16 | SOVERSION ${LIBRARY_SOVERSION}) | ||
17 | -TARGET_LINK_LIBRARIES(libh2o-evloop ${EXTRA_LIBS}) | ||
18 | +TARGET_LINK_LIBRARIES(libh2o-evloop ${WSLAY_LIBRARIES} ${EXTRA_LIBS}) | ||
19 | |||
20 | IF (OPENSSL_FOUND) | ||
21 | TARGET_INCLUDE_DIRECTORIES(libh2o PUBLIC ${OPENSSL_INCLUDE_DIR}) | ||
22 | @@ -553,7 +553,7 @@ | ||
23 | ENDIF (OPENSSL_FOUND) | ||
24 | ENDIF (WITH_BUNDLED_SSL) | ||
25 | |||
26 | -ADD_CUSTOM_TARGET(check env H2O_ROOT=. BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR} prove -v t/*.t | ||
27 | +ADD_CUSTOM_TARGET(check env H2O_ROOT=. BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR} prove -I. -v t/*.t | ||
28 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} | ||
29 | DEPENDS h2o t-00unit-evloop.t) | ||
30 | IF (LIBUV_FOUND) | ||
31 | @@ -563,7 +563,7 @@ | ||
32 | ENDIF () | ||
33 | ENDIF () | ||
34 | |||
35 | -ADD_CUSTOM_TARGET(check-as-root env H2O_ROOT=. BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR} prove -v t/90root-*.t | ||
36 | +ADD_CUSTOM_TARGET(check-as-root env H2O_ROOT=. BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR} prove -I. -v t/90root-*.t | ||
37 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | ||
38 | |||
39 | IF (BUILD_FUZZER) | ||
diff --git a/community/h2o/disabletls13intls12tests.patch b/community/h2o/disabletls13intls12tests.patch new file mode 100644 index 0000000000..714e9fa4bd --- /dev/null +++ b/community/h2o/disabletls13intls12tests.patch | |||
@@ -0,0 +1,25 @@ | |||
1 | Upstream: Yes | ||
2 | Reason: Without this patch certain TLS1.2 bahavior tests fail as TLS1.3 is chosen by default | ||
3 | Url: https://github.com/h2o/h2o/commit/442908871b935311c903d2d234708b3de9b40fd5 | ||
4 | --- a/t/40ssl-cipher-suite.t | ||
5 | +++ b/t/40ssl-cipher-suite.t | ||
6 | @@ -32,7 +32,7 @@ | ||
7 | ); | ||
8 | |||
9 | # connect to the server with AES256-SHA as the first choice, and check that AES128-SHA was selected | ||
10 | -my $log = `openssl s_client -cipher AES256-SHA:AES128-SHA -host 127.0.0.1 -port $port < /dev/null 2>&1`; | ||
11 | +my $log = `openssl s_client -cipher AES256-SHA:AES128-SHA -host 127.0.0.1 -port $port -tls1_2 < /dev/null 2>&1`; | ||
12 | like $log, qr/^\s*Cipher\s*:\s*AES128-SHA\s*$/m; | ||
13 | |||
14 | done_testing; | ||
15 | --- a/t/50access-log.t | ||
16 | +++ b/t/50access-log.t | ||
17 | @@ -168,7 +168,7 @@ | ||
18 | sub { | ||
19 | my $server = shift; | ||
20 | system("curl --silent http://127.0.0.1:$server->{port}/ > /dev/null"); | ||
21 | - system("curl --silent --insecure @{[curl_supports_http2() ? ' --http1.1' : '']} https://127.0.0.1:$server->{tls_port}/ > /dev/null"); | ||
22 | + system("curl --silent --insecure @{[curl_supports_http2() ? ' --http1.1' : '']} https://127.0.0.1:$server->{tls_port}/ --tls-max 1.2 > /dev/null"); | ||
23 | if (prog_exists("nghttp")) { | ||
24 | system("nghttp -n https://127.0.0.1:$server->{tls_port}/"); | ||
25 | system("nghttp -n --weight=22 https://127.0.0.1:$server->{tls_port}/"); | ||
diff --git a/community/h2o/increasewaitforserverstartintests.patch b/community/h2o/increasewaitforserverstartintests.patch new file mode 100644 index 0000000000..057341c026 --- /dev/null +++ b/community/h2o/increasewaitforserverstartintests.patch | |||
@@ -0,0 +1,14 @@ | |||
1 | Upstream: No | ||
2 | Reason: Without this patch some tests fail as the server is not fully started, | ||
3 | issue only present on Alpine running in docker | ||
4 | --- a/t/Util.pm | ||
5 | +++ b/t/Util.pm | ||
6 | @@ -125,7 +125,7 @@ | ||
7 | if (waitpid($pid, WNOHANG) == $pid) { | ||
8 | die "server failed to start (got $?)\n"; | ||
9 | } | ||
10 | - sleep 0.1; | ||
11 | + sleep 3; | ||
12 | } | ||
13 | } | ||
14 | my $guard = scope_guard(sub { | ||
diff --git a/community/h2o/largeheadertest.patch b/community/h2o/largeheadertest.patch new file mode 100644 index 0000000000..3c3770b522 --- /dev/null +++ b/community/h2o/largeheadertest.patch | |||
@@ -0,0 +1,19 @@ | |||
1 | Upstream: No | ||
2 | Reason: Without this patch tests using curl for large http headers fail, issue not present with curl on other distro's | ||
3 | Url: https://lists.alpinelinux.org/~alpine/users/%3CCAG5E%3DNdf%3Dc1+Hwt2rY%3DK-kJTtWuMHLnitDoCLrCKkp7n5ksD6w%40mail.gmail.com%3E | ||
4 | --- a/t/50fastcgi.t | ||
5 | +++ b/t/50fastcgi.t | ||
6 | @@ -66,7 +66,12 @@ | ||
7 | my ($proto, $port, $curl) = @_; | ||
8 | plan skip_all => "skip due to curl bug #659" | ||
9 | if $curl =~ /--http2/; | ||
10 | - my $content = `$curl --silent --show-error -H foo:@{["0123456789"x7000]} $proto://127.0.0.1:$port/echo-headers`; | ||
11 | + my $content; | ||
12 | + if ($curl =~ /--http1.1/) { | ||
13 | + $content = `wget --no-check-certificate -O - --header="foo:@{["0123456789"x7000]}" https://127.0.0.1:$port/echo-headers`; | ||
14 | + } else { | ||
15 | + $content = `$curl --silent --show-error -H foo:@{["0123456789"x7000]} $proto://127.0.0.1:$port/echo-headers`; | ||
16 | + } | ||
17 | like $content, qr/^foo: (0123456789){7000,7000}$/mi; | ||
18 | if ($proto eq 'https') { | ||
19 | like $content, qr/^https: on$/m; | ||
diff --git a/community/h2o/missingsubmodules.patch b/community/h2o/missingsubmodules.patch new file mode 100644 index 0000000000..85063bbcc9 --- /dev/null +++ b/community/h2o/missingsubmodules.patch | |||
@@ -0,0 +1,503 @@ | |||
1 | Upstream: Yes | ||
2 | Reason: Without this patch certain tests are failing as these files are dependencies for tests | ||
3 | Url: https://github.com/h2o/h2o/issues/2329 | ||
4 | --- /dev/null | ||
5 | +++ b/misc/cache-digest/cache-digest.js | ||
6 | @@ -0,0 +1,247 @@ | ||
7 | +/* | ||
8 | + * Copyright (c) 2015,2016 Jxck, DeNA Co., Ltd., Kazuho Oku | ||
9 | + * | ||
10 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
11 | + * of this software and associated documentation files (the "Software"), to | ||
12 | + * deal in the Software without restriction, including without limitation the | ||
13 | + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
14 | + * sell copies of the Software, and to permit persons to whom the Software is | ||
15 | + * furnished to do so, subject to the following conditions: | ||
16 | + * | ||
17 | + * The above copyright notice and this permission notice shall be included in | ||
18 | + * all copies or substantial portions of the Software. | ||
19 | + * | ||
20 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
21 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
22 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
23 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
24 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
25 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
26 | + * IN THE SOFTWARE. | ||
27 | + * | ||
28 | + * | ||
29 | + * Includes a minified SHA256 implementation taken from https://gist.github.com/kazuho/bb8aab1a2946bbf42127d8a6197ad18c, | ||
30 | + * licensed under the following copyright: | ||
31 | + * | ||
32 | + * Copyright (c) 2015,2016 Chen Yi-Cyuan, Kazuho Oku | ||
33 | + * | ||
34 | + * MIT License | ||
35 | + * | ||
36 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
37 | + * of this software and associated documentation files (the "Software"), to | ||
38 | + * deal in the Software without restriction, including without limitation the | ||
39 | + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
40 | + * sell copies of the Software, and to permit persons to whom the Software is | ||
41 | + * furnished to do so, subject to the following conditions: | ||
42 | + * | ||
43 | + * The above copyright notice and this permission notice shall be included in | ||
44 | + * all copies or substantial portions of the Software. | ||
45 | + * | ||
46 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
47 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
48 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
49 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
50 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
51 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
52 | + * IN THE SOFTWARE. | ||
53 | + */ | ||
54 | +"use strict"; | ||
55 | + | ||
56 | +if (typeof self !== "undefined" && "ServiceWorkerGlobalScope" in self && | ||
57 | + self instanceof ServiceWorkerGlobalScope) { | ||
58 | + | ||
59 | + /* ServiceWorker */ | ||
60 | + self.addEventListener('fetch', function(evt) { | ||
61 | + var req = evt.request.clone(); | ||
62 | + if (req.method != "GET" || req.url.match(/\/cache-digests?\.js(?:\?|$)/)) { | ||
63 | + logInfo(req, "skip"); | ||
64 | + return; | ||
65 | + } | ||
66 | + evt.respondWith(caches.open("v1").then(function (cache) { | ||
67 | + return cache.match(req).then(function (res) { | ||
68 | + if (res && isFresh(res.headers.entries(), Date.now())) { | ||
69 | + logInfo(req, "hit"); | ||
70 | + return res; | ||
71 | + } | ||
72 | + var requestWithDigests = function (digests) { | ||
73 | + if (digests != null) { | ||
74 | + var err = null; | ||
75 | + try { | ||
76 | + req = new Request(req); | ||
77 | + req.headers.append("cache-digest", digests); | ||
78 | + if (req.headers.get("cache-digest") == null) | ||
79 | + err = "append failed"; | ||
80 | + } catch (e) { | ||
81 | + err = e; | ||
82 | + } | ||
83 | + if (err) | ||
84 | + logError(req, e); | ||
85 | + } | ||
86 | + return fetch(req).then(function (res) { | ||
87 | + var cached = false; | ||
88 | + if (res.status == 200 && isFresh(res.headers.entries(), Date.now())) { | ||
89 | + cache.put(req, res.clone()); | ||
90 | + cached = true; | ||
91 | + } | ||
92 | + logInfo(req, "fetched" + (cached ? " & cached" : "") + " with cache-digest:\"" + digests + "\""); | ||
93 | + return res; | ||
94 | + }); | ||
95 | + }; | ||
96 | + if (req.mode == "navigate") { | ||
97 | + return generateCacheDigests(cache).then(requestWithDigests); | ||
98 | + } else { | ||
99 | + return requestWithDigests(null); | ||
100 | + } | ||
101 | + }); | ||
102 | + })); | ||
103 | + }); | ||
104 | + | ||
105 | +} else if (typeof navigator !== "undefined") { | ||
106 | + | ||
107 | + /* bootstrap, loaded via <script src=...> */ | ||
108 | + navigator.serviceWorker.register("/cache-digest.js", {scope: "./"}).then(function(reg) { | ||
109 | + console.log("registered cache-digest.js service worker"); | ||
110 | + }).catch(function(e) { | ||
111 | + console.log("failed to register cache-digest.js service worker:" + e); | ||
112 | + }); | ||
113 | + | ||
114 | +} | ||
115 | + | ||
116 | +// returns a promise that returns the cache digest value | ||
117 | +function generateCacheDigests(cache) { | ||
118 | + var urls = []; | ||
119 | + return cache.keys().then(function (reqs) { | ||
120 | + // collect 31-bit hashes of fresh responses | ||
121 | + return Promise.all(reqs.map(function (req) { | ||
122 | + var now = Date.now(); | ||
123 | + return cache.match(req).then(function (resp) { | ||
124 | + if (resp && isFresh(resp.headers.entries(), now)) | ||
125 | + urls.push(req.url); | ||
126 | + }); | ||
127 | + })).then(function () { | ||
128 | + var dv = calcDigestValue(urls, 7); | ||
129 | + return dv != null ? base64Encode(dv) + "; complete" : null; | ||
130 | + }); | ||
131 | + }); | ||
132 | +} | ||
133 | + | ||
134 | +function calcDigestValue(urls, pbits) { | ||
135 | + var nbits = Math.round(Math.log(Math.max(urls.length, 1)) * 1.4426950408889634); // round log2(urls.length) | ||
136 | + if (nbits + pbits > 31) | ||
137 | + return null; | ||
138 | + var hashes = []; | ||
139 | + for (var i = 0; i != urls.length; ++i) | ||
140 | + hashes.push(sha256Truncated(urls[i], nbits + pbits)); | ||
141 | + return (new BitCoder).addBits(nbits, 5).addBits(pbits, 5).gcsEncode(hashes, pbits).value; | ||
142 | +} | ||
143 | + | ||
144 | +function isFresh(headers, now) { | ||
145 | + var date = 0, maxAge = null; | ||
146 | + var o; | ||
147 | + while (!(o = headers.next()).done) { | ||
148 | + var name = o.value[0], value = o.value[1]; | ||
149 | + if (name.match(/^expires$/i) != null) { | ||
150 | + var parsed = Date.parse(value); | ||
151 | + if (parsed && parsed > now) | ||
152 | + return true; | ||
153 | + } else if (name.match(/^cache-control$/i) != null) { | ||
154 | + var directives = value.split(/\s*,\s*/); | ||
155 | + for (var i = 0; i != directives.length; ++i) { | ||
156 | + var d = directives[i]; | ||
157 | + if (d.match(/^\s*no-(?:cache|store)\s*$/) != null) { | ||
158 | + return false; | ||
159 | + } else if (d.match(/^\s*max-age\s*=\s*([0-9]+)/) != null) { | ||
160 | + maxAge = Math.min(RegExp.$1, maxAge || Infinity); | ||
161 | + } | ||
162 | + } | ||
163 | + } else if (name.match(/^date$/i) != null) { | ||
164 | + date = Date.parse(value); | ||
165 | + } | ||
166 | + } | ||
167 | + | ||
168 | + if (maxAge != null) { | ||
169 | + if (date + maxAge * 1000 > now) | ||
170 | + return true; | ||
171 | + } | ||
172 | + | ||
173 | + return false; | ||
174 | +} | ||
175 | + | ||
176 | +function BitCoder() { | ||
177 | + this.value = []; | ||
178 | + this.leftBits = 0; | ||
179 | +} | ||
180 | + | ||
181 | +BitCoder.prototype.addBit = function (b) { | ||
182 | + if (this.leftBits == 0) { | ||
183 | + this.value.push(0); | ||
184 | + this.leftBits = 8; | ||
185 | + } | ||
186 | + --this.leftBits; | ||
187 | + if (b) | ||
188 | + this.value[this.value.length - 1] |= 1 << this.leftBits; | ||
189 | + return this; | ||
190 | +}; | ||
191 | + | ||
192 | +BitCoder.prototype.addBits = function (v, nbits) { | ||
193 | + if (nbits != 0) { | ||
194 | + do { | ||
195 | + --nbits; | ||
196 | + this.addBit(v & (1 << nbits)); | ||
197 | + } while (nbits != 0); | ||
198 | + } | ||
199 | + return this; | ||
200 | +}; | ||
201 | + | ||
202 | +BitCoder.prototype.gcsEncode = function (values, bits_fixed) { | ||
203 | + values = values.sort(function (a, b) { return a - b; }); | ||
204 | + var prev = -1; | ||
205 | + for (var i = 0; i != values.length; ++i) { | ||
206 | + if (prev == values[i]) | ||
207 | + continue; | ||
208 | + var v = values[i] - prev - 1; | ||
209 | + for (var q = v >> bits_fixed; q != 0; --q) | ||
210 | + this.addBit(0); | ||
211 | + this.addBit(1); | ||
212 | + this.addBits(v, bits_fixed); | ||
213 | + prev = values[i]; | ||
214 | + } | ||
215 | + return this; | ||
216 | +}; | ||
217 | + | ||
218 | +var base64Encode = function (buf) { | ||
219 | + var TOKENS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; | ||
220 | + return function base64Encode(buf) { | ||
221 | + var str = ''; | ||
222 | + for (var pos = 0; pos < buf.length; pos += 3) { | ||
223 | + var quad = buf[pos] << 16 | buf[pos + 1] << 8 | buf[pos + 2]; | ||
224 | + str += TOKENS[(quad >> 18)] + TOKENS[(quad >> 12) & 63] + TOKENS[(quad >> 6) & 63] + TOKENS[quad & 63]; | ||
225 | + } | ||
226 | + str = str.substring(0, str.length - pos + buf.length); | ||
227 | + return str; | ||
228 | + }; | ||
229 | +}(); | ||
230 | + | ||
231 | +function sha256Truncated(src, bits) { | ||
232 | + // only supports bits <= 31 | ||
233 | + return ((sha256(src)[0] >> 1) & 0x7fffffff) >> (31 - bits); | ||
234 | +} | ||
235 | + | ||
236 | +var sha256=function(){var r=[-2147483648,8388608,32768,128],o=[24,16,8,0],a=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];return function(n){var t,e,f,h,c,u,v,d,i,l,A,C,g,s=[],w=!0,b=!1,j=0,k=0,m=0,p=n.length,q=1779033703,x=3144134277,y=1013904242,z=2773480762,B=1359893119,D=2600822924,E=528734635,F=1541459225,G=0;do{for(s[0]=G,s[16]=s[1]=s[2]=s[3]=s[4]=s[5]=s[6]=s[7]=s[8]=s[9]=s[10]=s[11]=s[12]=s[13]=s[14]=s[15]=0,e=k;p>j&&64>e;++j)t=n.charCodeAt(j),128>t?s[e>>2]|=t<<o[3&e++]:2048>t?(s[e>>2]|=(192|t>>6)<<o[3&e++],s[e>>2]|=(128|63&t)<<o[3&e++]):55296>t||t>=57344?(s[e>>2]|=(224|t>>12)<<o[3&e++],s[e>>2]|=(128|t>>6&63)<<o[3&e++],s[e>>2]|=(128|63&t)<<o[3&e++]):(t=65536+((1023&t)<<10|1023&n.charCodeAt(++j)),s[e>>2]|=(240|t>>18)<<o[3&e++],s[e>>2]|=(128|t>>12&63)<<o[3&e++],s[e>>2]|=(128|t>>6&63)<<o[3&e++],s[e>>2]|=(128|63&t)<<o[3&e++]);m+=e-k,k=e-64,j==p&&(s[e>>2]|=r[3&e],++j),G=s[16],j>p&&56>e&&(s[15]=m<<3,b=!0);var H=q,I=x,J=y,K=z,L=B,M=D,N=E,O=F;for(f=16;64>f;++f)v=s[f-15],h=(v>>>7|v<<25)^(v>>>18|v<<14)^v>>>3,v=s[f-2],c=(v>>>17|v<<15)^(v>>>19|v<<13)^v>>>10,s[f]=s[f-16]+h+s[f-7]+c<<0;for(g=I&J,f=0;64>f;f+=4)w?(l=704751109,v=s[0]-210244248,O=v-1521486534<<0,K=v+143694565<<0,w=!1):(h=(H>>>2|H<<30)^(H>>>13|H<<19)^(H>>>22|H<<10),c=(L>>>6|L<<26)^(L>>>11|L<<21)^(L>>>25|L<<7),l=H&I,u=l^H&J^g,i=L&M^~L&N,v=O+c+i+a[f]+s[f],d=h+u,O=K+v<<0,K=v+d<<0),h=(K>>>2|K<<30)^(K>>>13|K<<19)^(K>>>22|K<<10),c=(O>>>6|O<<26)^(O>>>11|O<<21)^(O>>>25|O<<7),A=K&H,u=A^K&I^l,i=O&L^~O&M,v=N+c+i+a[f+1]+s[f+1],d=h+u,N=J+v<<0,J=v+d<<0,h=(J>>>2|J<<30)^(J>>>13|J<<19)^(J>>>22|J<<10),c=(N>>>6|N<<26)^(N>>>11|N<<21)^(N>>>25|N<<7),C=J&K,u=C^J&H^A,i=N&O^~N&L,v=M+c+i+a[f+2]+s[f+2],d=h+u,M=I+v<<0,I=v+d<<0,h=(I>>>2|I<<30)^(I>>>13|I<<19)^(I>>>22|I<<10),c=(M>>>6|M<<26)^(M>>>11|M<<21)^(M>>>25|M<<7),g=I&J,u=g^I&K^C,i=M&N^~M&O,v=L+c+i+a[f+3]+s[f+3],d=h+u,L=H+v<<0,H=v+d<<0;q=q+H<<0,x=x+I<<0,y=y+J<<0,z=z+K<<0,B=B+L<<0,D=D+M<<0,E=E+N<<0,F=F+O<<0}while(!b);return[q,x,y,z,B,D,E,F]}}(); | ||
237 | + | ||
238 | +function logRequest(req) { | ||
239 | + var s = req.method + " " + req.url + "\n"; | ||
240 | + var o; | ||
241 | + for (var iter = req.headers.entries(); !(o = iter.next()).done;) | ||
242 | + s += o.value[0] + ": " + o.value[1] + "\n"; | ||
243 | + console.log(s); | ||
244 | +} | ||
245 | +function logError(req, msg) { | ||
246 | + console.log(req.url + ":error:" + msg); | ||
247 | +} | ||
248 | +function logInfo(req, msg) { | ||
249 | + console.log(req.url + ":info:" + msg); | ||
250 | +} | ||
251 | +function logDebug(req, msg) { | ||
252 | + console.log(req.url + ":debug:" + msg); | ||
253 | +} | ||
254 | --- /dev/null | ||
255 | +++ b/misc/cache-digest/cli.js | ||
256 | @@ -0,0 +1,247 @@ | ||
257 | +/* | ||
258 | + * Copyright (c) 2015,2016 Jxck, DeNA Co., Ltd., Kazuho Oku | ||
259 | + * | ||
260 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
261 | + * of this software and associated documentation files (the "Software"), to | ||
262 | + * deal in the Software without restriction, including without limitation the | ||
263 | + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
264 | + * sell copies of the Software, and to permit persons to whom the Software is | ||
265 | + * furnished to do so, subject to the following conditions: | ||
266 | + * | ||
267 | + * The above copyright notice and this permission notice shall be included in | ||
268 | + * all copies or substantial portions of the Software. | ||
269 | + * | ||
270 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
271 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
272 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
273 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
274 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
275 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
276 | + * IN THE SOFTWARE. | ||
277 | + * | ||
278 | + * | ||
279 | + * Includes a minified SHA256 implementation taken from https://gist.github.com/kazuho/bb8aab1a2946bbf42127d8a6197ad18c, | ||
280 | + * licensed under the following copyright: | ||
281 | + * | ||
282 | + * Copyright (c) 2015,2016 Chen Yi-Cyuan, Kazuho Oku | ||
283 | + * | ||
284 | + * MIT License | ||
285 | + * | ||
286 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
287 | + * of this software and associated documentation files (the "Software"), to | ||
288 | + * deal in the Software without restriction, including without limitation the | ||
289 | + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
290 | + * sell copies of the Software, and to permit persons to whom the Software is | ||
291 | + * furnished to do so, subject to the following conditions: | ||
292 | + * | ||
293 | + * The above copyright notice and this permission notice shall be included in | ||
294 | + * all copies or substantial portions of the Software. | ||
295 | + * | ||
296 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
297 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
298 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
299 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
300 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
301 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
302 | + * IN THE SOFTWARE. | ||
303 | + */ | ||
304 | +"use strict"; | ||
305 | + | ||
306 | +if (typeof self !== "undefined" && "ServiceWorkerGlobalScope" in self && | ||
307 | + self instanceof ServiceWorkerGlobalScope) { | ||
308 | + | ||
309 | + /* ServiceWorker */ | ||
310 | + self.addEventListener('fetch', function(evt) { | ||
311 | + var req = evt.request.clone(); | ||
312 | + if (req.method != "GET" || req.url.match(/\/cache-digests?\.js(?:\?|$)/)) { | ||
313 | + logInfo(req, "skip"); | ||
314 | + return; | ||
315 | + } | ||
316 | + evt.respondWith(caches.open("v1").then(function (cache) { | ||
317 | + return cache.match(req).then(function (res) { | ||
318 | + if (res && isFresh(res.headers.entries(), Date.now())) { | ||
319 | + logInfo(req, "hit"); | ||
320 | + return res; | ||
321 | + } | ||
322 | + var requestWithDigests = function (digests) { | ||
323 | + if (digests != null) { | ||
324 | + var err = null; | ||
325 | + try { | ||
326 | + req = new Request(req); | ||
327 | + req.headers.append("cache-digest", digests); | ||
328 | + if (req.headers.get("cache-digest") == null) | ||
329 | + err = "append failed"; | ||
330 | + } catch (e) { | ||
331 | + err = e; | ||
332 | + } | ||
333 | + if (err) | ||
334 | + logError(req, e); | ||
335 | + } | ||
336 | + return fetch(req).then(function (res) { | ||
337 | + var cached = false; | ||
338 | + if (res.status == 200 && isFresh(res.headers.entries(), Date.now())) { | ||
339 | + cache.put(req, res.clone()); | ||
340 | + cached = true; | ||
341 | + } | ||
342 | + logInfo(req, "fetched" + (cached ? " & cached" : "") + " with cache-digest:\"" + digests + "\""); | ||
343 | + return res; | ||
344 | + }); | ||
345 | + }; | ||
346 | + if (req.mode == "navigate") { | ||
347 | + return generateCacheDigests(cache).then(requestWithDigests); | ||
348 | + } else { | ||
349 | + return requestWithDigests(null); | ||
350 | + } | ||
351 | + }); | ||
352 | + })); | ||
353 | + }); | ||
354 | + | ||
355 | +} else if (typeof navigator !== "undefined") { | ||
356 | + | ||
357 | + /* bootstrap, loaded via <script src=...> */ | ||
358 | + navigator.serviceWorker.register("/cache-digest.js", {scope: "./"}).then(function(reg) { | ||
359 | + console.log("registered cache-digest.js service worker"); | ||
360 | + }).catch(function(e) { | ||
361 | + console.log("failed to register cache-digest.js service worker:" + e); | ||
362 | + }); | ||
363 | + | ||
364 | +} | ||
365 | + | ||
366 | +// returns a promise that returns the cache digest value | ||
367 | +function generateCacheDigests(cache) { | ||
368 | + var urls = []; | ||
369 | + return cache.keys().then(function (reqs) { | ||
370 | + // collect 31-bit hashes of fresh responses | ||
371 | + return Promise.all(reqs.map(function (req) { | ||
372 | + var now = Date.now(); | ||
373 | + return cache.match(req).then(function (resp) { | ||
374 | + if (resp && isFresh(resp.headers.entries(), now)) | ||
375 | + urls.push(req.url); | ||
376 | + }); | ||
377 | + })).then(function () { | ||
378 | + var dv = calcDigestValue(urls, 7); | ||
379 | + return dv != null ? base64Encode(dv) + "; complete" : null; | ||
380 | + }); | ||
381 | + }); | ||
382 | +} | ||
383 | + | ||
384 | +function calcDigestValue(urls, pbits) { | ||
385 | + var nbits = Math.round(Math.log(Math.max(urls.length, 1)) * 1.4426950408889634); // round log2(urls.length) | ||
386 | + if (nbits + pbits > 31) | ||
387 | + return null; | ||
388 | + var hashes = []; | ||
389 | + for (var i = 0; i != urls.length; ++i) | ||
390 | + hashes.push(sha256Truncated(urls[i], nbits + pbits)); | ||
391 | + return (new BitCoder).addBits(nbits, 5).addBits(pbits, 5).gcsEncode(hashes, pbits).value; | ||
392 | +} | ||
393 | + | ||
394 | +function isFresh(headers, now) { | ||
395 | + var date = 0, maxAge = null; | ||
396 | + var o; | ||
397 | + while (!(o = headers.next()).done) { | ||
398 | + var name = o.value[0], value = o.value[1]; | ||
399 | + if (name.match(/^expires$/i) != null) { | ||
400 | + var parsed = Date.parse(value); | ||
401 | + if (parsed && parsed > now) | ||
402 | + return true; | ||
403 | + } else if (name.match(/^cache-control$/i) != null) { | ||
404 | + var directives = value.split(/\s*,\s*/); | ||
405 | + for (var i = 0; i != directives.length; ++i) { | ||
406 | + var d = directives[i]; | ||
407 | + if (d.match(/^\s*no-(?:cache|store)\s*$/) != null) { | ||
408 | + return false; | ||
409 | + } else if (d.match(/^\s*max-age\s*=\s*([0-9]+)/) != null) { | ||
410 | + maxAge = Math.min(RegExp.$1, maxAge || Infinity); | ||
411 | + } | ||
412 | + } | ||
413 | + } else if (name.match(/^date$/i) != null) { | ||
414 | + date = Date.parse(value); | ||
415 | + } | ||
416 | + } | ||
417 | + | ||
418 | + if (maxAge != null) { | ||
419 | + if (date + maxAge * 1000 > now) | ||
420 | + return true; | ||
421 | + } | ||
422 | + | ||
423 | + return false; | ||
424 | +} | ||
425 | + | ||
426 | +function BitCoder() { | ||
427 | + this.value = []; | ||
428 | + this.leftBits = 0; | ||
429 | +} | ||
430 | + | ||
431 | +BitCoder.prototype.addBit = function (b) { | ||
432 | + if (this.leftBits == 0) { | ||
433 | + this.value.push(0); | ||
434 | + this.leftBits = 8; | ||
435 | + } | ||
436 | + --this.leftBits; | ||
437 | + if (b) | ||
438 | + this.value[this.value.length - 1] |= 1 << this.leftBits; | ||
439 | + return this; | ||
440 | +}; | ||
441 | + | ||
442 | +BitCoder.prototype.addBits = function (v, nbits) { | ||
443 | + if (nbits != 0) { | ||
444 | + do { | ||
445 | + --nbits; | ||
446 | + this.addBit(v & (1 << nbits)); | ||
447 | + } while (nbits != 0); | ||
448 | + } | ||
449 | + return this; | ||
450 | +}; | ||
451 | + | ||
452 | +BitCoder.prototype.gcsEncode = function (values, bits_fixed) { | ||
453 | + values = values.sort(function (a, b) { return a - b; }); | ||
454 | + var prev = -1; | ||
455 | + for (var i = 0; i != values.length; ++i) { | ||
456 | + if (prev == values[i]) | ||
457 | + continue; | ||
458 | + var v = values[i] - prev - 1; | ||
459 | + for (var q = v >> bits_fixed; q != 0; --q) | ||
460 | + this.addBit(0); | ||
461 | + this.addBit(1); | ||
462 | + this.addBits(v, bits_fixed); | ||
463 | + prev = values[i]; | ||
464 | + } | ||
465 | + return this; | ||
466 | +}; | ||
467 | + | ||
468 | +var base64Encode = function (buf) { | ||
469 | + var TOKENS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; | ||
470 | + return function base64Encode(buf) { | ||
471 | + var str = ''; | ||
472 | + for (var pos = 0; pos < buf.length; pos += 3) { | ||
473 | + var quad = buf[pos] << 16 | buf[pos + 1] << 8 | buf[pos + 2]; | ||
474 | + str += TOKENS[(quad >> 18)] + TOKENS[(quad >> 12) & 63] + TOKENS[(quad >> 6) & 63] + TOKENS[quad & 63]; | ||
475 | + } | ||
476 | + str = str.substring(0, str.length - pos + buf.length); | ||
477 | + return str; | ||
478 | + }; | ||
479 | +}(); | ||
480 | + | ||
481 | +function sha256Truncated(src, bits) { | ||
482 | + // only supports bits <= 31 | ||
483 | + return ((sha256(src)[0] >> 1) & 0x7fffffff) >> (31 - bits); | ||
484 | +} | ||
485 | + | ||
486 | +var sha256=function(){var r=[-2147483648,8388608,32768,128],o=[24,16,8,0],a=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];return function(n){var t,e,f,h,c,u,v,d,i,l,A,C,g,s=[],w=!0,b=!1,j=0,k=0,m=0,p=n.length,q=1779033703,x=3144134277,y=1013904242,z=2773480762,B=1359893119,D=2600822924,E=528734635,F=1541459225,G=0;do{for(s[0]=G,s[16]=s[1]=s[2]=s[3]=s[4]=s[5]=s[6]=s[7]=s[8]=s[9]=s[10]=s[11]=s[12]=s[13]=s[14]=s[15]=0,e=k;p>j&&64>e;++j)t=n.charCodeAt(j),128>t?s[e>>2]|=t<<o[3&e++]:2048>t?(s[e>>2]|=(192|t>>6)<<o[3&e++],s[e>>2]|=(128|63&t)<<o[3&e++]):55296>t||t>=57344?(s[e>>2]|=(224|t>>12)<<o[3&e++],s[e>>2]|=(128|t>>6&63)<<o[3&e++],s[e>>2]|=(128|63&t)<<o[3&e++]):(t=65536+((1023&t)<<10|1023&n.charCodeAt(++j)),s[e>>2]|=(240|t>>18)<<o[3&e++],s[e>>2]|=(128|t>>12&63)<<o[3&e++],s[e>>2]|=(128|t>>6&63)<<o[3&e++],s[e>>2]|=(128|63&t)<<o[3&e++]);m+=e-k,k=e-64,j==p&&(s[e>>2]|=r[3&e],++j),G=s[16],j>p&&56>e&&(s[15]=m<<3,b=!0);var H=q,I=x,J=y,K=z,L=B,M=D,N=E,O=F;for(f=16;64>f;++f)v=s[f-15],h=(v>>>7|v<<25)^(v>>>18|v<<14)^v>>>3,v=s[f-2],c=(v>>>17|v<<15)^(v>>>19|v<<13)^v>>>10,s[f]=s[f-16]+h+s[f-7]+c<<0;for(g=I&J,f=0;64>f;f+=4)w?(l=704751109,v=s[0]-210244248,O=v-1521486534<<0,K=v+143694565<<0,w=!1):(h=(H>>>2|H<<30)^(H>>>13|H<<19)^(H>>>22|H<<10),c=(L>>>6|L<<26)^(L>>>11|L<<21)^(L>>>25|L<<7),l=H&I,u=l^H&J^g,i=L&M^~L&N,v=O+c+i+a[f]+s[f],d=h+u,O=K+v<<0,K=v+d<<0),h=(K>>>2|K<<30)^(K>>>13|K<<19)^(K>>>22|K<<10),c=(O>>>6|O<<26)^(O>>>11|O<<21)^(O>>>25|O<<7),A=K&H,u=A^K&I^l,i=O&L^~O&M,v=N+c+i+a[f+1]+s[f+1],d=h+u,N=J+v<<0,J=v+d<<0,h=(J>>>2|J<<30)^(J>>>13|J<<19)^(J>>>22|J<<10),c=(N>>>6|N<<26)^(N>>>11|N<<21)^(N>>>25|N<<7),C=J&K,u=C^J&H^A,i=N&O^~N&L,v=M+c+i+a[f+2]+s[f+2],d=h+u,M=I+v<<0,I=v+d<<0,h=(I>>>2|I<<30)^(I>>>13|I<<19)^(I>>>22|I<<10),c=(M>>>6|M<<26)^(M>>>11|M<<21)^(M>>>25|M<<7),g=I&J,u=g^I&K^C,i=M&N^~M&O,v=L+c+i+a[f+3]+s[f+3],d=h+u,L=H+v<<0,H=v+d<<0;q=q+H<<0,x=x+I<<0,y=y+J<<0,z=z+K<<0,B=B+L<<0,D=D+M<<0,E=E+N<<0,F=F+O<<0}while(!b);return[q,x,y,z,B,D,E,F]}}(); | ||
487 | + | ||
488 | +function logRequest(req) { | ||
489 | + var s = req.method + " " + req.url + "\n"; | ||
490 | + var o; | ||
491 | + for (var iter = req.headers.entries(); !(o = iter.next()).done;) | ||
492 | + s += o.value[0] + ": " + o.value[1] + "\n"; | ||
493 | + console.log(s); | ||
494 | +} | ||
495 | +function logError(req, msg) { | ||
496 | + console.log(req.url + ":error:" + msg); | ||
497 | +} | ||
498 | +function logInfo(req, msg) { | ||
499 | + console.log(req.url + ":info:" + msg); | ||
500 | +} | ||
501 | +function logDebug(req, msg) { | ||
502 | + console.log(req.url + ":debug:" + msg); | ||
503 | +} | ||
diff --git a/community/h2o/proxysessionresumption.patch b/community/h2o/proxysessionresumption.patch new file mode 100644 index 0000000000..c7d45336a7 --- /dev/null +++ b/community/h2o/proxysessionresumption.patch | |||
@@ -0,0 +1,134 @@ | |||
1 | Upstream: Yes | ||
2 | Reason: Without this patch proxy ssl session resumptions fails | ||
3 | Url: https://github.com/h2o/h2o/pull/2088 | ||
4 | --- a/include/h2o/socket.h | ||
5 | +++ b/include/h2o/socket.h | ||
6 | @@ -71,6 +71,9 @@ | ||
7 | |||
8 | #define H2O_SOCKET_INITIAL_INPUT_BUFFER_SIZE 4096 | ||
9 | |||
10 | +#define H2O_SESSID_CTX ((const uint8_t*)"h2o") | ||
11 | +#define H2O_SESSID_CTX_LEN (sizeof("h2o") - 1) | ||
12 | + | ||
13 | typedef struct st_h2o_socket_t h2o_socket_t; | ||
14 | |||
15 | typedef void (*h2o_socket_cb)(h2o_socket_t *sock, const char *err); | ||
16 | @@ -266,6 +269,7 @@ | ||
17 | static h2o_iovec_t h2o_socket_log_ssl_cipher(h2o_socket_t *sock, h2o_mem_pool_t *pool); | ||
18 | h2o_iovec_t h2o_socket_log_ssl_cipher_bits(h2o_socket_t *sock, h2o_mem_pool_t *pool); | ||
19 | h2o_iovec_t h2o_socket_log_ssl_session_id(h2o_socket_t *sock, h2o_mem_pool_t *pool); | ||
20 | +int h2o_socket_ssl_new_session_cb(SSL *s, SSL_SESSION *sess); | ||
21 | |||
22 | /** | ||
23 | * compares socket addresses | ||
24 | --- a/lib/common/socket.c | ||
25 | +++ b/lib/common/socket.c | ||
26 | @@ -916,6 +916,8 @@ | ||
27 | static void create_ossl(h2o_socket_t *sock) | ||
28 | { | ||
29 | sock->ssl->ossl = SSL_new(sock->ssl->ssl_ctx); | ||
30 | + /* set app data to be used in h2o_socket_ssl_new_session_cb */ | ||
31 | + SSL_set_app_data(sock->ssl->ossl, sock); | ||
32 | setup_bio(sock); | ||
33 | } | ||
34 | |||
35 | @@ -942,6 +944,26 @@ | ||
36 | } | ||
37 | } | ||
38 | |||
39 | +int h2o_socket_ssl_new_session_cb(SSL *s, SSL_SESSION *sess) | ||
40 | +{ | ||
41 | + h2o_socket_t *sock = (h2o_socket_t *)SSL_get_app_data(s); | ||
42 | + assert(sock != NULL); | ||
43 | + assert(sock->ssl != NULL); | ||
44 | + | ||
45 | + if (!SSL_is_server(s) && sock->ssl->handshake.client.session_cache != NULL | ||
46 | +#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1010100fL | ||
47 | + && SSL_SESSION_is_resumable(sess) | ||
48 | +#endif | ||
49 | + ) { | ||
50 | + h2o_cache_set(sock->ssl->handshake.client.session_cache, h2o_now(h2o_socket_get_loop(sock)), | ||
51 | + sock->ssl->handshake.client.session_cache_key, sock->ssl->handshake.client.session_cache_key_hash, | ||
52 | + h2o_iovec_init(sess, 1)); | ||
53 | + return 1; /* retain ref count */ | ||
54 | + } | ||
55 | + | ||
56 | + return 0; /* drop ref count */ | ||
57 | +} | ||
58 | + | ||
59 | static int on_async_resumption_new(SSL *ssl, SSL_SESSION *session) | ||
60 | { | ||
61 | h2o_iovec_t data; | ||
62 | @@ -992,16 +1014,6 @@ | ||
63 | sock->ssl->record_overhead = 32; /* sufficiently large number that can hold most payloads */ | ||
64 | break; | ||
65 | } | ||
66 | - } | ||
67 | - } | ||
68 | - | ||
69 | - /* set ssl session into the cache */ | ||
70 | - if (sock->ssl->ossl != NULL && !SSL_is_server(sock->ssl->ossl) && sock->ssl->handshake.client.session_cache != NULL) { | ||
71 | - if (err == NULL || err == h2o_socket_error_ssl_cert_name_mismatch) { | ||
72 | - SSL_SESSION *session = SSL_get1_session(sock->ssl->ossl); | ||
73 | - h2o_cache_set(sock->ssl->handshake.client.session_cache, h2o_now(h2o_socket_get_loop(sock)), | ||
74 | - sock->ssl->handshake.client.session_cache_key, sock->ssl->handshake.client.session_cache_key_hash, | ||
75 | - h2o_iovec_init(session, 1)); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | --- a/lib/handler/configurator/proxy.c | ||
80 | +++ b/lib/handler/configurator/proxy.c | ||
81 | @@ -27,6 +27,7 @@ | ||
82 | #include <openssl/ssl.h> | ||
83 | #include "h2o.h" | ||
84 | #include "h2o/configurator.h" | ||
85 | +#include "h2o/socket.h" | ||
86 | |||
87 | struct proxy_configurator_t { | ||
88 | h2o_configurator_t super; | ||
89 | @@ -86,6 +87,9 @@ | ||
90 | { | ||
91 | SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); | ||
92 | SSL_CTX_set_options(ctx, SSL_CTX_get_options(ctx) | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); | ||
93 | + SSL_CTX_set_session_id_context(ctx, H2O_SESSID_CTX, H2O_SESSID_CTX_LEN); | ||
94 | + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE); | ||
95 | + SSL_CTX_sess_set_new_cb(ctx, h2o_socket_ssl_new_session_cb); | ||
96 | return ctx; | ||
97 | } | ||
98 | |||
99 | @@ -119,6 +123,7 @@ | ||
100 | |||
101 | /* create new ctx */ | ||
102 | *ctx = create_ssl_ctx(); | ||
103 | + SSL_CTX_set_session_id_context(*ctx, H2O_SESSID_CTX, H2O_SESSID_CTX_LEN); | ||
104 | SSL_CTX_set_cert_store(*ctx, cert_store); | ||
105 | SSL_CTX_set_verify(*ctx, verify_mode, NULL); | ||
106 | if (new_session_cache != NULL) | ||
107 | --- a/src/main.c | ||
108 | +++ b/src/main.c | ||
109 | @@ -674,9 +674,15 @@ | ||
110 | ssl_options |= SSL_OP_NO_COMPRESSION; | ||
111 | #endif | ||
112 | |||
113 | +#ifdef SSL_OP_NO_RENEGOTIATION | ||
114 | + ssl_options |= SSL_OP_NO_RENEGOTIATION; | ||
115 | +#endif | ||
116 | + | ||
117 | /* setup */ | ||
118 | ssl_ctx = SSL_CTX_new(SSLv23_server_method()); | ||
119 | SSL_CTX_set_options(ssl_ctx, ssl_options); | ||
120 | + | ||
121 | + SSL_CTX_set_session_id_context(ssl_ctx, H2O_SESSID_CTX, H2O_SESSID_CTX_LEN); | ||
122 | |||
123 | setup_ecc_key(ssl_ctx); | ||
124 | if (SSL_CTX_use_certificate_chain_file(ssl_ctx, certificate_file->data.scalar) != 1) { | ||
125 | --- a/src/ssl.c | ||
126 | +++ b/src/ssl.c | ||
127 | @@ -116,6 +116,7 @@ | ||
128 | size_t i; | ||
129 | for (i = 0; i != num_contexts; ++i) { | ||
130 | SSL_CTX_set_session_cache_mode(contexts[i], SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR); | ||
131 | + SSL_CTX_set_session_id_context(contexts[i], H2O_SESSID_CTX, H2O_SESSID_CTX_LEN); | ||
132 | SSL_CTX_set_timeout(contexts[i], conf.lifetime); | ||
133 | } | ||
134 | spawn_cache_cleanup_thread(contexts, num_contexts); | ||
diff --git a/community/h2o/sessiontickettest.patch b/community/h2o/sessiontickettest.patch new file mode 100644 index 0000000000..86ea5ba4ca --- /dev/null +++ b/community/h2o/sessiontickettest.patch | |||
@@ -0,0 +1,140 @@ | |||
1 | Upstream: Yes | ||
2 | Reason: Without this patch the session ticket test fails | ||
3 | Url: https://github.com/h2o/h2o/pull/2334 | ||
4 | --- a/t/40session-ticket.t | ||
5 | +++ b/t/40session-ticket.t | ||
6 | @@ -3,6 +3,7 @@ | ||
7 | use File::Temp qw(tempdir); | ||
8 | use Net::EmptyPort qw(check_port empty_port); | ||
9 | use Test::More; | ||
10 | +use Time::HiRes qw(sleep); | ||
11 | use t::Util; | ||
12 | |||
13 | plan skip_all => "could not find openssl" | ||
14 | @@ -17,16 +18,16 @@ | ||
15 | mode: ticket | ||
16 | EOT | ||
17 | sub { | ||
18 | - is test(), "New"; | ||
19 | - test(); # openssl 0.9.8 seems to return "New" (maybe because in the first run we did not specify -sess_in) | ||
20 | - is test(), "Reused"; | ||
21 | - is test(), "Reused"; | ||
22 | + sleep 5; | ||
23 | + is test("new"), "New"; | ||
24 | + is test("reuse"), "Reused"; | ||
25 | + is test("reuse"), "Reused"; | ||
26 | }); | ||
27 | spawn_with(<< "EOT", | ||
28 | mode: ticket | ||
29 | EOT | ||
30 | sub { | ||
31 | - is test(), "New"; | ||
32 | + is test("reuse"), "New"; | ||
33 | }); | ||
34 | }; | ||
35 | |||
36 | @@ -36,11 +37,13 @@ | ||
37 | mode: ticket | ||
38 | ticket-store: file | ||
39 | ticket-file: $tickets_file | ||
40 | +num-threads: 1 | ||
41 | EOT | ||
42 | sub { | ||
43 | - is test(), "New"; | ||
44 | - is test(), "Reused"; | ||
45 | - is test(), "Reused"; | ||
46 | + sleep 5; # wait for tickets file to be loaded | ||
47 | + is test("new"), "New"; | ||
48 | + is test("reuse"), "Reused"; | ||
49 | + is test("reuse"), "Reused"; | ||
50 | }); | ||
51 | spawn_with(<< "EOT", | ||
52 | mode: ticket | ||
53 | @@ -48,8 +51,8 @@ | ||
54 | ticket-file: $tickets_file | ||
55 | EOT | ||
56 | sub { | ||
57 | - sleep 1; | ||
58 | - is test(), "Reused"; | ||
59 | + sleep 5; # wait for tickets file to be loaded | ||
60 | + is test("reuse"), "Reused"; | ||
61 | }); | ||
62 | }; | ||
63 | |||
64 | @@ -59,11 +62,13 @@ | ||
65 | mode: ticket | ||
66 | ticket-store: file | ||
67 | ticket-file: $tickets_file | ||
68 | +num-threads: 1 | ||
69 | EOT | ||
70 | sub { | ||
71 | - is test(), "New"; | ||
72 | - is test(), "New"; | ||
73 | - is test(), "New"; | ||
74 | + sleep 5; # wait for tickets file to be loaded | ||
75 | + is test("new"), "New"; | ||
76 | + is test("reuse"), "New"; | ||
77 | + is test("reuse"), "New"; | ||
78 | }); | ||
79 | }; | ||
80 | |||
81 | @@ -86,15 +91,17 @@ | ||
82 | host: 127.0.0.1 | ||
83 | port: $memc_port | ||
84 | protocol: $memc_proto | ||
85 | +num-threads: 1 | ||
86 | EOT | ||
87 | spawn_with($conf, sub { | ||
88 | - is test(), "New"; | ||
89 | - is test(), "Reused"; | ||
90 | - is test(), "Reused"; | ||
91 | + sleep 5; | ||
92 | + is test("new"), "New"; | ||
93 | + is test("reuse"), "Reused"; | ||
94 | + is test("reuse"), "Reused"; | ||
95 | }); | ||
96 | spawn_with($conf, sub { | ||
97 | - sleep 1; | ||
98 | - is test(), "Reused"; | ||
99 | + sleep 5; | ||
100 | + is test("reuse"), "Reused"; | ||
101 | }); | ||
102 | }; | ||
103 | $doit->("binary"); | ||
104 | @@ -120,14 +127,33 @@ | ||
105 | } | ||
106 | |||
107 | sub test { | ||
108 | + my $sess_mode = shift @_; # reuse or new | ||
109 | + | ||
110 | + # 'openssl -sess_out' writes a session file ONLY if | ||
111 | + # a session was handed out by the server! | ||
112 | + | ||
113 | + my $cmd_opts; | ||
114 | + if ( $sess_mode eq 'new' ) { | ||
115 | + unlink "$tempdir/session"; | ||
116 | + $cmd_opts = "-sess_out $tempdir/session"; | ||
117 | + } else { | ||
118 | + return "no session to reuse $tempdir/session does no exist" unless ( -e "$tempdir/session" ); | ||
119 | + $cmd_opts = "-sess_in $tempdir/session"; | ||
120 | + } | ||
121 | + | ||
122 | my $lines = do { | ||
123 | - my $cmd_opts = (-e "$tempdir/session" ? "-sess_in $tempdir/session" : "") . " -sess_out $tempdir/session"; | ||
124 | - open my $fh, "-|", "openssl s_client $cmd_opts -connect 127.0.0.1:$server->{tls_port} 2>&1 < /dev/null" | ||
125 | + open my $fh, "-|", "openssl s_client $cmd_opts -prexit -servername 127.0.0.1 -connect 127.0.0.1:$server->{tls_port} -tls1_2 2>&1" | ||
126 | or die "failed to open pipe:$!"; | ||
127 | local $/; | ||
128 | <$fh>; | ||
129 | }; | ||
130 | + print $lines; | ||
131 | $lines =~ m{---\n(New|Reused),}s | ||
132 | or die "failed to parse the output of s_client:{{{$lines}}}"; | ||
133 | - $1; | ||
134 | + | ||
135 | + if ( $sess_mode eq 'new' ) { | ||
136 | + -e "$tempdir/session" ? $1 : "no session created $tempdir/session does no exist"; | ||
137 | + } else { | ||
138 | + $1; | ||
139 | + } | ||
140 | } | ||
diff --git a/testing/perl-http-entity-parser/APKBUILD b/community/perl-http-entity-parser/APKBUILD index f5541a00ab..f5541a00ab 100644 --- a/testing/perl-http-entity-parser/APKBUILD +++ b/community/perl-http-entity-parser/APKBUILD | |||
diff --git a/testing/perl-http-multipartparser/APKBUILD b/community/perl-http-multipartparser/APKBUILD index 262cd14b43..262cd14b43 100644 --- a/testing/perl-http-multipartparser/APKBUILD +++ b/community/perl-http-multipartparser/APKBUILD | |||
diff --git a/testing/perl-protocol-http2/APKBUILD b/community/perl-protocol-http2/APKBUILD index 11bd53dd6c..11bd53dd6c 100644 --- a/testing/perl-protocol-http2/APKBUILD +++ b/community/perl-protocol-http2/APKBUILD | |||
diff --git a/testing/perl-www-form-urlencoded/APKBUILD b/community/perl-www-form-urlencoded/APKBUILD index 57ab9bb2d3..57ab9bb2d3 100644 --- a/testing/perl-www-form-urlencoded/APKBUILD +++ b/community/perl-www-form-urlencoded/APKBUILD | |||