aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Gopkg.lock46
-rw-r--r--Gopkg.toml68
-rw-r--r--Makefile11
-rw-r--r--vendor/github.com/hashicorp/golang-lru/.gitignore23
-rw-r--r--vendor/github.com/hashicorp/golang-lru/2q.go212
-rw-r--r--vendor/github.com/hashicorp/golang-lru/2q_test.go306
-rw-r--r--vendor/github.com/hashicorp/golang-lru/LICENSE362
-rw-r--r--vendor/github.com/hashicorp/golang-lru/README.md25
-rw-r--r--vendor/github.com/hashicorp/golang-lru/arc.go257
-rw-r--r--vendor/github.com/hashicorp/golang-lru/arc_test.go377
-rw-r--r--vendor/github.com/hashicorp/golang-lru/lru.go114
-rw-r--r--vendor/github.com/hashicorp/golang-lru/lru_test.go221
-rw-r--r--vendor/github.com/hashicorp/golang-lru/simplelru/lru.go160
-rw-r--r--vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go167
-rw-r--r--vendor/github.com/miekg/dns/.gitignore4
-rw-r--r--vendor/github.com/miekg/dns/.travis.yml14
-rw-r--r--vendor/github.com/miekg/dns/AUTHORS1
-rw-r--r--vendor/github.com/miekg/dns/CONTRIBUTORS9
-rw-r--r--vendor/github.com/miekg/dns/COPYRIGHT9
-rw-r--r--vendor/github.com/miekg/dns/LICENSE32
-rw-r--r--vendor/github.com/miekg/dns/README.md162
-rw-r--r--vendor/github.com/miekg/dns/client.go467
-rw-r--r--vendor/github.com/miekg/dns/client_test.go511
-rw-r--r--vendor/github.com/miekg/dns/clientconfig.go131
-rw-r--r--vendor/github.com/miekg/dns/clientconfig_test.go87
-rw-r--r--vendor/github.com/miekg/dns/compress_generate.go184
-rw-r--r--vendor/github.com/miekg/dns/dane.go43
-rw-r--r--vendor/github.com/miekg/dns/defaults.go285
-rw-r--r--vendor/github.com/miekg/dns/dns.go104
-rw-r--r--vendor/github.com/miekg/dns/dns_bench_test.go211
-rw-r--r--vendor/github.com/miekg/dns/dns_test.go450
-rw-r--r--vendor/github.com/miekg/dns/dnssec.go720
-rw-r--r--vendor/github.com/miekg/dns/dnssec_keygen.go156
-rw-r--r--vendor/github.com/miekg/dns/dnssec_keyscan.go249
-rw-r--r--vendor/github.com/miekg/dns/dnssec_privkey.go85
-rw-r--r--vendor/github.com/miekg/dns/dnssec_test.go733
-rw-r--r--vendor/github.com/miekg/dns/doc.go251
-rw-r--r--vendor/github.com/miekg/dns/dyn_test.go3
-rw-r--r--vendor/github.com/miekg/dns/edns.go597
-rw-r--r--vendor/github.com/miekg/dns/edns_test.go68
-rw-r--r--vendor/github.com/miekg/dns/example_test.go146
-rw-r--r--vendor/github.com/miekg/dns/format.go87
-rw-r--r--vendor/github.com/miekg/dns/fuzz_test.go25
-rw-r--r--vendor/github.com/miekg/dns/generate.go159
-rw-r--r--vendor/github.com/miekg/dns/issue_test.go68
-rw-r--r--vendor/github.com/miekg/dns/labels.go171
-rw-r--r--vendor/github.com/miekg/dns/labels_test.go203
-rw-r--r--vendor/github.com/miekg/dns/msg.go1159
-rw-r--r--vendor/github.com/miekg/dns/msg_generate.go349
-rw-r--r--vendor/github.com/miekg/dns/msg_helpers.go633
-rw-r--r--vendor/github.com/miekg/dns/msg_test.go124
-rw-r--r--vendor/github.com/miekg/dns/nsecx.go106
-rw-r--r--vendor/github.com/miekg/dns/nsecx_test.go133
-rw-r--r--vendor/github.com/miekg/dns/parse_test.go1540
-rw-r--r--vendor/github.com/miekg/dns/privaterr.go149
-rw-r--r--vendor/github.com/miekg/dns/privaterr_test.go171
-rw-r--r--vendor/github.com/miekg/dns/rawmsg.go49
-rw-r--r--vendor/github.com/miekg/dns/remote_test.go19
-rw-r--r--vendor/github.com/miekg/dns/reverse.go38
-rw-r--r--vendor/github.com/miekg/dns/sanitize.go84
-rw-r--r--vendor/github.com/miekg/dns/sanitize_test.go84
-rw-r--r--vendor/github.com/miekg/dns/scan.go987
-rw-r--r--vendor/github.com/miekg/dns/scan_rr.go2184
-rw-r--r--vendor/github.com/miekg/dns/scanner.go43
-rw-r--r--vendor/github.com/miekg/dns/server.go734
-rw-r--r--vendor/github.com/miekg/dns/server_test.go719
-rw-r--r--vendor/github.com/miekg/dns/sig0.go218
-rw-r--r--vendor/github.com/miekg/dns/sig0_test.go89
-rw-r--r--vendor/github.com/miekg/dns/singleinflight.go57
-rw-r--r--vendor/github.com/miekg/dns/smimea.go47
-rw-r--r--vendor/github.com/miekg/dns/tlsa.go47
-rw-r--r--vendor/github.com/miekg/dns/tsig.go383
-rw-r--r--vendor/github.com/miekg/dns/tsig_test.go37
-rw-r--r--vendor/github.com/miekg/dns/types.go1287
-rw-r--r--vendor/github.com/miekg/dns/types_generate.go271
-rw-r--r--vendor/github.com/miekg/dns/types_test.go74
-rw-r--r--vendor/github.com/miekg/dns/udp.go34
-rw-r--r--vendor/github.com/miekg/dns/udp_linux.go105
-rw-r--r--vendor/github.com/miekg/dns/udp_other.go15
-rw-r--r--vendor/github.com/miekg/dns/udp_windows.go29
-rw-r--r--vendor/github.com/miekg/dns/update.go106
-rw-r--r--vendor/github.com/miekg/dns/update_test.go145
-rw-r--r--vendor/github.com/miekg/dns/xfr.go255
-rw-r--r--vendor/github.com/miekg/dns/xfr_test.go184
-rw-r--r--vendor/github.com/miekg/dns/zcompress.go119
-rw-r--r--vendor/github.com/miekg/dns/zmsg.go3565
-rw-r--r--vendor/github.com/miekg/dns/ztypes.go857
-rw-r--r--vendor/golang.org/x/net/.gitattributes10
-rw-r--r--vendor/golang.org/x/net/.gitignore2
-rw-r--r--vendor/golang.org/x/net/AUTHORS3
-rw-r--r--vendor/golang.org/x/net/CONTRIBUTING.md31
-rw-r--r--vendor/golang.org/x/net/CONTRIBUTORS3
-rw-r--r--vendor/golang.org/x/net/LICENSE27
-rw-r--r--vendor/golang.org/x/net/PATENTS22
-rw-r--r--vendor/golang.org/x/net/README3
-rw-r--r--vendor/golang.org/x/net/codereview.cfg1
-rw-r--r--vendor/golang.org/x/net/context/context.go156
-rw-r--r--vendor/golang.org/x/net/context/context_test.go583
-rw-r--r--vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go74
-rw-r--r--vendor/golang.org/x/net/context/ctxhttp/ctxhttp_17_test.go29
-rw-r--r--vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go147
-rw-r--r--vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17_test.go79
-rw-r--r--vendor/golang.org/x/net/context/ctxhttp/ctxhttp_test.go105
-rw-r--r--vendor/golang.org/x/net/context/go17.go72
-rw-r--r--vendor/golang.org/x/net/context/pre_go17.go300
-rw-r--r--vendor/golang.org/x/net/context/withtimeout_test.go26
-rw-r--r--vendor/golang.org/x/net/http2/.gitignore2
-rw-r--r--vendor/golang.org/x/net/http2/Dockerfile51
-rw-r--r--vendor/golang.org/x/net/http2/Makefile3
-rw-r--r--vendor/golang.org/x/net/http2/README20
-rw-r--r--vendor/golang.org/x/net/http2/ciphers.go641
-rw-r--r--vendor/golang.org/x/net/http2/ciphers_test.go309
-rw-r--r--vendor/golang.org/x/net/http2/client_conn_pool.go256
-rw-r--r--vendor/golang.org/x/net/http2/configure_transport.go80
-rw-r--r--vendor/golang.org/x/net/http2/databuffer.go146
-rw-r--r--vendor/golang.org/x/net/http2/databuffer_test.go157
-rw-r--r--vendor/golang.org/x/net/http2/errors.go130
-rw-r--r--vendor/golang.org/x/net/http2/errors_test.go24
-rw-r--r--vendor/golang.org/x/net/http2/flow.go50
-rw-r--r--vendor/golang.org/x/net/http2/flow_test.go53
-rw-r--r--vendor/golang.org/x/net/http2/frame.go1579
-rw-r--r--vendor/golang.org/x/net/http2/frame_test.go1191
-rw-r--r--vendor/golang.org/x/net/http2/go16.go16
-rw-r--r--vendor/golang.org/x/net/http2/go17.go106
-rw-r--r--vendor/golang.org/x/net/http2/go17_not18.go36
-rw-r--r--vendor/golang.org/x/net/http2/go18.go54
-rw-r--r--vendor/golang.org/x/net/http2/go18_test.go79
-rw-r--r--vendor/golang.org/x/net/http2/go19.go16
-rw-r--r--vendor/golang.org/x/net/http2/go19_test.go60
-rw-r--r--vendor/golang.org/x/net/http2/gotrack.go170
-rw-r--r--vendor/golang.org/x/net/http2/gotrack_test.go33
-rw-r--r--vendor/golang.org/x/net/http2/headermap.go78
-rw-r--r--vendor/golang.org/x/net/http2/hpack/encode.go240
-rw-r--r--vendor/golang.org/x/net/http2/hpack/encode_test.go386
-rw-r--r--vendor/golang.org/x/net/http2/hpack/hpack.go490
-rw-r--r--vendor/golang.org/x/net/http2/hpack/hpack_test.go722
-rw-r--r--vendor/golang.org/x/net/http2/hpack/huffman.go212
-rw-r--r--vendor/golang.org/x/net/http2/hpack/tables.go479
-rw-r--r--vendor/golang.org/x/net/http2/hpack/tables_test.go214
-rw-r--r--vendor/golang.org/x/net/http2/http2.go387
-rw-r--r--vendor/golang.org/x/net/http2/http2_test.go199
-rw-r--r--vendor/golang.org/x/net/http2/not_go16.go21
-rw-r--r--vendor/golang.org/x/net/http2/not_go17.go87
-rw-r--r--vendor/golang.org/x/net/http2/not_go18.go27
-rw-r--r--vendor/golang.org/x/net/http2/not_go19.go16
-rw-r--r--vendor/golang.org/x/net/http2/pipe.go163
-rw-r--r--vendor/golang.org/x/net/http2/pipe_test.go130
-rw-r--r--vendor/golang.org/x/net/http2/server.go2842
-rw-r--r--vendor/golang.org/x/net/http2/server_push_test.go521
-rw-r--r--vendor/golang.org/x/net/http2/server_test.go3687
-rw-r--r--vendor/golang.org/x/net/http2/transport.go2123
-rw-r--r--vendor/golang.org/x/net/http2/transport_test.go2971
-rw-r--r--vendor/golang.org/x/net/http2/write.go370
-rw-r--r--vendor/golang.org/x/net/http2/writesched.go242
-rw-r--r--vendor/golang.org/x/net/http2/writesched_priority.go452
-rw-r--r--vendor/golang.org/x/net/http2/writesched_priority_test.go541
-rw-r--r--vendor/golang.org/x/net/http2/writesched_random.go72
-rw-r--r--vendor/golang.org/x/net/http2/writesched_random_test.go44
-rw-r--r--vendor/golang.org/x/net/http2/writesched_test.go125
-rw-r--r--vendor/golang.org/x/net/http2/z_spec_test.go356
-rw-r--r--vendor/golang.org/x/net/idna/example_test.go65
-rw-r--r--vendor/golang.org/x/net/idna/idna.go668
-rw-r--r--vendor/golang.org/x/net/idna/idna_test.go43
-rw-r--r--vendor/golang.org/x/net/idna/punycode.go203
-rw-r--r--vendor/golang.org/x/net/idna/punycode_test.go198
-rw-r--r--vendor/golang.org/x/net/idna/tables.go4477
-rw-r--r--vendor/golang.org/x/net/idna/trie.go72
-rw-r--r--vendor/golang.org/x/net/idna/trieval.go114
-rw-r--r--vendor/golang.org/x/net/internal/timeseries/timeseries.go525
-rw-r--r--vendor/golang.org/x/net/internal/timeseries/timeseries_test.go170
-rw-r--r--vendor/golang.org/x/net/lex/httplex/httplex.go351
-rw-r--r--vendor/golang.org/x/net/lex/httplex/httplex_test.go119
-rw-r--r--vendor/golang.org/x/net/trace/events.go532
-rw-r--r--vendor/golang.org/x/net/trace/histogram.go365
-rw-r--r--vendor/golang.org/x/net/trace/histogram_test.go325
-rw-r--r--vendor/golang.org/x/net/trace/trace.go1066
-rw-r--r--vendor/golang.org/x/net/trace/trace_go16.go21
-rw-r--r--vendor/golang.org/x/net/trace/trace_go17.go21
-rw-r--r--vendor/golang.org/x/net/trace/trace_test.go178
179 files changed, 38 insertions, 60610 deletions
diff --git a/Gopkg.lock b/Gopkg.lock
index 93ab1f37f..7c99fe017 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -68,6 +68,12 @@
version = "v1.1.0"
[[projects]]
+ branch = "master"
+ name = "github.com/dnstap/golang-dnstap"
+ packages = ["."]
+ revision = "c32b266c26b040b00f522a0183527a9eb2a1cf8b"
+
+[[projects]]
name = "github.com/docker/distribution"
packages = ["digest","reference"]
revision = "a25b9ef0c9fe242ac04bb20d3a028442b7d266b6"
@@ -98,6 +104,12 @@
version = "v1.2"
[[projects]]
+ branch = "master"
+ name = "github.com/farsightsec/golang-framestream"
+ packages = ["."]
+ revision = "dec85654e8b8cf6712870afb14ee53d1c98cd5e2"
+
+[[projects]]
name = "github.com/fsnotify/fsnotify"
packages = ["."]
revision = "629574ca2a5df945712d3079857300b5e4da0236"
@@ -183,12 +195,6 @@
[[projects]]
branch = "master"
- name = "github.com/hashicorp/golang-lru"
- packages = [".","simplelru"]
- revision = "0a025b7e63adc15a622f29b0b2c4c3848243bbf6"
-
-[[projects]]
- branch = "master"
name = "github.com/howeyc/gopass"
packages = ["."]
revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
@@ -230,12 +236,6 @@
version = "v1.0.0"
[[projects]]
- branch = "master"
- name = "github.com/miekg/dns"
- packages = ["."]
- revision = "e78414ef75607394ad7d917824f07f381df2eafa"
-
-[[projects]]
name = "github.com/opentracing/opentracing-go"
packages = [".","ext","log"]
revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
@@ -315,12 +315,6 @@
[[projects]]
branch = "master"
- name = "golang.org/x/net"
- packages = ["context","context/ctxhttp","http2","http2/hpack","idna","internal/timeseries","lex/httplex","trace"]
- revision = "3da985ce5951d99de868be4385f21ea6c2b22f24"
-
-[[projects]]
- branch = "master"
name = "golang.org/x/oauth2"
packages = [".","google","internal","jws","jwt"]
revision = "f047394b6d14284165300fd82dad67edb3a4d7f6"
@@ -334,7 +328,7 @@
[[projects]]
branch = "master"
name = "golang.org/x/text"
- packages = ["internal/gen","internal/triegen","internal/ucd","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable","width"]
+ packages = ["internal/gen","internal/triegen","internal/ucd","transform","unicode/cldr","unicode/norm","width"]
revision = "4ee4af566555f5fbe026368b75596286a312663a"
[[projects]]
@@ -373,21 +367,9 @@
revision = "1195e3a8ee1a529d53eed7c624527a68555ddf1f"
version = "v1.5.1"
-[[projects]]
- branch = "master"
- name = "github.com/farsightsec/golang-framestream"
- packages = ["."]
- revision = "dec85654e8b8cf6712870afb14ee53d1c98cd5e2"
-
-[[projects]]
- branch = "master"
- name = "github.com/dnstap/golang-dnstap"
- packages = ["."]
- revision = "c32b266c26b040b00f522a0183527a9eb2a1cf8b"
-
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
- inputs-digest = "a59be89c7a92b81f951b47efd072c2af04fb66b4f2b7a780cadb7466559d0d6b"
+ inputs-digest = "0ddaab68018c7f38bccad1d9932df961ae52544dc56e3c0060ce1c28e5da0a47"
solver-name = "gps-cdcl"
solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
index 8ea3dba0a..62d933fd8 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -1,52 +1,18 @@
+ignored = [
+ "github.com/mholt/caddy",
+ "github.com/mholt/caddy/caddyfile",
+ "github.com/mholt/caddy/startupshutdown",
+ "github.com/miekg/dns",
+ "golang.org/x/net/context",
+ "golang.org/x/net/context/ctxhttp",
+ "golang.org/x/net/http2",
+ "golang.org/x/net/http2/hpack",
+ "golang.org/x/net/idna",
+ "golang.org/x/net/internal/timeseries",
+ "golang.org/x/net/lex/httplex",
+ "golang.org/x/net/trace",
+]
-## Gopkg.toml example (these lines may be deleted)
-
-## "required" lists a set of packages (not projects) that must be included in
-## Gopkg.lock. This list is merged with the set of packages imported by the current
-## project. Use it when your project needs a package it doesn't explicitly import -
-## including "main" packages.
-# required = ["github.com/user/thing/cmd/thing"]
-
-## "ignored" lists a set of packages (not projects) that are ignored when
-## dep statically analyzes source code. Ignored packages can be in this project,
-## or in a dependency.
-ignored = ["github.com/mholt/caddy", "github.com/mholt/caddy/caddyfile", "github.com/mholt/caddy/startupshutdown"]
-
-## Dependencies define constraints on dependent projects. They are respected by
-## dep whether coming from the Gopkg.toml of the current project or a dependency.
-# [[dependencies]]
-## Required: the root import path of the project being constrained.
-# name = "github.com/user/project"
-#
-## Recommended: the version constraint to enforce for the project.
-## Only one of "branch", "version" or "revision" can be specified.
-# version = "1.0.0"
-# branch = "master"
-# revision = "abc123"
-#
-## Optional: an alternate location (URL or import path) for the project's source.
-# source = "https://github.com/myfork/package.git"
-
-## Overrides have the same structure as [[dependencies]], but supercede all
-## [[dependencies]] declarations from all projects. Only the current project's
-## [[overrides]] are applied.
-##
-## Overrides are a sledgehammer. Use them only as a last resort.
-# [[overrides]]
-## Required: the root import path of the project being constrained.
-# name = "github.com/user/project"
-#
-## Optional: specifying a version constraint override will cause all other
-## constraints on this project to be ignored; only the overriden constraint
-## need be satisfied.
-## Again, only one of "branch", "version" or "revision" can be specified.
-# version = "1.0.0"
-# branch = "master"
-# revision = "abc123"
-#
-## Optional: specifying an alternate source location as an override will
-## enforce that the alternate location is used for that project, regardless of
-## what source location any dependent projects specify.
-# source = "https://github.com/myfork/package.git"
-
-
+[[constraint]]
+ name = "github.com/openzipkin/zipkin-go-opentracing"
+ version = "v0.2.3"
diff --git a/Makefile b/Makefile
index 1fbbbdd5b..f4bfd2686 100644
--- a/Makefile
+++ b/Makefile
@@ -7,11 +7,11 @@ all: coredns
# Phony this to ensure we always build the binary.
# TODO: Add .go file dependencies.
.PHONY: coredns
-coredns: check caddy
+coredns: check godeps
go build $(BUILD_VERBOSE) -ldflags="-s -w"
.PHONY: deps
-deps: core/zmiddleware.go core/dnsserver/zdirectives.go caddy
+deps: core/zmiddleware.go core/dnsserver/zdirectives.go godeps
go get -u github.com/golang/lint/golint
.PHONY: check
@@ -25,9 +25,12 @@ test: check
testk8s: check
go test -race $(TEST_VERBOSE) -tags=k8s -run 'TestKubernetes' ./test ./middleware/kubernetes/...
-.PHONY: caddy
-caddy:
+.PHONY: godeps
+godeps:
go get github.com/mholt/caddy
+ go get github.com/miekg/dns
+ go get golang.org/x/net/context
+ go get golang.org/x/text
.PHONY: coverage
coverage: check
diff --git a/vendor/github.com/hashicorp/golang-lru/.gitignore b/vendor/github.com/hashicorp/golang-lru/.gitignore
deleted file mode 100644
index 836562412..000000000
--- a/vendor/github.com/hashicorp/golang-lru/.gitignore
+++ /dev/null
@@ -1,23 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
diff --git a/vendor/github.com/hashicorp/golang-lru/2q.go b/vendor/github.com/hashicorp/golang-lru/2q.go
deleted file mode 100644
index 337d96329..000000000
--- a/vendor/github.com/hashicorp/golang-lru/2q.go
+++ /dev/null
@@ -1,212 +0,0 @@
-package lru
-
-import (
- "fmt"
- "sync"
-
- "github.com/hashicorp/golang-lru/simplelru"
-)
-
-const (
- // Default2QRecentRatio is the ratio of the 2Q cache dedicated
- // to recently added entries that have only been accessed once.
- Default2QRecentRatio = 0.25
-
- // Default2QGhostEntries is the default ratio of ghost
- // entries kept to track entries recently evicted
- Default2QGhostEntries = 0.50
-)
-
-// TwoQueueCache is a thread-safe fixed size 2Q cache.
-// 2Q is an enhancement over the standard LRU cache
-// in that it tracks both frequently and recently used
-// entries separately. This avoids a burst in access to new
-// entries from evicting frequently used entries. It adds some
-// additional tracking overhead to the standard LRU cache, and is
-// computationally about 2x the cost, and adds some metadata over
-// head. The ARCCache is similar, but does not require setting any
-// parameters.
-type TwoQueueCache struct {
- size int
- recentSize int
-
- recent *simplelru.LRU
- frequent *simplelru.LRU
- recentEvict *simplelru.LRU
- lock sync.RWMutex
-}
-
-// New2Q creates a new TwoQueueCache using the default
-// values for the parameters.
-func New2Q(size int) (*TwoQueueCache, error) {
- return New2QParams(size, Default2QRecentRatio, Default2QGhostEntries)
-}
-
-// New2QParams creates a new TwoQueueCache using the provided
-// parameter values.
-func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCache, error) {
- if size <= 0 {
- return nil, fmt.Errorf("invalid size")
- }
- if recentRatio < 0.0 || recentRatio > 1.0 {
- return nil, fmt.Errorf("invalid recent ratio")
- }
- if ghostRatio < 0.0 || ghostRatio > 1.0 {
- return nil, fmt.Errorf("invalid ghost ratio")
- }
-
- // Determine the sub-sizes
- recentSize := int(float64(size) * recentRatio)
- evictSize := int(float64(size) * ghostRatio)
-
- // Allocate the LRUs
- recent, err := simplelru.NewLRU(size, nil)
- if err != nil {
- return nil, err
- }
- frequent, err := simplelru.NewLRU(size, nil)
- if err != nil {
- return nil, err
- }
- recentEvict, err := simplelru.NewLRU(evictSize, nil)
- if err != nil {
- return nil, err
- }
-
- // Initialize the cache
- c := &TwoQueueCache{
- size: size,
- recentSize: recentSize,
- recent: recent,
- frequent: frequent,
- recentEvict: recentEvict,
- }
- return c, nil
-}
-
-func (c *TwoQueueCache) Get(key interface{}) (interface{}, bool) {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- // Check if this is a frequent value
- if val, ok := c.frequent.Get(key); ok {
- return val, ok
- }
-
- // If the value is contained in recent, then we
- // promote it to frequent
- if val, ok := c.recent.Peek(key); ok {
- c.recent.Remove(key)
- c.frequent.Add(key, val)
- return val, ok
- }
-
- // No hit
- return nil, false
-}
-
-func (c *TwoQueueCache) Add(key, value interface{}) {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- // Check if the value is frequently used already,
- // and just update the value
- if c.frequent.Contains(key) {
- c.frequent.Add(key, value)
- return
- }
-
- // Check if the value is recently used, and promote
- // the value into the frequent list
- if c.recent.Contains(key) {
- c.recent.Remove(key)
- c.frequent.Add(key, value)
- return
- }
-
- // If the value was recently evicted, add it to the
- // frequently used list
- if c.recentEvict.Contains(key) {
- c.ensureSpace(true)
- c.recentEvict.Remove(key)
- c.frequent.Add(key, value)
- return
- }
-
- // Add to the recently seen list
- c.ensureSpace(false)
- c.recent.Add(key, value)
- return
-}
-
-// ensureSpace is used to ensure we have space in the cache
-func (c *TwoQueueCache) ensureSpace(recentEvict bool) {
- // If we have space, nothing to do
- recentLen := c.recent.Len()
- freqLen := c.frequent.Len()
- if recentLen+freqLen < c.size {
- return
- }
-
- // If the recent buffer is larger than
- // the target, evict from there
- if recentLen > 0 && (recentLen > c.recentSize || (recentLen == c.recentSize && !recentEvict)) {
- k, _, _ := c.recent.RemoveOldest()
- c.recentEvict.Add(k, nil)
- return
- }
-
- // Remove from the frequent list otherwise
- c.frequent.RemoveOldest()
-}
-
-func (c *TwoQueueCache) Len() int {
- c.lock.RLock()
- defer c.lock.RUnlock()
- return c.recent.Len() + c.frequent.Len()
-}
-
-func (c *TwoQueueCache) Keys() []interface{} {
- c.lock.RLock()
- defer c.lock.RUnlock()
- k1 := c.frequent.Keys()
- k2 := c.recent.Keys()
- return append(k1, k2...)
-}
-
-func (c *TwoQueueCache) Remove(key interface{}) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if c.frequent.Remove(key) {
- return
- }
- if c.recent.Remove(key) {
- return
- }
- if c.recentEvict.Remove(key) {
- return
- }
-}
-
-func (c *TwoQueueCache) Purge() {
- c.lock.Lock()
- defer c.lock.Unlock()
- c.recent.Purge()
- c.frequent.Purge()
- c.recentEvict.Purge()
-}
-
-func (c *TwoQueueCache) Contains(key interface{}) bool {
- c.lock.RLock()
- defer c.lock.RUnlock()
- return c.frequent.Contains(key) || c.recent.Contains(key)
-}
-
-func (c *TwoQueueCache) Peek(key interface{}) (interface{}, bool) {
- c.lock.RLock()
- defer c.lock.RUnlock()
- if val, ok := c.frequent.Peek(key); ok {
- return val, ok
- }
- return c.recent.Peek(key)
-}
diff --git a/vendor/github.com/hashicorp/golang-lru/2q_test.go b/vendor/github.com/hashicorp/golang-lru/2q_test.go
deleted file mode 100644
index 1b0f35181..000000000
--- a/vendor/github.com/hashicorp/golang-lru/2q_test.go
+++ /dev/null
@@ -1,306 +0,0 @@
-package lru
-
-import (
- "math/rand"
- "testing"
-)
-
-func Benchmark2Q_Rand(b *testing.B) {
- l, err := New2Q(8192)
- if err != nil {
- b.Fatalf("err: %v", err)
- }
-
- trace := make([]int64, b.N*2)
- for i := 0; i < b.N*2; i++ {
- trace[i] = rand.Int63() % 32768
- }
-
- b.ResetTimer()
-
- var hit, miss int
- for i := 0; i < 2*b.N; i++ {
- if i%2 == 0 {
- l.Add(trace[i], trace[i])
- } else {
- _, ok := l.Get(trace[i])
- if ok {
- hit++
- } else {
- miss++
- }
- }
- }
- b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
-}
-
-func Benchmark2Q_Freq(b *testing.B) {
- l, err := New2Q(8192)
- if err != nil {
- b.Fatalf("err: %v", err)
- }
-
- trace := make([]int64, b.N*2)
- for i := 0; i < b.N*2; i++ {
- if i%2 == 0 {
- trace[i] = rand.Int63() % 16384
- } else {
- trace[i] = rand.Int63() % 32768
- }
- }
-
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- l.Add(trace[i], trace[i])
- }
- var hit, miss int
- for i := 0; i < b.N; i++ {
- _, ok := l.Get(trace[i])
- if ok {
- hit++
- } else {
- miss++
- }
- }
- b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
-}
-
-func Test2Q_RandomOps(t *testing.T) {
- size := 128
- l, err := New2Q(128)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- n := 200000
- for i := 0; i < n; i++ {
- key := rand.Int63() % 512
- r := rand.Int63()
- switch r % 3 {
- case 0:
- l.Add(key, key)
- case 1:
- l.Get(key)
- case 2:
- l.Remove(key)
- }
-
- if l.recent.Len()+l.frequent.Len() > size {
- t.Fatalf("bad: recent: %d freq: %d",
- l.recent.Len(), l.frequent.Len())
- }
- }
-}
-
-func Test2Q_Get_RecentToFrequent(t *testing.T) {
- l, err := New2Q(128)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Touch all the entries, should be in t1
- for i := 0; i < 128; i++ {
- l.Add(i, i)
- }
- if n := l.recent.Len(); n != 128 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
-
- // Get should upgrade to t2
- for i := 0; i < 128; i++ {
- _, ok := l.Get(i)
- if !ok {
- t.Fatalf("missing: %d", i)
- }
- }
- if n := l.recent.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 128 {
- t.Fatalf("bad: %d", n)
- }
-
- // Get be from t2
- for i := 0; i < 128; i++ {
- _, ok := l.Get(i)
- if !ok {
- t.Fatalf("missing: %d", i)
- }
- }
- if n := l.recent.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 128 {
- t.Fatalf("bad: %d", n)
- }
-}
-
-func Test2Q_Add_RecentToFrequent(t *testing.T) {
- l, err := New2Q(128)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Add initially to recent
- l.Add(1, 1)
- if n := l.recent.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
-
- // Add should upgrade to frequent
- l.Add(1, 1)
- if n := l.recent.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
-
- // Add should remain in frequent
- l.Add(1, 1)
- if n := l.recent.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
-}
-
-func Test2Q_Add_RecentEvict(t *testing.T) {
- l, err := New2Q(4)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Add 1,2,3,4,5 -> Evict 1
- l.Add(1, 1)
- l.Add(2, 2)
- l.Add(3, 3)
- l.Add(4, 4)
- l.Add(5, 5)
- if n := l.recent.Len(); n != 4 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.recentEvict.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
-
- // Pull in the recently evicted
- l.Add(1, 1)
- if n := l.recent.Len(); n != 3 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.recentEvict.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
-
- // Add 6, should cause another recent evict
- l.Add(6, 6)
- if n := l.recent.Len(); n != 3 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.recentEvict.Len(); n != 2 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.frequent.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
-}
-
-func Test2Q(t *testing.T) {
- l, err := New2Q(128)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- for i := 0; i < 256; i++ {
- l.Add(i, i)
- }
- if l.Len() != 128 {
- t.Fatalf("bad len: %v", l.Len())
- }
-
- for i, k := range l.Keys() {
- if v, ok := l.Get(k); !ok || v != k || v != i+128 {
- t.Fatalf("bad key: %v", k)
- }
- }
- for i := 0; i < 128; i++ {
- _, ok := l.Get(i)
- if ok {
- t.Fatalf("should be evicted")
- }
- }
- for i := 128; i < 256; i++ {
- _, ok := l.Get(i)
- if !ok {
- t.Fatalf("should not be evicted")
- }
- }
- for i := 128; i < 192; i++ {
- l.Remove(i)
- _, ok := l.Get(i)
- if ok {
- t.Fatalf("should be deleted")
- }
- }
-
- l.Purge()
- if l.Len() != 0 {
- t.Fatalf("bad len: %v", l.Len())
- }
- if _, ok := l.Get(200); ok {
- t.Fatalf("should contain nothing")
- }
-}
-
-// Test that Contains doesn't update recent-ness
-func Test2Q_Contains(t *testing.T) {
- l, err := New2Q(2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- if !l.Contains(1) {
- t.Errorf("1 should be contained")
- }
-
- l.Add(3, 3)
- if l.Contains(1) {
- t.Errorf("Contains should not have updated recent-ness of 1")
- }
-}
-
-// Test that Peek doesn't update recent-ness
-func Test2Q_Peek(t *testing.T) {
- l, err := New2Q(2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- if v, ok := l.Peek(1); !ok || v != 1 {
- t.Errorf("1 should be set to 1: %v, %v", v, ok)
- }
-
- l.Add(3, 3)
- if l.Contains(1) {
- t.Errorf("should not have updated recent-ness of 1")
- }
-}
diff --git a/vendor/github.com/hashicorp/golang-lru/LICENSE b/vendor/github.com/hashicorp/golang-lru/LICENSE
deleted file mode 100644
index be2cc4dfb..000000000
--- a/vendor/github.com/hashicorp/golang-lru/LICENSE
+++ /dev/null
@@ -1,362 +0,0 @@
-Mozilla Public License, version 2.0
-
-1. Definitions
-
-1.1. "Contributor"
-
- means each individual or legal entity that creates, contributes to the
- creation of, or owns Covered Software.
-
-1.2. "Contributor Version"
-
- means the combination of the Contributions of others (if any) used by a
- Contributor and that particular Contributor's Contribution.
-
-1.3. "Contribution"
-
- means Covered Software of a particular Contributor.
-
-1.4. "Covered Software"
-
- means Source Code Form to which the initial Contributor has attached the
- notice in Exhibit A, the Executable Form of such Source Code Form, and
- Modifications of such Source Code Form, in each case including portions
- thereof.
-
-1.5. "Incompatible With Secondary Licenses"
- means
-
- a. that the initial Contributor has attached the notice described in
- Exhibit B to the Covered Software; or
-
- b. that the Covered Software was made available under the terms of
- version 1.1 or earlier of the License, but not also under the terms of
- a Secondary License.
-
-1.6. "Executable Form"
-
- means any form of the work other than Source Code Form.
-
-1.7. "Larger Work"
-
- means a work that combines Covered Software with other material, in a
- separate file or files, that is not Covered Software.
-
-1.8. "License"
-
- means this document.
-
-1.9. "Licensable"
-
- means having the right to grant, to the maximum extent possible, whether
- at the time of the initial grant or subsequently, any and all of the
- rights conveyed by this License.
-
-1.10. "Modifications"
-
- means any of the following:
-
- a. any file in Source Code Form that results from an addition to,
- deletion from, or modification of the contents of Covered Software; or
-
- b. any new file in Source Code Form that contains any Covered Software.
-
-1.11. "Patent Claims" of a Contributor
-
- means any patent claim(s), including without limitation, method,
- process, and apparatus claims, in any patent Licensable by such
- Contributor that would be infringed, but for the grant of the License,
- by the making, using, selling, offering for sale, having made, import,
- or transfer of either its Contributions or its Contributor Version.
-
-1.12. "Secondary License"
-
- means either the GNU General Public License, Version 2.0, the GNU Lesser
- General Public License, Version 2.1, the GNU Affero General Public
- License, Version 3.0, or any later versions of those licenses.
-
-1.13. "Source Code Form"
-
- means the form of the work preferred for making modifications.
-
-1.14. "You" (or "Your")
-
- means an individual or a legal entity exercising rights under this
- License. For legal entities, "You" includes any entity that controls, is
- controlled by, or is under common control with You. For purposes of this
- definition, "control" means (a) the power, direct or indirect, to cause
- the direction or management of such entity, whether by contract or
- otherwise, or (b) ownership of more than fifty percent (50%) of the
- outstanding shares or beneficial ownership of such entity.
-
-
-2. License Grants and Conditions
-
-2.1. Grants
-
- Each Contributor hereby grants You a world-wide, royalty-free,
- non-exclusive license:
-
- a. under intellectual property rights (other than patent or trademark)
- Licensable by such Contributor to use, reproduce, make available,
- modify, display, perform, distribute, and otherwise exploit its
- Contributions, either on an unmodified basis, with Modifications, or
- as part of a Larger Work; and
-
- b. under Patent Claims of such Contributor to make, use, sell, offer for
- sale, have made, import, and otherwise transfer either its
- Contributions or its Contributor Version.
-
-2.2. Effective Date
-
- The licenses granted in Section 2.1 with respect to any Contribution
- become effective for each Contribution on the date the Contributor first
- distributes such Contribution.
-
-2.3. Limitations on Grant Scope
-
- The licenses granted in this Section 2 are the only rights granted under
- this License. No additional rights or licenses will be implied from the
- distribution or licensing of Covered Software under this License.
- Notwithstanding Section 2.1(b) above, no patent license is granted by a
- Contributor:
-
- a. for any code that a Contributor has removed from Covered Software; or
-
- b. for infringements caused by: (i) Your and any other third party's
- modifications of Covered Software, or (ii) the combination of its
- Contributions with other software (except as part of its Contributor
- Version); or
-
- c. under Patent Claims infringed by Covered Software in the absence of
- its Contributions.
-
- This License does not grant any rights in the trademarks, service marks,
- or logos of any Contributor (except as may be necessary to comply with
- the notice requirements in Section 3.4).
-
-2.4. Subsequent Licenses
-
- No Contributor makes additional grants as a result of Your choice to
- distribute the Covered Software under a subsequent version of this
- License (see Section 10.2) or under the terms of a Secondary License (if
- permitted under the terms of Section 3.3).
-
-2.5. Representation
-
- Each Contributor represents that the Contributor believes its
- Contributions are its original creation(s) or it has sufficient rights to
- grant the rights to its Contributions conveyed by this License.
-
-2.6. Fair Use
-
- This License is not intended to limit any rights You have under
- applicable copyright doctrines of fair use, fair dealing, or other
- equivalents.
-
-2.7. Conditions
-
- Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
- Section 2.1.
-
-
-3. Responsibilities
-
-3.1. Distribution of Source Form
-
- All distribution of Covered Software in Source Code Form, including any
- Modifications that You create or to which You contribute, must be under
- the terms of this License. You must inform recipients that the Source
- Code Form of the Covered Software is governed by the terms of this
- License, and how they can obtain a copy of this License. You may not
- attempt to alter or restrict the recipients' rights in the Source Code
- Form.
-
-3.2. Distribution of Executable Form
-
- If You distribute Covered Software in Executable Form then:
-
- a. such Covered Software must also be made available in Source Code Form,
- as described in Section 3.1, and You must inform recipients of the
- Executable Form how they can obtain a copy of such Source Code Form by
- reasonable means in a timely manner, at a charge no more than the cost
- of distribution to the recipient; and
-
- b. You may distribute such Executable Form under the terms of this
- License, or sublicense it under different terms, provided that the
- license for the Executable Form does not attempt to limit or alter the
- recipients' rights in the Source Code Form under this License.
-
-3.3. Distribution of a Larger Work
-
- You may create and distribute a Larger Work under terms of Your choice,
- provided that You also comply with the requirements of this License for
- the Covered Software. If the Larger Work is a combination of Covered
- Software with a work governed by one or more Secondary Licenses, and the
- Covered Software is not Incompatible With Secondary Licenses, this
- License permits You to additionally distribute such Covered Software
- under the terms of such Secondary License(s), so that the recipient of
- the Larger Work may, at their option, further distribute the Covered
- Software under the terms of either this License or such Secondary
- License(s).
-
-3.4. Notices
-
- You may not remove or alter the substance of any license notices
- (including copyright notices, patent notices, disclaimers of warranty, or
- limitations of liability) contained within the Source Code Form of the
- Covered Software, except that You may alter any license notices to the
- extent required to remedy known factual inaccuracies.
-
-3.5. Application of Additional Terms
-
- You may choose to offer, and to charge a fee for, warranty, support,
- indemnity or liability obligations to one or more recipients of Covered
- Software. However, You may do so only on Your own behalf, and not on
- behalf of any Contributor. You must make it absolutely clear that any
- such warranty, support, indemnity, or liability obligation is offered by
- You alone, and You hereby agree to indemnify every Contributor for any
- liability incurred by such Contributor as a result of warranty, support,
- indemnity or liability terms You offer. You may include additional
- disclaimers of warranty and limitations of liability specific to any
- jurisdiction.
-
-4. Inability to Comply Due to Statute or Regulation
-
- If it is impossible for You to comply with any of the terms of this License
- with respect to some or all of the Covered Software due to statute,
- judicial order, or regulation then You must: (a) comply with the terms of
- this License to the maximum extent possible; and (b) describe the
- limitations and the code they affect. Such description must be placed in a
- text file included with all distributions of the Covered Software under
- this License. Except to the extent prohibited by statute or regulation,
- such description must be sufficiently detailed for a recipient of ordinary
- skill to be able to understand it.
-
-5. Termination
-
-5.1. The rights granted under this License will terminate automatically if You
- fail to comply with any of its terms. However, if You become compliant,
- then the rights granted under this License from a particular Contributor
- are reinstated (a) provisionally, unless and until such Contributor
- explicitly and finally terminates Your grants, and (b) on an ongoing
- basis, if such Contributor fails to notify You of the non-compliance by
- some reasonable means prior to 60 days after You have come back into
- compliance. Moreover, Your grants from a particular Contributor are
- reinstated on an ongoing basis if such Contributor notifies You of the
- non-compliance by some reasonable means, this is the first time You have
- received notice of non-compliance with this License from such
- Contributor, and You become compliant prior to 30 days after Your receipt
- of the notice.
-
-5.2. If You initiate litigation against any entity by asserting a patent
- infringement claim (excluding declaratory judgment actions,
- counter-claims, and cross-claims) alleging that a Contributor Version
- directly or indirectly infringes any patent, then the rights granted to
- You by any and all Contributors for the Covered Software under Section
- 2.1 of this License shall terminate.
-
-5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
- license agreements (excluding distributors and resellers) which have been
- validly granted by You or Your distributors under this License prior to
- termination shall survive termination.
-
-6. Disclaimer of Warranty
-
- Covered Software is provided under this License on an "as is" basis,
- without warranty of any kind, either expressed, implied, or statutory,
- including, without limitation, warranties that the Covered Software is free
- of defects, merchantable, fit for a particular purpose or non-infringing.
- The entire risk as to the quality and performance of the Covered Software
- is with You. Should any Covered Software prove defective in any respect,
- You (not any Contributor) assume the cost of any necessary servicing,
- repair, or correction. This disclaimer of warranty constitutes an essential
- part of this License. No use of any Covered Software is authorized under
- this License except under this disclaimer.
-
-7. Limitation of Liability
-
- Under no circumstances and under no legal theory, whether tort (including
- negligence), contract, or otherwise, shall any Contributor, or anyone who
- distributes Covered Software as permitted above, be liable to You for any
- direct, indirect, special, incidental, or consequential damages of any
- character including, without limitation, damages for lost profits, loss of
- goodwill, work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses, even if such party shall have been
- informed of the possibility of such damages. This limitation of liability
- shall not apply to liability for death or personal injury resulting from
- such party's negligence to the extent applicable law prohibits such
- limitation. Some jurisdictions do not allow the exclusion or limitation of
- incidental or consequential damages, so this exclusion and limitation may
- not apply to You.
-
-8. Litigation
-
- Any litigation relating to this License may be brought only in the courts
- of a jurisdiction where the defendant maintains its principal place of
- business and such litigation shall be governed by laws of that
- jurisdiction, without reference to its conflict-of-law provisions. Nothing
- in this Section shall prevent a party's ability to bring cross-claims or
- counter-claims.
-
-9. Miscellaneous
-
- This License represents the complete agreement concerning the subject
- matter hereof. If any provision of this License is held to be
- unenforceable, such provision shall be reformed only to the extent
- necessary to make it enforceable. Any law or regulation which provides that
- the language of a contract shall be construed against the drafter shall not
- be used to construe this License against a Contributor.
-
-
-10. Versions of the License
-
-10.1. New Versions
-
- Mozilla Foundation is the license steward. Except as provided in Section
- 10.3, no one other than the license steward has the right to modify or
- publish new versions of this License. Each version will be given a
- distinguishing version number.
-
-10.2. Effect of New Versions
-
- You may distribute the Covered Software under the terms of the version
- of the License under which You originally received the Covered Software,
- or under the terms of any subsequent version published by the license
- steward.
-
-10.3. Modified Versions
-
- If you create software not governed by this License, and you want to
- create a new license for such software, you may create and use a
- modified version of this License if you rename the license and remove
- any references to the name of the license steward (except to note that
- such modified license differs from this License).
-
-10.4. Distributing Source Code Form that is Incompatible With Secondary
- Licenses If You choose to distribute Source Code Form that is
- Incompatible With Secondary Licenses under the terms of this version of
- the License, the notice described in Exhibit B of this License must be
- attached.
-
-Exhibit A - Source Code Form License Notice
-
- This Source Code Form is subject to the
- terms of the Mozilla Public License, v.
- 2.0. If a copy of the MPL was not
- distributed with this file, You can
- obtain one at
- http://mozilla.org/MPL/2.0/.
-
-If it is not possible or desirable to put the notice in a particular file,
-then You may include the notice in a location (such as a LICENSE file in a
-relevant directory) where a recipient would be likely to look for such a
-notice.
-
-You may add additional accurate notices of copyright ownership.
-
-Exhibit B - "Incompatible With Secondary Licenses" Notice
-
- This Source Code Form is "Incompatible
- With Secondary Licenses", as defined by
- the Mozilla Public License, v. 2.0.
diff --git a/vendor/github.com/hashicorp/golang-lru/README.md b/vendor/github.com/hashicorp/golang-lru/README.md
deleted file mode 100644
index 33e58cfaf..000000000
--- a/vendor/github.com/hashicorp/golang-lru/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-golang-lru
-==========
-
-This provides the `lru` package which implements a fixed-size
-thread safe LRU cache. It is based on the cache in Groupcache.
-
-Documentation
-=============
-
-Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru)
-
-Example
-=======
-
-Using the LRU is very simple:
-
-```go
-l, _ := New(128)
-for i := 0; i < 256; i++ {
- l.Add(i, nil)
-}
-if l.Len() != 128 {
- panic(fmt.Sprintf("bad len: %v", l.Len()))
-}
-```
diff --git a/vendor/github.com/hashicorp/golang-lru/arc.go b/vendor/github.com/hashicorp/golang-lru/arc.go
deleted file mode 100644
index a2a252817..000000000
--- a/vendor/github.com/hashicorp/golang-lru/arc.go
+++ /dev/null
@@ -1,257 +0,0 @@
-package lru
-
-import (
- "sync"
-
- "github.com/hashicorp/golang-lru/simplelru"
-)
-
-// ARCCache is a thread-safe fixed size Adaptive Replacement Cache (ARC).
-// ARC is an enhancement over the standard LRU cache in that tracks both
-// frequency and recency of use. This avoids a burst in access to new
-// entries from evicting the frequently used older entries. It adds some
-// additional tracking overhead to a standard LRU cache, computationally
-// it is roughly 2x the cost, and the extra memory overhead is linear
-// with the size of the cache. ARC has been patented by IBM, but is
-// similar to the TwoQueueCache (2Q) which requires setting parameters.
-type ARCCache struct {
- size int // Size is the total capacity of the cache
- p int // P is the dynamic preference towards T1 or T2
-
- t1 *simplelru.LRU // T1 is the LRU for recently accessed items
- b1 *simplelru.LRU // B1 is the LRU for evictions from t1
-
- t2 *simplelru.LRU // T2 is the LRU for frequently accessed items
- b2 *simplelru.LRU // B2 is the LRU for evictions from t2
-
- lock sync.RWMutex
-}
-
-// NewARC creates an ARC of the given size
-func NewARC(size int) (*ARCCache, error) {
- // Create the sub LRUs
- b1, err := simplelru.NewLRU(size, nil)
- if err != nil {
- return nil, err
- }
- b2, err := simplelru.NewLRU(size, nil)
- if err != nil {
- return nil, err
- }
- t1, err := simplelru.NewLRU(size, nil)
- if err != nil {
- return nil, err
- }
- t2, err := simplelru.NewLRU(size, nil)
- if err != nil {
- return nil, err
- }
-
- // Initialize the ARC
- c := &ARCCache{
- size: size,
- p: 0,
- t1: t1,
- b1: b1,
- t2: t2,
- b2: b2,
- }
- return c, nil
-}
-
-// Get looks up a key's value from the cache.
-func (c *ARCCache) Get(key interface{}) (interface{}, bool) {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- // Ff the value is contained in T1 (recent), then
- // promote it to T2 (frequent)
- if val, ok := c.t1.Peek(key); ok {
- c.t1.Remove(key)
- c.t2.Add(key, val)
- return val, ok
- }
-
- // Check if the value is contained in T2 (frequent)
- if val, ok := c.t2.Get(key); ok {
- return val, ok
- }
-
- // No hit
- return nil, false
-}
-
-// Add adds a value to the cache.
-func (c *ARCCache) Add(key, value interface{}) {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- // Check if the value is contained in T1 (recent), and potentially
- // promote it to frequent T2
- if c.t1.Contains(key) {
- c.t1.Remove(key)
- c.t2.Add(key, value)
- return
- }
-
- // Check if the value is already in T2 (frequent) and update it
- if c.t2.Contains(key) {
- c.t2.Add(key, value)
- return
- }
-
- // Check if this value was recently evicted as part of the
- // recently used list
- if c.b1.Contains(key) {
- // T1 set is too small, increase P appropriately
- delta := 1
- b1Len := c.b1.Len()
- b2Len := c.b2.Len()
- if b2Len > b1Len {
- delta = b2Len / b1Len
- }
- if c.p+delta >= c.size {
- c.p = c.size
- } else {
- c.p += delta
- }
-
- // Potentially need to make room in the cache
- if c.t1.Len()+c.t2.Len() >= c.size {
- c.replace(false)
- }
-
- // Remove from B1
- c.b1.Remove(key)
-
- // Add the key to the frequently used list
- c.t2.Add(key, value)
- return
- }
-
- // Check if this value was recently evicted as part of the
- // frequently used list
- if c.b2.Contains(key) {
- // T2 set is too small, decrease P appropriately
- delta := 1
- b1Len := c.b1.Len()
- b2Len := c.b2.Len()
- if b1Len > b2Len {
- delta = b1Len / b2Len
- }
- if delta >= c.p {
- c.p = 0
- } else {
- c.p -= delta
- }
-
- // Potentially need to make room in the cache
- if c.t1.Len()+c.t2.Len() >= c.size {
- c.replace(true)
- }
-
- // Remove from B2
- c.b2.Remove(key)
-
- // Add the key to the frequntly used list
- c.t2.Add(key, value)
- return
- }
-
- // Potentially need to make room in the cache
- if c.t1.Len()+c.t2.Len() >= c.size {
- c.replace(false)
- }
-
- // Keep the size of the ghost buffers trim
- if c.b1.Len() > c.size-c.p {
- c.b1.RemoveOldest()
- }
- if c.b2.Len() > c.p {
- c.b2.RemoveOldest()
- }
-
- // Add to the recently seen list
- c.t1.Add(key, value)
- return
-}
-
-// replace is used to adaptively evict from either T1 or T2
-// based on the current learned value of P
-func (c *ARCCache) replace(b2ContainsKey bool) {
- t1Len := c.t1.Len()
- if t1Len > 0 && (t1Len > c.p || (t1Len == c.p && b2ContainsKey)) {
- k, _, ok := c.t1.RemoveOldest()
- if ok {
- c.b1.Add(k, nil)
- }
- } else {
- k, _, ok := c.t2.RemoveOldest()
- if ok {
- c.b2.Add(k, nil)
- }
- }
-}
-
-// Len returns the number of cached entries
-func (c *ARCCache) Len() int {
- c.lock.RLock()
- defer c.lock.RUnlock()
- return c.t1.Len() + c.t2.Len()
-}
-
-// Keys returns all the cached keys
-func (c *ARCCache) Keys() []interface{} {
- c.lock.RLock()
- defer c.lock.RUnlock()
- k1 := c.t1.Keys()
- k2 := c.t2.Keys()
- return append(k1, k2...)
-}
-
-// Remove is used to purge a key from the cache
-func (c *ARCCache) Remove(key interface{}) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if c.t1.Remove(key) {
- return
- }
- if c.t2.Remove(key) {
- return
- }
- if c.b1.Remove(key) {
- return
- }
- if c.b2.Remove(key) {
- return
- }
-}
-
-// Purge is used to clear the cache
-func (c *ARCCache) Purge() {
- c.lock.Lock()
- defer c.lock.Unlock()
- c.t1.Purge()
- c.t2.Purge()
- c.b1.Purge()
- c.b2.Purge()
-}
-
-// Contains is used to check if the cache contains a key
-// without updating recency or frequency.
-func (c *ARCCache) Contains(key interface{}) bool {
- c.lock.RLock()
- defer c.lock.RUnlock()
- return c.t1.Contains(key) || c.t2.Contains(key)
-}
-
-// Peek is used to inspect the cache value of a key
-// without updating recency or frequency.
-func (c *ARCCache) Peek(key interface{}) (interface{}, bool) {
- c.lock.RLock()
- defer c.lock.RUnlock()
- if val, ok := c.t1.Peek(key); ok {
- return val, ok
- }
- return c.t2.Peek(key)
-}
diff --git a/vendor/github.com/hashicorp/golang-lru/arc_test.go b/vendor/github.com/hashicorp/golang-lru/arc_test.go
deleted file mode 100644
index e2d9b68c6..000000000
--- a/vendor/github.com/hashicorp/golang-lru/arc_test.go
+++ /dev/null
@@ -1,377 +0,0 @@
-package lru
-
-import (
- "math/rand"
- "testing"
- "time"
-)
-
-func init() {
- rand.Seed(time.Now().Unix())
-}
-
-func BenchmarkARC_Rand(b *testing.B) {
- l, err := NewARC(8192)
- if err != nil {
- b.Fatalf("err: %v", err)
- }
-
- trace := make([]int64, b.N*2)
- for i := 0; i < b.N*2; i++ {
- trace[i] = rand.Int63() % 32768
- }
-
- b.ResetTimer()
-
- var hit, miss int
- for i := 0; i < 2*b.N; i++ {
- if i%2 == 0 {
- l.Add(trace[i], trace[i])
- } else {
- _, ok := l.Get(trace[i])
- if ok {
- hit++
- } else {
- miss++
- }
- }
- }
- b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
-}
-
-func BenchmarkARC_Freq(b *testing.B) {
- l, err := NewARC(8192)
- if err != nil {
- b.Fatalf("err: %v", err)
- }
-
- trace := make([]int64, b.N*2)
- for i := 0; i < b.N*2; i++ {
- if i%2 == 0 {
- trace[i] = rand.Int63() % 16384
- } else {
- trace[i] = rand.Int63() % 32768
- }
- }
-
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- l.Add(trace[i], trace[i])
- }
- var hit, miss int
- for i := 0; i < b.N; i++ {
- _, ok := l.Get(trace[i])
- if ok {
- hit++
- } else {
- miss++
- }
- }
- b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
-}
-
-func TestARC_RandomOps(t *testing.T) {
- size := 128
- l, err := NewARC(128)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- n := 200000
- for i := 0; i < n; i++ {
- key := rand.Int63() % 512
- r := rand.Int63()
- switch r % 3 {
- case 0:
- l.Add(key, key)
- case 1:
- l.Get(key)
- case 2:
- l.Remove(key)
- }
-
- if l.t1.Len()+l.t2.Len() > size {
- t.Fatalf("bad: t1: %d t2: %d b1: %d b2: %d p: %d",
- l.t1.Len(), l.t2.Len(), l.b1.Len(), l.b2.Len(), l.p)
- }
- if l.b1.Len()+l.b2.Len() > size {
- t.Fatalf("bad: t1: %d t2: %d b1: %d b2: %d p: %d",
- l.t1.Len(), l.t2.Len(), l.b1.Len(), l.b2.Len(), l.p)
- }
- }
-}
-
-func TestARC_Get_RecentToFrequent(t *testing.T) {
- l, err := NewARC(128)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Touch all the entries, should be in t1
- for i := 0; i < 128; i++ {
- l.Add(i, i)
- }
- if n := l.t1.Len(); n != 128 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
-
- // Get should upgrade to t2
- for i := 0; i < 128; i++ {
- _, ok := l.Get(i)
- if !ok {
- t.Fatalf("missing: %d", i)
- }
- }
- if n := l.t1.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 128 {
- t.Fatalf("bad: %d", n)
- }
-
- // Get be from t2
- for i := 0; i < 128; i++ {
- _, ok := l.Get(i)
- if !ok {
- t.Fatalf("missing: %d", i)
- }
- }
- if n := l.t1.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 128 {
- t.Fatalf("bad: %d", n)
- }
-}
-
-func TestARC_Add_RecentToFrequent(t *testing.T) {
- l, err := NewARC(128)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Add initially to t1
- l.Add(1, 1)
- if n := l.t1.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
-
- // Add should upgrade to t2
- l.Add(1, 1)
- if n := l.t1.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
-
- // Add should remain in t2
- l.Add(1, 1)
- if n := l.t1.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
-}
-
-func TestARC_Adaptive(t *testing.T) {
- l, err := NewARC(4)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Fill t1
- for i := 0; i < 4; i++ {
- l.Add(i, i)
- }
- if n := l.t1.Len(); n != 4 {
- t.Fatalf("bad: %d", n)
- }
-
- // Move to t2
- l.Get(0)
- l.Get(1)
- if n := l.t2.Len(); n != 2 {
- t.Fatalf("bad: %d", n)
- }
-
- // Evict from t1
- l.Add(4, 4)
- if n := l.b1.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
-
- // Current state
- // t1 : (MRU) [4, 3] (LRU)
- // t2 : (MRU) [1, 0] (LRU)
- // b1 : (MRU) [2] (LRU)
- // b2 : (MRU) [] (LRU)
-
- // Add 2, should cause hit on b1
- l.Add(2, 2)
- if n := l.b1.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
- if l.p != 1 {
- t.Fatalf("bad: %d", l.p)
- }
- if n := l.t2.Len(); n != 3 {
- t.Fatalf("bad: %d", n)
- }
-
- // Current state
- // t1 : (MRU) [4] (LRU)
- // t2 : (MRU) [2, 1, 0] (LRU)
- // b1 : (MRU) [3] (LRU)
- // b2 : (MRU) [] (LRU)
-
- // Add 4, should migrate to t2
- l.Add(4, 4)
- if n := l.t1.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 4 {
- t.Fatalf("bad: %d", n)
- }
-
- // Current state
- // t1 : (MRU) [] (LRU)
- // t2 : (MRU) [4, 2, 1, 0] (LRU)
- // b1 : (MRU) [3] (LRU)
- // b2 : (MRU) [] (LRU)
-
- // Add 4, should evict to b2
- l.Add(5, 5)
- if n := l.t1.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 3 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.b2.Len(); n != 1 {
- t.Fatalf("bad: %d", n)
- }
-
- // Current state
- // t1 : (MRU) [5] (LRU)
- // t2 : (MRU) [4, 2, 1] (LRU)
- // b1 : (MRU) [3] (LRU)
- // b2 : (MRU) [0] (LRU)
-
- // Add 0, should decrease p
- l.Add(0, 0)
- if n := l.t1.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.t2.Len(); n != 4 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.b1.Len(); n != 2 {
- t.Fatalf("bad: %d", n)
- }
- if n := l.b2.Len(); n != 0 {
- t.Fatalf("bad: %d", n)
- }
- if l.p != 0 {
- t.Fatalf("bad: %d", l.p)
- }
-
- // Current state
- // t1 : (MRU) [] (LRU)
- // t2 : (MRU) [0, 4, 2, 1] (LRU)
- // b1 : (MRU) [5, 3] (LRU)
- // b2 : (MRU) [0] (LRU)
-}
-
-func TestARC(t *testing.T) {
- l, err := NewARC(128)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- for i := 0; i < 256; i++ {
- l.Add(i, i)
- }
- if l.Len() != 128 {
- t.Fatalf("bad len: %v", l.Len())
- }
-
- for i, k := range l.Keys() {
- if v, ok := l.Get(k); !ok || v != k || v != i+128 {
- t.Fatalf("bad key: %v", k)
- }
- }
- for i := 0; i < 128; i++ {
- _, ok := l.Get(i)
- if ok {
- t.Fatalf("should be evicted")
- }
- }
- for i := 128; i < 256; i++ {
- _, ok := l.Get(i)
- if !ok {
- t.Fatalf("should not be evicted")
- }
- }
- for i := 128; i < 192; i++ {
- l.Remove(i)
- _, ok := l.Get(i)
- if ok {
- t.Fatalf("should be deleted")
- }
- }
-
- l.Purge()
- if l.Len() != 0 {
- t.Fatalf("bad len: %v", l.Len())
- }
- if _, ok := l.Get(200); ok {
- t.Fatalf("should contain nothing")
- }
-}
-
-// Test that Contains doesn't update recent-ness
-func TestARC_Contains(t *testing.T) {
- l, err := NewARC(2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- if !l.Contains(1) {
- t.Errorf("1 should be contained")
- }
-
- l.Add(3, 3)
- if l.Contains(1) {
- t.Errorf("Contains should not have updated recent-ness of 1")
- }
-}
-
-// Test that Peek doesn't update recent-ness
-func TestARC_Peek(t *testing.T) {
- l, err := NewARC(2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- if v, ok := l.Peek(1); !ok || v != 1 {
- t.Errorf("1 should be set to 1: %v, %v", v, ok)
- }
-
- l.Add(3, 3)
- if l.Contains(1) {
- t.Errorf("should not have updated recent-ness of 1")
- }
-}
diff --git a/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go
deleted file mode 100644
index a6285f989..000000000
--- a/vendor/github.com/hashicorp/golang-lru/lru.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// This package provides a simple LRU cache. It is based on the
-// LRU implementation in groupcache:
-// https://github.com/golang/groupcache/tree/master/lru
-package lru
-
-import (
- "sync"
-
- "github.com/hashicorp/golang-lru/simplelru"
-)
-
-// Cache is a thread-safe fixed size LRU cache.
-type Cache struct {
- lru *simplelru.LRU
- lock sync.RWMutex
-}
-
-// New creates an LRU of the given size
-func New(size int) (*Cache, error) {
- return NewWithEvict(size, nil)
-}
-
-// NewWithEvict constructs a fixed size cache with the given eviction
-// callback.
-func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) {
- lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted))
- if err != nil {
- return nil, err
- }
- c := &Cache{
- lru: lru,
- }
- return c, nil
-}
-
-// Purge is used to completely clear the cache
-func (c *Cache) Purge() {
- c.lock.Lock()
- c.lru.Purge()
- c.lock.Unlock()
-}
-
-// Add adds a value to the cache. Returns true if an eviction occurred.
-func (c *Cache) Add(key, value interface{}) bool {
- c.lock.Lock()
- defer c.lock.Unlock()
- return c.lru.Add(key, value)
-}
-
-// Get looks up a key's value from the cache.
-func (c *Cache) Get(key interface{}) (interface{}, bool) {
- c.lock.Lock()
- defer c.lock.Unlock()
- return c.lru.Get(key)
-}
-
-// Check if a key is in the cache, without updating the recent-ness
-// or deleting it for being stale.
-func (c *Cache) Contains(key interface{}) bool {
- c.lock.RLock()
- defer c.lock.RUnlock()
- return c.lru.Contains(key)
-}
-
-// Returns the key value (or undefined if not found) without updating
-// the "recently used"-ness of the key.
-func (c *Cache) Peek(key interface{}) (interface{}, bool) {
- c.lock.RLock()
- defer c.lock.RUnlock()
- return c.lru.Peek(key)
-}
-
-// ContainsOrAdd checks if a key is in the cache without updating the
-// recent-ness or deleting it for being stale, and if not, adds the value.
-// Returns whether found and whether an eviction occurred.
-func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evict bool) {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- if c.lru.Contains(key) {
- return true, false
- } else {
- evict := c.lru.Add(key, value)
- return false, evict
- }
-}
-
-// Remove removes the provided key from the cache.
-func (c *Cache) Remove(key interface{}) {
- c.lock.Lock()
- c.lru.Remove(key)
- c.lock.Unlock()
-}
-
-// RemoveOldest removes the oldest item from the cache.
-func (c *Cache) RemoveOldest() {
- c.lock.Lock()
- c.lru.RemoveOldest()
- c.lock.Unlock()
-}
-
-// Keys returns a slice of the keys in the cache, from oldest to newest.
-func (c *Cache) Keys() []interface{} {
- c.lock.RLock()
- defer c.lock.RUnlock()
- return c.lru.Keys()
-}
-
-// Len returns the number of items in the cache.
-func (c *Cache) Len() int {
- c.lock.RLock()
- defer c.lock.RUnlock()
- return c.lru.Len()
-}
diff --git a/vendor/github.com/hashicorp/golang-lru/lru_test.go b/vendor/github.com/hashicorp/golang-lru/lru_test.go
deleted file mode 100644
index 2b31218b0..000000000
--- a/vendor/github.com/hashicorp/golang-lru/lru_test.go
+++ /dev/null
@@ -1,221 +0,0 @@
-package lru
-
-import (
- "math/rand"
- "testing"
-)
-
-func BenchmarkLRU_Rand(b *testing.B) {
- l, err := New(8192)
- if err != nil {
- b.Fatalf("err: %v", err)
- }
-
- trace := make([]int64, b.N*2)
- for i := 0; i < b.N*2; i++ {
- trace[i] = rand.Int63() % 32768
- }
-
- b.ResetTimer()
-
- var hit, miss int
- for i := 0; i < 2*b.N; i++ {
- if i%2 == 0 {
- l.Add(trace[i], trace[i])
- } else {
- _, ok := l.Get(trace[i])
- if ok {
- hit++
- } else {
- miss++
- }
- }
- }
- b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
-}
-
-func BenchmarkLRU_Freq(b *testing.B) {
- l, err := New(8192)
- if err != nil {
- b.Fatalf("err: %v", err)
- }
-
- trace := make([]int64, b.N*2)
- for i := 0; i < b.N*2; i++ {
- if i%2 == 0 {
- trace[i] = rand.Int63() % 16384
- } else {
- trace[i] = rand.Int63() % 32768
- }
- }
-
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- l.Add(trace[i], trace[i])
- }
- var hit, miss int
- for i := 0; i < b.N; i++ {
- _, ok := l.Get(trace[i])
- if ok {
- hit++
- } else {
- miss++
- }
- }
- b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
-}
-
-func TestLRU(t *testing.T) {
- evictCounter := 0
- onEvicted := func(k interface{}, v interface{}) {
- if k != v {
- t.Fatalf("Evict values not equal (%v!=%v)", k, v)
- }
- evictCounter += 1
- }
- l, err := NewWithEvict(128, onEvicted)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- for i := 0; i < 256; i++ {
- l.Add(i, i)
- }
- if l.Len() != 128 {
- t.Fatalf("bad len: %v", l.Len())
- }
-
- if evictCounter != 128 {
- t.Fatalf("bad evict count: %v", evictCounter)
- }
-
- for i, k := range l.Keys() {
- if v, ok := l.Get(k); !ok || v != k || v != i+128 {
- t.Fatalf("bad key: %v", k)
- }
- }
- for i := 0; i < 128; i++ {
- _, ok := l.Get(i)
- if ok {
- t.Fatalf("should be evicted")
- }
- }
- for i := 128; i < 256; i++ {
- _, ok := l.Get(i)
- if !ok {
- t.Fatalf("should not be evicted")
- }
- }
- for i := 128; i < 192; i++ {
- l.Remove(i)
- _, ok := l.Get(i)
- if ok {
- t.Fatalf("should be deleted")
- }
- }
-
- l.Get(192) // expect 192 to be last key in l.Keys()
-
- for i, k := range l.Keys() {
- if (i < 63 && k != i+193) || (i == 63 && k != 192) {
- t.Fatalf("out of order key: %v", k)
- }
- }
-
- l.Purge()
- if l.Len() != 0 {
- t.Fatalf("bad len: %v", l.Len())
- }
- if _, ok := l.Get(200); ok {
- t.Fatalf("should contain nothing")
- }
-}
-
-// test that Add returns true/false if an eviction occurred
-func TestLRUAdd(t *testing.T) {
- evictCounter := 0
- onEvicted := func(k interface{}, v interface{}) {
- evictCounter += 1
- }
-
- l, err := NewWithEvict(1, onEvicted)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- if l.Add(1, 1) == true || evictCounter != 0 {
- t.Errorf("should not have an eviction")
- }
- if l.Add(2, 2) == false || evictCounter != 1 {
- t.Errorf("should have an eviction")
- }
-}
-
-// test that Contains doesn't update recent-ness
-func TestLRUContains(t *testing.T) {
- l, err := New(2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- if !l.Contains(1) {
- t.Errorf("1 should be contained")
- }
-
- l.Add(3, 3)
- if l.Contains(1) {
- t.Errorf("Contains should not have updated recent-ness of 1")
- }
-}
-
-// test that Contains doesn't update recent-ness
-func TestLRUContainsOrAdd(t *testing.T) {
- l, err := New(2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- contains, evict := l.ContainsOrAdd(1, 1)
- if !contains {
- t.Errorf("1 should be contained")
- }
- if evict {
- t.Errorf("nothing should be evicted here")
- }
-
- l.Add(3, 3)
- contains, evict = l.ContainsOrAdd(1, 1)
- if contains {
- t.Errorf("1 should not have been contained")
- }
- if !evict {
- t.Errorf("an eviction should have occurred")
- }
- if !l.Contains(1) {
- t.Errorf("now 1 should be contained")
- }
-}
-
-// test that Peek doesn't update recent-ness
-func TestLRUPeek(t *testing.T) {
- l, err := New(2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- if v, ok := l.Peek(1); !ok || v != 1 {
- t.Errorf("1 should be set to 1: %v, %v", v, ok)
- }
-
- l.Add(3, 3)
- if l.Contains(1) {
- t.Errorf("should not have updated recent-ness of 1")
- }
-}
diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
deleted file mode 100644
index cb416b394..000000000
--- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
+++ /dev/null
@@ -1,160 +0,0 @@
-package simplelru
-
-import (
- "container/list"
- "errors"
-)
-
-// EvictCallback is used to get a callback when a cache entry is evicted
-type EvictCallback func(key interface{}, value interface{})
-
-// LRU implements a non-thread safe fixed size LRU cache
-type LRU struct {
- size int
- evictList *list.List
- items map[interface{}]*list.Element
- onEvict EvictCallback
-}
-
-// entry is used to hold a value in the evictList
-type entry struct {
- key interface{}
- value interface{}
-}
-
-// NewLRU constructs an LRU of the given size
-func NewLRU(size int, onEvict EvictCallback) (*LRU, error) {
- if size <= 0 {
- return nil, errors.New("Must provide a positive size")
- }
- c := &LRU{
- size: size,
- evictList: list.New(),
- items: make(map[interface{}]*list.Element),
- onEvict: onEvict,
- }
- return c, nil
-}
-
-// Purge is used to completely clear the cache
-func (c *LRU) Purge() {
- for k, v := range c.items {
- if c.onEvict != nil {
- c.onEvict(k, v.Value.(*entry).value)
- }
- delete(c.items, k)
- }
- c.evictList.Init()
-}
-
-// Add adds a value to the cache. Returns true if an eviction occurred.
-func (c *LRU) Add(key, value interface{}) bool {
- // Check for existing item
- if ent, ok := c.items[key]; ok {
- c.evictList.MoveToFront(ent)
- ent.Value.(*entry).value = value
- return false
- }
-
- // Add new item
- ent := &entry{key, value}
- entry := c.evictList.PushFront(ent)
- c.items[key] = entry
-
- evict := c.evictList.Len() > c.size
- // Verify size not exceeded
- if evict {
- c.removeOldest()
- }
- return evict
-}
-
-// Get looks up a key's value from the cache.
-func (c *LRU) Get(key interface{}) (value interface{}, ok bool) {
- if ent, ok := c.items[key]; ok {
- c.evictList.MoveToFront(ent)
- return ent.Value.(*entry).value, true
- }
- return
-}
-
-// Check if a key is in the cache, without updating the recent-ness
-// or deleting it for being stale.
-func (c *LRU) Contains(key interface{}) (ok bool) {
- _, ok = c.items[key]
- return ok
-}
-
-// Returns the key value (or undefined if not found) without updating
-// the "recently used"-ness of the key.
-func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) {
- if ent, ok := c.items[key]; ok {
- return ent.Value.(*entry).value, true
- }
- return nil, ok
-}
-
-// Remove removes the provided key from the cache, returning if the
-// key was contained.
-func (c *LRU) Remove(key interface{}) bool {
- if ent, ok := c.items[key]; ok {
- c.removeElement(ent)
- return true
- }
- return false
-}
-
-// RemoveOldest removes the oldest item from the cache.
-func (c *LRU) RemoveOldest() (interface{}, interface{}, bool) {
- ent := c.evictList.Back()
- if ent != nil {
- c.removeElement(ent)
- kv := ent.Value.(*entry)
- return kv.key, kv.value, true
- }
- return nil, nil, false
-}
-
-// GetOldest returns the oldest entry
-func (c *LRU) GetOldest() (interface{}, interface{}, bool) {
- ent := c.evictList.Back()
- if ent != nil {
- kv := ent.Value.(*entry)
- return kv.key, kv.value, true
- }
- return nil, nil, false
-}
-
-// Keys returns a slice of the keys in the cache, from oldest to newest.
-func (c *LRU) Keys() []interface{} {
- keys := make([]interface{}, len(c.items))
- i := 0
- for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() {
- keys[i] = ent.Value.(*entry).key
- i++
- }
- return keys
-}
-
-// Len returns the number of items in the cache.
-func (c *LRU) Len() int {
- return c.evictList.Len()
-}
-
-// removeOldest removes the oldest item from the cache.
-func (c *LRU) removeOldest() {
- ent := c.evictList.Back()
- if ent != nil {
- c.removeElement(ent)
- }
-}
-
-// removeElement is used to remove a given list element from the cache
-func (c *LRU) removeElement(e *list.Element) {
- c.evictList.Remove(e)
- kv := e.Value.(*entry)
- delete(c.items, kv.key)
- if c.onEvict != nil {
- c.onEvict(kv.key, kv.value)
- }
-}
diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go
deleted file mode 100644
index a958934f6..000000000
--- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package simplelru
-
-import "testing"
-
-func TestLRU(t *testing.T) {
- evictCounter := 0
- onEvicted := func(k interface{}, v interface{}) {
- if k != v {
- t.Fatalf("Evict values not equal (%v!=%v)", k, v)
- }
- evictCounter += 1
- }
- l, err := NewLRU(128, onEvicted)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- for i := 0; i < 256; i++ {
- l.Add(i, i)
- }
- if l.Len() != 128 {
- t.Fatalf("bad len: %v", l.Len())
- }
-
- if evictCounter != 128 {
- t.Fatalf("bad evict count: %v", evictCounter)
- }
-
- for i, k := range l.Keys() {
- if v, ok := l.Get(k); !ok || v != k || v != i+128 {
- t.Fatalf("bad key: %v", k)
- }
- }
- for i := 0; i < 128; i++ {
- _, ok := l.Get(i)
- if ok {
- t.Fatalf("should be evicted")
- }
- }
- for i := 128; i < 256; i++ {
- _, ok := l.Get(i)
- if !ok {
- t.Fatalf("should not be evicted")
- }
- }
- for i := 128; i < 192; i++ {
- ok := l.Remove(i)
- if !ok {
- t.Fatalf("should be contained")
- }
- ok = l.Remove(i)
- if ok {
- t.Fatalf("should not be contained")
- }
- _, ok = l.Get(i)
- if ok {
- t.Fatalf("should be deleted")
- }
- }
-
- l.Get(192) // expect 192 to be last key in l.Keys()
-
- for i, k := range l.Keys() {
- if (i < 63 && k != i+193) || (i == 63 && k != 192) {
- t.Fatalf("out of order key: %v", k)
- }
- }
-
- l.Purge()
- if l.Len() != 0 {
- t.Fatalf("bad len: %v", l.Len())
- }
- if _, ok := l.Get(200); ok {
- t.Fatalf("should contain nothing")
- }
-}
-
-func TestLRU_GetOldest_RemoveOldest(t *testing.T) {
- l, err := NewLRU(128, nil)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- for i := 0; i < 256; i++ {
- l.Add(i, i)
- }
- k, _, ok := l.GetOldest()
- if !ok {
- t.Fatalf("missing")
- }
- if k.(int) != 128 {
- t.Fatalf("bad: %v", k)
- }
-
- k, _, ok = l.RemoveOldest()
- if !ok {
- t.Fatalf("missing")
- }
- if k.(int) != 128 {
- t.Fatalf("bad: %v", k)
- }
-
- k, _, ok = l.RemoveOldest()
- if !ok {
- t.Fatalf("missing")
- }
- if k.(int) != 129 {
- t.Fatalf("bad: %v", k)
- }
-}
-
-// Test that Add returns true/false if an eviction occurred
-func TestLRU_Add(t *testing.T) {
- evictCounter := 0
- onEvicted := func(k interface{}, v interface{}) {
- evictCounter += 1
- }
-
- l, err := NewLRU(1, onEvicted)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- if l.Add(1, 1) == true || evictCounter != 0 {
- t.Errorf("should not have an eviction")
- }
- if l.Add(2, 2) == false || evictCounter != 1 {
- t.Errorf("should have an eviction")
- }
-}
-
-// Test that Contains doesn't update recent-ness
-func TestLRU_Contains(t *testing.T) {
- l, err := NewLRU(2, nil)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- if !l.Contains(1) {
- t.Errorf("1 should be contained")
- }
-
- l.Add(3, 3)
- if l.Contains(1) {
- t.Errorf("Contains should not have updated recent-ness of 1")
- }
-}
-
-// Test that Peek doesn't update recent-ness
-func TestLRU_Peek(t *testing.T) {
- l, err := NewLRU(2, nil)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- l.Add(1, 1)
- l.Add(2, 2)
- if v, ok := l.Peek(1); !ok || v != 1 {
- t.Errorf("1 should be set to 1: %v, %v", v, ok)
- }
-
- l.Add(3, 3)
- if l.Contains(1) {
- t.Errorf("should not have updated recent-ness of 1")
- }
-}
diff --git a/vendor/github.com/miekg/dns/.gitignore b/vendor/github.com/miekg/dns/.gitignore
deleted file mode 100644
index 776cd950c..000000000
--- a/vendor/github.com/miekg/dns/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-*.6
-tags
-test.out
-a.out
diff --git a/vendor/github.com/miekg/dns/.travis.yml b/vendor/github.com/miekg/dns/.travis.yml
deleted file mode 100644
index bb8b8d40b..000000000
--- a/vendor/github.com/miekg/dns/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-language: go
-sudo: false
-go:
- - 1.7.x
- - 1.8.x
- - tip
-
-before_install:
- # don't use the miekg/dns when testing forks
- - mkdir -p $GOPATH/src/github.com/miekg
- - ln -s $TRAVIS_BUILD_DIR $GOPATH/src/github.com/miekg/ || true
-
-script:
- - go test -race -v -bench=.
diff --git a/vendor/github.com/miekg/dns/AUTHORS b/vendor/github.com/miekg/dns/AUTHORS
deleted file mode 100644
index 196568352..000000000
--- a/vendor/github.com/miekg/dns/AUTHORS
+++ /dev/null
@@ -1 +0,0 @@
-Miek Gieben <miek@miek.nl>
diff --git a/vendor/github.com/miekg/dns/CONTRIBUTORS b/vendor/github.com/miekg/dns/CONTRIBUTORS
deleted file mode 100644
index f77e8a895..000000000
--- a/vendor/github.com/miekg/dns/CONTRIBUTORS
+++ /dev/null
@@ -1,9 +0,0 @@
-Alex A. Skinner
-Andrew Tunnell-Jones
-Ask Bjørn Hansen
-Dave Cheney
-Dusty Wilson
-Marek Majkowski
-Peter van Dijk
-Omri Bahumi
-Alex Sergeyev
diff --git a/vendor/github.com/miekg/dns/COPYRIGHT b/vendor/github.com/miekg/dns/COPYRIGHT
deleted file mode 100644
index 35702b10e..000000000
--- a/vendor/github.com/miekg/dns/COPYRIGHT
+++ /dev/null
@@ -1,9 +0,0 @@
-Copyright 2009 The Go Authors. All rights reserved. Use of this source code
-is governed by a BSD-style license that can be found in the LICENSE file.
-Extensions of the original work are copyright (c) 2011 Miek Gieben
-
-Copyright 2011 Miek Gieben. All rights reserved. Use of this source code is
-governed by a BSD-style license that can be found in the LICENSE file.
-
-Copyright 2014 CloudFlare. All rights reserved. Use of this source code is
-governed by a BSD-style license that can be found in the LICENSE file.
diff --git a/vendor/github.com/miekg/dns/LICENSE b/vendor/github.com/miekg/dns/LICENSE
deleted file mode 100644
index 5763fa7fe..000000000
--- a/vendor/github.com/miekg/dns/LICENSE
+++ /dev/null
@@ -1,32 +0,0 @@
-Extensions of the original work are copyright (c) 2011 Miek Gieben
-
-As this is fork of the official Go code the same license applies:
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md
deleted file mode 100644
index 32a49cbf5..000000000
--- a/vendor/github.com/miekg/dns/README.md
+++ /dev/null
@@ -1,162 +0,0 @@
-[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns)
-[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns)
-
-# Alternative (more granular) approach to a DNS library
-
-> Less is more.
-
-Complete and usable DNS library. All widely used Resource Records are
-supported, including the DNSSEC types. It follows a lean and mean philosophy.
-If there is stuff you should know as a DNS programmer there isn't a convenience
-function for it. Server side and client side programming is supported, i.e. you
-can build servers and resolvers with it.
-
-We try to keep the "master" branch as sane as possible and at the bleeding edge
-of standards, avoiding breaking changes wherever reasonable. We support the last
-two versions of Go, currently: 1.7 and 1.8.
-
-# Goals
-
-* KISS;
-* Fast;
-* Small API. If it's easy to code in Go, don't make a function for it.
-
-# Users
-
-A not-so-up-to-date-list-that-may-be-actually-current:
-
-* https://github.com/coredns/coredns
-* https://cloudflare.com
-* https://github.com/abh/geodns
-* http://www.statdns.com/
-* http://www.dnsinspect.com/
-* https://github.com/chuangbo/jianbing-dictionary-dns
-* http://www.dns-lg.com/
-* https://github.com/fcambus/rrda
-* https://github.com/kenshinx/godns
-* https://github.com/skynetservices/skydns
-* https://github.com/hashicorp/consul
-* https://github.com/DevelopersPL/godnsagent
-* https://github.com/duedil-ltd/discodns
-* https://github.com/StalkR/dns-reverse-proxy
-* https://github.com/tianon/rawdns
-* https://mesosphere.github.io/mesos-dns/
-* https://pulse.turbobytes.com/
-* https://play.google.com/store/apps/details?id=com.turbobytes.dig
-* https://github.com/fcambus/statzone
-* https://github.com/benschw/dns-clb-go
-* https://github.com/corny/dnscheck for http://public-dns.info/
-* https://namesmith.io
-* https://github.com/miekg/unbound
-* https://github.com/miekg/exdns
-* https://dnslookup.org
-* https://github.com/looterz/grimd
-* https://github.com/phamhongviet/serf-dns
-* https://github.com/mehrdadrad/mylg
-* https://github.com/bamarni/dockness
-* https://github.com/fffaraz/microdns
-* http://quilt.io
-* https://github.com/ipdcode/hades (JD.COM)
-* https://github.com/StackExchange/dnscontrol/
-* https://www.dnsperf.com/
-* https://dnssectest.net/
-
-Send pull request if you want to be listed here.
-
-# Features
-
-* UDP/TCP queries, IPv4 and IPv6;
-* RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported;
-* Fast:
- * Reply speed around ~ 80K qps (faster hardware results in more qps);
- * Parsing RRs ~ 100K RR/s, that's 5M records in about 50 seconds;
-* Server side programming (mimicking the net/http package);
-* Client side programming;
-* DNSSEC: signing, validating and key generation for DSA, RSA and ECDSA;
-* EDNS0, NSID, Cookies;
-* AXFR/IXFR;
-* TSIG, SIG(0);
-* DNS over TLS: optional encrypted connection between client and server;
-* DNS name compression;
-* Depends only on the standard library.
-
-Have fun!
-
-Miek Gieben - 2010-2012 - <miek@miek.nl>
-
-# Building
-
-Building is done with the `go` tool. If you have setup your GOPATH
-correctly, the following should work:
-
- go get github.com/miekg/dns
- go build github.com/miekg/dns
-
-## Examples
-
-A short "how to use the API" is at the beginning of doc.go (this also will show
-when you call `godoc github.com/miekg/dns`).
-
-Example programs can be found in the `github.com/miekg/exdns` repository.
-
-## Supported RFCs
-
-*all of them*
-
-* 103{4,5} - DNS standard
-* 1348 - NSAP record (removed the record)
-* 1982 - Serial Arithmetic
-* 1876 - LOC record
-* 1995 - IXFR
-* 1996 - DNS notify
-* 2136 - DNS Update (dynamic updates)
-* 2181 - RRset definition - there is no RRset type though, just []RR
-* 2537 - RSAMD5 DNS keys
-* 2065 - DNSSEC (updated in later RFCs)
-* 2671 - EDNS record
-* 2782 - SRV record
-* 2845 - TSIG record
-* 2915 - NAPTR record
-* 2929 - DNS IANA Considerations
-* 3110 - RSASHA1 DNS keys
-* 3225 - DO bit (DNSSEC OK)
-* 340{1,2,3} - NAPTR record
-* 3445 - Limiting the scope of (DNS)KEY
-* 3597 - Unknown RRs
-* 403{3,4,5} - DNSSEC + validation functions
-* 4255 - SSHFP record
-* 4343 - Case insensitivity
-* 4408 - SPF record
-* 4509 - SHA256 Hash in DS
-* 4592 - Wildcards in the DNS
-* 4635 - HMAC SHA TSIG
-* 4701 - DHCID
-* 4892 - id.server
-* 5001 - NSID
-* 5155 - NSEC3 record
-* 5205 - HIP record
-* 5702 - SHA2 in the DNS
-* 5936 - AXFR
-* 5966 - TCP implementation recommendations
-* 6605 - ECDSA
-* 6725 - IANA Registry Update
-* 6742 - ILNP DNS
-* 6840 - Clarifications and Implementation Notes for DNS Security
-* 6844 - CAA record
-* 6891 - EDNS0 update
-* 6895 - DNS IANA considerations
-* 6975 - Algorithm Understanding in DNSSEC
-* 7043 - EUI48/EUI64 records
-* 7314 - DNS (EDNS) EXPIRE Option
-* 7828 - edns-tcp-keepalive EDNS0 Option
-* 7553 - URI record
-* 7858 - DNS over TLS: Initiation and Performance Considerations (draft)
-* 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies)
-* xxxx - EDNS0 DNS Update Lease (draft)
-
-## Loosely based upon
-
-* `ldns`
-* `NSD`
-* `Net::DNS`
-* `GRONG`
diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go
deleted file mode 100644
index 301dab9c1..000000000
--- a/vendor/github.com/miekg/dns/client.go
+++ /dev/null
@@ -1,467 +0,0 @@
-package dns
-
-// A client implementation.
-
-import (
- "bytes"
- "crypto/tls"
- "encoding/binary"
- "io"
- "net"
- "time"
-)
-
-const dnsTimeout time.Duration = 2 * time.Second
-const tcpIdleTimeout time.Duration = 8 * time.Second
-
-// A Conn represents a connection to a DNS server.
-type Conn struct {
- net.Conn // a net.Conn holding the connection
- UDPSize uint16 // minimum receive buffer for UDP messages
- TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
- rtt time.Duration
- t time.Time
- tsigRequestMAC string
-}
-
-// A Client defines parameters for a DNS client.
-type Client struct {
- Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
- UDPSize uint16 // minimum receive buffer for UDP messages
- TLSConfig *tls.Config // TLS connection configuration
- Timeout time.Duration // a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout and WriteTimeout when non-zero
- DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds - overridden by Timeout when that value is non-zero
- ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
- WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
- TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
- SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
- group singleflight
-}
-
-// Exchange performs a synchronous UDP query. It sends the message m to the address
-// contained in a and waits for a reply. Exchange does not retry a failed query, nor
-// will it fall back to TCP in case of truncation.
-// See client.Exchange for more information on setting larger buffer sizes.
-func Exchange(m *Msg, a string) (r *Msg, err error) {
- var co *Conn
- co, err = DialTimeout("udp", a, dnsTimeout)
- if err != nil {
- return nil, err
- }
-
- defer co.Close()
-
- opt := m.IsEdns0()
- // If EDNS0 is used use that for size.
- if opt != nil && opt.UDPSize() >= MinMsgSize {
- co.UDPSize = opt.UDPSize()
- }
-
- co.SetWriteDeadline(time.Now().Add(dnsTimeout))
- if err = co.WriteMsg(m); err != nil {
- return nil, err
- }
-
- co.SetReadDeadline(time.Now().Add(dnsTimeout))
- r, err = co.ReadMsg()
- if err == nil && r.Id != m.Id {
- err = ErrId
- }
- return r, err
-}
-
-// ExchangeConn performs a synchronous query. It sends the message m via the connection
-// c and waits for a reply. The connection c is not closed by ExchangeConn.
-// This function is going away, but can easily be mimicked:
-//
-// co := &dns.Conn{Conn: c} // c is your net.Conn
-// co.WriteMsg(m)
-// in, _ := co.ReadMsg()
-// co.Close()
-//
-func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
- println("dns: this function is deprecated")
- co := new(Conn)
- co.Conn = c
- if err = co.WriteMsg(m); err != nil {
- return nil, err
- }
- r, err = co.ReadMsg()
- if err == nil && r.Id != m.Id {
- err = ErrId
- }
- return r, err
-}
-
-// Exchange performs a synchronous query. It sends the message m to the address
-// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
-//
-// c := new(dns.Client)
-// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
-//
-// Exchange does not retry a failed query, nor will it fall back to TCP in
-// case of truncation.
-// It is up to the caller to create a message that allows for larger responses to be
-// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
-// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
-// of 512 bytes.
-func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
- if !c.SingleInflight {
- return c.exchange(m, a)
- }
- // This adds a bunch of garbage, TODO(miek).
- t := "nop"
- if t1, ok := TypeToString[m.Question[0].Qtype]; ok {
- t = t1
- }
- cl := "nop"
- if cl1, ok := ClassToString[m.Question[0].Qclass]; ok {
- cl = cl1
- }
- r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
- return c.exchange(m, a)
- })
- if r != nil && shared {
- r = r.Copy()
- }
- if err != nil {
- return r, rtt, err
- }
- return r, rtt, nil
-}
-
-func (c *Client) dialTimeout() time.Duration {
- if c.Timeout != 0 {
- return c.Timeout
- }
- if c.DialTimeout != 0 {
- return c.DialTimeout
- }
- return dnsTimeout
-}
-
-func (c *Client) readTimeout() time.Duration {
- if c.ReadTimeout != 0 {
- return c.ReadTimeout
- }
- return dnsTimeout
-}
-
-func (c *Client) writeTimeout() time.Duration {
- if c.WriteTimeout != 0 {
- return c.WriteTimeout
- }
- return dnsTimeout
-}
-
-func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
- var co *Conn
- network := "udp"
- tls := false
-
- switch c.Net {
- case "tcp-tls":
- network = "tcp"
- tls = true
- case "tcp4-tls":
- network = "tcp4"
- tls = true
- case "tcp6-tls":
- network = "tcp6"
- tls = true
- default:
- if c.Net != "" {
- network = c.Net
- }
- }
-
- var deadline time.Time
- if c.Timeout != 0 {
- deadline = time.Now().Add(c.Timeout)
- }
-
- if tls {
- co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, c.dialTimeout())
- } else {
- co, err = DialTimeout(network, a, c.dialTimeout())
- }
-
- if err != nil {
- return nil, 0, err
- }
- defer co.Close()
-
- opt := m.IsEdns0()
- // If EDNS0 is used use that for size.
- if opt != nil && opt.UDPSize() >= MinMsgSize {
- co.UDPSize = opt.UDPSize()
- }
- // Otherwise use the client's configured UDP size.
- if opt == nil && c.UDPSize >= MinMsgSize {
- co.UDPSize = c.UDPSize
- }
-
- co.TsigSecret = c.TsigSecret
- co.SetWriteDeadline(deadlineOrTimeout(deadline, c.writeTimeout()))
- if err = co.WriteMsg(m); err != nil {
- return nil, 0, err
- }
-
- co.SetReadDeadline(deadlineOrTimeout(deadline, c.readTimeout()))
- r, err = co.ReadMsg()
- if err == nil && r.Id != m.Id {
- err = ErrId
- }
- return r, co.rtt, err
-}
-
-// ReadMsg reads a message from the connection co.
-// If the received message contains a TSIG record the transaction
-// signature is verified.
-func (co *Conn) ReadMsg() (*Msg, error) {
- p, err := co.ReadMsgHeader(nil)
- if err != nil {
- return nil, err
- }
-
- m := new(Msg)
- if err := m.Unpack(p); err != nil {
- // If ErrTruncated was returned, we still want to allow the user to use
- // the message, but naively they can just check err if they don't want
- // to use a truncated message
- if err == ErrTruncated {
- return m, err
- }
- return nil, err
- }
- if t := m.IsTsig(); t != nil {
- if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
- return m, ErrSecret
- }
- // Need to work on the original message p, as that was used to calculate the tsig.
- err = TsigVerify(p, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
- }
- return m, err
-}
-
-// ReadMsgHeader reads a DNS message, parses and populates hdr (when hdr is not nil).
-// Returns message as a byte slice to be parsed with Msg.Unpack later on.
-// Note that error handling on the message body is not possible as only the header is parsed.
-func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) {
- var (
- p []byte
- n int
- err error
- )
-
- switch t := co.Conn.(type) {
- case *net.TCPConn, *tls.Conn:
- r := t.(io.Reader)
-
- // First two bytes specify the length of the entire message.
- l, err := tcpMsgLen(r)
- if err != nil {
- return nil, err
- }
- p = make([]byte, l)
- n, err = tcpRead(r, p)
- co.rtt = time.Since(co.t)
- default:
- if co.UDPSize > MinMsgSize {
- p = make([]byte, co.UDPSize)
- } else {
- p = make([]byte, MinMsgSize)
- }
- n, err = co.Read(p)
- co.rtt = time.Since(co.t)
- }
-
- if err != nil {
- return nil, err
- } else if n < headerSize {
- return nil, ErrShortRead
- }
-
- p = p[:n]
- if hdr != nil {
- dh, _, err := unpackMsgHdr(p, 0)
- if err != nil {
- return nil, err
- }
- *hdr = dh
- }
- return p, err
-}
-
-// tcpMsgLen is a helper func to read first two bytes of stream as uint16 packet length.
-func tcpMsgLen(t io.Reader) (int, error) {
- p := []byte{0, 0}
- n, err := t.Read(p)
- if err != nil {
- return 0, err
- }
-
- // As seen with my local router/switch, retursn 1 byte on the above read,
- // resulting a a ShortRead. Just write it out (instead of loop) and read the
- // other byte.
- if n == 1 {
- n1, err := t.Read(p[1:])
- if err != nil {
- return 0, err
- }
- n += n1
- }
-
- if n != 2 {
- return 0, ErrShortRead
- }
- l := binary.BigEndian.Uint16(p)
- if l == 0 {
- return 0, ErrShortRead
- }
- return int(l), nil
-}
-
-// tcpRead calls TCPConn.Read enough times to fill allocated buffer.
-func tcpRead(t io.Reader, p []byte) (int, error) {
- n, err := t.Read(p)
- if err != nil {
- return n, err
- }
- for n < len(p) {
- j, err := t.Read(p[n:])
- if err != nil {
- return n, err
- }
- n += j
- }
- return n, err
-}
-
-// Read implements the net.Conn read method.
-func (co *Conn) Read(p []byte) (n int, err error) {
- if co.Conn == nil {
- return 0, ErrConnEmpty
- }
- if len(p) < 2 {
- return 0, io.ErrShortBuffer
- }
- switch t := co.Conn.(type) {
- case *net.TCPConn, *tls.Conn:
- r := t.(io.Reader)
-
- l, err := tcpMsgLen(r)
- if err != nil {
- return 0, err
- }
- if l > len(p) {
- return int(l), io.ErrShortBuffer
- }
- return tcpRead(r, p[:l])
- }
- // UDP connection
- n, err = co.Conn.Read(p)
- if err != nil {
- return n, err
- }
- return n, err
-}
-
-// WriteMsg sends a message through the connection co.
-// If the message m contains a TSIG record the transaction
-// signature is calculated.
-func (co *Conn) WriteMsg(m *Msg) (err error) {
- var out []byte
- if t := m.IsTsig(); t != nil {
- mac := ""
- if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
- return ErrSecret
- }
- out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
- // Set for the next read, although only used in zone transfers
- co.tsigRequestMAC = mac
- } else {
- out, err = m.Pack()
- }
- if err != nil {
- return err
- }
- co.t = time.Now()
- if _, err = co.Write(out); err != nil {
- return err
- }
- return nil
-}
-
-// Write implements the net.Conn Write method.
-func (co *Conn) Write(p []byte) (n int, err error) {
- switch t := co.Conn.(type) {
- case *net.TCPConn, *tls.Conn:
- w := t.(io.Writer)
-
- lp := len(p)
- if lp < 2 {
- return 0, io.ErrShortBuffer
- }
- if lp > MaxMsgSize {
- return 0, &Error{err: "message too large"}
- }
- l := make([]byte, 2, lp+2)
- binary.BigEndian.PutUint16(l, uint16(lp))
- p = append(l, p...)
- n, err := io.Copy(w, bytes.NewReader(p))
- return int(n), err
- }
- n, err = co.Conn.Write(p)
- return n, err
-}
-
-// Dial connects to the address on the named network.
-func Dial(network, address string) (conn *Conn, err error) {
- conn = new(Conn)
- conn.Conn, err = net.Dial(network, address)
- if err != nil {
- return nil, err
- }
- return conn, nil
-}
-
-// DialTimeout acts like Dial but takes a timeout.
-func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
- conn = new(Conn)
- conn.Conn, err = net.DialTimeout(network, address, timeout)
- if err != nil {
- return nil, err
- }
- return conn, nil
-}
-
-// DialWithTLS connects to the address on the named network with TLS.
-func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) {
- conn = new(Conn)
- conn.Conn, err = tls.Dial(network, address, tlsConfig)
- if err != nil {
- return nil, err
- }
- return conn, nil
-}
-
-// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout.
-func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) {
- var dialer net.Dialer
- dialer.Timeout = timeout
-
- conn = new(Conn)
- conn.Conn, err = tls.DialWithDialer(&dialer, network, address, tlsConfig)
- if err != nil {
- return nil, err
- }
- return conn, nil
-}
-
-func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time {
- if deadline.IsZero() {
- return time.Now().Add(timeout)
- }
- return deadline
-}
diff --git a/vendor/github.com/miekg/dns/client_test.go b/vendor/github.com/miekg/dns/client_test.go
deleted file mode 100644
index dee585f36..000000000
--- a/vendor/github.com/miekg/dns/client_test.go
+++ /dev/null
@@ -1,511 +0,0 @@
-package dns
-
-import (
- "crypto/tls"
- "fmt"
- "net"
- "strconv"
- "sync"
- "testing"
- "time"
-)
-
-func TestClientSync(t *testing.T) {
- HandleFunc("miek.nl.", HelloServer)
- defer HandleRemove("miek.nl.")
-
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeSOA)
-
- c := new(Client)
- r, _, err := c.Exchange(m, addrstr)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
- if r != nil && r.Rcode != RcodeSuccess {
- t.Errorf("failed to get an valid answer\n%v", r)
- }
- // And now with plain Exchange().
- r, err = Exchange(m, addrstr)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
- if r == nil || r.Rcode != RcodeSuccess {
- t.Errorf("failed to get an valid answer\n%v", r)
- }
-}
-
-func TestClientTLSSync(t *testing.T) {
- HandleFunc("miek.nl.", HelloServer)
- defer HandleRemove("miek.nl.")
-
- cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock)
- if err != nil {
- t.Fatalf("unable to build certificate: %v", err)
- }
-
- config := tls.Config{
- Certificates: []tls.Certificate{cert},
- }
-
- s, addrstr, err := RunLocalTLSServer("127.0.0.1:0", &config)
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeSOA)
-
- c := new(Client)
- c.Net = "tcp-tls"
- c.TLSConfig = &tls.Config{
- InsecureSkipVerify: true,
- }
-
- r, _, err := c.Exchange(m, addrstr)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
- if r != nil && r.Rcode != RcodeSuccess {
- t.Errorf("failed to get an valid answer\n%v", r)
- }
-}
-
-func TestClientSyncBadID(t *testing.T) {
- HandleFunc("miek.nl.", HelloServerBadID)
- defer HandleRemove("miek.nl.")
-
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeSOA)
-
- c := new(Client)
- if _, _, err := c.Exchange(m, addrstr); err != ErrId {
- t.Errorf("did not find a bad Id")
- }
- // And now with plain Exchange().
- if _, err := Exchange(m, addrstr); err != ErrId {
- t.Errorf("did not find a bad Id")
- }
-}
-
-func TestClientEDNS0(t *testing.T) {
- HandleFunc("miek.nl.", HelloServer)
- defer HandleRemove("miek.nl.")
-
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeDNSKEY)
-
- m.SetEdns0(2048, true)
-
- c := new(Client)
- r, _, err := c.Exchange(m, addrstr)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
-
- if r != nil && r.Rcode != RcodeSuccess {
- t.Errorf("failed to get an valid answer\n%v", r)
- }
-}
-
-// Validates the transmission and parsing of local EDNS0 options.
-func TestClientEDNS0Local(t *testing.T) {
- optStr1 := "1979:0x0707"
- optStr2 := strconv.Itoa(EDNS0LOCALSTART) + ":0x0601"
-
- handler := func(w ResponseWriter, req *Msg) {
- m := new(Msg)
- m.SetReply(req)
-
- m.Extra = make([]RR, 1, 2)
- m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello local edns"}}
-
- // If the local options are what we expect, then reflect them back.
- ec1 := req.Extra[0].(*OPT).Option[0].(*EDNS0_LOCAL).String()
- ec2 := req.Extra[0].(*OPT).Option[1].(*EDNS0_LOCAL).String()
- if ec1 == optStr1 && ec2 == optStr2 {
- m.Extra = append(m.Extra, req.Extra[0])
- }
-
- w.WriteMsg(m)
- }
-
- HandleFunc("miek.nl.", handler)
- defer HandleRemove("miek.nl.")
-
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %s", err)
- }
- defer s.Shutdown()
-
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeTXT)
-
- // Add two local edns options to the query.
- ec1 := &EDNS0_LOCAL{Code: 1979, Data: []byte{7, 7}}
- ec2 := &EDNS0_LOCAL{Code: EDNS0LOCALSTART, Data: []byte{6, 1}}
- o := &OPT{Hdr: RR_Header{Name: ".", Rrtype: TypeOPT}, Option: []EDNS0{ec1, ec2}}
- m.Extra = append(m.Extra, o)
-
- c := new(Client)
- r, _, err := c.Exchange(m, addrstr)
- if err != nil {
- t.Errorf("failed to exchange: %s", err)
- }
-
- if r != nil && r.Rcode != RcodeSuccess {
- t.Error("failed to get a valid answer")
- t.Logf("%v\n", r)
- }
-
- txt := r.Extra[0].(*TXT).Txt[0]
- if txt != "Hello local edns" {
- t.Error("Unexpected result for miek.nl", txt, "!= Hello local edns")
- }
-
- // Validate the local options in the reply.
- got := r.Extra[1].(*OPT).Option[0].(*EDNS0_LOCAL).String()
- if got != optStr1 {
- t.Errorf("failed to get local edns0 answer; got %s, expected %s", got, optStr1)
- t.Logf("%v\n", r)
- }
-
- got = r.Extra[1].(*OPT).Option[1].(*EDNS0_LOCAL).String()
- if got != optStr2 {
- t.Errorf("failed to get local edns0 answer; got %s, expected %s", got, optStr2)
- t.Logf("%v\n", r)
- }
-}
-
-// ExampleTsigSecret_updateLeaseTSIG shows how to update a lease signed with TSIG
-func ExampleTsigSecret_updateLeaseTSIG() {
- m := new(Msg)
- m.SetUpdate("t.local.ip6.io.")
- rr, _ := NewRR("t.local.ip6.io. 30 A 127.0.0.1")
- rrs := make([]RR, 1)
- rrs[0] = rr
- m.Insert(rrs)
-
- leaseRr := new(OPT)
- leaseRr.Hdr.Name = "."
- leaseRr.Hdr.Rrtype = TypeOPT
- e := new(EDNS0_UL)
- e.Code = EDNS0UL
- e.Lease = 120
- leaseRr.Option = append(leaseRr.Option, e)
- m.Extra = append(m.Extra, leaseRr)
-
- c := new(Client)
- m.SetTsig("polvi.", HmacMD5, 300, time.Now().Unix())
- c.TsigSecret = map[string]string{"polvi.": "pRZgBrBvI4NAHZYhxmhs/Q=="}
-
- _, _, err := c.Exchange(m, "127.0.0.1:53")
- if err != nil {
- panic(err)
- }
-}
-
-func TestClientConn(t *testing.T) {
- HandleFunc("miek.nl.", HelloServer)
- defer HandleRemove("miek.nl.")
-
- // This uses TCP just to make it slightly different than TestClientSync
- s, addrstr, err := RunLocalTCPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeSOA)
-
- cn, err := Dial("tcp", addrstr)
- if err != nil {
- t.Errorf("failed to dial %s: %v", addrstr, err)
- }
-
- err = cn.WriteMsg(m)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
- r, err := cn.ReadMsg()
- if r == nil || r.Rcode != RcodeSuccess {
- t.Errorf("failed to get an valid answer\n%v", r)
- }
-
- err = cn.WriteMsg(m)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
- h := new(Header)
- buf, err := cn.ReadMsgHeader(h)
- if buf == nil {
- t.Errorf("failed to get an valid answer\n%v", r)
- }
- if int(h.Bits&0xF) != RcodeSuccess {
- t.Errorf("failed to get an valid answer in ReadMsgHeader\n%v", r)
- }
- if h.Ancount != 0 || h.Qdcount != 1 || h.Nscount != 0 || h.Arcount != 1 {
- t.Errorf("expected to have question and additional in response; got something else: %+v", h)
- }
- if err = r.Unpack(buf); err != nil {
- t.Errorf("unable to unpack message fully: %v", err)
- }
-}
-
-func TestTruncatedMsg(t *testing.T) {
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeSRV)
- cnt := 10
- for i := 0; i < cnt; i++ {
- r := &SRV{
- Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeSRV, Class: ClassINET, Ttl: 0},
- Port: uint16(i + 8000),
- Target: "target.miek.nl.",
- }
- m.Answer = append(m.Answer, r)
-
- re := &A{
- Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeA, Class: ClassINET, Ttl: 0},
- A: net.ParseIP(fmt.Sprintf("127.0.0.%d", i)).To4(),
- }
- m.Extra = append(m.Extra, re)
- }
- buf, err := m.Pack()
- if err != nil {
- t.Errorf("failed to pack: %v", err)
- }
-
- r := new(Msg)
- if err = r.Unpack(buf); err != nil {
- t.Errorf("unable to unpack message: %v", err)
- }
- if len(r.Answer) != cnt {
- t.Errorf("answer count after regular unpack doesn't match: %d", len(r.Answer))
- }
- if len(r.Extra) != cnt {
- t.Errorf("extra count after regular unpack doesn't match: %d", len(r.Extra))
- }
-
- m.Truncated = true
- buf, err = m.Pack()
- if err != nil {
- t.Errorf("failed to pack truncated: %v", err)
- }
-
- r = new(Msg)
- if err = r.Unpack(buf); err != nil && err != ErrTruncated {
- t.Errorf("unable to unpack truncated message: %v", err)
- }
- if !r.Truncated {
- t.Errorf("truncated message wasn't unpacked as truncated")
- }
- if len(r.Answer) != cnt {
- t.Errorf("answer count after truncated unpack doesn't match: %d", len(r.Answer))
- }
- if len(r.Extra) != cnt {
- t.Errorf("extra count after truncated unpack doesn't match: %d", len(r.Extra))
- }
-
- // Now we want to remove almost all of the extra records
- // We're going to loop over the extra to get the count of the size of all
- // of them
- off := 0
- buf1 := make([]byte, m.Len())
- for i := 0; i < len(m.Extra); i++ {
- off, err = PackRR(m.Extra[i], buf1, off, nil, m.Compress)
- if err != nil {
- t.Errorf("failed to pack extra: %v", err)
- }
- }
-
- // Remove all of the extra bytes but 10 bytes from the end of buf
- off -= 10
- buf1 = buf[:len(buf)-off]
-
- r = new(Msg)
- if err = r.Unpack(buf1); err != nil && err != ErrTruncated {
- t.Errorf("unable to unpack cutoff message: %v", err)
- }
- if !r.Truncated {
- t.Error("truncated cutoff message wasn't unpacked as truncated")
- }
- if len(r.Answer) != cnt {
- t.Errorf("answer count after cutoff unpack doesn't match: %d", len(r.Answer))
- }
- if len(r.Extra) != 0 {
- t.Errorf("extra count after cutoff unpack is not zero: %d", len(r.Extra))
- }
-
- // Now we want to remove almost all of the answer records too
- buf1 = make([]byte, m.Len())
- as := 0
- for i := 0; i < len(m.Extra); i++ {
- off1 := off
- off, err = PackRR(m.Extra[i], buf1, off, nil, m.Compress)
- as = off - off1
- if err != nil {
- t.Errorf("failed to pack extra: %v", err)
- }
- }
-
- // Keep exactly one answer left
- // This should still cause Answer to be nil
- off -= as
- buf1 = buf[:len(buf)-off]
-
- r = new(Msg)
- if err = r.Unpack(buf1); err != nil && err != ErrTruncated {
- t.Errorf("unable to unpack cutoff message: %v", err)
- }
- if !r.Truncated {
- t.Error("truncated cutoff message wasn't unpacked as truncated")
- }
- if len(r.Answer) != 0 {
- t.Errorf("answer count after second cutoff unpack is not zero: %d", len(r.Answer))
- }
-
- // Now leave only 1 byte of the question
- // Since the header is always 12 bytes, we just need to keep 13
- buf1 = buf[:13]
-
- r = new(Msg)
- err = r.Unpack(buf1)
- if err == nil || err == ErrTruncated {
- t.Errorf("error should not be ErrTruncated from question cutoff unpack: %v", err)
- }
-
- // Finally, if we only have the header, we should still return an error
- buf1 = buf[:12]
-
- r = new(Msg)
- if err = r.Unpack(buf1); err == nil || err != ErrTruncated {
- t.Errorf("error not ErrTruncated from header-only unpack: %v", err)
- }
-}
-
-func TestTimeout(t *testing.T) {
- // Set up a dummy UDP server that won't respond
- addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to resolve local udp address: %v", err)
- }
- conn, err := net.ListenUDP("udp", addr)
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer conn.Close()
- addrstr := conn.LocalAddr().String()
-
- // Message to send
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeTXT)
-
- // Use a channel + timeout to ensure we don't get stuck if the
- // Client Timeout is not working properly
- done := make(chan struct{})
-
- timeout := time.Millisecond
- allowable := timeout + (10 * time.Millisecond)
- abortAfter := timeout + (100 * time.Millisecond)
-
- start := time.Now()
-
- go func() {
- c := &Client{Timeout: timeout}
- _, _, err := c.Exchange(m, addrstr)
- if err == nil {
- t.Error("no timeout using Client")
- }
- done <- struct{}{}
- }()
-
- select {
- case <-done:
- case <-time.After(abortAfter):
- }
-
- length := time.Since(start)
-
- if length > allowable {
- t.Errorf("exchange took longer (%v) than specified Timeout (%v)", length, timeout)
- }
-}
-
-// Check that responses from deduplicated requests aren't shared between callers
-func TestConcurrentExchanges(t *testing.T) {
- cases := make([]*Msg, 2)
- cases[0] = new(Msg)
- cases[1] = new(Msg)
- cases[1].Truncated = true
- for _, m := range cases {
- block := make(chan struct{})
- waiting := make(chan struct{})
-
- handler := func(w ResponseWriter, req *Msg) {
- r := m.Copy()
- r.SetReply(req)
-
- waiting <- struct{}{}
- <-block
- w.WriteMsg(r)
- }
-
- HandleFunc("miek.nl.", handler)
- defer HandleRemove("miek.nl.")
-
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %s", err)
- }
- defer s.Shutdown()
-
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeSRV)
- c := &Client{
- SingleInflight: true,
- }
- r := make([]*Msg, 2)
-
- var wg sync.WaitGroup
- wg.Add(len(r))
- for i := 0; i < len(r); i++ {
- go func(i int) {
- r[i], _, _ = c.Exchange(m.Copy(), addrstr)
- wg.Done()
- }(i)
- }
- select {
- case <-waiting:
- case <-time.After(time.Second):
- t.FailNow()
- }
- close(block)
- wg.Wait()
-
- if r[0] == r[1] {
- t.Log("Got same response object, expected non-shared responses")
- t.Fail()
- }
- }
-}
diff --git a/vendor/github.com/miekg/dns/clientconfig.go b/vendor/github.com/miekg/dns/clientconfig.go
deleted file mode 100644
index 0a1f5a92c..000000000
--- a/vendor/github.com/miekg/dns/clientconfig.go
+++ /dev/null
@@ -1,131 +0,0 @@
-package dns
-
-import (
- "bufio"
- "os"
- "strconv"
- "strings"
-)
-
-// ClientConfig wraps the contents of the /etc/resolv.conf file.
-type ClientConfig struct {
- Servers []string // servers to use
- Search []string // suffixes to append to local name
- Port string // what port to use
- Ndots int // number of dots in name to trigger absolute lookup
- Timeout int // seconds before giving up on packet
- Attempts int // lost packets before giving up on server, not used in the package dns
-}
-
-// ClientConfigFromFile parses a resolv.conf(5) like file and returns
-// a *ClientConfig.
-func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
- file, err := os.Open(resolvconf)
- if err != nil {
- return nil, err
- }
- defer file.Close()
- c := new(ClientConfig)
- scanner := bufio.NewScanner(file)
- c.Servers = make([]string, 0)
- c.Search = make([]string, 0)
- c.Port = "53"
- c.Ndots = 1
- c.Timeout = 5
- c.Attempts = 2
-
- for scanner.Scan() {
- if err := scanner.Err(); err != nil {
- return nil, err
- }
- line := scanner.Text()
- f := strings.Fields(line)
- if len(f) < 1 {
- continue
- }
- switch f[0] {
- case "nameserver": // add one name server
- if len(f) > 1 {
- // One more check: make sure server name is
- // just an IP address. Otherwise we need DNS
- // to look it up.
- name := f[1]
- c.Servers = append(c.Servers, name)
- }
-
- case "domain": // set search path to just this domain
- if len(f) > 1 {
- c.Search = make([]string, 1)
- c.Search[0] = f[1]
- } else {
- c.Search = make([]string, 0)
- }
-
- case "search": // set search path to given servers
- c.Search = make([]string, len(f)-1)
- for i := 0; i < len(c.Search); i++ {
- c.Search[i] = f[i+1]
- }
-
- case "options": // magic options
- for i := 1; i < len(f); i++ {
- s := f[i]
- switch {
- case len(s) >= 6 && s[:6] == "ndots:":
- n, _ := strconv.Atoi(s[6:])
- if n < 1 {
- n = 1
- }
- c.Ndots = n
- case len(s) >= 8 && s[:8] == "timeout:":
- n, _ := strconv.Atoi(s[8:])
- if n < 1 {
- n = 1
- }
- c.Timeout = n
- case len(s) >= 8 && s[:9] == "attempts:":
- n, _ := strconv.Atoi(s[9:])
- if n < 1 {
- n = 1
- }
- c.Attempts = n
- case s == "rotate":
- /* not imp */
- }
- }
- }
- }
- return c, nil
-}
-
-// NameList returns all of the names that should be queried based on the
-// config. It is based off of go's net/dns name building, but it does not
-// check the length of the resulting names.
-func (c *ClientConfig) NameList(name string) []string {
- // if this domain is already fully qualified, no append needed.
- if IsFqdn(name) {
- return []string{name}
- }
-
- // Check to see if the name has more labels than Ndots. Do this before making
- // the domain fully qualified.
- hasNdots := CountLabel(name) > c.Ndots
- // Make the domain fully qualified.
- name = Fqdn(name)
-
- // Make a list of names based off search.
- names := []string{}
-
- // If name has enough dots, try that first.
- if hasNdots {
- names = append(names, name)
- }
- for _, s := range c.Search {
- names = append(names, Fqdn(name+s))
- }
- // If we didn't have enough dots, try after suffixes.
- if !hasNdots {
- names = append(names, name)
- }
- return names
-}
diff --git a/vendor/github.com/miekg/dns/clientconfig_test.go b/vendor/github.com/miekg/dns/clientconfig_test.go
deleted file mode 100644
index 7755a8a6f..000000000
--- a/vendor/github.com/miekg/dns/clientconfig_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package dns
-
-import (
- "io/ioutil"
- "os"
- "path/filepath"
- "testing"
-)
-
-const normal string = `
-# Comment
-domain somedomain.com
-nameserver 10.28.10.2
-nameserver 11.28.10.1
-`
-
-const missingNewline string = `
-domain somedomain.com
-nameserver 10.28.10.2
-nameserver 11.28.10.1` // <- NOTE: NO newline.
-
-func testConfig(t *testing.T, data string) {
- tempDir, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("tempDir: %v", err)
- }
- defer os.RemoveAll(tempDir)
-
- path := filepath.Join(tempDir, "resolv.conf")
- if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil {
- t.Fatalf("writeFile: %v", err)
- }
- cc, err := ClientConfigFromFile(path)
- if err != nil {
- t.Errorf("error parsing resolv.conf: %v", err)
- }
- if l := len(cc.Servers); l != 2 {
- t.Errorf("incorrect number of nameservers detected: %d", l)
- }
- if l := len(cc.Search); l != 1 {
- t.Errorf("domain directive not parsed correctly: %v", cc.Search)
- } else {
- if cc.Search[0] != "somedomain.com" {
- t.Errorf("domain is unexpected: %v", cc.Search[0])
- }
- }
-}
-
-func TestNameserver(t *testing.T) { testConfig(t, normal) }
-func TestMissingFinalNewLine(t *testing.T) { testConfig(t, missingNewline) }
-
-func TestNameList(t *testing.T) {
- cfg := ClientConfig{
- Ndots: 1,
- }
- // fqdn should be only result returned
- names := cfg.NameList("miek.nl.")
- if len(names) != 1 {
- t.Errorf("NameList returned != 1 names: %v", names)
- } else if names[0] != "miek.nl." {
- t.Errorf("NameList didn't return sent fqdn domain: %v", names[0])
- }
-
- cfg.Search = []string{
- "test",
- }
- // Sent domain has NDots and search
- names = cfg.NameList("miek.nl")
- if len(names) != 2 {
- t.Errorf("NameList returned != 2 names: %v", names)
- } else if names[0] != "miek.nl." {
- t.Errorf("NameList didn't return sent domain first: %v", names[0])
- } else if names[1] != "miek.nl.test." {
- t.Errorf("NameList didn't return search last: %v", names[1])
- }
-
- cfg.Ndots = 2
- // Sent domain has less than NDots and search
- names = cfg.NameList("miek.nl")
- if len(names) != 2 {
- t.Errorf("NameList returned != 2 names: %v", names)
- } else if names[0] != "miek.nl.test." {
- t.Errorf("NameList didn't return search first: %v", names[0])
- } else if names[1] != "miek.nl." {
- t.Errorf("NameList didn't return sent domain last: %v", names[1])
- }
-}
diff --git a/vendor/github.com/miekg/dns/compress_generate.go b/vendor/github.com/miekg/dns/compress_generate.go
deleted file mode 100644
index 1a301e9f3..000000000
--- a/vendor/github.com/miekg/dns/compress_generate.go
+++ /dev/null
@@ -1,184 +0,0 @@
-//+build ignore
-
-// compression_generate.go is meant to run with go generate. It will use
-// go/{importer,types} to track down all the RR struct types. Then for each type
-// it will look to see if there are (compressible) names, if so it will add that
-// type to compressionLenHelperType and comressionLenSearchType which "fake" the
-// compression so that Len() is fast.
-package main
-
-import (
- "bytes"
- "fmt"
- "go/format"
- "go/importer"
- "go/types"
- "log"
- "os"
-)
-
-var packageHdr = `
-// *** DO NOT MODIFY ***
-// AUTOGENERATED BY go generate from compress_generate.go
-
-package dns
-
-`
-
-// getTypeStruct will take a type and the package scope, and return the
-// (innermost) struct if the type is considered a RR type (currently defined as
-// those structs beginning with a RR_Header, could be redefined as implementing
-// the RR interface). The bool return value indicates if embedded structs were
-// resolved.
-func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) {
- st, ok := t.Underlying().(*types.Struct)
- if !ok {
- return nil, false
- }
- if st.Field(0).Type() == scope.Lookup("RR_Header").Type() {
- return st, false
- }
- if st.Field(0).Anonymous() {
- st, _ := getTypeStruct(st.Field(0).Type(), scope)
- return st, true
- }
- return nil, false
-}
-
-func main() {
- // Import and type-check the package
- pkg, err := importer.Default().Import("github.com/miekg/dns")
- fatalIfErr(err)
- scope := pkg.Scope()
-
- domainTypes := map[string]bool{} // Types that have a domain name in them (either comressible or not).
- cdomainTypes := map[string]bool{} // Types that have a compressible domain name in them (subset of domainType)
- for _, name := range scope.Names() {
- o := scope.Lookup(name)
- if o == nil || !o.Exported() {
- continue
- }
- st, _ := getTypeStruct(o.Type(), scope)
- if st == nil {
- continue
- }
- if name == "PrivateRR" {
- continue
- }
-
- if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" {
- log.Fatalf("Constant Type%s does not exist.", o.Name())
- }
-
- for i := 1; i < st.NumFields(); i++ {
- if _, ok := st.Field(i).Type().(*types.Slice); ok {
- if st.Tag(i) == `dns:"domain-name"` {
- domainTypes[o.Name()] = true
- }
- if st.Tag(i) == `dns:"cdomain-name"` {
- cdomainTypes[o.Name()] = true
- domainTypes[o.Name()] = true
- }
- continue
- }
-
- switch {
- case st.Tag(i) == `dns:"domain-name"`:
- domainTypes[o.Name()] = true
- case st.Tag(i) == `dns:"cdomain-name"`:
- cdomainTypes[o.Name()] = true
- domainTypes[o.Name()] = true
- }
- }
- }
-
- b := &bytes.Buffer{}
- b.WriteString(packageHdr)
-
- // compressionLenHelperType - all types that have domain-name/cdomain-name can be used for compressing names
-
- fmt.Fprint(b, "func compressionLenHelperType(c map[string]int, r RR) {\n")
- fmt.Fprint(b, "switch x := r.(type) {\n")
- for name, _ := range domainTypes {
- o := scope.Lookup(name)
- st, _ := getTypeStruct(o.Type(), scope)
-
- fmt.Fprintf(b, "case *%s:\n", name)
- for i := 1; i < st.NumFields(); i++ {
- out := func(s string) { fmt.Fprintf(b, "compressionLenHelper(c, x.%s)\n", st.Field(i).Name()) }
-
- if _, ok := st.Field(i).Type().(*types.Slice); ok {
- switch st.Tag(i) {
- case `dns:"domain-name"`:
- fallthrough
- case `dns:"cdomain-name"`:
- // For HIP we need to slice over the elements in this slice.
- fmt.Fprintf(b, `for i := range x.%s {
- compressionLenHelper(c, x.%s[i])
- }
-`, st.Field(i).Name(), st.Field(i).Name())
- }
- continue
- }
-
- switch {
- case st.Tag(i) == `dns:"cdomain-name"`:
- fallthrough
- case st.Tag(i) == `dns:"domain-name"`:
- out(st.Field(i).Name())
- }
- }
- }
- fmt.Fprintln(b, "}\n}\n\n")
-
- // compressionLenSearchType - search cdomain-tags types for compressible names.
-
- fmt.Fprint(b, "func compressionLenSearchType(c map[string]int, r RR) (int, bool) {\n")
- fmt.Fprint(b, "switch x := r.(type) {\n")
- for name, _ := range cdomainTypes {
- o := scope.Lookup(name)
- st, _ := getTypeStruct(o.Type(), scope)
-
- fmt.Fprintf(b, "case *%s:\n", name)
- j := 1
- for i := 1; i < st.NumFields(); i++ {
- out := func(s string, j int) {
- fmt.Fprintf(b, "k%d, ok%d := compressionLenSearch(c, x.%s)\n", j, j, st.Field(i).Name())
- }
-
- // There are no slice types with names that can be compressed.
-
- switch {
- case st.Tag(i) == `dns:"cdomain-name"`:
- out(st.Field(i).Name(), j)
- j++
- }
- }
- k := "k1"
- ok := "ok1"
- for i := 2; i < j; i++ {
- k += fmt.Sprintf(" + k%d", i)
- ok += fmt.Sprintf(" && ok%d", i)
- }
- fmt.Fprintf(b, "return %s, %s\n", k, ok)
- }
- fmt.Fprintln(b, "}\nreturn 0, false\n}\n\n")
-
- // gofmt
- res, err := format.Source(b.Bytes())
- if err != nil {
- b.WriteTo(os.Stderr)
- log.Fatal(err)
- }
-
- f, err := os.Create("zcompress.go")
- fatalIfErr(err)
- defer f.Close()
- f.Write(res)
-}
-
-func fatalIfErr(err error) {
- if err != nil {
- log.Fatal(err)
- }
-}
diff --git a/vendor/github.com/miekg/dns/dane.go b/vendor/github.com/miekg/dns/dane.go
deleted file mode 100644
index 8c4a14ef1..000000000
--- a/vendor/github.com/miekg/dns/dane.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package dns
-
-import (
- "crypto/sha256"
- "crypto/sha512"
- "crypto/x509"
- "encoding/hex"
- "errors"
-)
-
-// CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records.
-func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) {
- switch matchingType {
- case 0:
- switch selector {
- case 0:
- return hex.EncodeToString(cert.Raw), nil
- case 1:
- return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil
- }
- case 1:
- h := sha256.New()
- switch selector {
- case 0:
- h.Write(cert.Raw)
- return hex.EncodeToString(h.Sum(nil)), nil
- case 1:
- h.Write(cert.RawSubjectPublicKeyInfo)
- return hex.EncodeToString(h.Sum(nil)), nil
- }
- case 2:
- h := sha512.New()
- switch selector {
- case 0:
- h.Write(cert.Raw)
- return hex.EncodeToString(h.Sum(nil)), nil
- case 1:
- h.Write(cert.RawSubjectPublicKeyInfo)
- return hex.EncodeToString(h.Sum(nil)), nil
- }
- }
- return "", errors.New("dns: bad MatchingType or Selector")
-}
diff --git a/vendor/github.com/miekg/dns/defaults.go b/vendor/github.com/miekg/dns/defaults.go
deleted file mode 100644
index c34890eec..000000000
--- a/vendor/github.com/miekg/dns/defaults.go
+++ /dev/null
@@ -1,285 +0,0 @@
-package dns
-
-import (
- "errors"
- "net"
- "strconv"
-)
-
-const hexDigit = "0123456789abcdef"
-
-// Everything is assumed in ClassINET.
-
-// SetReply creates a reply message from a request message.
-func (dns *Msg) SetReply(request *Msg) *Msg {
- dns.Id = request.Id
- dns.Response = true
- dns.Opcode = request.Opcode
- if dns.Opcode == OpcodeQuery {
- dns.RecursionDesired = request.RecursionDesired // Copy rd bit
- dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit
- }
- dns.Rcode = RcodeSuccess
- if len(request.Question) > 0 {
- dns.Question = make([]Question, 1)
- dns.Question[0] = request.Question[0]
- }
- return dns
-}
-
-// SetQuestion creates a question message, it sets the Question
-// section, generates an Id and sets the RecursionDesired (RD)
-// bit to true.
-func (dns *Msg) SetQuestion(z string, t uint16) *Msg {
- dns.Id = Id()
- dns.RecursionDesired = true
- dns.Question = make([]Question, 1)
- dns.Question[0] = Question{z, t, ClassINET}
- return dns
-}
-
-// SetNotify creates a notify message, it sets the Question
-// section, generates an Id and sets the Authoritative (AA)
-// bit to true.
-func (dns *Msg) SetNotify(z string) *Msg {
- dns.Opcode = OpcodeNotify
- dns.Authoritative = true
- dns.Id = Id()
- dns.Question = make([]Question, 1)
- dns.Question[0] = Question{z, TypeSOA, ClassINET}
- return dns
-}
-
-// SetRcode creates an error message suitable for the request.
-func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg {
- dns.SetReply(request)
- dns.Rcode = rcode
- return dns
-}
-
-// SetRcodeFormatError creates a message with FormError set.
-func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg {
- dns.Rcode = RcodeFormatError
- dns.Opcode = OpcodeQuery
- dns.Response = true
- dns.Authoritative = false
- dns.Id = request.Id
- return dns
-}
-
-// SetUpdate makes the message a dynamic update message. It
-// sets the ZONE section to: z, TypeSOA, ClassINET.
-func (dns *Msg) SetUpdate(z string) *Msg {
- dns.Id = Id()
- dns.Response = false
- dns.Opcode = OpcodeUpdate
- dns.Compress = false // BIND9 cannot handle compression
- dns.Question = make([]Question, 1)
- dns.Question[0] = Question{z, TypeSOA, ClassINET}
- return dns
-}
-
-// SetIxfr creates message for requesting an IXFR.
-func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg {
- dns.Id = Id()
- dns.Question = make([]Question, 1)
- dns.Ns = make([]RR, 1)
- s := new(SOA)
- s.Hdr = RR_Header{z, TypeSOA, ClassINET, defaultTtl, 0}
- s.Serial = serial
- s.Ns = ns
- s.Mbox = mbox
- dns.Question[0] = Question{z, TypeIXFR, ClassINET}
- dns.Ns[0] = s
- return dns
-}
-
-// SetAxfr creates message for requesting an AXFR.
-func (dns *Msg) SetAxfr(z string) *Msg {
- dns.Id = Id()
- dns.Question = make([]Question, 1)
- dns.Question[0] = Question{z, TypeAXFR, ClassINET}
- return dns
-}
-
-// SetTsig appends a TSIG RR to the message.
-// This is only a skeleton TSIG RR that is added as the last RR in the
-// additional section. The Tsig is calculated when the message is being send.
-func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg {
- t := new(TSIG)
- t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
- t.Algorithm = algo
- t.Fudge = fudge
- t.TimeSigned = uint64(timesigned)
- t.OrigId = dns.Id
- dns.Extra = append(dns.Extra, t)
- return dns
-}
-
-// SetEdns0 appends a EDNS0 OPT RR to the message.
-// TSIG should always the last RR in a message.
-func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg {
- e := new(OPT)
- e.Hdr.Name = "."
- e.Hdr.Rrtype = TypeOPT
- e.SetUDPSize(udpsize)
- if do {
- e.SetDo()
- }
- dns.Extra = append(dns.Extra, e)
- return dns
-}
-
-// IsTsig checks if the message has a TSIG record as the last record
-// in the additional section. It returns the TSIG record found or nil.
-func (dns *Msg) IsTsig() *TSIG {
- if len(dns.Extra) > 0 {
- if dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG {
- return dns.Extra[len(dns.Extra)-1].(*TSIG)
- }
- }
- return nil
-}
-
-// IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0
-// record in the additional section will do. It returns the OPT record
-// found or nil.
-func (dns *Msg) IsEdns0() *OPT {
- // EDNS0 is at the end of the additional section, start there.
- // We might want to change this to *only* look at the last two
- // records. So we see TSIG and/or OPT - this a slightly bigger
- // change though.
- for i := len(dns.Extra) - 1; i >= 0; i-- {
- if dns.Extra[i].Header().Rrtype == TypeOPT {
- return dns.Extra[i].(*OPT)
- }
- }
- return nil
-}
-
-// IsDomainName checks if s is a valid domain name, it returns the number of
-// labels and true, when a domain name is valid. Note that non fully qualified
-// domain name is considered valid, in this case the last label is counted in
-// the number of labels. When false is returned the number of labels is not
-// defined. Also note that this function is extremely liberal; almost any
-// string is a valid domain name as the DNS is 8 bit protocol. It checks if each
-// label fits in 63 characters, but there is no length check for the entire
-// string s. I.e. a domain name longer than 255 characters is considered valid.
-func IsDomainName(s string) (labels int, ok bool) {
- _, labels, err := packDomainName(s, nil, 0, nil, false)
- return labels, err == nil
-}
-
-// IsSubDomain checks if child is indeed a child of the parent. If child and parent
-// are the same domain true is returned as well.
-func IsSubDomain(parent, child string) bool {
- // Entire child is contained in parent
- return CompareDomainName(parent, child) == CountLabel(parent)
-}
-
-// IsMsg sanity checks buf and returns an error if it isn't a valid DNS packet.
-// The checking is performed on the binary payload.
-func IsMsg(buf []byte) error {
- // Header
- if len(buf) < 12 {
- return errors.New("dns: bad message header")
- }
- // Header: Opcode
- // TODO(miek): more checks here, e.g. check all header bits.
- return nil
-}
-
-// IsFqdn checks if a domain name is fully qualified.
-func IsFqdn(s string) bool {
- l := len(s)
- if l == 0 {
- return false
- }
- return s[l-1] == '.'
-}
-
-// IsRRset checks if a set of RRs is a valid RRset as defined by RFC 2181.
-// This means the RRs need to have the same type, name, and class. Returns true
-// if the RR set is valid, otherwise false.
-func IsRRset(rrset []RR) bool {
- if len(rrset) == 0 {
- return false
- }
- if len(rrset) == 1 {
- return true
- }
- rrHeader := rrset[0].Header()
- rrType := rrHeader.Rrtype
- rrClass := rrHeader.Class
- rrName := rrHeader.Name
-
- for _, rr := range rrset[1:] {
- curRRHeader := rr.Header()
- if curRRHeader.Rrtype != rrType || curRRHeader.Class != rrClass || curRRHeader.Name != rrName {
- // Mismatch between the records, so this is not a valid rrset for
- //signing/verifying
- return false
- }
- }
-
- return true
-}
-
-// Fqdn return the fully qualified domain name from s.
-// If s is already fully qualified, it behaves as the identity function.
-func Fqdn(s string) string {
- if IsFqdn(s) {
- return s
- }
- return s + "."
-}
-
-// Copied from the official Go code.
-
-// ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
-// address suitable for reverse DNS (PTR) record lookups or an error if it fails
-// to parse the IP address.
-func ReverseAddr(addr string) (arpa string, err error) {
- ip := net.ParseIP(addr)
- if ip == nil {
- return "", &Error{err: "unrecognized address: " + addr}
- }
- if ip.To4() != nil {
- return strconv.Itoa(int(ip[15])) + "." + strconv.Itoa(int(ip[14])) + "." + strconv.Itoa(int(ip[13])) + "." +
- strconv.Itoa(int(ip[12])) + ".in-addr.arpa.", nil
- }
- // Must be IPv6
- buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
- // Add it, in reverse, to the buffer
- for i := len(ip) - 1; i >= 0; i-- {
- v := ip[i]
- buf = append(buf, hexDigit[v&0xF])
- buf = append(buf, '.')
- buf = append(buf, hexDigit[v>>4])
- buf = append(buf, '.')
- }
- // Append "ip6.arpa." and return (buf already has the final .)
- buf = append(buf, "ip6.arpa."...)
- return string(buf), nil
-}
-
-// String returns the string representation for the type t.
-func (t Type) String() string {
- if t1, ok := TypeToString[uint16(t)]; ok {
- return t1
- }
- return "TYPE" + strconv.Itoa(int(t))
-}
-
-// String returns the string representation for the class c.
-func (c Class) String() string {
- if c1, ok := ClassToString[uint16(c)]; ok {
- return c1
- }
- return "CLASS" + strconv.Itoa(int(c))
-}
-
-// String returns the string representation for the name n.
-func (n Name) String() string {
- return sprintName(string(n))
-}
diff --git a/vendor/github.com/miekg/dns/dns.go b/vendor/github.com/miekg/dns/dns.go
deleted file mode 100644
index b3292287c..000000000
--- a/vendor/github.com/miekg/dns/dns.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package dns
-
-import "strconv"
-
-const (
- year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
- defaultTtl = 3600 // Default internal TTL.
-
- DefaultMsgSize = 4096 // DefaultMsgSize is the standard default for messages larger than 512 bytes.
- MinMsgSize = 512 // MinMsgSize is the minimal size of a DNS packet.
- MaxMsgSize = 65535 // MaxMsgSize is the largest possible DNS packet.
-)
-
-// Error represents a DNS error.
-type Error struct{ err string }
-
-func (e *Error) Error() string {
- if e == nil {
- return "dns: <nil>"
- }
- return "dns: " + e.err
-}
-
-// An RR represents a resource record.
-type RR interface {
- // Header returns the header of an resource record. The header contains
- // everything up to the rdata.
- Header() *RR_Header
- // String returns the text representation of the resource record.
- String() string
-
- // copy returns a copy of the RR
- copy() RR
- // len returns the length (in octets) of the uncompressed RR in wire format.
- len() int
- // pack packs an RR into wire format.
- pack([]byte, int, map[string]int, bool) (int, error)
-}
-
-// RR_Header is the header all DNS resource records share.
-type RR_Header struct {
- Name string `dns:"cdomain-name"`
- Rrtype uint16
- Class uint16
- Ttl uint32
- Rdlength uint16 // Length of data after header.
-}
-
-// Header returns itself. This is here to make RR_Header implements the RR interface.
-func (h *RR_Header) Header() *RR_Header { return h }
-
-// Just to implement the RR interface.
-func (h *RR_Header) copy() RR { return nil }
-
-func (h *RR_Header) copyHeader() *RR_Header {
- r := new(RR_Header)
- r.Name = h.Name
- r.Rrtype = h.Rrtype
- r.Class = h.Class
- r.Ttl = h.Ttl
- r.Rdlength = h.Rdlength
- return r
-}
-
-func (h *RR_Header) String() string {
- var s string
-
- if h.Rrtype == TypeOPT {
- s = ";"
- // and maybe other things
- }
-
- s += sprintName(h.Name) + "\t"
- s += strconv.FormatInt(int64(h.Ttl), 10) + "\t"
- s += Class(h.Class).String() + "\t"
- s += Type(h.Rrtype).String() + "\t"
- return s
-}
-
-func (h *RR_Header) len() int {
- l := len(h.Name) + 1
- l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2)
- return l
-}
-
-// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597.
-func (rr *RFC3597) ToRFC3597(r RR) error {
- buf := make([]byte, r.len()*2)
- off, err := PackRR(r, buf, 0, nil, false)
- if err != nil {
- return err
- }
- buf = buf[:off]
- if int(r.Header().Rdlength) > off {
- return ErrBuf
- }
-
- rfc3597, _, err := unpackRFC3597(*r.Header(), buf, off-int(r.Header().Rdlength))
- if err != nil {
- return err
- }
- *rr = *rfc3597.(*RFC3597)
- return nil
-}
diff --git a/vendor/github.com/miekg/dns/dns_bench_test.go b/vendor/github.com/miekg/dns/dns_bench_test.go
deleted file mode 100644
index bccc3d540..000000000
--- a/vendor/github.com/miekg/dns/dns_bench_test.go
+++ /dev/null
@@ -1,211 +0,0 @@
-package dns
-
-import (
- "net"
- "testing"
-)
-
-func BenchmarkMsgLength(b *testing.B) {
- b.StopTimer()
- makeMsg := func(question string, ans, ns, e []RR) *Msg {
- msg := new(Msg)
- msg.SetQuestion(Fqdn(question), TypeANY)
- msg.Answer = append(msg.Answer, ans...)
- msg.Ns = append(msg.Ns, ns...)
- msg.Extra = append(msg.Extra, e...)
- msg.Compress = true
- return msg
- }
- name1 := "12345678901234567890123456789012345.12345678.123."
- rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
- msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- msg.Len()
- }
-}
-
-func BenchmarkMsgLengthPack(b *testing.B) {
- makeMsg := func(question string, ans, ns, e []RR) *Msg {
- msg := new(Msg)
- msg.SetQuestion(Fqdn(question), TypeANY)
- msg.Answer = append(msg.Answer, ans...)
- msg.Ns = append(msg.Ns, ns...)
- msg.Extra = append(msg.Extra, e...)
- msg.Compress = true
- return msg
- }
- name1 := "12345678901234567890123456789012345.12345678.123."
- rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
- msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = msg.Pack()
- }
-}
-
-func BenchmarkPackDomainName(b *testing.B) {
- name1 := "12345678901234567890123456789012345.12345678.123."
- buf := make([]byte, len(name1)+1)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = PackDomainName(name1, buf, 0, nil, false)
- }
-}
-
-func BenchmarkUnpackDomainName(b *testing.B) {
- name1 := "12345678901234567890123456789012345.12345678.123."
- buf := make([]byte, len(name1)+1)
- _, _ = PackDomainName(name1, buf, 0, nil, false)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _, _ = UnpackDomainName(buf, 0)
- }
-}
-
-func BenchmarkUnpackDomainNameUnprintable(b *testing.B) {
- name1 := "\x02\x02\x02\x025\x02\x02\x02\x02.12345678.123."
- buf := make([]byte, len(name1)+1)
- _, _ = PackDomainName(name1, buf, 0, nil, false)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _, _ = UnpackDomainName(buf, 0)
- }
-}
-
-func BenchmarkCopy(b *testing.B) {
- b.ReportAllocs()
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeA)
- rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1")
- m.Answer = []RR{rr}
- rr, _ = NewRR("miek.nl. 2311 IN NS 127.0.0.1")
- m.Ns = []RR{rr}
- rr, _ = NewRR("miek.nl. 2311 IN A 127.0.0.1")
- m.Extra = []RR{rr}
-
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- m.Copy()
- }
-}
-
-func BenchmarkPackA(b *testing.B) {
- a := &A{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, A: net.IPv4(127, 0, 0, 1)}
-
- buf := make([]byte, a.len())
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = PackRR(a, buf, 0, nil, false)
- }
-}
-
-func BenchmarkUnpackA(b *testing.B) {
- a := &A{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, A: net.IPv4(127, 0, 0, 1)}
-
- buf := make([]byte, a.len())
- PackRR(a, buf, 0, nil, false)
- a = nil
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _, _ = UnpackRR(buf, 0)
- }
-}
-
-func BenchmarkPackMX(b *testing.B) {
- m := &MX{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, Mx: "mx.miek.nl."}
-
- buf := make([]byte, m.len())
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = PackRR(m, buf, 0, nil, false)
- }
-}
-
-func BenchmarkUnpackMX(b *testing.B) {
- m := &MX{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, Mx: "mx.miek.nl."}
-
- buf := make([]byte, m.len())
- PackRR(m, buf, 0, nil, false)
- m = nil
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _, _ = UnpackRR(buf, 0)
- }
-}
-
-func BenchmarkPackAAAAA(b *testing.B) {
- aaaa, _ := NewRR(". IN A ::1")
-
- buf := make([]byte, aaaa.len())
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = PackRR(aaaa, buf, 0, nil, false)
- }
-}
-
-func BenchmarkUnpackAAAA(b *testing.B) {
- aaaa, _ := NewRR(". IN A ::1")
-
- buf := make([]byte, aaaa.len())
- PackRR(aaaa, buf, 0, nil, false)
- aaaa = nil
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _, _ = UnpackRR(buf, 0)
- }
-}
-
-func BenchmarkPackMsg(b *testing.B) {
- makeMsg := func(question string, ans, ns, e []RR) *Msg {
- msg := new(Msg)
- msg.SetQuestion(Fqdn(question), TypeANY)
- msg.Answer = append(msg.Answer, ans...)
- msg.Ns = append(msg.Ns, ns...)
- msg.Extra = append(msg.Extra, e...)
- msg.Compress = true
- return msg
- }
- name1 := "12345678901234567890123456789012345.12345678.123."
- rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
- msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
- buf := make([]byte, 512)
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = msg.PackBuffer(buf)
- }
-}
-
-func BenchmarkUnpackMsg(b *testing.B) {
- makeMsg := func(question string, ans, ns, e []RR) *Msg {
- msg := new(Msg)
- msg.SetQuestion(Fqdn(question), TypeANY)
- msg.Answer = append(msg.Answer, ans...)
- msg.Ns = append(msg.Ns, ns...)
- msg.Extra = append(msg.Extra, e...)
- msg.Compress = true
- return msg
- }
- name1 := "12345678901234567890123456789012345.12345678.123."
- rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
- msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
- msgBuf, _ := msg.Pack()
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _ = msg.Unpack(msgBuf)
- }
-}
-
-func BenchmarkIdGeneration(b *testing.B) {
- for i := 0; i < b.N; i++ {
- _ = id()
- }
-}
diff --git a/vendor/github.com/miekg/dns/dns_test.go b/vendor/github.com/miekg/dns/dns_test.go
deleted file mode 100644
index dbfe25328..000000000
--- a/vendor/github.com/miekg/dns/dns_test.go
+++ /dev/null
@@ -1,450 +0,0 @@
-package dns
-
-import (
- "encoding/hex"
- "net"
- "testing"
-)
-
-func TestPackUnpack(t *testing.T) {
- out := new(Msg)
- out.Answer = make([]RR, 1)
- key := new(DNSKEY)
- key = &DNSKEY{Flags: 257, Protocol: 3, Algorithm: RSASHA1}
- key.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 3600}
- key.PublicKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
-
- out.Answer[0] = key
- msg, err := out.Pack()
- if err != nil {
- t.Error("failed to pack msg with DNSKEY")
- }
- in := new(Msg)
- if in.Unpack(msg) != nil {
- t.Error("failed to unpack msg with DNSKEY")
- }
-
- sig := new(RRSIG)
- sig = &RRSIG{TypeCovered: TypeDNSKEY, Algorithm: RSASHA1, Labels: 2,
- OrigTtl: 3600, Expiration: 4000, Inception: 4000, KeyTag: 34641, SignerName: "miek.nl.",
- Signature: "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"}
- sig.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeRRSIG, Class: ClassINET, Ttl: 3600}
-
- out.Answer[0] = sig
- msg, err = out.Pack()
- if err != nil {
- t.Error("failed to pack msg with RRSIG")
- }
-
- if in.Unpack(msg) != nil {
- t.Error("failed to unpack msg with RRSIG")
- }
-}
-
-func TestPackUnpack2(t *testing.T) {
- m := new(Msg)
- m.Extra = make([]RR, 1)
- m.Answer = make([]RR, 1)
- dom := "miek.nl."
- rr := new(A)
- rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0}
- rr.A = net.IPv4(127, 0, 0, 1)
-
- x := new(TXT)
- x.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
- x.Txt = []string{"heelalaollo"}
-
- m.Extra[0] = x
- m.Answer[0] = rr
- _, err := m.Pack()
- if err != nil {
- t.Error("Packing failed: ", err)
- return
- }
-}
-
-func TestPackUnpack3(t *testing.T) {
- m := new(Msg)
- m.Extra = make([]RR, 2)
- m.Answer = make([]RR, 1)
- dom := "miek.nl."
- rr := new(A)
- rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0}
- rr.A = net.IPv4(127, 0, 0, 1)
-
- x1 := new(TXT)
- x1.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
- x1.Txt = []string{}
-
- x2 := new(TXT)
- x2.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
- x2.Txt = []string{"heelalaollo"}
-
- m.Extra[0] = x1
- m.Extra[1] = x2
- m.Answer[0] = rr
- b, err := m.Pack()
- if err != nil {
- t.Error("packing failed: ", err)
- return
- }
-
- var unpackMsg Msg
- err = unpackMsg.Unpack(b)
- if err != nil {
- t.Error("unpacking failed")
- return
- }
-}
-
-func TestBailiwick(t *testing.T) {
- yes := map[string]string{
- "miek1.nl": "miek1.nl",
- "miek.nl": "ns.miek.nl",
- ".": "miek.nl",
- }
- for parent, child := range yes {
- if !IsSubDomain(parent, child) {
- t.Errorf("%s should be child of %s", child, parent)
- t.Errorf("comparelabels %d", CompareDomainName(parent, child))
- t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child))
- }
- }
- no := map[string]string{
- "www.miek.nl": "ns.miek.nl",
- "m\\.iek.nl": "ns.miek.nl",
- "w\\.iek.nl": "w.iek.nl",
- "p\\\\.iek.nl": "ns.p.iek.nl", // p\\.iek.nl , literal \ in domain name
- "miek.nl": ".",
- }
- for parent, child := range no {
- if IsSubDomain(parent, child) {
- t.Errorf("%s should not be child of %s", child, parent)
- t.Errorf("comparelabels %d", CompareDomainName(parent, child))
- t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child))
- }
- }
-}
-
-func TestPack(t *testing.T) {
- rr := []string{"US. 86400 IN NSEC 0-.us. NS SOA RRSIG NSEC DNSKEY TYPE65534"}
- m := new(Msg)
- var err error
- m.Answer = make([]RR, 1)
- for _, r := range rr {
- m.Answer[0], err = NewRR(r)
- if err != nil {
- t.Errorf("failed to create RR: %v", err)
- continue
- }
- if _, err := m.Pack(); err != nil {
- t.Errorf("packing failed: %v", err)
- }
- }
- x := new(Msg)
- ns, _ := NewRR("pool.ntp.org. 390 IN NS a.ntpns.org")
- ns.(*NS).Ns = "a.ntpns.org"
- x.Ns = append(m.Ns, ns)
- x.Ns = append(m.Ns, ns)
- x.Ns = append(m.Ns, ns)
- // This crashes due to the fact the a.ntpns.org isn't a FQDN
- // How to recover() from a remove panic()?
- if _, err := x.Pack(); err == nil {
- t.Error("packing should fail")
- }
- x.Answer = make([]RR, 1)
- x.Answer[0], err = NewRR(rr[0])
- if _, err := x.Pack(); err == nil {
- t.Error("packing should fail")
- }
- x.Question = make([]Question, 1)
- x.Question[0] = Question{";sd#edddds鍛↙赏‘℅∥↙xzztsestxssweewwsssstx@s@Z嵌e@cn.pool.ntp.org.", TypeA, ClassINET}
- if _, err := x.Pack(); err == nil {
- t.Error("packing should fail")
- }
-}
-
-func TestPackNAPTR(t *testing.T) {
- for _, n := range []string{
- `apple.com. IN NAPTR 100 50 "se" "SIP+D2U" "" _sip._udp.apple.com.`,
- `apple.com. IN NAPTR 90 50 "se" "SIP+D2T" "" _sip._tcp.apple.com.`,
- `apple.com. IN NAPTR 50 50 "se" "SIPS+D2T" "" _sips._tcp.apple.com.`,
- } {
- rr, _ := NewRR(n)
- msg := make([]byte, rr.len())
- if off, err := PackRR(rr, msg, 0, nil, false); err != nil {
- t.Errorf("packing failed: %v", err)
- t.Errorf("length %d, need more than %d", rr.len(), off)
- } else {
- t.Logf("buf size needed: %d", off)
- }
- }
-}
-
-func TestCompressLength(t *testing.T) {
- m := new(Msg)
- m.SetQuestion("miek.nl", TypeMX)
- ul := m.Len()
- m.Compress = true
- if ul != m.Len() {
- t.Fatalf("should be equal")
- }
-}
-
-// Does the predicted length match final packed length?
-func TestMsgCompressLength(t *testing.T) {
- makeMsg := func(question string, ans, ns, e []RR) *Msg {
- msg := new(Msg)
- msg.SetQuestion(Fqdn(question), TypeANY)
- msg.Answer = append(msg.Answer, ans...)
- msg.Ns = append(msg.Ns, ns...)
- msg.Extra = append(msg.Extra, e...)
- msg.Compress = true
- return msg
- }
-
- name1 := "12345678901234567890123456789012345.12345678.123."
- rrA, _ := NewRR(name1 + " 3600 IN A 192.0.2.1")
- rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
- tests := []*Msg{
- makeMsg(name1, []RR{rrA}, nil, nil),
- makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)}
-
- for _, msg := range tests {
- predicted := msg.Len()
- buf, err := msg.Pack()
- if err != nil {
- t.Error(err)
- }
- if predicted < len(buf) {
- t.Errorf("predicted compressed length is wrong: predicted %s (len=%d) %d, actual %d",
- msg.Question[0].Name, len(msg.Answer), predicted, len(buf))
- }
- }
-}
-
-func TestMsgLength(t *testing.T) {
- makeMsg := func(question string, ans, ns, e []RR) *Msg {
- msg := new(Msg)
- msg.SetQuestion(Fqdn(question), TypeANY)
- msg.Answer = append(msg.Answer, ans...)
- msg.Ns = append(msg.Ns, ns...)
- msg.Extra = append(msg.Extra, e...)
- return msg
- }
-
- name1 := "12345678901234567890123456789012345.12345678.123."
- rrA, _ := NewRR(name1 + " 3600 IN A 192.0.2.1")
- rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
- tests := []*Msg{
- makeMsg(name1, []RR{rrA}, nil, nil),
- makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)}
-
- for _, msg := range tests {
- predicted := msg.Len()
- buf, err := msg.Pack()
- if err != nil {
- t.Error(err)
- }
- if predicted < len(buf) {
- t.Errorf("predicted length is wrong: predicted %s (len=%d), actual %d",
- msg.Question[0].Name, predicted, len(buf))
- }
- }
-}
-
-func TestMsgLength2(t *testing.T) {
- // Serialized replies
- var testMessages = []string{
- // google.com. IN A?
- "064e81800001000b0004000506676f6f676c6503636f6d0000010001c00c00010001000000050004adc22986c00c00010001000000050004adc22987c00c00010001000000050004adc22988c00c00010001000000050004adc22989c00c00010001000000050004adc2298ec00c00010001000000050004adc22980c00c00010001000000050004adc22981c00c00010001000000050004adc22982c00c00010001000000050004adc22983c00c00010001000000050004adc22984c00c00010001000000050004adc22985c00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc0d800010001000000050004d8ef200ac0ea00010001000000050004d8ef220ac0fc00010001000000050004d8ef240ac10e00010001000000050004d8ef260a0000290500000000050000",
- // amazon.com. IN A? (reply has no EDNS0 record)
- // TODO(miek): this one is off-by-one, need to find out why
- //"6de1818000010004000a000806616d617a6f6e03636f6d0000010001c00c000100010000000500044815c2d4c00c000100010000000500044815d7e8c00c00010001000000050004b02062a6c00c00010001000000050004cdfbf236c00c000200010000000500140570646e733408756c747261646e73036f726700c00c000200010000000500150570646e733508756c747261646e7304696e666f00c00c000200010000000500160570646e733608756c747261646e7302636f02756b00c00c00020001000000050014036e7331037033310664796e656374036e657400c00c00020001000000050006036e7332c0cfc00c00020001000000050006036e7333c0cfc00c00020001000000050006036e7334c0cfc00c000200010000000500110570646e733108756c747261646e73c0dac00c000200010000000500080570646e7332c127c00c000200010000000500080570646e7333c06ec0cb00010001000000050004d04e461fc0eb00010001000000050004cc0dfa1fc0fd00010001000000050004d04e471fc10f00010001000000050004cc0dfb1fc12100010001000000050004cc4a6c01c121001c000100000005001020010502f3ff00000000000000000001c13e00010001000000050004cc4a6d01c13e001c0001000000050010261000a1101400000000000000000001",
- // yahoo.com. IN A?
- "fc2d81800001000300070008057961686f6f03636f6d0000010001c00c00010001000000050004628afd6dc00c00010001000000050004628bb718c00c00010001000000050004cebe242dc00c00020001000000050006036e7336c00cc00c00020001000000050006036e7338c00cc00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7335c00cc07b0001000100000005000444b48310c08d00010001000000050004448eff10c09f00010001000000050004cb54dd35c0b100010001000000050004628a0b9dc0c30001000100000005000477a0f77cc05700010001000000050004ca2bdfaac06900010001000000050004caa568160000290500000000050000",
- // microsoft.com. IN A?
- "f4368180000100020005000b096d6963726f736f667403636f6d0000010001c00c0001000100000005000440040b25c00c0001000100000005000441373ac9c00c0002000100000005000e036e7331046d736674036e657400c00c00020001000000050006036e7332c04fc00c00020001000000050006036e7333c04fc00c00020001000000050006036e7334c04fc00c00020001000000050006036e7335c04fc04b000100010000000500044137253ec04b001c00010000000500102a010111200500000000000000010001c0650001000100000005000440043badc065001c00010000000500102a010111200600060000000000010001c07700010001000000050004d5c7b435c077001c00010000000500102a010111202000000000000000010001c08900010001000000050004cf2e4bfec089001c00010000000500102404f800200300000000000000010001c09b000100010000000500044137e28cc09b001c00010000000500102a010111200f000100000000000100010000290500000000050000",
- // google.com. IN MX?
- "724b8180000100050004000b06676f6f676c6503636f6d00000f0001c00c000f000100000005000c000a056173706d78016cc00cc00c000f0001000000050009001404616c7431c02ac00c000f0001000000050009001e04616c7432c02ac00c000f0001000000050009002804616c7433c02ac00c000f0001000000050009003204616c7434c02ac00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7331c00cc02a00010001000000050004adc2421bc02a001c00010000000500102a00145040080c01000000000000001bc04200010001000000050004adc2461bc05700010001000000050004adc2451bc06c000100010000000500044a7d8f1bc081000100010000000500044a7d191bc0ca00010001000000050004d8ef200ac09400010001000000050004d8ef220ac0a600010001000000050004d8ef240ac0b800010001000000050004d8ef260a0000290500000000050000",
- // reddit.com. IN A?
- "12b98180000100080000000c0672656464697403636f6d0000020001c00c0002000100000005000f046175733204616b616d036e657400c00c000200010000000500070475736534c02dc00c000200010000000500070475737733c02dc00c000200010000000500070475737735c02dc00c00020001000000050008056173696131c02dc00c00020001000000050008056173696139c02dc00c00020001000000050008056e73312d31c02dc00c0002000100000005000a076e73312d313935c02dc02800010001000000050004c30a242ec04300010001000000050004451f1d39c05600010001000000050004451f3bc7c0690001000100000005000460073240c07c000100010000000500046007fb81c090000100010000000500047c283484c090001c00010000000500102a0226f0006700000000000000000064c0a400010001000000050004c16c5b01c0a4001c000100000005001026001401000200000000000000000001c0b800010001000000050004c16c5bc3c0b8001c0001000000050010260014010002000000000000000000c30000290500000000050000",
- }
-
- for i, hexData := range testMessages {
- // we won't fail the decoding of the hex
- input, _ := hex.DecodeString(hexData)
-
- m := new(Msg)
- m.Unpack(input)
- m.Compress = true
- lenComp := m.Len()
- b, _ := m.Pack()
- pacComp := len(b)
- m.Compress = false
- lenUnComp := m.Len()
- b, _ = m.Pack()
- pacUnComp := len(b)
- if pacComp+1 != lenComp {
- t.Errorf("msg.Len(compressed)=%d actual=%d for test %d", lenComp, pacComp, i)
- }
- if pacUnComp+1 != lenUnComp {
- t.Errorf("msg.Len(uncompressed)=%d actual=%d for test %d", lenUnComp, pacUnComp, i)
- }
- }
-}
-
-func TestMsgLengthCompressionMalformed(t *testing.T) {
- // SOA with empty hostmaster, which is illegal
- soa := &SOA{Hdr: RR_Header{Name: ".", Rrtype: TypeSOA, Class: ClassINET, Ttl: 12345},
- Ns: ".",
- Mbox: "",
- Serial: 0,
- Refresh: 28800,
- Retry: 7200,
- Expire: 604800,
- Minttl: 60}
- m := new(Msg)
- m.Compress = true
- m.Ns = []RR{soa}
- m.Len() // Should not crash.
-}
-
-func TestMsgCompressLength2(t *testing.T) {
- msg := new(Msg)
- msg.Compress = true
- msg.SetQuestion(Fqdn("bliep."), TypeANY)
- msg.Answer = append(msg.Answer, &SRV{Hdr: RR_Header{Name: "blaat.", Rrtype: 0x21, Class: 0x1, Ttl: 0x3c}, Port: 0x4c57, Target: "foo.bar."})
- msg.Extra = append(msg.Extra, &A{Hdr: RR_Header{Name: "foo.bar.", Rrtype: 0x1, Class: 0x1, Ttl: 0x3c}, A: net.IP{0xac, 0x11, 0x0, 0x3}})
- predicted := msg.Len()
- buf, err := msg.Pack()
- if err != nil {
- t.Error(err)
- }
- if predicted != len(buf) {
- t.Errorf("predicted compressed length is wrong: predicted %s (len=%d) %d, actual %d",
- msg.Question[0].Name, len(msg.Answer), predicted, len(buf))
- }
-}
-
-func TestToRFC3597(t *testing.T) {
- a, _ := NewRR("miek.nl. IN A 10.0.1.1")
- x := new(RFC3597)
- x.ToRFC3597(a)
- if x.String() != `miek.nl. 3600 CLASS1 TYPE1 \# 4 0a000101` {
- t.Errorf("string mismatch, got: %s", x)
- }
-
- b, _ := NewRR("miek.nl. IN MX 10 mx.miek.nl.")
- x.ToRFC3597(b)
- if x.String() != `miek.nl. 3600 CLASS1 TYPE15 \# 14 000a026d78046d69656b026e6c00` {
- t.Errorf("string mismatch, got: %s", x)
- }
-}
-
-func TestNoRdataPack(t *testing.T) {
- data := make([]byte, 1024)
- for typ, fn := range TypeToRR {
- r := fn()
- *r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 16}
- _, err := PackRR(r, data, 0, nil, false)
- if err != nil {
- t.Errorf("failed to pack RR with zero rdata: %s: %v", TypeToString[typ], err)
- }
- }
-}
-
-func TestNoRdataUnpack(t *testing.T) {
- data := make([]byte, 1024)
- for typ, fn := range TypeToRR {
- if typ == TypeSOA || typ == TypeTSIG {
- // SOA, TSIG will not be seen (like this) in dyn. updates?
- continue
- }
- r := fn()
- *r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 16}
- off, err := PackRR(r, data, 0, nil, false)
- if err != nil {
- // Should always works, TestNoDataPack should have caught this
- t.Errorf("failed to pack RR: %v", err)
- continue
- }
- rr, _, err := UnpackRR(data[:off], 0)
- if err != nil {
- t.Errorf("failed to unpack RR with zero rdata: %s: %v", TypeToString[typ], err)
- }
- t.Log(rr)
- }
-}
-
-func TestRdataOverflow(t *testing.T) {
- rr := new(RFC3597)
- rr.Hdr.Name = "."
- rr.Hdr.Class = ClassINET
- rr.Hdr.Rrtype = 65280
- rr.Rdata = hex.EncodeToString(make([]byte, 0xFFFF))
- buf := make([]byte, 0xFFFF*2)
- if _, err := PackRR(rr, buf, 0, nil, false); err != nil {
- t.Fatalf("maximum size rrdata pack failed: %v", err)
- }
- rr.Rdata += "00"
- if _, err := PackRR(rr, buf, 0, nil, false); err != ErrRdata {
- t.Fatalf("oversize rrdata pack didn't return ErrRdata - instead: %v", err)
- }
-}
-
-func TestCopy(t *testing.T) {
- rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1") // Weird TTL to avoid catching TTL
- rr1 := Copy(rr)
- if rr.String() != rr1.String() {
- t.Fatalf("Copy() failed %s != %s", rr.String(), rr1.String())
- }
-}
-
-func TestMsgCopy(t *testing.T) {
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeA)
- rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1")
- m.Answer = []RR{rr}
- rr, _ = NewRR("miek.nl. 2311 IN NS 127.0.0.1")
- m.Ns = []RR{rr}
-
- m1 := m.Copy()
- if m.String() != m1.String() {
- t.Fatalf("Msg.Copy() failed %s != %s", m.String(), m1.String())
- }
-
- m1.Answer[0], _ = NewRR("somethingelse.nl. 2311 IN A 127.0.0.1")
- if m.String() == m1.String() {
- t.Fatalf("Msg.Copy() failed; change to copy changed template %s", m.String())
- }
-
- rr, _ = NewRR("miek.nl. 2311 IN A 127.0.0.2")
- m1.Answer = append(m1.Answer, rr)
- if m1.Ns[0].String() == m1.Answer[1].String() {
- t.Fatalf("Msg.Copy() failed; append changed underlying array %s", m1.Ns[0].String())
- }
-}
-
-func TestMsgPackBuffer(t *testing.T) {
- var testMessages = []string{
- // news.ycombinator.com.in.escapemg.com. IN A, response
- "586285830001000000010000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001c0210006000100000e10002c036e7332c02103646e730b67726f6f7665736861726bc02d77ed50e600002a3000000e1000093a8000000e10",
-
- // news.ycombinator.com.in.escapemg.com. IN A, question
- "586201000001000000000000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001",
-
- "398781020001000000000000046e6577730b79636f6d62696e61746f7203636f6d0000010001",
- }
-
- for i, hexData := range testMessages {
- // we won't fail the decoding of the hex
- input, _ := hex.DecodeString(hexData)
- m := new(Msg)
- if err := m.Unpack(input); err != nil {
- t.Errorf("packet %d failed to unpack", i)
- continue
- }
- t.Logf("packet %d %s", i, m.String())
- }
-}
diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go
deleted file mode 100644
index 3bd55388d..000000000
--- a/vendor/github.com/miekg/dns/dnssec.go
+++ /dev/null
@@ -1,720 +0,0 @@
-package dns
-
-import (
- "bytes"
- "crypto"
- "crypto/dsa"
- "crypto/ecdsa"
- "crypto/elliptic"
- _ "crypto/md5"
- "crypto/rand"
- "crypto/rsa"
- _ "crypto/sha1"
- _ "crypto/sha256"
- _ "crypto/sha512"
- "encoding/asn1"
- "encoding/binary"
- "encoding/hex"
- "math/big"
- "sort"
- "strings"
- "time"
-)
-
-// DNSSEC encryption algorithm codes.
-const (
- _ uint8 = iota
- RSAMD5
- DH
- DSA
- _ // Skip 4, RFC 6725, section 2.1
- RSASHA1
- DSANSEC3SHA1
- RSASHA1NSEC3SHA1
- RSASHA256
- _ // Skip 9, RFC 6725, section 2.1
- RSASHA512
- _ // Skip 11, RFC 6725, section 2.1
- ECCGOST
- ECDSAP256SHA256
- ECDSAP384SHA384
- INDIRECT uint8 = 252
- PRIVATEDNS uint8 = 253 // Private (experimental keys)
- PRIVATEOID uint8 = 254
-)
-
-// AlgorithmToString is a map of algorithm IDs to algorithm names.
-var AlgorithmToString = map[uint8]string{
- RSAMD5: "RSAMD5",
- DH: "DH",
- DSA: "DSA",
- RSASHA1: "RSASHA1",
- DSANSEC3SHA1: "DSA-NSEC3-SHA1",
- RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1",
- RSASHA256: "RSASHA256",
- RSASHA512: "RSASHA512",
- ECCGOST: "ECC-GOST",
- ECDSAP256SHA256: "ECDSAP256SHA256",
- ECDSAP384SHA384: "ECDSAP384SHA384",
- INDIRECT: "INDIRECT",
- PRIVATEDNS: "PRIVATEDNS",
- PRIVATEOID: "PRIVATEOID",
-}
-
-// StringToAlgorithm is the reverse of AlgorithmToString.
-var StringToAlgorithm = reverseInt8(AlgorithmToString)
-
-// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
-var AlgorithmToHash = map[uint8]crypto.Hash{
- RSAMD5: crypto.MD5, // Deprecated in RFC 6725
- RSASHA1: crypto.SHA1,
- RSASHA1NSEC3SHA1: crypto.SHA1,
- RSASHA256: crypto.SHA256,
- ECDSAP256SHA256: crypto.SHA256,
- ECDSAP384SHA384: crypto.SHA384,
- RSASHA512: crypto.SHA512,
-}
-
-// DNSSEC hashing algorithm codes.
-const (
- _ uint8 = iota
- SHA1 // RFC 4034
- SHA256 // RFC 4509
- GOST94 // RFC 5933
- SHA384 // Experimental
- SHA512 // Experimental
-)
-
-// HashToString is a map of hash IDs to names.
-var HashToString = map[uint8]string{
- SHA1: "SHA1",
- SHA256: "SHA256",
- GOST94: "GOST94",
- SHA384: "SHA384",
- SHA512: "SHA512",
-}
-
-// StringToHash is a map of names to hash IDs.
-var StringToHash = reverseInt8(HashToString)
-
-// DNSKEY flag values.
-const (
- SEP = 1
- REVOKE = 1 << 7
- ZONE = 1 << 8
-)
-
-// The RRSIG needs to be converted to wireformat with some of the rdata (the signature) missing.
-type rrsigWireFmt struct {
- TypeCovered uint16
- Algorithm uint8
- Labels uint8
- OrigTtl uint32
- Expiration uint32
- Inception uint32
- KeyTag uint16
- SignerName string `dns:"domain-name"`
- /* No Signature */
-}
-
-// Used for converting DNSKEY's rdata to wirefmt.
-type dnskeyWireFmt struct {
- Flags uint16
- Protocol uint8
- Algorithm uint8
- PublicKey string `dns:"base64"`
- /* Nothing is left out */
-}
-
-func divRoundUp(a, b int) int {
- return (a + b - 1) / b
-}
-
-// KeyTag calculates the keytag (or key-id) of the DNSKEY.
-func (k *DNSKEY) KeyTag() uint16 {
- if k == nil {
- return 0
- }
- var keytag int
- switch k.Algorithm {
- case RSAMD5:
- // Look at the bottom two bytes of the modules, which the last
- // item in the pubkey. We could do this faster by looking directly
- // at the base64 values. But I'm lazy.
- modulus, _ := fromBase64([]byte(k.PublicKey))
- if len(modulus) > 1 {
- x := binary.BigEndian.Uint16(modulus[len(modulus)-2:])
- keytag = int(x)
- }
- default:
- keywire := new(dnskeyWireFmt)
- keywire.Flags = k.Flags
- keywire.Protocol = k.Protocol
- keywire.Algorithm = k.Algorithm
- keywire.PublicKey = k.PublicKey
- wire := make([]byte, DefaultMsgSize)
- n, err := packKeyWire(keywire, wire)
- if err != nil {
- return 0
- }
- wire = wire[:n]
- for i, v := range wire {
- if i&1 != 0 {
- keytag += int(v) // must be larger than uint32
- } else {
- keytag += int(v) << 8
- }
- }
- keytag += (keytag >> 16) & 0xFFFF
- keytag &= 0xFFFF
- }
- return uint16(keytag)
-}
-
-// ToDS converts a DNSKEY record to a DS record.
-func (k *DNSKEY) ToDS(h uint8) *DS {
- if k == nil {
- return nil
- }
- ds := new(DS)
- ds.Hdr.Name = k.Hdr.Name
- ds.Hdr.Class = k.Hdr.Class
- ds.Hdr.Rrtype = TypeDS
- ds.Hdr.Ttl = k.Hdr.Ttl
- ds.Algorithm = k.Algorithm
- ds.DigestType = h
- ds.KeyTag = k.KeyTag()
-
- keywire := new(dnskeyWireFmt)
- keywire.Flags = k.Flags
- keywire.Protocol = k.Protocol
- keywire.Algorithm = k.Algorithm
- keywire.PublicKey = k.PublicKey
- wire := make([]byte, DefaultMsgSize)
- n, err := packKeyWire(keywire, wire)
- if err != nil {
- return nil
- }
- wire = wire[:n]
-
- owner := make([]byte, 255)
- off, err1 := PackDomainName(strings.ToLower(k.Hdr.Name), owner, 0, nil, false)
- if err1 != nil {
- return nil
- }
- owner = owner[:off]
- // RFC4034:
- // digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
- // "|" denotes concatenation
- // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
-
- var hash crypto.Hash
- switch h {
- case SHA1:
- hash = crypto.SHA1
- case SHA256:
- hash = crypto.SHA256
- case SHA384:
- hash = crypto.SHA384
- case SHA512:
- hash = crypto.SHA512
- default:
- return nil
- }
-
- s := hash.New()
- s.Write(owner)
- s.Write(wire)
- ds.Digest = hex.EncodeToString(s.Sum(nil))
- return ds
-}
-
-// ToCDNSKEY converts a DNSKEY record to a CDNSKEY record.
-func (k *DNSKEY) ToCDNSKEY() *CDNSKEY {
- c := &CDNSKEY{DNSKEY: *k}
- c.Hdr = *k.Hdr.copyHeader()
- c.Hdr.Rrtype = TypeCDNSKEY
- return c
-}
-
-// ToCDS converts a DS record to a CDS record.
-func (d *DS) ToCDS() *CDS {
- c := &CDS{DS: *d}
- c.Hdr = *d.Hdr.copyHeader()
- c.Hdr.Rrtype = TypeCDS
- return c
-}
-
-// Sign signs an RRSet. The signature needs to be filled in with the values:
-// Inception, Expiration, KeyTag, SignerName and Algorithm. The rest is copied
-// from the RRset. Sign returns a non-nill error when the signing went OK.
-// There is no check if RRSet is a proper (RFC 2181) RRSet. If OrigTTL is non
-// zero, it is used as-is, otherwise the TTL of the RRset is used as the
-// OrigTTL.
-func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
- if k == nil {
- return ErrPrivKey
- }
- // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
- if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
- return ErrKey
- }
-
- rr.Hdr.Rrtype = TypeRRSIG
- rr.Hdr.Name = rrset[0].Header().Name
- rr.Hdr.Class = rrset[0].Header().Class
- if rr.OrigTtl == 0 { // If set don't override
- rr.OrigTtl = rrset[0].Header().Ttl
- }
- rr.TypeCovered = rrset[0].Header().Rrtype
- rr.Labels = uint8(CountLabel(rrset[0].Header().Name))
-
- if strings.HasPrefix(rrset[0].Header().Name, "*") {
- rr.Labels-- // wildcard, remove from label count
- }
-
- sigwire := new(rrsigWireFmt)
- sigwire.TypeCovered = rr.TypeCovered
- sigwire.Algorithm = rr.Algorithm
- sigwire.Labels = rr.Labels
- sigwire.OrigTtl = rr.OrigTtl
- sigwire.Expiration = rr.Expiration
- sigwire.Inception = rr.Inception
- sigwire.KeyTag = rr.KeyTag
- // For signing, lowercase this name
- sigwire.SignerName = strings.ToLower(rr.SignerName)
-
- // Create the desired binary blob
- signdata := make([]byte, DefaultMsgSize)
- n, err := packSigWire(sigwire, signdata)
- if err != nil {
- return err
- }
- signdata = signdata[:n]
- wire, err := rawSignatureData(rrset, rr)
- if err != nil {
- return err
- }
-
- hash, ok := AlgorithmToHash[rr.Algorithm]
- if !ok {
- return ErrAlg
- }
-
- h := hash.New()
- h.Write(signdata)
- h.Write(wire)
-
- signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm)
- if err != nil {
- return err
- }
-
- rr.Signature = toBase64(signature)
-
- return nil
-}
-
-func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) {
- signature, err := k.Sign(rand.Reader, hashed, hash)
- if err != nil {
- return nil, err
- }
-
- switch alg {
- case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
- return signature, nil
-
- case ECDSAP256SHA256, ECDSAP384SHA384:
- ecdsaSignature := &struct {
- R, S *big.Int
- }{}
- if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil {
- return nil, err
- }
-
- var intlen int
- switch alg {
- case ECDSAP256SHA256:
- intlen = 32
- case ECDSAP384SHA384:
- intlen = 48
- }
-
- signature := intToBytes(ecdsaSignature.R, intlen)
- signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
- return signature, nil
-
- // There is no defined interface for what a DSA backed crypto.Signer returns
- case DSA, DSANSEC3SHA1:
- // t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8)
- // signature := []byte{byte(t)}
- // signature = append(signature, intToBytes(r1, 20)...)
- // signature = append(signature, intToBytes(s1, 20)...)
- // rr.Signature = signature
- }
-
- return nil, ErrAlg
-}
-
-// Verify validates an RRSet with the signature and key. This is only the
-// cryptographic test, the signature validity period must be checked separately.
-// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
-func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
- // First the easy checks
- if !IsRRset(rrset) {
- return ErrRRset
- }
- if rr.KeyTag != k.KeyTag() {
- return ErrKey
- }
- if rr.Hdr.Class != k.Hdr.Class {
- return ErrKey
- }
- if rr.Algorithm != k.Algorithm {
- return ErrKey
- }
- if strings.ToLower(rr.SignerName) != strings.ToLower(k.Hdr.Name) {
- return ErrKey
- }
- if k.Protocol != 3 {
- return ErrKey
- }
-
- // IsRRset checked that we have at least one RR and that the RRs in
- // the set have consistent type, class, and name. Also check that type and
- // class matches the RRSIG record.
- if rrset[0].Header().Class != rr.Hdr.Class {
- return ErrRRset
- }
- if rrset[0].Header().Rrtype != rr.TypeCovered {
- return ErrRRset
- }
-
- // RFC 4035 5.3.2. Reconstructing the Signed Data
- // Copy the sig, except the rrsig data
- sigwire := new(rrsigWireFmt)
- sigwire.TypeCovered = rr.TypeCovered
- sigwire.Algorithm = rr.Algorithm
- sigwire.Labels = rr.Labels
- sigwire.OrigTtl = rr.OrigTtl
- sigwire.Expiration = rr.Expiration
- sigwire.Inception = rr.Inception
- sigwire.KeyTag = rr.KeyTag
- sigwire.SignerName = strings.ToLower(rr.SignerName)
- // Create the desired binary blob
- signeddata := make([]byte, DefaultMsgSize)
- n, err := packSigWire(sigwire, signeddata)
- if err != nil {
- return err
- }
- signeddata = signeddata[:n]
- wire, err := rawSignatureData(rrset, rr)
- if err != nil {
- return err
- }
-
- sigbuf := rr.sigBuf() // Get the binary signature data
- if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
- // TODO(miek)
- // remove the domain name and assume its ours?
- }
-
- hash, ok := AlgorithmToHash[rr.Algorithm]
- if !ok {
- return ErrAlg
- }
-
- switch rr.Algorithm {
- case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5:
- // TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
- pubkey := k.publicKeyRSA() // Get the key
- if pubkey == nil {
- return ErrKey
- }
-
- h := hash.New()
- h.Write(signeddata)
- h.Write(wire)
- return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf)
-
- case ECDSAP256SHA256, ECDSAP384SHA384:
- pubkey := k.publicKeyECDSA()
- if pubkey == nil {
- return ErrKey
- }
-
- // Split sigbuf into the r and s coordinates
- r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
- s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:])
-
- h := hash.New()
- h.Write(signeddata)
- h.Write(wire)
- if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
- return nil
- }
- return ErrSig
-
- default:
- return ErrAlg
- }
-}
-
-// ValidityPeriod uses RFC1982 serial arithmetic to calculate
-// if a signature period is valid. If t is the zero time, the
-// current time is taken other t is. Returns true if the signature
-// is valid at the given time, otherwise returns false.
-func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
- var utc int64
- if t.IsZero() {
- utc = time.Now().UTC().Unix()
- } else {
- utc = t.UTC().Unix()
- }
- modi := (int64(rr.Inception) - utc) / year68
- mode := (int64(rr.Expiration) - utc) / year68
- ti := int64(rr.Inception) + (modi * year68)
- te := int64(rr.Expiration) + (mode * year68)
- return ti <= utc && utc <= te
-}
-
-// Return the signatures base64 encodedig sigdata as a byte slice.
-func (rr *RRSIG) sigBuf() []byte {
- sigbuf, err := fromBase64([]byte(rr.Signature))
- if err != nil {
- return nil
- }
- return sigbuf
-}
-
-// publicKeyRSA returns the RSA public key from a DNSKEY record.
-func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
- keybuf, err := fromBase64([]byte(k.PublicKey))
- if err != nil {
- return nil
- }
-
- // RFC 2537/3110, section 2. RSA Public KEY Resource Records
- // Length is in the 0th byte, unless its zero, then it
- // it in bytes 1 and 2 and its a 16 bit number
- explen := uint16(keybuf[0])
- keyoff := 1
- if explen == 0 {
- explen = uint16(keybuf[1])<<8 | uint16(keybuf[2])
- keyoff = 3
- }
- pubkey := new(rsa.PublicKey)
-
- pubkey.N = big.NewInt(0)
- shift := uint64((explen - 1) * 8)
- expo := uint64(0)
- for i := int(explen - 1); i > 0; i-- {
- expo += uint64(keybuf[keyoff+i]) << shift
- shift -= 8
- }
- // Remainder
- expo += uint64(keybuf[keyoff])
- if expo > (2<<31)+1 {
- // Larger expo than supported.
- // println("dns: F5 primes (or larger) are not supported")
- return nil
- }
- pubkey.E = int(expo)
-
- pubkey.N.SetBytes(keybuf[keyoff+int(explen):])
- return pubkey
-}
-
-// publicKeyECDSA returns the Curve public key from the DNSKEY record.
-func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
- keybuf, err := fromBase64([]byte(k.PublicKey))
- if err != nil {
- return nil
- }
- pubkey := new(ecdsa.PublicKey)
- switch k.Algorithm {
- case ECDSAP256SHA256:
- pubkey.Curve = elliptic.P256()
- if len(keybuf) != 64 {
- // wrongly encoded key
- return nil
- }
- case ECDSAP384SHA384:
- pubkey.Curve = elliptic.P384()
- if len(keybuf) != 96 {
- // Wrongly encoded key
- return nil
- }
- }
- pubkey.X = big.NewInt(0)
- pubkey.X.SetBytes(keybuf[:len(keybuf)/2])
- pubkey.Y = big.NewInt(0)
- pubkey.Y.SetBytes(keybuf[len(keybuf)/2:])
- return pubkey
-}
-
-func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey {
- keybuf, err := fromBase64([]byte(k.PublicKey))
- if err != nil {
- return nil
- }
- if len(keybuf) < 22 {
- return nil
- }
- t, keybuf := int(keybuf[0]), keybuf[1:]
- size := 64 + t*8
- q, keybuf := keybuf[:20], keybuf[20:]
- if len(keybuf) != 3*size {
- return nil
- }
- p, keybuf := keybuf[:size], keybuf[size:]
- g, y := keybuf[:size], keybuf[size:]
- pubkey := new(dsa.PublicKey)
- pubkey.Parameters.Q = big.NewInt(0).SetBytes(q)
- pubkey.Parameters.P = big.NewInt(0).SetBytes(p)
- pubkey.Parameters.G = big.NewInt(0).SetBytes(g)
- pubkey.Y = big.NewInt(0).SetBytes(y)
- return pubkey
-}
-
-type wireSlice [][]byte
-
-func (p wireSlice) Len() int { return len(p) }
-func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-func (p wireSlice) Less(i, j int) bool {
- _, ioff, _ := UnpackDomainName(p[i], 0)
- _, joff, _ := UnpackDomainName(p[j], 0)
- return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0
-}
-
-// Return the raw signature data.
-func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
- wires := make(wireSlice, len(rrset))
- for i, r := range rrset {
- r1 := r.copy()
- r1.Header().Ttl = s.OrigTtl
- labels := SplitDomainName(r1.Header().Name)
- // 6.2. Canonical RR Form. (4) - wildcards
- if len(labels) > int(s.Labels) {
- // Wildcard
- r1.Header().Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
- }
- // RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase
- r1.Header().Name = strings.ToLower(r1.Header().Name)
- // 6.2. Canonical RR Form. (3) - domain rdata to lowercase.
- // NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
- // HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
- // SRV, DNAME, A6
- //
- // RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC):
- // Section 6.2 of [RFC4034] also erroneously lists HINFO as a record
- // that needs conversion to lowercase, and twice at that. Since HINFO
- // records contain no domain names, they are not subject to case
- // conversion.
- switch x := r1.(type) {
- case *NS:
- x.Ns = strings.ToLower(x.Ns)
- case *CNAME:
- x.Target = strings.ToLower(x.Target)
- case *SOA:
- x.Ns = strings.ToLower(x.Ns)
- x.Mbox = strings.ToLower(x.Mbox)
- case *MB:
- x.Mb = strings.ToLower(x.Mb)
- case *MG:
- x.Mg = strings.ToLower(x.Mg)
- case *MR:
- x.Mr = strings.ToLower(x.Mr)
- case *PTR:
- x.Ptr = strings.ToLower(x.Ptr)
- case *MINFO:
- x.Rmail = strings.ToLower(x.Rmail)
- x.Email = strings.ToLower(x.Email)
- case *MX:
- x.Mx = strings.ToLower(x.Mx)
- case *NAPTR:
- x.Replacement = strings.ToLower(x.Replacement)
- case *KX:
- x.Exchanger = strings.ToLower(x.Exchanger)
- case *SRV:
- x.Target = strings.ToLower(x.Target)
- case *DNAME:
- x.Target = strings.ToLower(x.Target)
- }
- // 6.2. Canonical RR Form. (5) - origTTL
- wire := make([]byte, r1.len()+1) // +1 to be safe(r)
- off, err1 := PackRR(r1, wire, 0, nil, false)
- if err1 != nil {
- return nil, err1
- }
- wire = wire[:off]
- wires[i] = wire
- }
- sort.Sort(wires)
- for i, wire := range wires {
- if i > 0 && bytes.Equal(wire, wires[i-1]) {
- continue
- }
- buf = append(buf, wire...)
- }
- return buf, nil
-}
-
-func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) {
- // copied from zmsg.go RRSIG packing
- off, err := packUint16(sw.TypeCovered, msg, 0)
- if err != nil {
- return off, err
- }
- off, err = packUint8(sw.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(sw.Labels, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(sw.OrigTtl, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(sw.Expiration, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(sw.Inception, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(sw.KeyTag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(sw.SignerName, msg, off, nil, false)
- if err != nil {
- return off, err
- }
- return off, nil
-}
-
-func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) {
- // copied from zmsg.go DNSKEY packing
- off, err := packUint16(dw.Flags, msg, 0)
- if err != nil {
- return off, err
- }
- off, err = packUint8(dw.Protocol, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(dw.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(dw.PublicKey, msg, off)
- if err != nil {
- return off, err
- }
- return off, nil
-}
diff --git a/vendor/github.com/miekg/dns/dnssec_keygen.go b/vendor/github.com/miekg/dns/dnssec_keygen.go
deleted file mode 100644
index 5e4b7741a..000000000
--- a/vendor/github.com/miekg/dns/dnssec_keygen.go
+++ /dev/null
@@ -1,156 +0,0 @@
-package dns
-
-import (
- "crypto"
- "crypto/dsa"
- "crypto/ecdsa"
- "crypto/elliptic"
- "crypto/rand"
- "crypto/rsa"
- "math/big"
-)
-
-// Generate generates a DNSKEY of the given bit size.
-// The public part is put inside the DNSKEY record.
-// The Algorithm in the key must be set as this will define
-// what kind of DNSKEY will be generated.
-// The ECDSA algorithms imply a fixed keysize, in that case
-// bits should be set to the size of the algorithm.
-func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
- switch k.Algorithm {
- case DSA, DSANSEC3SHA1:
- if bits != 1024 {
- return nil, ErrKeySize
- }
- case RSAMD5, RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
- if bits < 512 || bits > 4096 {
- return nil, ErrKeySize
- }
- case RSASHA512:
- if bits < 1024 || bits > 4096 {
- return nil, ErrKeySize
- }
- case ECDSAP256SHA256:
- if bits != 256 {
- return nil, ErrKeySize
- }
- case ECDSAP384SHA384:
- if bits != 384 {
- return nil, ErrKeySize
- }
- }
-
- switch k.Algorithm {
- case DSA, DSANSEC3SHA1:
- params := new(dsa.Parameters)
- if err := dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160); err != nil {
- return nil, err
- }
- priv := new(dsa.PrivateKey)
- priv.PublicKey.Parameters = *params
- err := dsa.GenerateKey(priv, rand.Reader)
- if err != nil {
- return nil, err
- }
- k.setPublicKeyDSA(params.Q, params.P, params.G, priv.PublicKey.Y)
- return priv, nil
- case RSAMD5, RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
- priv, err := rsa.GenerateKey(rand.Reader, bits)
- if err != nil {
- return nil, err
- }
- k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
- return priv, nil
- case ECDSAP256SHA256, ECDSAP384SHA384:
- var c elliptic.Curve
- switch k.Algorithm {
- case ECDSAP256SHA256:
- c = elliptic.P256()
- case ECDSAP384SHA384:
- c = elliptic.P384()
- }
- priv, err := ecdsa.GenerateKey(c, rand.Reader)
- if err != nil {
- return nil, err
- }
- k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
- return priv, nil
- default:
- return nil, ErrAlg
- }
-}
-
-// Set the public key (the value E and N)
-func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
- if _E == 0 || _N == nil {
- return false
- }
- buf := exponentToBuf(_E)
- buf = append(buf, _N.Bytes()...)
- k.PublicKey = toBase64(buf)
- return true
-}
-
-// Set the public key for Elliptic Curves
-func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool {
- if _X == nil || _Y == nil {
- return false
- }
- var intlen int
- switch k.Algorithm {
- case ECDSAP256SHA256:
- intlen = 32
- case ECDSAP384SHA384:
- intlen = 48
- }
- k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen))
- return true
-}
-
-// Set the public key for DSA
-func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool {
- if _Q == nil || _P == nil || _G == nil || _Y == nil {
- return false
- }
- buf := dsaToBuf(_Q, _P, _G, _Y)
- k.PublicKey = toBase64(buf)
- return true
-}
-
-// Set the public key (the values E and N) for RSA
-// RFC 3110: Section 2. RSA Public KEY Resource Records
-func exponentToBuf(_E int) []byte {
- var buf []byte
- i := big.NewInt(int64(_E)).Bytes()
- if len(i) < 256 {
- buf = make([]byte, 1, 1+len(i))
- buf[0] = uint8(len(i))
- } else {
- buf = make([]byte, 3, 3+len(i))
- buf[0] = 0
- buf[1] = uint8(len(i) >> 8)
- buf[2] = uint8(len(i))
- }
- buf = append(buf, i...)
- return buf
-}
-
-// Set the public key for X and Y for Curve. The two
-// values are just concatenated.
-func curveToBuf(_X, _Y *big.Int, intlen int) []byte {
- buf := intToBytes(_X, intlen)
- buf = append(buf, intToBytes(_Y, intlen)...)
- return buf
-}
-
-// Set the public key for X and Y for Curve. The two
-// values are just concatenated.
-func dsaToBuf(_Q, _P, _G, _Y *big.Int) []byte {
- t := divRoundUp(divRoundUp(_G.BitLen(), 8)-64, 8)
- buf := []byte{byte(t)}
- buf = append(buf, intToBytes(_Q, 20)...)
- buf = append(buf, intToBytes(_P, 64+t*8)...)
- buf = append(buf, intToBytes(_G, 64+t*8)...)
- buf = append(buf, intToBytes(_Y, 64+t*8)...)
- return buf
-}
diff --git a/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go
deleted file mode 100644
index 4f8d830b8..000000000
--- a/vendor/github.com/miekg/dns/dnssec_keyscan.go
+++ /dev/null
@@ -1,249 +0,0 @@
-package dns
-
-import (
- "crypto"
- "crypto/dsa"
- "crypto/ecdsa"
- "crypto/rsa"
- "io"
- "math/big"
- "strconv"
- "strings"
-)
-
-// NewPrivateKey returns a PrivateKey by parsing the string s.
-// s should be in the same form of the BIND private key files.
-func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) {
- if s == "" || s[len(s)-1] != '\n' { // We need a closing newline
- return k.ReadPrivateKey(strings.NewReader(s+"\n"), "")
- }
- return k.ReadPrivateKey(strings.NewReader(s), "")
-}
-
-// ReadPrivateKey reads a private key from the io.Reader q. The string file is
-// only used in error reporting.
-// The public key must be known, because some cryptographic algorithms embed
-// the public inside the privatekey.
-func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) {
- m, err := parseKey(q, file)
- if m == nil {
- return nil, err
- }
- if _, ok := m["private-key-format"]; !ok {
- return nil, ErrPrivKey
- }
- if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" {
- return nil, ErrPrivKey
- }
- // TODO(mg): check if the pubkey matches the private key
- algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 10, 8)
- if err != nil {
- return nil, ErrPrivKey
- }
- switch uint8(algo) {
- case DSA:
- priv, err := readPrivateKeyDSA(m)
- if err != nil {
- return nil, err
- }
- pub := k.publicKeyDSA()
- if pub == nil {
- return nil, ErrKey
- }
- priv.PublicKey = *pub
- return priv, nil
- case RSAMD5:
- fallthrough
- case RSASHA1:
- fallthrough
- case RSASHA1NSEC3SHA1:
- fallthrough
- case RSASHA256:
- fallthrough
- case RSASHA512:
- priv, err := readPrivateKeyRSA(m)
- if err != nil {
- return nil, err
- }
- pub := k.publicKeyRSA()
- if pub == nil {
- return nil, ErrKey
- }
- priv.PublicKey = *pub
- return priv, nil
- case ECCGOST:
- return nil, ErrPrivKey
- case ECDSAP256SHA256:
- fallthrough
- case ECDSAP384SHA384:
- priv, err := readPrivateKeyECDSA(m)
- if err != nil {
- return nil, err
- }
- pub := k.publicKeyECDSA()
- if pub == nil {
- return nil, ErrKey
- }
- priv.PublicKey = *pub
- return priv, nil
- default:
- return nil, ErrPrivKey
- }
-}
-
-// Read a private key (file) string and create a public key. Return the private key.
-func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) {
- p := new(rsa.PrivateKey)
- p.Primes = []*big.Int{nil, nil}
- for k, v := range m {
- switch k {
- case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
- v1, err := fromBase64([]byte(v))
- if err != nil {
- return nil, err
- }
- switch k {
- case "modulus":
- p.PublicKey.N = big.NewInt(0)
- p.PublicKey.N.SetBytes(v1)
- case "publicexponent":
- i := big.NewInt(0)
- i.SetBytes(v1)
- p.PublicKey.E = int(i.Int64()) // int64 should be large enough
- case "privateexponent":
- p.D = big.NewInt(0)
- p.D.SetBytes(v1)
- case "prime1":
- p.Primes[0] = big.NewInt(0)
- p.Primes[0].SetBytes(v1)
- case "prime2":
- p.Primes[1] = big.NewInt(0)
- p.Primes[1].SetBytes(v1)
- }
- case "exponent1", "exponent2", "coefficient":
- // not used in Go (yet)
- case "created", "publish", "activate":
- // not used in Go (yet)
- }
- }
- return p, nil
-}
-
-func readPrivateKeyDSA(m map[string]string) (*dsa.PrivateKey, error) {
- p := new(dsa.PrivateKey)
- p.X = big.NewInt(0)
- for k, v := range m {
- switch k {
- case "private_value(x)":
- v1, err := fromBase64([]byte(v))
- if err != nil {
- return nil, err
- }
- p.X.SetBytes(v1)
- case "created", "publish", "activate":
- /* not used in Go (yet) */
- }
- }
- return p, nil
-}
-
-func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) {
- p := new(ecdsa.PrivateKey)
- p.D = big.NewInt(0)
- // TODO: validate that the required flags are present
- for k, v := range m {
- switch k {
- case "privatekey":
- v1, err := fromBase64([]byte(v))
- if err != nil {
- return nil, err
- }
- p.D.SetBytes(v1)
- case "created", "publish", "activate":
- /* not used in Go (yet) */
- }
- }
- return p, nil
-}
-
-// parseKey reads a private key from r. It returns a map[string]string,
-// with the key-value pairs, or an error when the file is not correct.
-func parseKey(r io.Reader, file string) (map[string]string, error) {
- s := scanInit(r)
- m := make(map[string]string)
- c := make(chan lex)
- k := ""
- // Start the lexer
- go klexer(s, c)
- for l := range c {
- // It should alternate
- switch l.value {
- case zKey:
- k = l.token
- case zValue:
- if k == "" {
- return nil, &ParseError{file, "no private key seen", l}
- }
- //println("Setting", strings.ToLower(k), "to", l.token, "b")
- m[strings.ToLower(k)] = l.token
- k = ""
- }
- }
- return m, nil
-}
-
-// klexer scans the sourcefile and returns tokens on the channel c.
-func klexer(s *scan, c chan lex) {
- var l lex
- str := "" // Hold the current read text
- commt := false
- key := true
- x, err := s.tokenText()
- defer close(c)
- for err == nil {
- l.column = s.position.Column
- l.line = s.position.Line
- switch x {
- case ':':
- if commt {
- break
- }
- l.token = str
- if key {
- l.value = zKey
- c <- l
- // Next token is a space, eat it
- s.tokenText()
- key = false
- str = ""
- } else {
- l.value = zValue
- }
- case ';':
- commt = true
- case '\n':
- if commt {
- // Reset a comment
- commt = false
- }
- l.value = zValue
- l.token = str
- c <- l
- str = ""
- commt = false
- key = true
- default:
- if commt {
- break
- }
- str += string(x)
- }
- x, err = s.tokenText()
- }
- if len(str) > 0 {
- // Send remainder
- l.token = str
- l.value = zValue
- c <- l
- }
-}
diff --git a/vendor/github.com/miekg/dns/dnssec_privkey.go b/vendor/github.com/miekg/dns/dnssec_privkey.go
deleted file mode 100644
index 56f3ea934..000000000
--- a/vendor/github.com/miekg/dns/dnssec_privkey.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package dns
-
-import (
- "crypto"
- "crypto/dsa"
- "crypto/ecdsa"
- "crypto/rsa"
- "math/big"
- "strconv"
-)
-
-const format = "Private-key-format: v1.3\n"
-
-// PrivateKeyString converts a PrivateKey to a string. This string has the same
-// format as the private-key-file of BIND9 (Private-key-format: v1.3).
-// It needs some info from the key (the algorithm), so its a method of the DNSKEY
-// It supports rsa.PrivateKey, ecdsa.PrivateKey and dsa.PrivateKey
-func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
- algorithm := strconv.Itoa(int(r.Algorithm))
- algorithm += " (" + AlgorithmToString[r.Algorithm] + ")"
-
- switch p := p.(type) {
- case *rsa.PrivateKey:
- modulus := toBase64(p.PublicKey.N.Bytes())
- e := big.NewInt(int64(p.PublicKey.E))
- publicExponent := toBase64(e.Bytes())
- privateExponent := toBase64(p.D.Bytes())
- prime1 := toBase64(p.Primes[0].Bytes())
- prime2 := toBase64(p.Primes[1].Bytes())
- // Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm
- // and from: http://code.google.com/p/go/issues/detail?id=987
- one := big.NewInt(1)
- p1 := big.NewInt(0).Sub(p.Primes[0], one)
- q1 := big.NewInt(0).Sub(p.Primes[1], one)
- exp1 := big.NewInt(0).Mod(p.D, p1)
- exp2 := big.NewInt(0).Mod(p.D, q1)
- coeff := big.NewInt(0).ModInverse(p.Primes[1], p.Primes[0])
-
- exponent1 := toBase64(exp1.Bytes())
- exponent2 := toBase64(exp2.Bytes())
- coefficient := toBase64(coeff.Bytes())
-
- return format +
- "Algorithm: " + algorithm + "\n" +
- "Modulus: " + modulus + "\n" +
- "PublicExponent: " + publicExponent + "\n" +
- "PrivateExponent: " + privateExponent + "\n" +
- "Prime1: " + prime1 + "\n" +
- "Prime2: " + prime2 + "\n" +
- "Exponent1: " + exponent1 + "\n" +
- "Exponent2: " + exponent2 + "\n" +
- "Coefficient: " + coefficient + "\n"
-
- case *ecdsa.PrivateKey:
- var intlen int
- switch r.Algorithm {
- case ECDSAP256SHA256:
- intlen = 32
- case ECDSAP384SHA384:
- intlen = 48
- }
- private := toBase64(intToBytes(p.D, intlen))
- return format +
- "Algorithm: " + algorithm + "\n" +
- "PrivateKey: " + private + "\n"
-
- case *dsa.PrivateKey:
- T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8)
- prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8))
- subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20))
- base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8))
- priv := toBase64(intToBytes(p.X, 20))
- pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8))
- return format +
- "Algorithm: " + algorithm + "\n" +
- "Prime(p): " + prime + "\n" +
- "Subprime(q): " + subprime + "\n" +
- "Base(g): " + base + "\n" +
- "Private_value(x): " + priv + "\n" +
- "Public_value(y): " + pub + "\n"
-
- default:
- return ""
- }
-}
diff --git a/vendor/github.com/miekg/dns/dnssec_test.go b/vendor/github.com/miekg/dns/dnssec_test.go
deleted file mode 100644
index ca085ed3b..000000000
--- a/vendor/github.com/miekg/dns/dnssec_test.go
+++ /dev/null
@@ -1,733 +0,0 @@
-package dns
-
-import (
- "crypto"
- "crypto/ecdsa"
- "crypto/rsa"
- "reflect"
- "strings"
- "testing"
- "time"
-)
-
-func getKey() *DNSKEY {
- key := new(DNSKEY)
- key.Hdr.Name = "miek.nl."
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = RSASHA256
- key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
- return key
-}
-
-func getSoa() *SOA {
- soa := new(SOA)
- soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
- soa.Ns = "open.nlnetlabs.nl."
- soa.Mbox = "miekg.atoom.net."
- soa.Serial = 1293945905
- soa.Refresh = 14400
- soa.Retry = 3600
- soa.Expire = 604800
- soa.Minttl = 86400
- return soa
-}
-
-func TestGenerateEC(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- key := new(DNSKEY)
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Name = "miek.nl."
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = ECDSAP256SHA256
- privkey, _ := key.Generate(256)
- t.Log(key.String())
- t.Log(key.PrivateKeyString(privkey))
-}
-
-func TestGenerateDSA(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- key := new(DNSKEY)
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Name = "miek.nl."
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = DSA
- privkey, _ := key.Generate(1024)
- t.Log(key.String())
- t.Log(key.PrivateKeyString(privkey))
-}
-
-func TestGenerateRSA(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- key := new(DNSKEY)
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Name = "miek.nl."
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = RSASHA256
- privkey, _ := key.Generate(1024)
- t.Log(key.String())
- t.Log(key.PrivateKeyString(privkey))
-}
-
-func TestSecure(t *testing.T) {
- soa := getSoa()
-
- sig := new(RRSIG)
- sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
- sig.TypeCovered = TypeSOA
- sig.Algorithm = RSASHA256
- sig.Labels = 2
- sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
- sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
- sig.OrigTtl = 14400
- sig.KeyTag = 12051
- sig.SignerName = "miek.nl."
- sig.Signature = "oMCbslaAVIp/8kVtLSms3tDABpcPRUgHLrOR48OOplkYo+8TeEGWwkSwaz/MRo2fB4FxW0qj/hTlIjUGuACSd+b1wKdH5GvzRJc2pFmxtCbm55ygAh4EUL0F6U5cKtGJGSXxxg6UFCQ0doJCmiGFa78LolaUOXImJrk6AFrGa0M="
-
- key := new(DNSKEY)
- key.Hdr.Name = "miek.nl."
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = RSASHA256
- key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
-
- // It should validate. Period is checked separately, so this will keep on working
- if sig.Verify(key, []RR{soa}) != nil {
- t.Error("failure to validate")
- }
-}
-
-func TestSignature(t *testing.T) {
- sig := new(RRSIG)
- sig.Hdr.Name = "miek.nl."
- sig.Hdr.Class = ClassINET
- sig.Hdr.Ttl = 3600
- sig.TypeCovered = TypeDNSKEY
- sig.Algorithm = RSASHA1
- sig.Labels = 2
- sig.OrigTtl = 4000
- sig.Expiration = 1000 //Thu Jan 1 02:06:40 CET 1970
- sig.Inception = 800 //Thu Jan 1 01:13:20 CET 1970
- sig.KeyTag = 34641
- sig.SignerName = "miek.nl."
- sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
-
- // Should not be valid
- if sig.ValidityPeriod(time.Now()) {
- t.Error("should not be valid")
- }
-
- sig.Inception = 315565800 //Tue Jan 1 10:10:00 CET 1980
- sig.Expiration = 4102477800 //Fri Jan 1 10:10:00 CET 2100
- if !sig.ValidityPeriod(time.Now()) {
- t.Error("should be valid")
- }
-}
-
-func TestSignVerify(t *testing.T) {
- // The record we want to sign
- soa := new(SOA)
- soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
- soa.Ns = "open.nlnetlabs.nl."
- soa.Mbox = "miekg.atoom.net."
- soa.Serial = 1293945905
- soa.Refresh = 14400
- soa.Retry = 3600
- soa.Expire = 604800
- soa.Minttl = 86400
-
- soa1 := new(SOA)
- soa1.Hdr = RR_Header{"*.miek.nl.", TypeSOA, ClassINET, 14400, 0}
- soa1.Ns = "open.nlnetlabs.nl."
- soa1.Mbox = "miekg.atoom.net."
- soa1.Serial = 1293945905
- soa1.Refresh = 14400
- soa1.Retry = 3600
- soa1.Expire = 604800
- soa1.Minttl = 86400
-
- srv := new(SRV)
- srv.Hdr = RR_Header{"srv.miek.nl.", TypeSRV, ClassINET, 14400, 0}
- srv.Port = 1000
- srv.Weight = 800
- srv.Target = "web1.miek.nl."
-
- hinfo := &HINFO{
- Hdr: RR_Header{
- Name: "miek.nl.",
- Rrtype: TypeHINFO,
- Class: ClassINET,
- Ttl: 3789,
- },
- Cpu: "X",
- Os: "Y",
- }
-
- // With this key
- key := new(DNSKEY)
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Name = "miek.nl."
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = RSASHA256
- privkey, _ := key.Generate(512)
-
- // Fill in the values of the Sig, before signing
- sig := new(RRSIG)
- sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
- sig.TypeCovered = soa.Hdr.Rrtype
- sig.Labels = uint8(CountLabel(soa.Hdr.Name)) // works for all 3
- sig.OrigTtl = soa.Hdr.Ttl
- sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
- sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
- sig.KeyTag = key.KeyTag() // Get the keyfrom the Key
- sig.SignerName = key.Hdr.Name
- sig.Algorithm = RSASHA256
-
- for _, r := range []RR{soa, soa1, srv, hinfo} {
- if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{r}); err != nil {
- t.Error("failure to sign the record:", err)
- continue
- }
- if err := sig.Verify(key, []RR{r}); err != nil {
- t.Error("failure to validate")
- continue
- }
- t.Logf("validated: %s", r.Header().Name)
- }
-}
-
-func Test65534(t *testing.T) {
- t6 := new(RFC3597)
- t6.Hdr = RR_Header{"miek.nl.", 65534, ClassINET, 14400, 0}
- t6.Rdata = "505D870001"
- key := new(DNSKEY)
- key.Hdr.Name = "miek.nl."
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = RSASHA256
- privkey, _ := key.Generate(1024)
-
- sig := new(RRSIG)
- sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
- sig.TypeCovered = t6.Hdr.Rrtype
- sig.Labels = uint8(CountLabel(t6.Hdr.Name))
- sig.OrigTtl = t6.Hdr.Ttl
- sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
- sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
- sig.KeyTag = key.KeyTag()
- sig.SignerName = key.Hdr.Name
- sig.Algorithm = RSASHA256
- if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{t6}); err != nil {
- t.Error(err)
- t.Error("failure to sign the TYPE65534 record")
- }
- if err := sig.Verify(key, []RR{t6}); err != nil {
- t.Error(err)
- t.Error("failure to validate")
- } else {
- t.Logf("validated: %s", t6.Header().Name)
- }
-}
-
-func TestDnskey(t *testing.T) {
- pubkey, err := ReadRR(strings.NewReader(`
-miek.nl. IN DNSKEY 256 3 10 AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL ;{id = 5240 (zsk), size = 1024b}
-`), "Kmiek.nl.+010+05240.key")
- if err != nil {
- t.Fatal(err)
- }
- privStr := `Private-key-format: v1.3
-Algorithm: 10 (RSASHA512)
-Modulus: m4wK7YV26AeROtdiCXmqLG9wPDVoMOW8vjr/EkpscEAdjXp81RvZvrlzCSjYmz9onFRgltmTl3AINnFh+t9tlW0M9C5zejxBoKFXELv8ljPYAdz2oe+pDWPhWsfvVFYg2VCjpViPM38EakyE5mhk4TDOnUd+w4TeU1hyhZTWyYs=
-PublicExponent: AQAB
-PrivateExponent: UfCoIQ/Z38l8vB6SSqOI/feGjHEl/fxIPX4euKf0D/32k30fHbSaNFrFOuIFmWMB3LimWVEs6u3dpbB9CQeCVg7hwU5puG7OtuiZJgDAhNeOnxvo5btp4XzPZrJSxR4WNQnwIiYWbl0aFlL1VGgHC/3By89ENZyWaZcMLW4KGWE=
-Prime1: yxwC6ogAu8aVcDx2wg1V0b5M5P6jP8qkRFVMxWNTw60Vkn+ECvw6YAZZBHZPaMyRYZLzPgUlyYRd0cjupy4+fQ==
-Prime2: xA1bF8M0RTIQ6+A11AoVG6GIR/aPGg5sogRkIZ7ID/sF6g9HMVU/CM2TqVEBJLRPp73cv6ZeC3bcqOCqZhz+pw==
-Exponent1: xzkblyZ96bGYxTVZm2/vHMOXswod4KWIyMoOepK6B/ZPcZoIT6omLCgtypWtwHLfqyCz3MK51Nc0G2EGzg8rFQ==
-Exponent2: Pu5+mCEb7T5F+kFNZhQadHUklt0JUHbi3hsEvVoHpEGSw3BGDQrtIflDde0/rbWHgDPM4WQY+hscd8UuTXrvLw==
-Coefficient: UuRoNqe7YHnKmQzE6iDWKTMIWTuoqqrFAmXPmKQnC+Y+BQzOVEHUo9bXdDnoI9hzXP1gf8zENMYwYLeWpuYlFQ==
-`
- privkey, err := pubkey.(*DNSKEY).ReadPrivateKey(strings.NewReader(privStr),
- "Kmiek.nl.+010+05240.private")
- if err != nil {
- t.Fatal(err)
- }
- if pubkey.(*DNSKEY).PublicKey != "AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL" {
- t.Error("pubkey is not what we've read")
- }
- if pubkey.(*DNSKEY).PrivateKeyString(privkey) != privStr {
- t.Error("privkey is not what we've read")
- t.Errorf("%v", pubkey.(*DNSKEY).PrivateKeyString(privkey))
- }
-}
-
-func TestTag(t *testing.T) {
- key := new(DNSKEY)
- key.Hdr.Name = "miek.nl."
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 3600
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = RSASHA256
- key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
-
- tag := key.KeyTag()
- if tag != 12051 {
- t.Errorf("wrong key tag: %d for key %v", tag, key)
- }
-}
-
-func TestKeyRSA(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- key := new(DNSKEY)
- key.Hdr.Name = "miek.nl."
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 3600
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = RSASHA256
- priv, _ := key.Generate(2048)
-
- soa := new(SOA)
- soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
- soa.Ns = "open.nlnetlabs.nl."
- soa.Mbox = "miekg.atoom.net."
- soa.Serial = 1293945905
- soa.Refresh = 14400
- soa.Retry = 3600
- soa.Expire = 604800
- soa.Minttl = 86400
-
- sig := new(RRSIG)
- sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
- sig.TypeCovered = TypeSOA
- sig.Algorithm = RSASHA256
- sig.Labels = 2
- sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
- sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
- sig.OrigTtl = soa.Hdr.Ttl
- sig.KeyTag = key.KeyTag()
- sig.SignerName = key.Hdr.Name
-
- if err := sig.Sign(priv.(*rsa.PrivateKey), []RR{soa}); err != nil {
- t.Error("failed to sign")
- return
- }
- if err := sig.Verify(key, []RR{soa}); err != nil {
- t.Error("failed to verify")
- }
-}
-
-func TestKeyToDS(t *testing.T) {
- key := new(DNSKEY)
- key.Hdr.Name = "miek.nl."
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 3600
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = RSASHA256
- key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
-
- ds := key.ToDS(SHA1)
- if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" {
- t.Errorf("wrong DS digest for SHA1\n%v", ds)
- }
-}
-
-func TestSignRSA(t *testing.T) {
- pub := "miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ"
-
- priv := `Private-key-format: v1.3
-Algorithm: 5 (RSASHA1)
-Modulus: v7yUY0LEmAtLythV6voScdW4iRAOCF2N217APNTcblHs9sxspVG8fYxrulDJhx6hqpZlCKtKPvZ649Z8/FCczL25wLKUD4W4f1xKMhw9/g+ol926keT1foQFiPGsItjinX/IHCDIEhEm1m0Cozdx4AfZai8QkPqtO064ejkCW4k=
-PublicExponent: AQAB
-PrivateExponent: YPwEmwjk5HuiROKU4xzHQ6l1hG8Iiha4cKRG3P5W2b66/EN/GUh07ZSf0UiYB67o257jUDVEgwCuPJz776zfApcCB4oGV+YDyEu7Hp/rL8KcSN0la0k2r9scKwxTp4BTJT23zyBFXsV/1wRDK1A5NxsHPDMYi2SoK63Enm/1ptk=
-Prime1: /wjOG+fD0ybNoSRn7nQ79udGeR1b0YhUA5mNjDx/x2fxtIXzygYk0Rhx9QFfDy6LOBvz92gbNQlzCLz3DJt5hw==
-Prime2: wHZsJ8OGhkp5p3mrJFZXMDc2mbYusDVTA+t+iRPdS797Tj0pjvU2HN4vTnTj8KBQp6hmnY7dLp9Y1qserySGbw==
-Exponent1: N0A7FsSRIg+IAN8YPQqlawoTtG1t1OkJ+nWrurPootScApX6iMvn8fyvw3p2k51rv84efnzpWAYiC8SUaQDNxQ==
-Exponent2: SvuYRaGyvo0zemE3oS+WRm2scxR8eiA8WJGeOc+obwOKCcBgeZblXzfdHGcEC1KaOcetOwNW/vwMA46lpLzJNw==
-Coefficient: 8+7ZN/JgByqv0NfULiFKTjtyegUcijRuyij7yNxYbCBneDvZGxJwKNi4YYXWx743pcAj4Oi4Oh86gcmxLs+hGw==
-Created: 20110302104537
-Publish: 20110302104537
-Activate: 20110302104537`
-
- xk, _ := NewRR(pub)
- k := xk.(*DNSKEY)
- p, err := k.NewPrivateKey(priv)
- if err != nil {
- t.Error(err)
- }
- switch priv := p.(type) {
- case *rsa.PrivateKey:
- if 65537 != priv.PublicKey.E {
- t.Error("exponenent should be 65537")
- }
- default:
- t.Errorf("we should have read an RSA key: %v", priv)
- }
- if k.KeyTag() != 37350 {
- t.Errorf("keytag should be 37350, got %d %v", k.KeyTag(), k)
- }
-
- soa := new(SOA)
- soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
- soa.Ns = "open.nlnetlabs.nl."
- soa.Mbox = "miekg.atoom.net."
- soa.Serial = 1293945905
- soa.Refresh = 14400
- soa.Retry = 3600
- soa.Expire = 604800
- soa.Minttl = 86400
-
- sig := new(RRSIG)
- sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
- sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
- sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
- sig.KeyTag = k.KeyTag()
- sig.SignerName = k.Hdr.Name
- sig.Algorithm = k.Algorithm
-
- sig.Sign(p.(*rsa.PrivateKey), []RR{soa})
- if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
- t.Errorf("signature is not correct: %v", sig)
- }
-}
-
-func TestSignVerifyECDSA(t *testing.T) {
- pub := `example.net. 3600 IN DNSKEY 257 3 14 (
- xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
- w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
- /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
- priv := `Private-key-format: v1.2
-Algorithm: 14 (ECDSAP384SHA384)
-PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
-
- eckey, err := NewRR(pub)
- if err != nil {
- t.Fatal(err)
- }
- privkey, err := eckey.(*DNSKEY).NewPrivateKey(priv)
- if err != nil {
- t.Fatal(err)
- }
- // TODO: Create separate test for this
- ds := eckey.(*DNSKEY).ToDS(SHA384)
- if ds.KeyTag != 10771 {
- t.Fatal("wrong keytag on DS")
- }
- if ds.Digest != "72d7b62976ce06438e9c0bf319013cf801f09ecc84b8d7e9495f27e305c6a9b0563a9b5f4d288405c3008a946df983d6" {
- t.Fatal("wrong DS Digest")
- }
- a, _ := NewRR("www.example.net. 3600 IN A 192.0.2.1")
- sig := new(RRSIG)
- sig.Hdr = RR_Header{"example.net.", TypeRRSIG, ClassINET, 14400, 0}
- sig.Expiration, _ = StringToTime("20100909102025")
- sig.Inception, _ = StringToTime("20100812102025")
- sig.KeyTag = eckey.(*DNSKEY).KeyTag()
- sig.SignerName = eckey.(*DNSKEY).Hdr.Name
- sig.Algorithm = eckey.(*DNSKEY).Algorithm
-
- if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{a}) != nil {
- t.Fatal("failure to sign the record")
- }
-
- if err := sig.Verify(eckey.(*DNSKEY), []RR{a}); err != nil {
- t.Fatalf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
- eckey.(*DNSKEY).String(),
- a.String(),
- sig.String(),
- eckey.(*DNSKEY).PrivateKeyString(privkey),
- err,
- )
- }
-}
-
-func TestSignVerifyECDSA2(t *testing.T) {
- srv1, err := NewRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.")
- if err != nil {
- t.Fatal(err)
- }
- srv := srv1.(*SRV)
-
- // With this key
- key := new(DNSKEY)
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Name = "miek.nl."
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = ECDSAP256SHA256
- privkey, err := key.Generate(256)
- if err != nil {
- t.Fatal("failure to generate key")
- }
-
- // Fill in the values of the Sig, before signing
- sig := new(RRSIG)
- sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
- sig.TypeCovered = srv.Hdr.Rrtype
- sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3
- sig.OrigTtl = srv.Hdr.Ttl
- sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
- sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
- sig.KeyTag = key.KeyTag() // Get the keyfrom the Key
- sig.SignerName = key.Hdr.Name
- sig.Algorithm = ECDSAP256SHA256
-
- if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{srv}) != nil {
- t.Fatal("failure to sign the record")
- }
-
- err = sig.Verify(key, []RR{srv})
- if err != nil {
- t.Logf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
- key.String(),
- srv.String(),
- sig.String(),
- key.PrivateKeyString(privkey),
- err,
- )
- }
-}
-
-// Here the test vectors from the relevant RFCs are checked.
-// rfc6605 6.1
-func TestRFC6605P256(t *testing.T) {
- exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 13 (
- GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb
- krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )`
- exPriv := `Private-key-format: v1.2
-Algorithm: 13 (ECDSAP256SHA256)
-PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=`
- rrDNSKEY, err := NewRR(exDNSKEY)
- if err != nil {
- t.Fatal(err)
- }
- priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
- if err != nil {
- t.Fatal(err)
- }
-
- exDS := `example.net. 3600 IN DS 55648 13 2 (
- b4c8c1fe2e7477127b27115656ad6256f424625bf5c1
- e2770ce6d6e37df61d17 )`
- rrDS, err := NewRR(exDS)
- if err != nil {
- t.Fatal(err)
- }
- ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
- if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
- t.Errorf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
- }
-
- exA := `www.example.net. 3600 IN A 192.0.2.1`
- exRRSIG := `www.example.net. 3600 IN RRSIG A 13 3 3600 (
- 20100909100439 20100812100439 55648 example.net.
- qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA
- yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )`
- rrA, err := NewRR(exA)
- if err != nil {
- t.Fatal(err)
- }
- rrRRSIG, err := NewRR(exRRSIG)
- if err != nil {
- t.Fatal(err)
- }
- if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
- t.Errorf("failure to validate the spec RRSIG: %v", err)
- }
-
- ourRRSIG := &RRSIG{
- Hdr: RR_Header{
- Ttl: rrA.Header().Ttl,
- },
- KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(),
- SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
- Algorithm: rrDNSKEY.(*DNSKEY).Algorithm,
- }
- ourRRSIG.Expiration, _ = StringToTime("20100909100439")
- ourRRSIG.Inception, _ = StringToTime("20100812100439")
- err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
- if err != nil {
- t.Fatal(err)
- }
-
- if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
- t.Errorf("failure to validate our RRSIG: %v", err)
- }
-
- // Signatures are randomized
- rrRRSIG.(*RRSIG).Signature = ""
- ourRRSIG.Signature = ""
- if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
- t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
- }
-}
-
-// rfc6605 6.2
-func TestRFC6605P384(t *testing.T) {
- exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 14 (
- xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
- w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
- /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
- exPriv := `Private-key-format: v1.2
-Algorithm: 14 (ECDSAP384SHA384)
-PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
- rrDNSKEY, err := NewRR(exDNSKEY)
- if err != nil {
- t.Fatal(err)
- }
- priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
- if err != nil {
- t.Fatal(err)
- }
-
- exDS := `example.net. 3600 IN DS 10771 14 4 (
- 72d7b62976ce06438e9c0bf319013cf801f09ecc84b8
- d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94
- 6df983d6 )`
- rrDS, err := NewRR(exDS)
- if err != nil {
- t.Fatal(err)
- }
- ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA384)
- if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
- t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
- }
-
- exA := `www.example.net. 3600 IN A 192.0.2.1`
- exRRSIG := `www.example.net. 3600 IN RRSIG A 14 3 3600 (
- 20100909102025 20100812102025 10771 example.net.
- /L5hDKIvGDyI1fcARX3z65qrmPsVz73QD1Mr5CEqOiLP
- 95hxQouuroGCeZOvzFaxsT8Glr74hbavRKayJNuydCuz
- WTSSPdz7wnqXL5bdcJzusdnI0RSMROxxwGipWcJm )`
- rrA, err := NewRR(exA)
- if err != nil {
- t.Fatal(err)
- }
- rrRRSIG, err := NewRR(exRRSIG)
- if err != nil {
- t.Fatal(err)
- }
- if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
- t.Errorf("failure to validate the spec RRSIG: %v", err)
- }
-
- ourRRSIG := &RRSIG{
- Hdr: RR_Header{
- Ttl: rrA.Header().Ttl,
- },
- KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(),
- SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
- Algorithm: rrDNSKEY.(*DNSKEY).Algorithm,
- }
- ourRRSIG.Expiration, _ = StringToTime("20100909102025")
- ourRRSIG.Inception, _ = StringToTime("20100812102025")
- err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
- if err != nil {
- t.Fatal(err)
- }
-
- if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
- t.Errorf("failure to validate our RRSIG: %v", err)
- }
-
- // Signatures are randomized
- rrRRSIG.(*RRSIG).Signature = ""
- ourRRSIG.Signature = ""
- if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
- t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
- }
-}
-
-func TestInvalidRRSet(t *testing.T) {
- goodRecords := make([]RR, 2)
- goodRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
- goodRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}}
-
- // Generate key
- keyname := "cloudflare.com."
- key := &DNSKEY{
- Hdr: RR_Header{Name: keyname, Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 0},
- Algorithm: ECDSAP256SHA256,
- Flags: ZONE,
- Protocol: 3,
- }
- privatekey, err := key.Generate(256)
- if err != nil {
- t.Fatal(err.Error())
- }
-
- // Need to fill in: Inception, Expiration, KeyTag, SignerName and Algorithm
- curTime := time.Now()
- signature := &RRSIG{
- Inception: uint32(curTime.Unix()),
- Expiration: uint32(curTime.Add(time.Hour).Unix()),
- KeyTag: key.KeyTag(),
- SignerName: keyname,
- Algorithm: ECDSAP256SHA256,
- }
-
- // Inconsistent name between records
- badRecords := make([]RR, 2)
- badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
- badRecords[1] = &TXT{Hdr: RR_Header{Name: "nama.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}}
-
- if IsRRset(badRecords) {
- t.Fatal("Record set with inconsistent names considered valid")
- }
-
- badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
- badRecords[1] = &A{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeA, Class: ClassINET, Ttl: 0}}
-
- if IsRRset(badRecords) {
- t.Fatal("Record set with inconsistent record types considered valid")
- }
-
- badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
- badRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassCHAOS, Ttl: 0}, Txt: []string{"_o/"}}
-
- if IsRRset(badRecords) {
- t.Fatal("Record set with inconsistent record class considered valid")
- }
-
- // Sign the good record set and then make sure verification fails on the bad record set
- if err := signature.Sign(privatekey.(crypto.Signer), goodRecords); err != nil {
- t.Fatal("Signing good records failed")
- }
-
- if err := signature.Verify(key, badRecords); err != ErrRRset {
- t.Fatal("Verification did not return ErrRRset with inconsistent records")
- }
-}
diff --git a/vendor/github.com/miekg/dns/doc.go b/vendor/github.com/miekg/dns/doc.go
deleted file mode 100644
index e38753d7d..000000000
--- a/vendor/github.com/miekg/dns/doc.go
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
-Package dns implements a full featured interface to the Domain Name System.
-Server- and client-side programming is supported.
-The package allows complete control over what is send out to the DNS. The package
-API follows the less-is-more principle, by presenting a small, clean interface.
-
-The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
-TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.
-Note that domain names MUST be fully qualified, before sending them, unqualified
-names in a message will result in a packing failure.
-
-Resource records are native types. They are not stored in wire format.
-Basic usage pattern for creating a new resource record:
-
- r := new(dns.MX)
- r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX,
- Class: dns.ClassINET, Ttl: 3600}
- r.Preference = 10
- r.Mx = "mx.miek.nl."
-
-Or directly from a string:
-
- mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
-
-Or when the default TTL (3600) and class (IN) suit you:
-
- mx, err := dns.NewRR("miek.nl. MX 10 mx.miek.nl.")
-
-Or even:
-
- mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
-
-In the DNS messages are exchanged, these messages contain resource
-records (sets). Use pattern for creating a message:
-
- m := new(dns.Msg)
- m.SetQuestion("miek.nl.", dns.TypeMX)
-
-Or when not certain if the domain name is fully qualified:
-
- m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)
-
-The message m is now a message with the question section set to ask
-the MX records for the miek.nl. zone.
-
-The following is slightly more verbose, but more flexible:
-
- m1 := new(dns.Msg)
- m1.Id = dns.Id()
- m1.RecursionDesired = true
- m1.Question = make([]dns.Question, 1)
- m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
-
-After creating a message it can be send.
-Basic use pattern for synchronous querying the DNS at a
-server configured on 127.0.0.1 and port 53:
-
- c := new(dns.Client)
- in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
-
-Suppressing multiple outstanding queries (with the same question, type and
-class) is as easy as setting:
-
- c.SingleInflight = true
-
-If these "advanced" features are not needed, a simple UDP query can be send,
-with:
-
- in, err := dns.Exchange(m1, "127.0.0.1:53")
-
-When this functions returns you will get dns message. A dns message consists
-out of four sections.
-The question section: in.Question, the answer section: in.Answer,
-the authority section: in.Ns and the additional section: in.Extra.
-
-Each of these sections (except the Question section) contain a []RR. Basic
-use pattern for accessing the rdata of a TXT RR as the first RR in
-the Answer section:
-
- if t, ok := in.Answer[0].(*dns.TXT); ok {
- // do something with t.Txt
- }
-
-Domain Name and TXT Character String Representations
-
-Both domain names and TXT character strings are converted to presentation
-form both when unpacked and when converted to strings.
-
-For TXT character strings, tabs, carriage returns and line feeds will be
-converted to \t, \r and \n respectively. Back slashes and quotations marks
-will be escaped. Bytes below 32 and above 127 will be converted to \DDD
-form.
-
-For domain names, in addition to the above rules brackets, periods,
-spaces, semicolons and the at symbol are escaped.
-
-DNSSEC
-
-DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It
-uses public key cryptography to sign resource records. The
-public keys are stored in DNSKEY records and the signatures in RRSIG records.
-
-Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit
-to a request.
-
- m := new(dns.Msg)
- m.SetEdns0(4096, true)
-
-Signature generation, signature verification and key generation are all supported.
-
-DYNAMIC UPDATES
-
-Dynamic updates reuses the DNS message format, but renames three of
-the sections. Question is Zone, Answer is Prerequisite, Authority is
-Update, only the Additional is not renamed. See RFC 2136 for the gory details.
-
-You can set a rather complex set of rules for the existence of absence of
-certain resource records or names in a zone to specify if resource records
-should be added or removed. The table from RFC 2136 supplemented with the Go
-DNS function shows which functions exist to specify the prerequisites.
-
- 3.2.4 - Table Of Metavalues Used In Prerequisite Section
-
- CLASS TYPE RDATA Meaning Function
- --------------------------------------------------------------
- ANY ANY empty Name is in use dns.NameUsed
- ANY rrset empty RRset exists (value indep) dns.RRsetUsed
- NONE ANY empty Name is not in use dns.NameNotUsed
- NONE rrset empty RRset does not exist dns.RRsetNotUsed
- zone rrset rr RRset exists (value dep) dns.Used
-
-The prerequisite section can also be left empty.
-If you have decided on the prerequisites you can tell what RRs should
-be added or deleted. The next table shows the options you have and
-what functions to call.
-
- 3.4.2.6 - Table Of Metavalues Used In Update Section
-
- CLASS TYPE RDATA Meaning Function
- ---------------------------------------------------------------
- ANY ANY empty Delete all RRsets from name dns.RemoveName
- ANY rrset empty Delete an RRset dns.RemoveRRset
- NONE rrset rr Delete an RR from RRset dns.Remove
- zone rrset rr Add to an RRset dns.Insert
-
-TRANSACTION SIGNATURE
-
-An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
-The supported algorithms include: HmacMD5, HmacSHA1, HmacSHA256 and HmacSHA512.
-
-Basic use pattern when querying with a TSIG name "axfr." (note that these key names
-must be fully qualified - as they are domain names) and the base64 secret
-"so6ZGir4GPAqINNh9U5c3A==":
-
- c := new(dns.Client)
- c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
- m := new(dns.Msg)
- m.SetQuestion("miek.nl.", dns.TypeMX)
- m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
- ...
- // When sending the TSIG RR is calculated and filled in before sending
-
-When requesting an zone transfer (almost all TSIG usage is when requesting zone transfers), with
-TSIG, this is the basic use pattern. In this example we request an AXFR for
-miek.nl. with TSIG key named "axfr." and secret "so6ZGir4GPAqINNh9U5c3A=="
-and using the server 176.58.119.54:
-
- t := new(dns.Transfer)
- m := new(dns.Msg)
- t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
- m.SetAxfr("miek.nl.")
- m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
- c, err := t.In(m, "176.58.119.54:53")
- for r := range c { ... }
-
-You can now read the records from the transfer as they come in. Each envelope is checked with TSIG.
-If something is not correct an error is returned.
-
-Basic use pattern validating and replying to a message that has TSIG set.
-
- server := &dns.Server{Addr: ":53", Net: "udp"}
- server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
- go server.ListenAndServe()
- dns.HandleFunc(".", handleRequest)
-
- func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
- m := new(dns.Msg)
- m.SetReply(r)
- if r.IsTsig() != nil {
- if w.TsigStatus() == nil {
- // *Msg r has an TSIG record and it was validated
- m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
- } else {
- // *Msg r has an TSIG records and it was not valided
- }
- }
- w.WriteMsg(m)
- }
-
-PRIVATE RRS
-
-RFC 6895 sets aside a range of type codes for private use. This range
-is 65,280 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these
-can be used, before requesting an official type code from IANA.
-
-see http://miek.nl/2014/September/21/idn-and-private-rr-in-go-dns/ for more
-information.
-
-EDNS0
-
-EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated
-by RFC 6891. It defines an new RR type, the OPT RR, which is then completely
-abused.
-Basic use pattern for creating an (empty) OPT RR:
-
- o := new(dns.OPT)
- o.Hdr.Name = "." // MUST be the root zone, per definition.
- o.Hdr.Rrtype = dns.TypeOPT
-
-The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891)
-interfaces. Currently only a few have been standardized: EDNS0_NSID
-(RFC 5001) and EDNS0_SUBNET (draft-vandergaast-edns-client-subnet-02). Note
-that these options may be combined in an OPT RR.
-Basic use pattern for a server to check if (and which) options are set:
-
- // o is a dns.OPT
- for _, s := range o.Option {
- switch e := s.(type) {
- case *dns.EDNS0_NSID:
- // do stuff with e.Nsid
- case *dns.EDNS0_SUBNET:
- // access e.Family, e.Address, etc.
- }
- }
-
-SIG(0)
-
-From RFC 2931:
-
- SIG(0) provides protection for DNS transactions and requests ....
- ... protection for glue records, DNS requests, protection for message headers
- on requests and responses, and protection of the overall integrity of a response.
-
-It works like TSIG, except that SIG(0) uses public key cryptography, instead of the shared
-secret approach in TSIG.
-Supported algorithms: DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256 and
-RSASHA512.
-
-Signing subsequent messages in multi-message sessions is not implemented.
-*/
-package dns
diff --git a/vendor/github.com/miekg/dns/dyn_test.go b/vendor/github.com/miekg/dns/dyn_test.go
deleted file mode 100644
index 09986a5e4..000000000
--- a/vendor/github.com/miekg/dns/dyn_test.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package dns
-
-// Find better solution
diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go
deleted file mode 100644
index dbff3714c..000000000
--- a/vendor/github.com/miekg/dns/edns.go
+++ /dev/null
@@ -1,597 +0,0 @@
-package dns
-
-import (
- "encoding/binary"
- "encoding/hex"
- "errors"
- "fmt"
- "net"
- "strconv"
-)
-
-// EDNS0 Option codes.
-const (
- EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
- EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
- EDNS0NSID = 0x3 // nsid (RFC5001)
- EDNS0DAU = 0x5 // DNSSEC Algorithm Understood
- EDNS0DHU = 0x6 // DS Hash Understood
- EDNS0N3U = 0x7 // NSEC3 Hash Understood
- EDNS0SUBNET = 0x8 // client-subnet (RFC6891)
- EDNS0EXPIRE = 0x9 // EDNS0 expire
- EDNS0COOKIE = 0xa // EDNS0 Cookie
- EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (RFC7828)
- EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET
- EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891)
- EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891)
- _DO = 1 << 15 // dnssec ok
-)
-
-// OPT is the EDNS0 RR appended to messages to convey extra (meta) information.
-// See RFC 6891.
-type OPT struct {
- Hdr RR_Header
- Option []EDNS0 `dns:"opt"`
-}
-
-func (rr *OPT) String() string {
- s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; "
- if rr.Do() {
- s += "flags: do; "
- } else {
- s += "flags: ; "
- }
- s += "udp: " + strconv.Itoa(int(rr.UDPSize()))
-
- for _, o := range rr.Option {
- switch o.(type) {
- case *EDNS0_NSID:
- s += "\n; NSID: " + o.String()
- h, e := o.pack()
- var r string
- if e == nil {
- for _, c := range h {
- r += "(" + string(c) + ")"
- }
- s += " " + r
- }
- case *EDNS0_SUBNET:
- s += "\n; SUBNET: " + o.String()
- if o.(*EDNS0_SUBNET).DraftOption {
- s += " (draft)"
- }
- case *EDNS0_COOKIE:
- s += "\n; COOKIE: " + o.String()
- case *EDNS0_UL:
- s += "\n; UPDATE LEASE: " + o.String()
- case *EDNS0_LLQ:
- s += "\n; LONG LIVED QUERIES: " + o.String()
- case *EDNS0_DAU:
- s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String()
- case *EDNS0_DHU:
- s += "\n; DS HASH UNDERSTOOD: " + o.String()
- case *EDNS0_N3U:
- s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
- case *EDNS0_LOCAL:
- s += "\n; LOCAL OPT: " + o.String()
- }
- }
- return s
-}
-
-func (rr *OPT) len() int {
- l := rr.Hdr.len()
- for i := 0; i < len(rr.Option); i++ {
- l += 4 // Account for 2-byte option code and 2-byte option length.
- lo, _ := rr.Option[i].pack()
- l += len(lo)
- }
- return l
-}
-
-// return the old value -> delete SetVersion?
-
-// Version returns the EDNS version used. Only zero is defined.
-func (rr *OPT) Version() uint8 {
- return uint8((rr.Hdr.Ttl & 0x00FF0000) >> 16)
-}
-
-// SetVersion sets the version of EDNS. This is usually zero.
-func (rr *OPT) SetVersion(v uint8) {
- rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | (uint32(v) << 16)
-}
-
-// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
-func (rr *OPT) ExtendedRcode() int {
- return int((rr.Hdr.Ttl&0xFF000000)>>24) + 15
-}
-
-// SetExtendedRcode sets the EDNS extended RCODE field.
-func (rr *OPT) SetExtendedRcode(v uint8) {
- if v < RcodeBadVers { // Smaller than 16.. Use the 4 bits you have!
- return
- }
- rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v-15) << 24)
-}
-
-// UDPSize returns the UDP buffer size.
-func (rr *OPT) UDPSize() uint16 {
- return rr.Hdr.Class
-}
-
-// SetUDPSize sets the UDP buffer size.
-func (rr *OPT) SetUDPSize(size uint16) {
- rr.Hdr.Class = size
-}
-
-// Do returns the value of the DO (DNSSEC OK) bit.
-func (rr *OPT) Do() bool {
- return rr.Hdr.Ttl&_DO == _DO
-}
-
-// SetDo sets the DO (DNSSEC OK) bit.
-// If we pass an argument, set the DO bit to that value.
-// It is possible to pass 2 or more arguments. Any arguments after the 1st is silently ignored.
-func (rr *OPT) SetDo(do ...bool) {
- if len(do) == 1 {
- if do[0] {
- rr.Hdr.Ttl |= _DO
- } else {
- rr.Hdr.Ttl &^= _DO
- }
- } else {
- rr.Hdr.Ttl |= _DO
- }
-}
-
-// EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it.
-type EDNS0 interface {
- // Option returns the option code for the option.
- Option() uint16
- // pack returns the bytes of the option data.
- pack() ([]byte, error)
- // unpack sets the data as found in the buffer. Is also sets
- // the length of the slice as the length of the option data.
- unpack([]byte) error
- // String returns the string representation of the option.
- String() string
-}
-
-// EDNS0_NSID option is used to retrieve a nameserver
-// identifier. When sending a request Nsid must be set to the empty string
-// The identifier is an opaque string encoded as hex.
-// Basic use pattern for creating an nsid option:
-//
-// o := new(dns.OPT)
-// o.Hdr.Name = "."
-// o.Hdr.Rrtype = dns.TypeOPT
-// e := new(dns.EDNS0_NSID)
-// e.Code = dns.EDNS0NSID
-// e.Nsid = "AA"
-// o.Option = append(o.Option, e)
-type EDNS0_NSID struct {
- Code uint16 // Always EDNS0NSID
- Nsid string // This string needs to be hex encoded
-}
-
-func (e *EDNS0_NSID) pack() ([]byte, error) {
- h, err := hex.DecodeString(e.Nsid)
- if err != nil {
- return nil, err
- }
- return h, nil
-}
-
-func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID }
-func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
-func (e *EDNS0_NSID) String() string { return string(e.Nsid) }
-
-// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver
-// an idea of where the client lives. It can then give back a different
-// answer depending on the location or network topology.
-// Basic use pattern for creating an subnet option:
-//
-// o := new(dns.OPT)
-// o.Hdr.Name = "."
-// o.Hdr.Rrtype = dns.TypeOPT
-// e := new(dns.EDNS0_SUBNET)
-// e.Code = dns.EDNS0SUBNET
-// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6
-// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6
-// e.SourceScope = 0
-// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4
-// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6
-// o.Option = append(o.Option, e)
-//
-// Note: the spec (draft-ietf-dnsop-edns-client-subnet-00) has some insane logic
-// for which netmask applies to the address. This code will parse all the
-// available bits when unpacking (up to optlen). When packing it will apply
-// SourceNetmask. If you need more advanced logic, patches welcome and good luck.
-type EDNS0_SUBNET struct {
- Code uint16 // Always EDNS0SUBNET
- Family uint16 // 1 for IP, 2 for IP6
- SourceNetmask uint8
- SourceScope uint8
- Address net.IP
- DraftOption bool // Set to true if using the old (0x50fa) option code
-}
-
-func (e *EDNS0_SUBNET) Option() uint16 {
- if e.DraftOption {
- return EDNS0SUBNETDRAFT
- }
- return EDNS0SUBNET
-}
-
-func (e *EDNS0_SUBNET) pack() ([]byte, error) {
- b := make([]byte, 4)
- binary.BigEndian.PutUint16(b[0:], e.Family)
- b[2] = e.SourceNetmask
- b[3] = e.SourceScope
- switch e.Family {
- case 1:
- if e.SourceNetmask > net.IPv4len*8 {
- return nil, errors.New("dns: bad netmask")
- }
- if len(e.Address.To4()) != net.IPv4len {
- return nil, errors.New("dns: bad address")
- }
- ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8))
- needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
- b = append(b, ip[:needLength]...)
- case 2:
- if e.SourceNetmask > net.IPv6len*8 {
- return nil, errors.New("dns: bad netmask")
- }
- if len(e.Address) != net.IPv6len {
- return nil, errors.New("dns: bad address")
- }
- ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8))
- needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up
- b = append(b, ip[:needLength]...)
- default:
- return nil, errors.New("dns: bad address family")
- }
- return b, nil
-}
-
-func (e *EDNS0_SUBNET) unpack(b []byte) error {
- if len(b) < 4 {
- return ErrBuf
- }
- e.Family = binary.BigEndian.Uint16(b)
- e.SourceNetmask = b[2]
- e.SourceScope = b[3]
- switch e.Family {
- case 1:
- if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 {
- return errors.New("dns: bad netmask")
- }
- addr := make([]byte, net.IPv4len)
- for i := 0; i < net.IPv4len && 4+i < len(b); i++ {
- addr[i] = b[4+i]
- }
- e.Address = net.IPv4(addr[0], addr[1], addr[2], addr[3])
- case 2:
- if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 {
- return errors.New("dns: bad netmask")
- }
- addr := make([]byte, net.IPv6len)
- for i := 0; i < net.IPv6len && 4+i < len(b); i++ {
- addr[i] = b[4+i]
- }
- e.Address = net.IP{addr[0], addr[1], addr[2], addr[3], addr[4],
- addr[5], addr[6], addr[7], addr[8], addr[9], addr[10],
- addr[11], addr[12], addr[13], addr[14], addr[15]}
- default:
- return errors.New("dns: bad address family")
- }
- return nil
-}
-
-func (e *EDNS0_SUBNET) String() (s string) {
- if e.Address == nil {
- s = "<nil>"
- } else if e.Address.To4() != nil {
- s = e.Address.String()
- } else {
- s = "[" + e.Address.String() + "]"
- }
- s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope))
- return
-}
-
-// The EDNS0_COOKIE option is used to add a DNS Cookie to a message.
-//
-// o := new(dns.OPT)
-// o.Hdr.Name = "."
-// o.Hdr.Rrtype = dns.TypeOPT
-// e := new(dns.EDNS0_COOKIE)
-// e.Code = dns.EDNS0COOKIE
-// e.Cookie = "24a5ac.."
-// o.Option = append(o.Option, e)
-//
-// The Cookie field consists out of a client cookie (RFC 7873 Section 4), that is
-// always 8 bytes. It may then optionally be followed by the server cookie. The server
-// cookie is of variable length, 8 to a maximum of 32 bytes. In other words:
-//
-// cCookie := o.Cookie[:16]
-// sCookie := o.Cookie[16:]
-//
-// There is no guarantee that the Cookie string has a specific length.
-type EDNS0_COOKIE struct {
- Code uint16 // Always EDNS0COOKIE
- Cookie string // Hex-encoded cookie data
-}
-
-func (e *EDNS0_COOKIE) pack() ([]byte, error) {
- h, err := hex.DecodeString(e.Cookie)
- if err != nil {
- return nil, err
- }
- return h, nil
-}
-
-func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE }
-func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil }
-func (e *EDNS0_COOKIE) String() string { return e.Cookie }
-
-// The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set
-// an expiration on an update RR. This is helpful for clients that cannot clean
-// up after themselves. This is a draft RFC and more information can be found at
-// http://files.dns-sd.org/draft-sekar-dns-ul.txt
-//
-// o := new(dns.OPT)
-// o.Hdr.Name = "."
-// o.Hdr.Rrtype = dns.TypeOPT
-// e := new(dns.EDNS0_UL)
-// e.Code = dns.EDNS0UL
-// e.Lease = 120 // in seconds
-// o.Option = append(o.Option, e)
-type EDNS0_UL struct {
- Code uint16 // Always EDNS0UL
- Lease uint32
-}
-
-func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
-func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease), 10) }
-
-// Copied: http://golang.org/src/pkg/net/dnsmsg.go
-func (e *EDNS0_UL) pack() ([]byte, error) {
- b := make([]byte, 4)
- binary.BigEndian.PutUint32(b, e.Lease)
- return b, nil
-}
-
-func (e *EDNS0_UL) unpack(b []byte) error {
- if len(b) < 4 {
- return ErrBuf
- }
- e.Lease = binary.BigEndian.Uint32(b)
- return nil
-}
-
-// EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
-// Implemented for completeness, as the EDNS0 type code is assigned.
-type EDNS0_LLQ struct {
- Code uint16 // Always EDNS0LLQ
- Version uint16
- Opcode uint16
- Error uint16
- Id uint64
- LeaseLife uint32
-}
-
-func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
-
-func (e *EDNS0_LLQ) pack() ([]byte, error) {
- b := make([]byte, 18)
- binary.BigEndian.PutUint16(b[0:], e.Version)
- binary.BigEndian.PutUint16(b[2:], e.Opcode)
- binary.BigEndian.PutUint16(b[4:], e.Error)
- binary.BigEndian.PutUint64(b[6:], e.Id)
- binary.BigEndian.PutUint32(b[14:], e.LeaseLife)
- return b, nil
-}
-
-func (e *EDNS0_LLQ) unpack(b []byte) error {
- if len(b) < 18 {
- return ErrBuf
- }
- e.Version = binary.BigEndian.Uint16(b[0:])
- e.Opcode = binary.BigEndian.Uint16(b[2:])
- e.Error = binary.BigEndian.Uint16(b[4:])
- e.Id = binary.BigEndian.Uint64(b[6:])
- e.LeaseLife = binary.BigEndian.Uint32(b[14:])
- return nil
-}
-
-func (e *EDNS0_LLQ) String() string {
- s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) +
- " " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(uint64(e.Id), 10) +
- " " + strconv.FormatUint(uint64(e.LeaseLife), 10)
- return s
-}
-
-type EDNS0_DAU struct {
- Code uint16 // Always EDNS0DAU
- AlgCode []uint8
-}
-
-func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU }
-func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil }
-func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil }
-
-func (e *EDNS0_DAU) String() string {
- s := ""
- for i := 0; i < len(e.AlgCode); i++ {
- if a, ok := AlgorithmToString[e.AlgCode[i]]; ok {
- s += " " + a
- } else {
- s += " " + strconv.Itoa(int(e.AlgCode[i]))
- }
- }
- return s
-}
-
-type EDNS0_DHU struct {
- Code uint16 // Always EDNS0DHU
- AlgCode []uint8
-}
-
-func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU }
-func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil }
-func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil }
-
-func (e *EDNS0_DHU) String() string {
- s := ""
- for i := 0; i < len(e.AlgCode); i++ {
- if a, ok := HashToString[e.AlgCode[i]]; ok {
- s += " " + a
- } else {
- s += " " + strconv.Itoa(int(e.AlgCode[i]))
- }
- }
- return s
-}
-
-type EDNS0_N3U struct {
- Code uint16 // Always EDNS0N3U
- AlgCode []uint8
-}
-
-func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U }
-func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil }
-func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil }
-
-func (e *EDNS0_N3U) String() string {
- // Re-use the hash map
- s := ""
- for i := 0; i < len(e.AlgCode); i++ {
- if a, ok := HashToString[e.AlgCode[i]]; ok {
- s += " " + a
- } else {
- s += " " + strconv.Itoa(int(e.AlgCode[i]))
- }
- }
- return s
-}
-
-type EDNS0_EXPIRE struct {
- Code uint16 // Always EDNS0EXPIRE
- Expire uint32
-}
-
-func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
-func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) }
-
-func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
- b := make([]byte, 4)
- b[0] = byte(e.Expire >> 24)
- b[1] = byte(e.Expire >> 16)
- b[2] = byte(e.Expire >> 8)
- b[3] = byte(e.Expire)
- return b, nil
-}
-
-func (e *EDNS0_EXPIRE) unpack(b []byte) error {
- if len(b) < 4 {
- return ErrBuf
- }
- e.Expire = binary.BigEndian.Uint32(b)
- return nil
-}
-
-// The EDNS0_LOCAL option is used for local/experimental purposes. The option
-// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
-// (RFC6891), although any unassigned code can actually be used. The content of
-// the option is made available in Data, unaltered.
-// Basic use pattern for creating a local option:
-//
-// o := new(dns.OPT)
-// o.Hdr.Name = "."
-// o.Hdr.Rrtype = dns.TypeOPT
-// e := new(dns.EDNS0_LOCAL)
-// e.Code = dns.EDNS0LOCALSTART
-// e.Data = []byte{72, 82, 74}
-// o.Option = append(o.Option, e)
-type EDNS0_LOCAL struct {
- Code uint16
- Data []byte
-}
-
-func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
-func (e *EDNS0_LOCAL) String() string {
- return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
-}
-
-func (e *EDNS0_LOCAL) pack() ([]byte, error) {
- b := make([]byte, len(e.Data))
- copied := copy(b, e.Data)
- if copied != len(e.Data) {
- return nil, ErrBuf
- }
- return b, nil
-}
-
-func (e *EDNS0_LOCAL) unpack(b []byte) error {
- e.Data = make([]byte, len(b))
- copied := copy(e.Data, b)
- if copied != len(b) {
- return ErrBuf
- }
- return nil
-}
-
-// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep
-// the TCP connection alive. See RFC 7828.
-type EDNS0_TCP_KEEPALIVE struct {
- Code uint16 // Always EDNSTCPKEEPALIVE
- Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present;
- Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order.
-}
-
-func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE }
-
-func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
- if e.Timeout != 0 && e.Length != 2 {
- return nil, errors.New("dns: timeout specified but length is not 2")
- }
- if e.Timeout == 0 && e.Length != 0 {
- return nil, errors.New("dns: timeout not specified but length is not 0")
- }
- b := make([]byte, 4+e.Length)
- binary.BigEndian.PutUint16(b[0:], e.Code)
- binary.BigEndian.PutUint16(b[2:], e.Length)
- if e.Length == 2 {
- binary.BigEndian.PutUint16(b[4:], e.Timeout)
- }
- return b, nil
-}
-
-func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
- if len(b) < 4 {
- return ErrBuf
- }
- e.Length = binary.BigEndian.Uint16(b[2:4])
- if e.Length != 0 && e.Length != 2 {
- return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10))
- }
- if e.Length == 2 {
- if len(b) < 6 {
- return ErrBuf
- }
- e.Timeout = binary.BigEndian.Uint16(b[4:6])
- }
- return nil
-}
-
-func (e *EDNS0_TCP_KEEPALIVE) String() (s string) {
- s = "use tcp keep-alive"
- if e.Length == 0 {
- s += ", timeout omitted"
- } else {
- s += fmt.Sprintf(", timeout %dms", e.Timeout*100)
- }
- return
-}
diff --git a/vendor/github.com/miekg/dns/edns_test.go b/vendor/github.com/miekg/dns/edns_test.go
deleted file mode 100644
index c290b0c8a..000000000
--- a/vendor/github.com/miekg/dns/edns_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package dns
-
-import "testing"
-
-func TestOPTTtl(t *testing.T) {
- e := &OPT{}
- e.Hdr.Name = "."
- e.Hdr.Rrtype = TypeOPT
-
- // verify the default setting of DO=0
- if e.Do() {
- t.Errorf("DO bit should be zero")
- }
-
- // There are 6 possible invocations of SetDo():
- //
- // 1. Starting with DO=0, using SetDo()
- // 2. Starting with DO=0, using SetDo(true)
- // 3. Starting with DO=0, using SetDo(false)
- // 4. Starting with DO=1, using SetDo()
- // 5. Starting with DO=1, using SetDo(true)
- // 6. Starting with DO=1, using SetDo(false)
-
- // verify that invoking SetDo() sets DO=1 (TEST #1)
- e.SetDo()
- if !e.Do() {
- t.Errorf("DO bit should be non-zero")
- }
- // verify that using SetDo(true) works when DO=1 (TEST #5)
- e.SetDo(true)
- if !e.Do() {
- t.Errorf("DO bit should still be non-zero")
- }
- // verify that we can use SetDo(false) to set DO=0 (TEST #6)
- e.SetDo(false)
- if e.Do() {
- t.Errorf("DO bit should be zero")
- }
- // verify that if we call SetDo(false) when DO=0 that it is unchanged (TEST #3)
- e.SetDo(false)
- if e.Do() {
- t.Errorf("DO bit should still be zero")
- }
- // verify that using SetDo(true) works for DO=0 (TEST #2)
- e.SetDo(true)
- if !e.Do() {
- t.Errorf("DO bit should be non-zero")
- }
- // verify that using SetDo() works for DO=1 (TEST #4)
- e.SetDo()
- if !e.Do() {
- t.Errorf("DO bit should be non-zero")
- }
-
- if e.Version() != 0 {
- t.Errorf("version should be non-zero")
- }
-
- e.SetVersion(42)
- if e.Version() != 42 {
- t.Errorf("set 42, expected %d, got %d", 42, e.Version())
- }
-
- e.SetExtendedRcode(42)
- if e.ExtendedRcode() != 42 {
- t.Errorf("set 42, expected %d, got %d", 42-15, e.ExtendedRcode())
- }
-}
diff --git a/vendor/github.com/miekg/dns/example_test.go b/vendor/github.com/miekg/dns/example_test.go
deleted file mode 100644
index 64c14962c..000000000
--- a/vendor/github.com/miekg/dns/example_test.go
+++ /dev/null
@@ -1,146 +0,0 @@
-package dns_test
-
-import (
- "errors"
- "fmt"
- "log"
- "net"
-
- "github.com/miekg/dns"
-)
-
-// Retrieve the MX records for miek.nl.
-func ExampleMX() {
- config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
- c := new(dns.Client)
- m := new(dns.Msg)
- m.SetQuestion("miek.nl.", dns.TypeMX)
- m.RecursionDesired = true
- r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
- if err != nil {
- return
- }
- if r.Rcode != dns.RcodeSuccess {
- return
- }
- for _, a := range r.Answer {
- if mx, ok := a.(*dns.MX); ok {
- fmt.Printf("%s\n", mx.String())
- }
- }
-}
-
-// Retrieve the DNSKEY records of a zone and convert them
-// to DS records for SHA1, SHA256 and SHA384.
-func ExampleDS() {
- config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
- c := new(dns.Client)
- m := new(dns.Msg)
- zone := "miek.nl"
- m.SetQuestion(dns.Fqdn(zone), dns.TypeDNSKEY)
- m.SetEdns0(4096, true)
- r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
- if err != nil {
- return
- }
- if r.Rcode != dns.RcodeSuccess {
- return
- }
- for _, k := range r.Answer {
- if key, ok := k.(*dns.DNSKEY); ok {
- for _, alg := range []uint8{dns.SHA1, dns.SHA256, dns.SHA384} {
- fmt.Printf("%s; %d\n", key.ToDS(alg).String(), key.Flags)
- }
- }
- }
-}
-
-const TypeAPAIR = 0x0F99
-
-type APAIR struct {
- addr [2]net.IP
-}
-
-func NewAPAIR() dns.PrivateRdata { return new(APAIR) }
-
-func (rd *APAIR) String() string { return rd.addr[0].String() + " " + rd.addr[1].String() }
-func (rd *APAIR) Parse(txt []string) error {
- if len(txt) != 2 {
- return errors.New("two addresses required for APAIR")
- }
- for i, s := range txt {
- ip := net.ParseIP(s)
- if ip == nil {
- return errors.New("invalid IP in APAIR text representation")
- }
- rd.addr[i] = ip
- }
- return nil
-}
-
-func (rd *APAIR) Pack(buf []byte) (int, error) {
- b := append([]byte(rd.addr[0]), []byte(rd.addr[1])...)
- n := copy(buf, b)
- if n != len(b) {
- return n, dns.ErrBuf
- }
- return n, nil
-}
-
-func (rd *APAIR) Unpack(buf []byte) (int, error) {
- ln := net.IPv4len * 2
- if len(buf) != ln {
- return 0, errors.New("invalid length of APAIR rdata")
- }
- cp := make([]byte, ln)
- copy(cp, buf) // clone bytes to use them in IPs
-
- rd.addr[0] = net.IP(cp[:3])
- rd.addr[1] = net.IP(cp[4:])
-
- return len(buf), nil
-}
-
-func (rd *APAIR) Copy(dest dns.PrivateRdata) error {
- cp := make([]byte, rd.Len())
- _, err := rd.Pack(cp)
- if err != nil {
- return err
- }
-
- d := dest.(*APAIR)
- d.addr[0] = net.IP(cp[:3])
- d.addr[1] = net.IP(cp[4:])
- return nil
-}
-
-func (rd *APAIR) Len() int {
- return net.IPv4len * 2
-}
-
-func ExamplePrivateHandle() {
- dns.PrivateHandle("APAIR", TypeAPAIR, NewAPAIR)
- defer dns.PrivateHandleRemove(TypeAPAIR)
-
- rr, err := dns.NewRR("miek.nl. APAIR (1.2.3.4 1.2.3.5)")
- if err != nil {
- log.Fatal("could not parse APAIR record: ", err)
- }
- fmt.Println(rr)
- // Output: miek.nl. 3600 IN APAIR 1.2.3.4 1.2.3.5
-
- m := new(dns.Msg)
- m.Id = 12345
- m.SetQuestion("miek.nl.", TypeAPAIR)
- m.Answer = append(m.Answer, rr)
-
- fmt.Println(m)
- // ;; opcode: QUERY, status: NOERROR, id: 12345
- // ;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
- //
- // ;; QUESTION SECTION:
- // ;miek.nl. IN APAIR
- //
- // ;; ANSWER SECTION:
- // miek.nl. 3600 IN APAIR 1.2.3.4 1.2.3.5
-}
diff --git a/vendor/github.com/miekg/dns/format.go b/vendor/github.com/miekg/dns/format.go
deleted file mode 100644
index 3f5303c20..000000000
--- a/vendor/github.com/miekg/dns/format.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package dns
-
-import (
- "net"
- "reflect"
- "strconv"
-)
-
-// NumField returns the number of rdata fields r has.
-func NumField(r RR) int {
- return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header
-}
-
-// Field returns the rdata field i as a string. Fields are indexed starting from 1.
-// RR types that holds slice data, for instance the NSEC type bitmap will return a single
-// string where the types are concatenated using a space.
-// Accessing non existing fields will cause a panic.
-func Field(r RR, i int) string {
- if i == 0 {
- return ""
- }
- d := reflect.ValueOf(r).Elem().Field(i)
- switch k := d.Kind(); k {
- case reflect.String:
- return d.String()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return strconv.FormatInt(d.Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return strconv.FormatUint(d.Uint(), 10)
- case reflect.Slice:
- switch reflect.ValueOf(r).Elem().Type().Field(i).Tag {
- case `dns:"a"`:
- // TODO(miek): Hmm store this as 16 bytes
- if d.Len() < net.IPv6len {
- return net.IPv4(byte(d.Index(0).Uint()),
- byte(d.Index(1).Uint()),
- byte(d.Index(2).Uint()),
- byte(d.Index(3).Uint())).String()
- }
- return net.IPv4(byte(d.Index(12).Uint()),
- byte(d.Index(13).Uint()),
- byte(d.Index(14).Uint()),
- byte(d.Index(15).Uint())).String()
- case `dns:"aaaa"`:
- return net.IP{
- byte(d.Index(0).Uint()),
- byte(d.Index(1).Uint()),
- byte(d.Index(2).Uint()),
- byte(d.Index(3).Uint()),
- byte(d.Index(4).Uint()),
- byte(d.Index(5).Uint()),
- byte(d.Index(6).Uint()),
- byte(d.Index(7).Uint()),
- byte(d.Index(8).Uint()),
- byte(d.Index(9).Uint()),
- byte(d.Index(10).Uint()),
- byte(d.Index(11).Uint()),
- byte(d.Index(12).Uint()),
- byte(d.Index(13).Uint()),
- byte(d.Index(14).Uint()),
- byte(d.Index(15).Uint()),
- }.String()
- case `dns:"nsec"`:
- if d.Len() == 0 {
- return ""
- }
- s := Type(d.Index(0).Uint()).String()
- for i := 1; i < d.Len(); i++ {
- s += " " + Type(d.Index(i).Uint()).String()
- }
- return s
- default:
- // if it does not have a tag its a string slice
- fallthrough
- case `dns:"txt"`:
- if d.Len() == 0 {
- return ""
- }
- s := d.Index(0).String()
- for i := 1; i < d.Len(); i++ {
- s += " " + d.Index(i).String()
- }
- return s
- }
- }
- return ""
-}
diff --git a/vendor/github.com/miekg/dns/fuzz_test.go b/vendor/github.com/miekg/dns/fuzz_test.go
deleted file mode 100644
index 255869730..000000000
--- a/vendor/github.com/miekg/dns/fuzz_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package dns
-
-import "testing"
-
-func TestFuzzString(t *testing.T) {
- testcases := []string{"", " MINFO ", " RP ", " NSEC 0 0", " \" NSEC 0 0\"", " \" MINFO \"",
- ";a ", ";a����������",
- " NSAP O ", " NSAP N ",
- " TYPE4 TYPE6a789a3bc0045c8a5fb42c7d1bd998f5444 IN 9579b47d46817afbd17273e6",
- " TYPE45 3 3 4147994 TYPE\\(\\)\\)\\(\\)\\(\\(\\)\\(\\)\\)\\)\\(\\)\\(\\)\\(\\(\\R 948\"\")\\(\\)\\)\\)\\(\\ ",
- "$GENERATE 0-3 ${441189,5039418474430,o}",
- "$INCLUDE 00 TYPE00000000000n ",
- "$INCLUDE PE4 TYPE061463623/727071511 \\(\\)\\$GENERATE 6-462/0",
- }
- for i, tc := range testcases {
- rr, err := NewRR(tc)
- if err == nil {
- // rr can be nil because we can (for instance) just parse a comment
- if rr == nil {
- continue
- }
- t.Fatalf("parsed mailformed RR %d: %s", i, rr.String())
- }
- }
-}
diff --git a/vendor/github.com/miekg/dns/generate.go b/vendor/github.com/miekg/dns/generate.go
deleted file mode 100644
index e4481a4b0..000000000
--- a/vendor/github.com/miekg/dns/generate.go
+++ /dev/null
@@ -1,159 +0,0 @@
-package dns
-
-import (
- "bytes"
- "errors"
- "fmt"
- "strconv"
- "strings"
-)
-
-// Parse the $GENERATE statement as used in BIND9 zones.
-// See http://www.zytrax.com/books/dns/ch8/generate.html for instance.
-// We are called after '$GENERATE '. After which we expect:
-// * the range (12-24/2)
-// * lhs (ownername)
-// * [[ttl][class]]
-// * type
-// * rhs (rdata)
-// But we are lazy here, only the range is parsed *all* occurrences
-// of $ after that are interpreted.
-// Any error are returned as a string value, the empty string signals
-// "no error".
-func generate(l lex, c chan lex, t chan *Token, o string) string {
- step := 1
- if i := strings.IndexAny(l.token, "/"); i != -1 {
- if i+1 == len(l.token) {
- return "bad step in $GENERATE range"
- }
- if s, err := strconv.Atoi(l.token[i+1:]); err == nil {
- if s < 0 {
- return "bad step in $GENERATE range"
- }
- step = s
- } else {
- return "bad step in $GENERATE range"
- }
- l.token = l.token[:i]
- }
- sx := strings.SplitN(l.token, "-", 2)
- if len(sx) != 2 {
- return "bad start-stop in $GENERATE range"
- }
- start, err := strconv.Atoi(sx[0])
- if err != nil {
- return "bad start in $GENERATE range"
- }
- end, err := strconv.Atoi(sx[1])
- if err != nil {
- return "bad stop in $GENERATE range"
- }
- if end < 0 || start < 0 || end < start {
- return "bad range in $GENERATE range"
- }
-
- <-c // _BLANK
- // Create a complete new string, which we then parse again.
- s := ""
-BuildRR:
- l = <-c
- if l.value != zNewline && l.value != zEOF {
- s += l.token
- goto BuildRR
- }
- for i := start; i <= end; i += step {
- var (
- escape bool
- dom bytes.Buffer
- mod string
- err error
- offset int
- )
-
- for j := 0; j < len(s); j++ { // No 'range' because we need to jump around
- switch s[j] {
- case '\\':
- if escape {
- dom.WriteByte('\\')
- escape = false
- continue
- }
- escape = true
- case '$':
- mod = "%d"
- offset = 0
- if escape {
- dom.WriteByte('$')
- escape = false
- continue
- }
- escape = false
- if j+1 >= len(s) { // End of the string
- dom.WriteString(fmt.Sprintf(mod, i+offset))
- continue
- } else {
- if s[j+1] == '$' {
- dom.WriteByte('$')
- j++
- continue
- }
- }
- // Search for { and }
- if s[j+1] == '{' { // Modifier block
- sep := strings.Index(s[j+2:], "}")
- if sep == -1 {
- return "bad modifier in $GENERATE"
- }
- mod, offset, err = modToPrintf(s[j+2 : j+2+sep])
- if err != nil {
- return err.Error()
- }
- j += 2 + sep // Jump to it
- }
- dom.WriteString(fmt.Sprintf(mod, i+offset))
- default:
- if escape { // Pretty useless here
- escape = false
- continue
- }
- dom.WriteByte(s[j])
- }
- }
- // Re-parse the RR and send it on the current channel t
- rx, err := NewRR("$ORIGIN " + o + "\n" + dom.String())
- if err != nil {
- return err.Error()
- }
- t <- &Token{RR: rx}
- // Its more efficient to first built the rrlist and then parse it in
- // one go! But is this a problem?
- }
- return ""
-}
-
-// Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
-func modToPrintf(s string) (string, int, error) {
- xs := strings.SplitN(s, ",", 3)
- if len(xs) != 3 {
- return "", 0, errors.New("bad modifier in $GENERATE")
- }
- // xs[0] is offset, xs[1] is width, xs[2] is base
- if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" {
- return "", 0, errors.New("bad base in $GENERATE")
- }
- offset, err := strconv.Atoi(xs[0])
- if err != nil || offset > 255 {
- return "", 0, errors.New("bad offset in $GENERATE")
- }
- width, err := strconv.Atoi(xs[1])
- if err != nil || width > 255 {
- return "", offset, errors.New("bad width in $GENERATE")
- }
- switch {
- case width < 0:
- return "", offset, errors.New("bad width in $GENERATE")
- case width == 0:
- return "%" + xs[1] + xs[2], offset, nil
- }
- return "%0" + xs[1] + xs[2], offset, nil
-}
diff --git a/vendor/github.com/miekg/dns/issue_test.go b/vendor/github.com/miekg/dns/issue_test.go
deleted file mode 100644
index 265ad56c0..000000000
--- a/vendor/github.com/miekg/dns/issue_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package dns
-
-// Tests that solve that an specific issue.
-
-import (
- "strings"
- "testing"
-)
-
-func TestTCPRtt(t *testing.T) {
- m := new(Msg)
- m.RecursionDesired = true
- m.SetQuestion("example.org.", TypeA)
-
- c := &Client{}
- for _, proto := range []string{"udp", "tcp"} {
- c.Net = proto
- _, rtt, err := c.Exchange(m, "8.8.4.4:53")
- if err != nil {
- t.Fatal(err)
- }
- if rtt == 0 {
- t.Fatalf("expecting non zero rtt %s, got zero", c.Net)
- }
- }
-}
-
-func TestNSEC3MissingSalt(t *testing.T) {
- rr, err := NewRR("ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 aabbccdd K8UDEMVP1J2F7EG6JEBPS17VP3N8I58H")
- if err != nil {
- t.Fatalf("failed to parse example rr: %s", err)
- }
- m := new(Msg)
- m.Answer = []RR{rr}
- mb, err := m.Pack()
- if err != nil {
- t.Fatalf("expected to pack message. err: %s", err)
- }
- if err := m.Unpack(mb); err != nil {
- t.Fatalf("expected to unpack message. missing salt? err: %s", err)
- }
- in := rr.(*NSEC3).Salt
- out := m.Answer[0].(*NSEC3).Salt
- if in != out {
- t.Fatalf("expected salts to match. packed: `%s`. returned: `%s`", in, out)
- }
-}
-
-func TestNSEC3MixedNextDomain(t *testing.T) {
- rr, err := NewRR("ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 - k8udemvp1j2f7eg6jebps17vp3n8i58h")
- if err != nil {
- t.Fatalf("failed to parse example rr: %s", err)
- }
- m := new(Msg)
- m.Answer = []RR{rr}
- mb, err := m.Pack()
- if err != nil {
- t.Fatalf("expected to pack message. err: %s", err)
- }
- if err := m.Unpack(mb); err != nil {
- t.Fatalf("expected to unpack message. err: %s", err)
- }
- in := strings.ToUpper(rr.(*NSEC3).NextDomain)
- out := m.Answer[0].(*NSEC3).NextDomain
- if in != out {
- t.Fatalf("expected round trip to produce NextDomain `%s`, instead `%s`", in, out)
- }
-}
diff --git a/vendor/github.com/miekg/dns/labels.go b/vendor/github.com/miekg/dns/labels.go
deleted file mode 100644
index 9538d9c3a..000000000
--- a/vendor/github.com/miekg/dns/labels.go
+++ /dev/null
@@ -1,171 +0,0 @@
-package dns
-
-import "strings"
-
-// Holds a bunch of helper functions for dealing with labels.
-
-// SplitDomainName splits a name string into it's labels.
-// www.miek.nl. returns []string{"www", "miek", "nl"}
-// .www.miek.nl. returns []string{"", "www", "miek", "nl"},
-// The root label (.) returns nil. Note that using
-// strings.Split(s) will work in most cases, but does not handle
-// escaped dots (\.) for instance.
-// s must be a syntactically valid domain name, see IsDomainName.
-func SplitDomainName(s string) (labels []string) {
- if len(s) == 0 {
- return nil
- }
- fqdnEnd := 0 // offset of the final '.' or the length of the name
- idx := Split(s)
- begin := 0
- if s[len(s)-1] == '.' {
- fqdnEnd = len(s) - 1
- } else {
- fqdnEnd = len(s)
- }
-
- switch len(idx) {
- case 0:
- return nil
- case 1:
- // no-op
- default:
- end := 0
- for i := 1; i < len(idx); i++ {
- end = idx[i]
- labels = append(labels, s[begin:end-1])
- begin = end
- }
- }
-
- labels = append(labels, s[begin:fqdnEnd])
- return labels
-}
-
-// CompareDomainName compares the names s1 and s2 and
-// returns how many labels they have in common starting from the *right*.
-// The comparison stops at the first inequality. The names are not downcased
-// before the comparison.
-//
-// www.miek.nl. and miek.nl. have two labels in common: miek and nl
-// www.miek.nl. and www.bla.nl. have one label in common: nl
-//
-// s1 and s2 must be syntactically valid domain names.
-func CompareDomainName(s1, s2 string) (n int) {
- s1, s2 = strings.ToLower(s1), strings.ToLower(s2)
- s1 = Fqdn(s1)
- s2 = Fqdn(s2)
- l1 := Split(s1)
- l2 := Split(s2)
-
- // the first check: root label
- if l1 == nil || l2 == nil {
- return
- }
-
- j1 := len(l1) - 1 // end
- i1 := len(l1) - 2 // start
- j2 := len(l2) - 1
- i2 := len(l2) - 2
- // the second check can be done here: last/only label
- // before we fall through into the for-loop below
- if s1[l1[j1]:] == s2[l2[j2]:] {
- n++
- } else {
- return
- }
- for {
- if i1 < 0 || i2 < 0 {
- break
- }
- if s1[l1[i1]:l1[j1]] == s2[l2[i2]:l2[j2]] {
- n++
- } else {
- break
- }
- j1--
- i1--
- j2--
- i2--
- }
- return
-}
-
-// CountLabel counts the the number of labels in the string s.
-// s must be a syntactically valid domain name.
-func CountLabel(s string) (labels int) {
- if s == "." {
- return
- }
- off := 0
- end := false
- for {
- off, end = NextLabel(s, off)
- labels++
- if end {
- return
- }
- }
-}
-
-// Split splits a name s into its label indexes.
-// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}.
-// The root name (.) returns nil. Also see SplitDomainName.
-// s must be a syntactically valid domain name.
-func Split(s string) []int {
- if s == "." {
- return nil
- }
- idx := make([]int, 1, 3)
- off := 0
- end := false
-
- for {
- off, end = NextLabel(s, off)
- if end {
- return idx
- }
- idx = append(idx, off)
- }
-}
-
-// NextLabel returns the index of the start of the next label in the
-// string s starting at offset.
-// The bool end is true when the end of the string has been reached.
-// Also see PrevLabel.
-func NextLabel(s string, offset int) (i int, end bool) {
- quote := false
- for i = offset; i < len(s)-1; i++ {
- switch s[i] {
- case '\\':
- quote = !quote
- default:
- quote = false
- case '.':
- if quote {
- quote = !quote
- continue
- }
- return i + 1, false
- }
- }
- return i + 1, true
-}
-
-// PrevLabel returns the index of the label when starting from the right and
-// jumping n labels to the left.
-// The bool start is true when the start of the string has been overshot.
-// Also see NextLabel.
-func PrevLabel(s string, n int) (i int, start bool) {
- if n == 0 {
- return len(s), false
- }
- lab := Split(s)
- if lab == nil {
- return 0, true
- }
- if n > len(lab) {
- return 0, true
- }
- return lab[len(lab)-n], false
-}
diff --git a/vendor/github.com/miekg/dns/labels_test.go b/vendor/github.com/miekg/dns/labels_test.go
deleted file mode 100644
index 9875d6cd9..000000000
--- a/vendor/github.com/miekg/dns/labels_test.go
+++ /dev/null
@@ -1,203 +0,0 @@
-package dns
-
-import "testing"
-
-func TestCompareDomainName(t *testing.T) {
- s1 := "www.miek.nl."
- s2 := "miek.nl."
- s3 := "www.bla.nl."
- s4 := "nl.www.bla."
- s5 := "nl"
- s6 := "miek.nl"
-
- if CompareDomainName(s1, s2) != 2 {
- t.Errorf("%s with %s should be %d", s1, s2, 2)
- }
- if CompareDomainName(s1, s3) != 1 {
- t.Errorf("%s with %s should be %d", s1, s3, 1)
- }
- if CompareDomainName(s3, s4) != 0 {
- t.Errorf("%s with %s should be %d", s3, s4, 0)
- }
- // Non qualified tests
- if CompareDomainName(s1, s5) != 1 {
- t.Errorf("%s with %s should be %d", s1, s5, 1)
- }
- if CompareDomainName(s1, s6) != 2 {
- t.Errorf("%s with %s should be %d", s1, s5, 2)
- }
-
- if CompareDomainName(s1, ".") != 0 {
- t.Errorf("%s with %s should be %d", s1, s5, 0)
- }
- if CompareDomainName(".", ".") != 0 {
- t.Errorf("%s with %s should be %d", ".", ".", 0)
- }
- if CompareDomainName("test.com.", "TEST.COM.") != 2 {
- t.Errorf("test.com. and TEST.COM. should be an exact match")
- }
-}
-
-func TestSplit(t *testing.T) {
- splitter := map[string]int{
- "www.miek.nl.": 3,
- "www.miek.nl": 3,
- "www..miek.nl": 4,
- `www\.miek.nl.`: 2,
- `www\\.miek.nl.`: 3,
- ".": 0,
- "nl.": 1,
- "nl": 1,
- "com.": 1,
- ".com.": 2,
- }
- for s, i := range splitter {
- if x := len(Split(s)); x != i {
- t.Errorf("labels should be %d, got %d: %s %v", i, x, s, Split(s))
- } else {
- t.Logf("%s %v", s, Split(s))
- }
- }
-}
-
-func TestSplit2(t *testing.T) {
- splitter := map[string][]int{
- "www.miek.nl.": {0, 4, 9},
- "www.miek.nl": {0, 4, 9},
- "nl": {0},
- }
- for s, i := range splitter {
- x := Split(s)
- switch len(i) {
- case 1:
- if x[0] != i[0] {
- t.Errorf("labels should be %v, got %v: %s", i, x, s)
- }
- default:
- if x[0] != i[0] || x[1] != i[1] || x[2] != i[2] {
- t.Errorf("labels should be %v, got %v: %s", i, x, s)
- }
- }
- }
-}
-
-func TestPrevLabel(t *testing.T) {
- type prev struct {
- string
- int
- }
- prever := map[prev]int{
- prev{"www.miek.nl.", 0}: 12,
- prev{"www.miek.nl.", 1}: 9,
- prev{"www.miek.nl.", 2}: 4,
-
- prev{"www.miek.nl", 0}: 11,
- prev{"www.miek.nl", 1}: 9,
- prev{"www.miek.nl", 2}: 4,
-
- prev{"www.miek.nl.", 5}: 0,
- prev{"www.miek.nl", 5}: 0,
-
- prev{"www.miek.nl.", 3}: 0,
- prev{"www.miek.nl", 3}: 0,
- }
- for s, i := range prever {
- x, ok := PrevLabel(s.string, s.int)
- if i != x {
- t.Errorf("label should be %d, got %d, %t: preving %d, %s", i, x, ok, s.int, s.string)
- }
- }
-}
-
-func TestCountLabel(t *testing.T) {
- splitter := map[string]int{
- "www.miek.nl.": 3,
- "www.miek.nl": 3,
- "nl": 1,
- ".": 0,
- }
- for s, i := range splitter {
- x := CountLabel(s)
- if x != i {
- t.Errorf("CountLabel should have %d, got %d", i, x)
- }
- }
-}
-
-func TestSplitDomainName(t *testing.T) {
- labels := map[string][]string{
- "miek.nl": {"miek", "nl"},
- ".": nil,
- "www.miek.nl.": {"www", "miek", "nl"},
- "www.miek.nl": {"www", "miek", "nl"},
- "www..miek.nl": {"www", "", "miek", "nl"},
- `www\.miek.nl`: {`www\.miek`, "nl"},
- `www\\.miek.nl`: {`www\\`, "miek", "nl"},
- ".www.miek.nl.": {"", "www", "miek", "nl"},
- }
-domainLoop:
- for domain, splits := range labels {
- parts := SplitDomainName(domain)
- if len(parts) != len(splits) {
- t.Errorf("SplitDomainName returned %v for %s, expected %v", parts, domain, splits)
- continue domainLoop
- }
- for i := range parts {
- if parts[i] != splits[i] {
- t.Errorf("SplitDomainName returned %v for %s, expected %v", parts, domain, splits)
- continue domainLoop
- }
- }
- }
-}
-
-func TestIsDomainName(t *testing.T) {
- type ret struct {
- ok bool
- lab int
- }
- names := map[string]*ret{
- "..": {false, 1},
- "@.": {true, 1},
- "www.example.com": {true, 3},
- "www.e%ample.com": {true, 3},
- "www.example.com.": {true, 3},
- "mi\\k.nl.": {true, 2},
- "mi\\k.nl": {true, 2},
- }
- for d, ok := range names {
- l, k := IsDomainName(d)
- if ok.ok != k || ok.lab != l {
- t.Errorf(" got %v %d for %s ", k, l, d)
- t.Errorf("have %v %d for %s ", ok.ok, ok.lab, d)
- }
- }
-}
-
-func BenchmarkSplitLabels(b *testing.B) {
- for i := 0; i < b.N; i++ {
- Split("www.example.com")
- }
-}
-
-func BenchmarkLenLabels(b *testing.B) {
- for i := 0; i < b.N; i++ {
- CountLabel("www.example.com")
- }
-}
-
-func BenchmarkCompareLabels(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- CompareDomainName("www.example.com", "aa.example.com")
- }
-}
-
-func BenchmarkIsSubDomain(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- IsSubDomain("www.example.com", "aa.example.com")
- IsSubDomain("example.com", "aa.example.com")
- IsSubDomain("miek.nl", "aa.example.com")
- }
-}
diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go
deleted file mode 100644
index 605fe6c5c..000000000
--- a/vendor/github.com/miekg/dns/msg.go
+++ /dev/null
@@ -1,1159 +0,0 @@
-// DNS packet assembly, see RFC 1035. Converting from - Unpack() -
-// and to - Pack() - wire format.
-// All the packers and unpackers take a (msg []byte, off int)
-// and return (off1 int, ok bool). If they return ok==false, they
-// also return off1==len(msg), so that the next unpacker will
-// also fail. This lets us avoid checks of ok until the end of a
-// packing sequence.
-
-package dns
-
-//go:generate go run msg_generate.go
-//go:generate go run compress_generate.go
-
-import (
- crand "crypto/rand"
- "encoding/binary"
- "fmt"
- "math/big"
- "math/rand"
- "strconv"
- "sync"
-)
-
-const (
- maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
- maxDomainNameWireOctets = 255 // See RFC 1035 section 2.3.4
-)
-
-var (
- ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm.
- ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication.
- ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message.
- ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized.
- ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ...
- ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot.
- ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID.
- ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid.
- ErrKey error = &Error{err: "bad key"}
- ErrKeySize error = &Error{err: "bad key size"}
- ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)}
- ErrNoSig error = &Error{err: "no signature found"}
- ErrPrivKey error = &Error{err: "bad private key"}
- ErrRcode error = &Error{err: "bad rcode"}
- ErrRdata error = &Error{err: "bad rdata"}
- ErrRRset error = &Error{err: "bad rrset"}
- ErrSecret error = &Error{err: "no secrets defined"}
- ErrShortRead error = &Error{err: "short read"}
- ErrSig error = &Error{err: "bad signature"} // ErrSig indicates that a signature can not be cryptographically validated.
- ErrSoa error = &Error{err: "no SOA"} // ErrSOA indicates that no SOA RR was seen when doing zone transfers.
- ErrTime error = &Error{err: "bad time"} // ErrTime indicates a timing error in TSIG authentication.
- ErrTruncated error = &Error{err: "failed to unpack truncated message"} // ErrTruncated indicates that we failed to unpack a truncated message. We unpacked as much as we had so Msg can still be used, if desired.
-)
-
-// Id by default, returns a 16 bits random number to be used as a
-// message id. The random provided should be good enough. This being a
-// variable the function can be reassigned to a custom function.
-// For instance, to make it return a static value:
-//
-// dns.Id = func() uint16 { return 3 }
-var Id func() uint16 = id
-
-var (
- idLock sync.Mutex
- idRand *rand.Rand
-)
-
-// id returns a 16 bits random number to be used as a
-// message id. The random provided should be good enough.
-func id() uint16 {
- idLock.Lock()
-
- if idRand == nil {
- // This (partially) works around
- // https://github.com/golang/go/issues/11833 by only
- // seeding idRand upon the first call to id.
-
- var seed int64
- var buf [8]byte
-
- if _, err := crand.Read(buf[:]); err == nil {
- seed = int64(binary.LittleEndian.Uint64(buf[:]))
- } else {
- seed = rand.Int63()
- }
-
- idRand = rand.New(rand.NewSource(seed))
- }
-
- // The call to idRand.Uint32 must be within the
- // mutex lock because *rand.Rand is not safe for
- // concurrent use.
- //
- // There is no added performance overhead to calling
- // idRand.Uint32 inside a mutex lock over just
- // calling rand.Uint32 as the global math/rand rng
- // is internally protected by a sync.Mutex.
- id := uint16(idRand.Uint32())
-
- idLock.Unlock()
- return id
-}
-
-// MsgHdr is a a manually-unpacked version of (id, bits).
-type MsgHdr struct {
- Id uint16
- Response bool
- Opcode int
- Authoritative bool
- Truncated bool
- RecursionDesired bool
- RecursionAvailable bool
- Zero bool
- AuthenticatedData bool
- CheckingDisabled bool
- Rcode int
-}
-
-// Msg contains the layout of a DNS message.
-type Msg struct {
- MsgHdr
- Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format.
- Question []Question // Holds the RR(s) of the question section.
- Answer []RR // Holds the RR(s) of the answer section.
- Ns []RR // Holds the RR(s) of the authority section.
- Extra []RR // Holds the RR(s) of the additional section.
-}
-
-// ClassToString is a maps Classes to strings for each CLASS wire type.
-var ClassToString = map[uint16]string{
- ClassINET: "IN",
- ClassCSNET: "CS",
- ClassCHAOS: "CH",
- ClassHESIOD: "HS",
- ClassNONE: "NONE",
- ClassANY: "ANY",
-}
-
-// OpcodeToString maps Opcodes to strings.
-var OpcodeToString = map[int]string{
- OpcodeQuery: "QUERY",
- OpcodeIQuery: "IQUERY",
- OpcodeStatus: "STATUS",
- OpcodeNotify: "NOTIFY",
- OpcodeUpdate: "UPDATE",
-}
-
-// RcodeToString maps Rcodes to strings.
-var RcodeToString = map[int]string{
- RcodeSuccess: "NOERROR",
- RcodeFormatError: "FORMERR",
- RcodeServerFailure: "SERVFAIL",
- RcodeNameError: "NXDOMAIN",
- RcodeNotImplemented: "NOTIMPL",
- RcodeRefused: "REFUSED",
- RcodeYXDomain: "YXDOMAIN", // See RFC 2136
- RcodeYXRrset: "YXRRSET",
- RcodeNXRrset: "NXRRSET",
- RcodeNotAuth: "NOTAUTH",
- RcodeNotZone: "NOTZONE",
- RcodeBadSig: "BADSIG", // Also known as RcodeBadVers, see RFC 6891
- // RcodeBadVers: "BADVERS",
- RcodeBadKey: "BADKEY",
- RcodeBadTime: "BADTIME",
- RcodeBadMode: "BADMODE",
- RcodeBadName: "BADNAME",
- RcodeBadAlg: "BADALG",
- RcodeBadTrunc: "BADTRUNC",
- RcodeBadCookie: "BADCOOKIE",
-}
-
-// Domain names are a sequence of counted strings
-// split at the dots. They end with a zero-length string.
-
-// PackDomainName packs a domain name s into msg[off:].
-// If compression is wanted compress must be true and the compression
-// map needs to hold a mapping between domain names and offsets
-// pointing into msg.
-func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
- off1, _, err = packDomainName(s, msg, off, compression, compress)
- return
-}
-
-func packDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, labels int, err error) {
- // special case if msg == nil
- lenmsg := 256
- if msg != nil {
- lenmsg = len(msg)
- }
- ls := len(s)
- if ls == 0 { // Ok, for instance when dealing with update RR without any rdata.
- return off, 0, nil
- }
- // If not fully qualified, error out, but only if msg == nil #ugly
- switch {
- case msg == nil:
- if s[ls-1] != '.' {
- s += "."
- ls++
- }
- case msg != nil:
- if s[ls-1] != '.' {
- return lenmsg, 0, ErrFqdn
- }
- }
- // Each dot ends a segment of the name.
- // We trade each dot byte for a length byte.
- // Except for escaped dots (\.), which are normal dots.
- // There is also a trailing zero.
-
- // Compression
- nameoffset := -1
- pointer := -1
- // Emit sequence of counted strings, chopping at dots.
- begin := 0
- bs := []byte(s)
- roBs, bsFresh, escapedDot := s, true, false
- for i := 0; i < ls; i++ {
- if bs[i] == '\\' {
- for j := i; j < ls-1; j++ {
- bs[j] = bs[j+1]
- }
- ls--
- if off+1 > lenmsg {
- return lenmsg, labels, ErrBuf
- }
- // check for \DDD
- if i+2 < ls && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
- bs[i] = dddToByte(bs[i:])
- for j := i + 1; j < ls-2; j++ {
- bs[j] = bs[j+2]
- }
- ls -= 2
- }
- escapedDot = bs[i] == '.'
- bsFresh = false
- continue
- }
-
- if bs[i] == '.' {
- if i > 0 && bs[i-1] == '.' && !escapedDot {
- // two dots back to back is not legal
- return lenmsg, labels, ErrRdata
- }
- if i-begin >= 1<<6 { // top two bits of length must be clear
- return lenmsg, labels, ErrRdata
- }
- // off can already (we're in a loop) be bigger than len(msg)
- // this happens when a name isn't fully qualified
- if off+1 > lenmsg {
- return lenmsg, labels, ErrBuf
- }
- if msg != nil {
- msg[off] = byte(i - begin)
- }
- offset := off
- off++
- for j := begin; j < i; j++ {
- if off+1 > lenmsg {
- return lenmsg, labels, ErrBuf
- }
- if msg != nil {
- msg[off] = bs[j]
- }
- off++
- }
- if compress && !bsFresh {
- roBs = string(bs)
- bsFresh = true
- }
- // Don't try to compress '.'
- // We should only compress when compress it true, but we should also still pick
- // up names that can be used for *future* compression(s).
- if compression != nil && roBs[begin:] != "." {
- if p, ok := compression[roBs[begin:]]; !ok {
- // Only offsets smaller than this can be used.
- if offset < maxCompressionOffset {
- compression[roBs[begin:]] = offset
- }
- } else {
- // The first hit is the longest matching dname
- // keep the pointer offset we get back and store
- // the offset of the current name, because that's
- // where we need to insert the pointer later
-
- // If compress is true, we're allowed to compress this dname
- if pointer == -1 && compress {
- pointer = p // Where to point to
- nameoffset = offset // Where to point from
- break
- }
- }
- }
- labels++
- begin = i + 1
- }
- escapedDot = false
- }
- // Root label is special
- if len(bs) == 1 && bs[0] == '.' {
- return off, labels, nil
- }
- // If we did compression and we find something add the pointer here
- if pointer != -1 {
- // We have two bytes (14 bits) to put the pointer in
- // if msg == nil, we will never do compression
- binary.BigEndian.PutUint16(msg[nameoffset:], uint16(pointer^0xC000))
- off = nameoffset + 1
- goto End
- }
- if msg != nil && off < len(msg) {
- msg[off] = 0
- }
-End:
- off++
- return off, labels, nil
-}
-
-// Unpack a domain name.
-// In addition to the simple sequences of counted strings above,
-// domain names are allowed to refer to strings elsewhere in the
-// packet, to avoid repeating common suffixes when returning
-// many entries in a single domain. The pointers are marked
-// by a length byte with the top two bits set. Ignoring those
-// two bits, that byte and the next give a 14 bit offset from msg[0]
-// where we should pick up the trail.
-// Note that if we jump elsewhere in the packet,
-// we return off1 == the offset after the first pointer we found,
-// which is where the next record will start.
-// In theory, the pointers are only allowed to jump backward.
-// We let them jump anywhere and stop jumping after a while.
-
-// UnpackDomainName unpacks a domain name into a string.
-func UnpackDomainName(msg []byte, off int) (string, int, error) {
- s := make([]byte, 0, 64)
- off1 := 0
- lenmsg := len(msg)
- maxLen := maxDomainNameWireOctets
- ptr := 0 // number of pointers followed
-Loop:
- for {
- if off >= lenmsg {
- return "", lenmsg, ErrBuf
- }
- c := int(msg[off])
- off++
- switch c & 0xC0 {
- case 0x00:
- if c == 0x00 {
- // end of name
- break Loop
- }
- // literal string
- if off+c > lenmsg {
- return "", lenmsg, ErrBuf
- }
- for j := off; j < off+c; j++ {
- switch b := msg[j]; b {
- case '.', '(', ')', ';', ' ', '@':
- fallthrough
- case '"', '\\':
- s = append(s, '\\', b)
- // presentation-format \X escapes add an extra byte
- maxLen += 1
- default:
- if b < 32 || b >= 127 { // unprintable, use \DDD
- var buf [3]byte
- bufs := strconv.AppendInt(buf[:0], int64(b), 10)
- s = append(s, '\\')
- for i := 0; i < 3-len(bufs); i++ {
- s = append(s, '0')
- }
- for _, r := range bufs {
- s = append(s, r)
- }
- // presentation-format \DDD escapes add 3 extra bytes
- maxLen += 3
- } else {
- s = append(s, b)
- }
- }
- }
- s = append(s, '.')
- off += c
- case 0xC0:
- // pointer to somewhere else in msg.
- // remember location after first ptr,
- // since that's how many bytes we consumed.
- // also, don't follow too many pointers --
- // maybe there's a loop.
- if off >= lenmsg {
- return "", lenmsg, ErrBuf
- }
- c1 := msg[off]
- off++
- if ptr == 0 {
- off1 = off
- }
- if ptr++; ptr > 10 {
- return "", lenmsg, &Error{err: "too many compression pointers"}
- }
- // pointer should guarantee that it advances and points forwards at least
- // but the condition on previous three lines guarantees that it's
- // at least loop-free
- off = (c^0xC0)<<8 | int(c1)
- default:
- // 0x80 and 0x40 are reserved
- return "", lenmsg, ErrRdata
- }
- }
- if ptr == 0 {
- off1 = off
- }
- if len(s) == 0 {
- s = []byte(".")
- } else if len(s) >= maxLen {
- // error if the name is too long, but don't throw it away
- return string(s), lenmsg, ErrLongDomain
- }
- return string(s), off1, nil
-}
-
-func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) {
- if len(txt) == 0 {
- if offset >= len(msg) {
- return offset, ErrBuf
- }
- msg[offset] = 0
- return offset, nil
- }
- var err error
- for i := range txt {
- if len(txt[i]) > len(tmp) {
- return offset, ErrBuf
- }
- offset, err = packTxtString(txt[i], msg, offset, tmp)
- if err != nil {
- return offset, err
- }
- }
- return offset, nil
-}
-
-func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) {
- lenByteOffset := offset
- if offset >= len(msg) || len(s) > len(tmp) {
- return offset, ErrBuf
- }
- offset++
- bs := tmp[:len(s)]
- copy(bs, s)
- for i := 0; i < len(bs); i++ {
- if len(msg) <= offset {
- return offset, ErrBuf
- }
- if bs[i] == '\\' {
- i++
- if i == len(bs) {
- break
- }
- // check for \DDD
- if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
- msg[offset] = dddToByte(bs[i:])
- i += 2
- } else {
- msg[offset] = bs[i]
- }
- } else {
- msg[offset] = bs[i]
- }
- offset++
- }
- l := offset - lenByteOffset - 1
- if l > 255 {
- return offset, &Error{err: "string exceeded 255 bytes in txt"}
- }
- msg[lenByteOffset] = byte(l)
- return offset, nil
-}
-
-func packOctetString(s string, msg []byte, offset int, tmp []byte) (int, error) {
- if offset >= len(msg) || len(s) > len(tmp) {
- return offset, ErrBuf
- }
- bs := tmp[:len(s)]
- copy(bs, s)
- for i := 0; i < len(bs); i++ {
- if len(msg) <= offset {
- return offset, ErrBuf
- }
- if bs[i] == '\\' {
- i++
- if i == len(bs) {
- break
- }
- // check for \DDD
- if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
- msg[offset] = dddToByte(bs[i:])
- i += 2
- } else {
- msg[offset] = bs[i]
- }
- } else {
- msg[offset] = bs[i]
- }
- offset++
- }
- return offset, nil
-}
-
-func unpackTxt(msg []byte, off0 int) (ss []string, off int, err error) {
- off = off0
- var s string
- for off < len(msg) && err == nil {
- s, off, err = unpackTxtString(msg, off)
- if err == nil {
- ss = append(ss, s)
- }
- }
- return
-}
-
-func unpackTxtString(msg []byte, offset int) (string, int, error) {
- if offset+1 > len(msg) {
- return "", offset, &Error{err: "overflow unpacking txt"}
- }
- l := int(msg[offset])
- if offset+l+1 > len(msg) {
- return "", offset, &Error{err: "overflow unpacking txt"}
- }
- s := make([]byte, 0, l)
- for _, b := range msg[offset+1 : offset+1+l] {
- switch b {
- case '"', '\\':
- s = append(s, '\\', b)
- default:
- if b < 32 || b > 127 { // unprintable
- var buf [3]byte
- bufs := strconv.AppendInt(buf[:0], int64(b), 10)
- s = append(s, '\\')
- for i := 0; i < 3-len(bufs); i++ {
- s = append(s, '0')
- }
- for _, r := range bufs {
- s = append(s, r)
- }
- } else {
- s = append(s, b)
- }
- }
- }
- offset += 1 + l
- return string(s), offset, nil
-}
-
-// Helpers for dealing with escaped bytes
-func isDigit(b byte) bool { return b >= '0' && b <= '9' }
-
-func dddToByte(s []byte) byte {
- return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0'))
-}
-
-// Helper function for packing and unpacking
-func intToBytes(i *big.Int, length int) []byte {
- buf := i.Bytes()
- if len(buf) < length {
- b := make([]byte, length)
- copy(b[length-len(buf):], buf)
- return b
- }
- return buf
-}
-
-// PackRR packs a resource record rr into msg[off:].
-// See PackDomainName for documentation about the compression.
-func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
- if rr == nil {
- return len(msg), &Error{err: "nil rr"}
- }
-
- off1, err = rr.pack(msg, off, compression, compress)
- if err != nil {
- return len(msg), err
- }
- // TODO(miek): Not sure if this is needed? If removed we can remove rawmsg.go as well.
- if rawSetRdlength(msg, off, off1) {
- return off1, nil
- }
- return off, ErrRdata
-}
-
-// UnpackRR unpacks msg[off:] into an RR.
-func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
- h, off, msg, err := unpackHeader(msg, off)
- if err != nil {
- return nil, len(msg), err
- }
- end := off + int(h.Rdlength)
-
- if fn, known := typeToUnpack[h.Rrtype]; !known {
- rr, off, err = unpackRFC3597(h, msg, off)
- } else {
- rr, off, err = fn(h, msg, off)
- }
- if off != end {
- return &h, end, &Error{err: "bad rdlength"}
- }
- return rr, off, err
-}
-
-// unpackRRslice unpacks msg[off:] into an []RR.
-// If we cannot unpack the whole array, then it will return nil
-func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) {
- var r RR
- // Optimistically make dst be the length that was sent
- dst := make([]RR, 0, l)
- for i := 0; i < l; i++ {
- off1 := off
- r, off, err = UnpackRR(msg, off)
- if err != nil {
- off = len(msg)
- break
- }
- // If offset does not increase anymore, l is a lie
- if off1 == off {
- l = i
- break
- }
- dst = append(dst, r)
- }
- if err != nil && off == len(msg) {
- dst = nil
- }
- return dst, off, err
-}
-
-// Convert a MsgHdr to a string, with dig-like headers:
-//
-//;; opcode: QUERY, status: NOERROR, id: 48404
-//
-//;; flags: qr aa rd ra;
-func (h *MsgHdr) String() string {
- if h == nil {
- return "<nil> MsgHdr"
- }
-
- s := ";; opcode: " + OpcodeToString[h.Opcode]
- s += ", status: " + RcodeToString[h.Rcode]
- s += ", id: " + strconv.Itoa(int(h.Id)) + "\n"
-
- s += ";; flags:"
- if h.Response {
- s += " qr"
- }
- if h.Authoritative {
- s += " aa"
- }
- if h.Truncated {
- s += " tc"
- }
- if h.RecursionDesired {
- s += " rd"
- }
- if h.RecursionAvailable {
- s += " ra"
- }
- if h.Zero { // Hmm
- s += " z"
- }
- if h.AuthenticatedData {
- s += " ad"
- }
- if h.CheckingDisabled {
- s += " cd"
- }
-
- s += ";"
- return s
-}
-
-// Pack packs a Msg: it is converted to to wire format.
-// If the dns.Compress is true the message will be in compressed wire format.
-func (dns *Msg) Pack() (msg []byte, err error) {
- return dns.PackBuffer(nil)
-}
-
-// PackBuffer packs a Msg, using the given buffer buf. If buf is too small
-// a new buffer is allocated.
-func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
- // We use a similar function in tsig.go's stripTsig.
- var (
- dh Header
- compression map[string]int
- )
-
- if dns.Compress {
- compression = make(map[string]int) // Compression pointer mappings
- }
-
- if dns.Rcode < 0 || dns.Rcode > 0xFFF {
- return nil, ErrRcode
- }
- if dns.Rcode > 0xF {
- // Regular RCODE field is 4 bits
- opt := dns.IsEdns0()
- if opt == nil {
- return nil, ErrExtendedRcode
- }
- opt.SetExtendedRcode(uint8(dns.Rcode >> 4))
- dns.Rcode &= 0xF
- }
-
- // Convert convenient Msg into wire-like Header.
- dh.Id = dns.Id
- dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode)
- if dns.Response {
- dh.Bits |= _QR
- }
- if dns.Authoritative {
- dh.Bits |= _AA
- }
- if dns.Truncated {
- dh.Bits |= _TC
- }
- if dns.RecursionDesired {
- dh.Bits |= _RD
- }
- if dns.RecursionAvailable {
- dh.Bits |= _RA
- }
- if dns.Zero {
- dh.Bits |= _Z
- }
- if dns.AuthenticatedData {
- dh.Bits |= _AD
- }
- if dns.CheckingDisabled {
- dh.Bits |= _CD
- }
-
- // Prepare variable sized arrays.
- question := dns.Question
- answer := dns.Answer
- ns := dns.Ns
- extra := dns.Extra
-
- dh.Qdcount = uint16(len(question))
- dh.Ancount = uint16(len(answer))
- dh.Nscount = uint16(len(ns))
- dh.Arcount = uint16(len(extra))
-
- // We need the uncompressed length here, because we first pack it and then compress it.
- msg = buf
- uncompressedLen := compressedLen(dns, false)
- if packLen := uncompressedLen + 1; len(msg) < packLen {
- msg = make([]byte, packLen)
- }
-
- // Pack it in: header and then the pieces.
- off := 0
- off, err = dh.pack(msg, off, compression, dns.Compress)
- if err != nil {
- return nil, err
- }
- for i := 0; i < len(question); i++ {
- off, err = question[i].pack(msg, off, compression, dns.Compress)
- if err != nil {
- return nil, err
- }
- }
- for i := 0; i < len(answer); i++ {
- off, err = PackRR(answer[i], msg, off, compression, dns.Compress)
- if err != nil {
- return nil, err
- }
- }
- for i := 0; i < len(ns); i++ {
- off, err = PackRR(ns[i], msg, off, compression, dns.Compress)
- if err != nil {
- return nil, err
- }
- }
- for i := 0; i < len(extra); i++ {
- off, err = PackRR(extra[i], msg, off, compression, dns.Compress)
- if err != nil {
- return nil, err
- }
- }
- return msg[:off], nil
-}
-
-// Unpack unpacks a binary message to a Msg structure.
-func (dns *Msg) Unpack(msg []byte) (err error) {
- var (
- dh Header
- off int
- )
- if dh, off, err = unpackMsgHdr(msg, off); err != nil {
- return err
- }
-
- dns.Id = dh.Id
- dns.Response = (dh.Bits & _QR) != 0
- dns.Opcode = int(dh.Bits>>11) & 0xF
- dns.Authoritative = (dh.Bits & _AA) != 0
- dns.Truncated = (dh.Bits & _TC) != 0
- dns.RecursionDesired = (dh.Bits & _RD) != 0
- dns.RecursionAvailable = (dh.Bits & _RA) != 0
- dns.Zero = (dh.Bits & _Z) != 0
- dns.AuthenticatedData = (dh.Bits & _AD) != 0
- dns.CheckingDisabled = (dh.Bits & _CD) != 0
- dns.Rcode = int(dh.Bits & 0xF)
-
- if off == len(msg) {
- return ErrTruncated
- }
-
- // Optimistically use the count given to us in the header
- dns.Question = make([]Question, 0, int(dh.Qdcount))
-
- for i := 0; i < int(dh.Qdcount); i++ {
- off1 := off
- var q Question
- q, off, err = unpackQuestion(msg, off)
- if err != nil {
- // Even if Truncated is set, we only will set ErrTruncated if we
- // actually got the questions
- return err
- }
- if off1 == off { // Offset does not increase anymore, dh.Qdcount is a lie!
- dh.Qdcount = uint16(i)
- break
- }
- dns.Question = append(dns.Question, q)
- }
-
- dns.Answer, off, err = unpackRRslice(int(dh.Ancount), msg, off)
- // The header counts might have been wrong so we need to update it
- dh.Ancount = uint16(len(dns.Answer))
- if err == nil {
- dns.Ns, off, err = unpackRRslice(int(dh.Nscount), msg, off)
- }
- // The header counts might have been wrong so we need to update it
- dh.Nscount = uint16(len(dns.Ns))
- if err == nil {
- dns.Extra, off, err = unpackRRslice(int(dh.Arcount), msg, off)
- }
- // The header counts might have been wrong so we need to update it
- dh.Arcount = uint16(len(dns.Extra))
-
- if off != len(msg) {
- // TODO(miek) make this an error?
- // use PackOpt to let people tell how detailed the error reporting should be?
- // println("dns: extra bytes in dns packet", off, "<", len(msg))
- } else if dns.Truncated {
- // Whether we ran into a an error or not, we want to return that it
- // was truncated
- err = ErrTruncated
- }
- return err
-}
-
-// Convert a complete message to a string with dig-like output.
-func (dns *Msg) String() string {
- if dns == nil {
- return "<nil> MsgHdr"
- }
- s := dns.MsgHdr.String() + " "
- s += "QUERY: " + strconv.Itoa(len(dns.Question)) + ", "
- s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", "
- s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", "
- s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n"
- if len(dns.Question) > 0 {
- s += "\n;; QUESTION SECTION:\n"
- for i := 0; i < len(dns.Question); i++ {
- s += dns.Question[i].String() + "\n"
- }
- }
- if len(dns.Answer) > 0 {
- s += "\n;; ANSWER SECTION:\n"
- for i := 0; i < len(dns.Answer); i++ {
- if dns.Answer[i] != nil {
- s += dns.Answer[i].String() + "\n"
- }
- }
- }
- if len(dns.Ns) > 0 {
- s += "\n;; AUTHORITY SECTION:\n"
- for i := 0; i < len(dns.Ns); i++ {
- if dns.Ns[i] != nil {
- s += dns.Ns[i].String() + "\n"
- }
- }
- }
- if len(dns.Extra) > 0 {
- s += "\n;; ADDITIONAL SECTION:\n"
- for i := 0; i < len(dns.Extra); i++ {
- if dns.Extra[i] != nil {
- s += dns.Extra[i].String() + "\n"
- }
- }
- }
- return s
-}
-
-// Len returns the message length when in (un)compressed wire format.
-// If dns.Compress is true compression it is taken into account. Len()
-// is provided to be a faster way to get the size of the resulting packet,
-// than packing it, measuring the size and discarding the buffer.
-func (dns *Msg) Len() int { return compressedLen(dns, dns.Compress) }
-
-// compressedLen returns the message length when in compressed wire format
-// when compress is true, otherwise the uncompressed length is returned.
-func compressedLen(dns *Msg, compress bool) int {
- // We always return one more than needed.
- l := 12 // Message header is always 12 bytes
- compression := map[string]int{}
-
- for i := 0; i < len(dns.Question); i++ {
- l += dns.Question[i].len()
- if compress {
- compressionLenHelper(compression, dns.Question[i].Name)
- }
- }
- for i := 0; i < len(dns.Answer); i++ {
- if dns.Answer[i] == nil {
- continue
- }
- l += dns.Answer[i].len()
- if compress {
- k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name)
- if ok {
- l += 1 - k
- }
- compressionLenHelper(compression, dns.Answer[i].Header().Name)
- k, ok = compressionLenSearchType(compression, dns.Answer[i])
- if ok {
- l += 1 - k
- }
- compressionLenHelperType(compression, dns.Answer[i])
- }
- }
- for i := 0; i < len(dns.Ns); i++ {
- if dns.Ns[i] == nil {
- continue
- }
- l += dns.Ns[i].len()
- if compress {
- k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name)
- if ok {
- l += 1 - k
- }
- compressionLenHelper(compression, dns.Ns[i].Header().Name)
- k, ok = compressionLenSearchType(compression, dns.Ns[i])
- if ok {
- l += 1 - k
- }
- compressionLenHelperType(compression, dns.Ns[i])
- }
- }
- for i := 0; i < len(dns.Extra); i++ {
- if dns.Extra[i] == nil {
- continue
- }
- l += dns.Extra[i].len()
- if compress {
- k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name)
- if ok {
- l += 1 - k
- }
- compressionLenHelper(compression, dns.Extra[i].Header().Name)
- k, ok = compressionLenSearchType(compression, dns.Extra[i])
- if ok {
- l += 1 - k
- }
- compressionLenHelperType(compression, dns.Extra[i])
- }
- }
- return l
-}
-
-// Put the parts of the name in the compression map.
-func compressionLenHelper(c map[string]int, s string) {
- pref := ""
- lbs := Split(s)
- for j := len(lbs) - 1; j >= 0; j-- {
- pref = s[lbs[j]:]
- if _, ok := c[pref]; !ok {
- c[pref] = len(pref)
- }
- }
-}
-
-// Look for each part in the compression map and returns its length,
-// keep on searching so we get the longest match.
-func compressionLenSearch(c map[string]int, s string) (int, bool) {
- off := 0
- end := false
- if s == "" { // don't bork on bogus data
- return 0, false
- }
- for {
- if _, ok := c[s[off:]]; ok {
- return len(s[off:]), true
- }
- if end {
- break
- }
- off, end = NextLabel(s, off)
- }
- return 0, false
-}
-
-// Copy returns a new RR which is a deep-copy of r.
-func Copy(r RR) RR { r1 := r.copy(); return r1 }
-
-// Len returns the length (in octets) of the uncompressed RR in wire format.
-func Len(r RR) int { return r.len() }
-
-// Copy returns a new *Msg which is a deep-copy of dns.
-func (dns *Msg) Copy() *Msg { return dns.CopyTo(new(Msg)) }
-
-// CopyTo copies the contents to the provided message using a deep-copy and returns the copy.
-func (dns *Msg) CopyTo(r1 *Msg) *Msg {
- r1.MsgHdr = dns.MsgHdr
- r1.Compress = dns.Compress
-
- if len(dns.Question) > 0 {
- r1.Question = make([]Question, len(dns.Question))
- copy(r1.Question, dns.Question) // TODO(miek): Question is an immutable value, ok to do a shallow-copy
- }
-
- rrArr := make([]RR, len(dns.Answer)+len(dns.Ns)+len(dns.Extra))
- var rri int
-
- if len(dns.Answer) > 0 {
- rrbegin := rri
- for i := 0; i < len(dns.Answer); i++ {
- rrArr[rri] = dns.Answer[i].copy()
- rri++
- }
- r1.Answer = rrArr[rrbegin:rri:rri]
- }
-
- if len(dns.Ns) > 0 {
- rrbegin := rri
- for i := 0; i < len(dns.Ns); i++ {
- rrArr[rri] = dns.Ns[i].copy()
- rri++
- }
- r1.Ns = rrArr[rrbegin:rri:rri]
- }
-
- if len(dns.Extra) > 0 {
- rrbegin := rri
- for i := 0; i < len(dns.Extra); i++ {
- rrArr[rri] = dns.Extra[i].copy()
- rri++
- }
- r1.Extra = rrArr[rrbegin:rri:rri]
- }
-
- return r1
-}
-
-func (q *Question) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := PackDomainName(q.Name, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- off, err = packUint16(q.Qtype, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(q.Qclass, msg, off)
- if err != nil {
- return off, err
- }
- return off, nil
-}
-
-func unpackQuestion(msg []byte, off int) (Question, int, error) {
- var (
- q Question
- err error
- )
- q.Name, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return q, off, err
- }
- if off == len(msg) {
- return q, off, nil
- }
- q.Qtype, off, err = unpackUint16(msg, off)
- if err != nil {
- return q, off, err
- }
- if off == len(msg) {
- return q, off, nil
- }
- q.Qclass, off, err = unpackUint16(msg, off)
- if off == len(msg) {
- return q, off, nil
- }
- return q, off, err
-}
-
-func (dh *Header) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := packUint16(dh.Id, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(dh.Bits, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(dh.Qdcount, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(dh.Ancount, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(dh.Nscount, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(dh.Arcount, msg, off)
- return off, err
-}
-
-func unpackMsgHdr(msg []byte, off int) (Header, int, error) {
- var (
- dh Header
- err error
- )
- dh.Id, off, err = unpackUint16(msg, off)
- if err != nil {
- return dh, off, err
- }
- dh.Bits, off, err = unpackUint16(msg, off)
- if err != nil {
- return dh, off, err
- }
- dh.Qdcount, off, err = unpackUint16(msg, off)
- if err != nil {
- return dh, off, err
- }
- dh.Ancount, off, err = unpackUint16(msg, off)
- if err != nil {
- return dh, off, err
- }
- dh.Nscount, off, err = unpackUint16(msg, off)
- if err != nil {
- return dh, off, err
- }
- dh.Arcount, off, err = unpackUint16(msg, off)
- return dh, off, err
-}
diff --git a/vendor/github.com/miekg/dns/msg_generate.go b/vendor/github.com/miekg/dns/msg_generate.go
deleted file mode 100644
index 4d9f81d43..000000000
--- a/vendor/github.com/miekg/dns/msg_generate.go
+++ /dev/null
@@ -1,349 +0,0 @@
-//+build ignore
-
-// msg_generate.go is meant to run with go generate. It will use
-// go/{importer,types} to track down all the RR struct types. Then for each type
-// it will generate pack/unpack methods based on the struct tags. The generated source is
-// written to zmsg.go, and is meant to be checked into git.
-package main
-
-import (
- "bytes"
- "fmt"
- "go/format"
- "go/importer"
- "go/types"
- "log"
- "os"
- "strings"
-)
-
-var packageHdr = `
-// *** DO NOT MODIFY ***
-// AUTOGENERATED BY go generate from msg_generate.go
-
-package dns
-
-`
-
-// getTypeStruct will take a type and the package scope, and return the
-// (innermost) struct if the type is considered a RR type (currently defined as
-// those structs beginning with a RR_Header, could be redefined as implementing
-// the RR interface). The bool return value indicates if embedded structs were
-// resolved.
-func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) {
- st, ok := t.Underlying().(*types.Struct)
- if !ok {
- return nil, false
- }
- if st.Field(0).Type() == scope.Lookup("RR_Header").Type() {
- return st, false
- }
- if st.Field(0).Anonymous() {
- st, _ := getTypeStruct(st.Field(0).Type(), scope)
- return st, true
- }
- return nil, false
-}
-
-func main() {
- // Import and type-check the package
- pkg, err := importer.Default().Import("github.com/miekg/dns")
- fatalIfErr(err)
- scope := pkg.Scope()
-
- // Collect actual types (*X)
- var namedTypes []string
- for _, name := range scope.Names() {
- o := scope.Lookup(name)
- if o == nil || !o.Exported() {
- continue
- }
- if st, _ := getTypeStruct(o.Type(), scope); st == nil {
- continue
- }
- if name == "PrivateRR" {
- continue
- }
-
- // Check if corresponding TypeX exists
- if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" {
- log.Fatalf("Constant Type%s does not exist.", o.Name())
- }
-
- namedTypes = append(namedTypes, o.Name())
- }
-
- b := &bytes.Buffer{}
- b.WriteString(packageHdr)
-
- fmt.Fprint(b, "// pack*() functions\n\n")
- for _, name := range namedTypes {
- o := scope.Lookup(name)
- st, _ := getTypeStruct(o.Type(), scope)
-
- fmt.Fprintf(b, "func (rr *%s) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {\n", name)
- fmt.Fprint(b, `off, err := rr.Hdr.pack(msg, off, compression, compress)
-if err != nil {
- return off, err
-}
-headerEnd := off
-`)
- for i := 1; i < st.NumFields(); i++ {
- o := func(s string) {
- fmt.Fprintf(b, s, st.Field(i).Name())
- fmt.Fprint(b, `if err != nil {
-return off, err
-}
-`)
- }
-
- if _, ok := st.Field(i).Type().(*types.Slice); ok {
- switch st.Tag(i) {
- case `dns:"-"`: // ignored
- case `dns:"txt"`:
- o("off, err = packStringTxt(rr.%s, msg, off)\n")
- case `dns:"opt"`:
- o("off, err = packDataOpt(rr.%s, msg, off)\n")
- case `dns:"nsec"`:
- o("off, err = packDataNsec(rr.%s, msg, off)\n")
- case `dns:"domain-name"`:
- o("off, err = packDataDomainNames(rr.%s, msg, off, compression, compress)\n")
- default:
- log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
- }
- continue
- }
-
- switch {
- case st.Tag(i) == `dns:"-"`: // ignored
- case st.Tag(i) == `dns:"cdomain-name"`:
- o("off, err = PackDomainName(rr.%s, msg, off, compression, compress)\n")
- case st.Tag(i) == `dns:"domain-name"`:
- o("off, err = PackDomainName(rr.%s, msg, off, compression, false)\n")
- case st.Tag(i) == `dns:"a"`:
- o("off, err = packDataA(rr.%s, msg, off)\n")
- case st.Tag(i) == `dns:"aaaa"`:
- o("off, err = packDataAAAA(rr.%s, msg, off)\n")
- case st.Tag(i) == `dns:"uint48"`:
- o("off, err = packUint48(rr.%s, msg, off)\n")
- case st.Tag(i) == `dns:"txt"`:
- o("off, err = packString(rr.%s, msg, off)\n")
-
- case strings.HasPrefix(st.Tag(i), `dns:"size-base32`): // size-base32 can be packed just like base32
- fallthrough
- case st.Tag(i) == `dns:"base32"`:
- o("off, err = packStringBase32(rr.%s, msg, off)\n")
-
- case strings.HasPrefix(st.Tag(i), `dns:"size-base64`): // size-base64 can be packed just like base64
- fallthrough
- case st.Tag(i) == `dns:"base64"`:
- o("off, err = packStringBase64(rr.%s, msg, off)\n")
-
- case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`):
- // directly write instead of using o() so we get the error check in the correct place
- field := st.Field(i).Name()
- fmt.Fprintf(b, `// Only pack salt if value is not "-", i.e. empty
-if rr.%s != "-" {
- off, err = packStringHex(rr.%s, msg, off)
- if err != nil {
- return off, err
- }
-}
-`, field, field)
- continue
- case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex
- fallthrough
- case st.Tag(i) == `dns:"hex"`:
- o("off, err = packStringHex(rr.%s, msg, off)\n")
-
- case st.Tag(i) == `dns:"octet"`:
- o("off, err = packStringOctet(rr.%s, msg, off)\n")
- case st.Tag(i) == "":
- switch st.Field(i).Type().(*types.Basic).Kind() {
- case types.Uint8:
- o("off, err = packUint8(rr.%s, msg, off)\n")
- case types.Uint16:
- o("off, err = packUint16(rr.%s, msg, off)\n")
- case types.Uint32:
- o("off, err = packUint32(rr.%s, msg, off)\n")
- case types.Uint64:
- o("off, err = packUint64(rr.%s, msg, off)\n")
- case types.String:
- o("off, err = packString(rr.%s, msg, off)\n")
- default:
- log.Fatalln(name, st.Field(i).Name())
- }
- default:
- log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
- }
- }
- // We have packed everything, only now we know the rdlength of this RR
- fmt.Fprintln(b, "rr.Header().Rdlength = uint16(off-headerEnd)")
- fmt.Fprintln(b, "return off, nil }\n")
- }
-
- fmt.Fprint(b, "// unpack*() functions\n\n")
- for _, name := range namedTypes {
- o := scope.Lookup(name)
- st, _ := getTypeStruct(o.Type(), scope)
-
- fmt.Fprintf(b, "func unpack%s(h RR_Header, msg []byte, off int) (RR, int, error) {\n", name)
- fmt.Fprintf(b, "rr := new(%s)\n", name)
- fmt.Fprint(b, "rr.Hdr = h\n")
- fmt.Fprint(b, `if noRdata(h) {
-return rr, off, nil
- }
-var err error
-rdStart := off
-_ = rdStart
-
-`)
- for i := 1; i < st.NumFields(); i++ {
- o := func(s string) {
- fmt.Fprintf(b, s, st.Field(i).Name())
- fmt.Fprint(b, `if err != nil {
-return rr, off, err
-}
-`)
- }
-
- // size-* are special, because they reference a struct member we should use for the length.
- if strings.HasPrefix(st.Tag(i), `dns:"size-`) {
- structMember := structMember(st.Tag(i))
- structTag := structTag(st.Tag(i))
- switch structTag {
- case "hex":
- fmt.Fprintf(b, "rr.%s, off, err = unpackStringHex(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember)
- case "base32":
- fmt.Fprintf(b, "rr.%s, off, err = unpackStringBase32(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember)
- case "base64":
- fmt.Fprintf(b, "rr.%s, off, err = unpackStringBase64(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember)
- default:
- log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
- }
- fmt.Fprint(b, `if err != nil {
-return rr, off, err
-}
-`)
- continue
- }
-
- if _, ok := st.Field(i).Type().(*types.Slice); ok {
- switch st.Tag(i) {
- case `dns:"-"`: // ignored
- case `dns:"txt"`:
- o("rr.%s, off, err = unpackStringTxt(msg, off)\n")
- case `dns:"opt"`:
- o("rr.%s, off, err = unpackDataOpt(msg, off)\n")
- case `dns:"nsec"`:
- o("rr.%s, off, err = unpackDataNsec(msg, off)\n")
- case `dns:"domain-name"`:
- o("rr.%s, off, err = unpackDataDomainNames(msg, off, rdStart + int(rr.Hdr.Rdlength))\n")
- default:
- log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
- }
- continue
- }
-
- switch st.Tag(i) {
- case `dns:"-"`: // ignored
- case `dns:"cdomain-name"`:
- fallthrough
- case `dns:"domain-name"`:
- o("rr.%s, off, err = UnpackDomainName(msg, off)\n")
- case `dns:"a"`:
- o("rr.%s, off, err = unpackDataA(msg, off)\n")
- case `dns:"aaaa"`:
- o("rr.%s, off, err = unpackDataAAAA(msg, off)\n")
- case `dns:"uint48"`:
- o("rr.%s, off, err = unpackUint48(msg, off)\n")
- case `dns:"txt"`:
- o("rr.%s, off, err = unpackString(msg, off)\n")
- case `dns:"base32"`:
- o("rr.%s, off, err = unpackStringBase32(msg, off, rdStart + int(rr.Hdr.Rdlength))\n")
- case `dns:"base64"`:
- o("rr.%s, off, err = unpackStringBase64(msg, off, rdStart + int(rr.Hdr.Rdlength))\n")
- case `dns:"hex"`:
- o("rr.%s, off, err = unpackStringHex(msg, off, rdStart + int(rr.Hdr.Rdlength))\n")
- case `dns:"octet"`:
- o("rr.%s, off, err = unpackStringOctet(msg, off)\n")
- case "":
- switch st.Field(i).Type().(*types.Basic).Kind() {
- case types.Uint8:
- o("rr.%s, off, err = unpackUint8(msg, off)\n")
- case types.Uint16:
- o("rr.%s, off, err = unpackUint16(msg, off)\n")
- case types.Uint32:
- o("rr.%s, off, err = unpackUint32(msg, off)\n")
- case types.Uint64:
- o("rr.%s, off, err = unpackUint64(msg, off)\n")
- case types.String:
- o("rr.%s, off, err = unpackString(msg, off)\n")
- default:
- log.Fatalln(name, st.Field(i).Name())
- }
- default:
- log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
- }
- // If we've hit len(msg) we return without error.
- if i < st.NumFields()-1 {
- fmt.Fprintf(b, `if off == len(msg) {
-return rr, off, nil
- }
-`)
- }
- }
- fmt.Fprintf(b, "return rr, off, err }\n\n")
- }
- // Generate typeToUnpack map
- fmt.Fprintln(b, "var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){")
- for _, name := range namedTypes {
- if name == "RFC3597" {
- continue
- }
- fmt.Fprintf(b, "Type%s: unpack%s,\n", name, name)
- }
- fmt.Fprintln(b, "}\n")
-
- // gofmt
- res, err := format.Source(b.Bytes())
- if err != nil {
- b.WriteTo(os.Stderr)
- log.Fatal(err)
- }
-
- // write result
- f, err := os.Create("zmsg.go")
- fatalIfErr(err)
- defer f.Close()
- f.Write(res)
-}
-
-// structMember will take a tag like dns:"size-base32:SaltLength" and return the last part of this string.
-func structMember(s string) string {
- fields := strings.Split(s, ":")
- if len(fields) == 0 {
- return ""
- }
- f := fields[len(fields)-1]
- // f should have a closing "
- if len(f) > 1 {
- return f[:len(f)-1]
- }
- return f
-}
-
-// structTag will take a tag like dns:"size-base32:SaltLength" and return base32.
-func structTag(s string) string {
- fields := strings.Split(s, ":")
- if len(fields) < 2 {
- return ""
- }
- return fields[1][len("\"size-"):]
-}
-
-func fatalIfErr(err error) {
- if err != nil {
- log.Fatal(err)
- }
-}
diff --git a/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/miekg/dns/msg_helpers.go
deleted file mode 100644
index 615274ab0..000000000
--- a/vendor/github.com/miekg/dns/msg_helpers.go
+++ /dev/null
@@ -1,633 +0,0 @@
-package dns
-
-import (
- "encoding/base32"
- "encoding/base64"
- "encoding/binary"
- "encoding/hex"
- "net"
- "strconv"
-)
-
-// helper functions called from the generated zmsg.go
-
-// These function are named after the tag to help pack/unpack, if there is no tag it is the name
-// of the type they pack/unpack (string, int, etc). We prefix all with unpackData or packData, so packDataA or
-// packDataDomainName.
-
-func unpackDataA(msg []byte, off int) (net.IP, int, error) {
- if off+net.IPv4len > len(msg) {
- return nil, len(msg), &Error{err: "overflow unpacking a"}
- }
- a := append(make(net.IP, 0, net.IPv4len), msg[off:off+net.IPv4len]...)
- off += net.IPv4len
- return a, off, nil
-}
-
-func packDataA(a net.IP, msg []byte, off int) (int, error) {
- // It must be a slice of 4, even if it is 16, we encode only the first 4
- if off+net.IPv4len > len(msg) {
- return len(msg), &Error{err: "overflow packing a"}
- }
- switch len(a) {
- case net.IPv4len, net.IPv6len:
- copy(msg[off:], a.To4())
- off += net.IPv4len
- case 0:
- // Allowed, for dynamic updates.
- default:
- return len(msg), &Error{err: "overflow packing a"}
- }
- return off, nil
-}
-
-func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) {
- if off+net.IPv6len > len(msg) {
- return nil, len(msg), &Error{err: "overflow unpacking aaaa"}
- }
- aaaa := append(make(net.IP, 0, net.IPv6len), msg[off:off+net.IPv6len]...)
- off += net.IPv6len
- return aaaa, off, nil
-}
-
-func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) {
- if off+net.IPv6len > len(msg) {
- return len(msg), &Error{err: "overflow packing aaaa"}
- }
-
- switch len(aaaa) {
- case net.IPv6len:
- copy(msg[off:], aaaa)
- off += net.IPv6len
- case 0:
- // Allowed, dynamic updates.
- default:
- return len(msg), &Error{err: "overflow packing aaaa"}
- }
- return off, nil
-}
-
-// unpackHeader unpacks an RR header, returning the offset to the end of the header and a
-// re-sliced msg according to the expected length of the RR.
-func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, err error) {
- hdr := RR_Header{}
- if off == len(msg) {
- return hdr, off, msg, nil
- }
-
- hdr.Name, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return hdr, len(msg), msg, err
- }
- hdr.Rrtype, off, err = unpackUint16(msg, off)
- if err != nil {
- return hdr, len(msg), msg, err
- }
- hdr.Class, off, err = unpackUint16(msg, off)
- if err != nil {
- return hdr, len(msg), msg, err
- }
- hdr.Ttl, off, err = unpackUint32(msg, off)
- if err != nil {
- return hdr, len(msg), msg, err
- }
- hdr.Rdlength, off, err = unpackUint16(msg, off)
- if err != nil {
- return hdr, len(msg), msg, err
- }
- msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength)
- return hdr, off, msg, nil
-}
-
-// pack packs an RR header, returning the offset to the end of the header.
-// See PackDomainName for documentation about the compression.
-func (hdr RR_Header) pack(msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
- if off == len(msg) {
- return off, nil
- }
-
- off, err = PackDomainName(hdr.Name, msg, off, compression, compress)
- if err != nil {
- return len(msg), err
- }
- off, err = packUint16(hdr.Rrtype, msg, off)
- if err != nil {
- return len(msg), err
- }
- off, err = packUint16(hdr.Class, msg, off)
- if err != nil {
- return len(msg), err
- }
- off, err = packUint32(hdr.Ttl, msg, off)
- if err != nil {
- return len(msg), err
- }
- off, err = packUint16(hdr.Rdlength, msg, off)
- if err != nil {
- return len(msg), err
- }
- return off, nil
-}
-
-// helper helper functions.
-
-// truncateMsgFromRdLength truncates msg to match the expected length of the RR.
-// Returns an error if msg is smaller than the expected size.
-func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []byte, err error) {
- lenrd := off + int(rdlength)
- if lenrd > len(msg) {
- return msg, &Error{err: "overflowing header size"}
- }
- return msg[:lenrd], nil
-}
-
-func fromBase32(s []byte) (buf []byte, err error) {
- for i, b := range s {
- if b >= 'a' && b <= 'z' {
- s[i] = b - 32
- }
- }
- buflen := base32.HexEncoding.DecodedLen(len(s))
- buf = make([]byte, buflen)
- n, err := base32.HexEncoding.Decode(buf, s)
- buf = buf[:n]
- return
-}
-
-func toBase32(b []byte) string { return base32.HexEncoding.EncodeToString(b) }
-
-func fromBase64(s []byte) (buf []byte, err error) {
- buflen := base64.StdEncoding.DecodedLen(len(s))
- buf = make([]byte, buflen)
- n, err := base64.StdEncoding.Decode(buf, s)
- buf = buf[:n]
- return
-}
-
-func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) }
-
-// dynamicUpdate returns true if the Rdlength is zero.
-func noRdata(h RR_Header) bool { return h.Rdlength == 0 }
-
-func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) {
- if off+1 > len(msg) {
- return 0, len(msg), &Error{err: "overflow unpacking uint8"}
- }
- return uint8(msg[off]), off + 1, nil
-}
-
-func packUint8(i uint8, msg []byte, off int) (off1 int, err error) {
- if off+1 > len(msg) {
- return len(msg), &Error{err: "overflow packing uint8"}
- }
- msg[off] = byte(i)
- return off + 1, nil
-}
-
-func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) {
- if off+2 > len(msg) {
- return 0, len(msg), &Error{err: "overflow unpacking uint16"}
- }
- return binary.BigEndian.Uint16(msg[off:]), off + 2, nil
-}
-
-func packUint16(i uint16, msg []byte, off int) (off1 int, err error) {
- if off+2 > len(msg) {
- return len(msg), &Error{err: "overflow packing uint16"}
- }
- binary.BigEndian.PutUint16(msg[off:], i)
- return off + 2, nil
-}
-
-func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) {
- if off+4 > len(msg) {
- return 0, len(msg), &Error{err: "overflow unpacking uint32"}
- }
- return binary.BigEndian.Uint32(msg[off:]), off + 4, nil
-}
-
-func packUint32(i uint32, msg []byte, off int) (off1 int, err error) {
- if off+4 > len(msg) {
- return len(msg), &Error{err: "overflow packing uint32"}
- }
- binary.BigEndian.PutUint32(msg[off:], i)
- return off + 4, nil
-}
-
-func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) {
- if off+6 > len(msg) {
- return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"}
- }
- // Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes)
- i = (uint64(uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 |
- uint64(msg[off+4])<<8 | uint64(msg[off+5])))
- off += 6
- return i, off, nil
-}
-
-func packUint48(i uint64, msg []byte, off int) (off1 int, err error) {
- if off+6 > len(msg) {
- return len(msg), &Error{err: "overflow packing uint64 as uint48"}
- }
- msg[off] = byte(i >> 40)
- msg[off+1] = byte(i >> 32)
- msg[off+2] = byte(i >> 24)
- msg[off+3] = byte(i >> 16)
- msg[off+4] = byte(i >> 8)
- msg[off+5] = byte(i)
- off += 6
- return off, nil
-}
-
-func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) {
- if off+8 > len(msg) {
- return 0, len(msg), &Error{err: "overflow unpacking uint64"}
- }
- return binary.BigEndian.Uint64(msg[off:]), off + 8, nil
-}
-
-func packUint64(i uint64, msg []byte, off int) (off1 int, err error) {
- if off+8 > len(msg) {
- return len(msg), &Error{err: "overflow packing uint64"}
- }
- binary.BigEndian.PutUint64(msg[off:], i)
- off += 8
- return off, nil
-}
-
-func unpackString(msg []byte, off int) (string, int, error) {
- if off+1 > len(msg) {
- return "", off, &Error{err: "overflow unpacking txt"}
- }
- l := int(msg[off])
- if off+l+1 > len(msg) {
- return "", off, &Error{err: "overflow unpacking txt"}
- }
- s := make([]byte, 0, l)
- for _, b := range msg[off+1 : off+1+l] {
- switch b {
- case '"', '\\':
- s = append(s, '\\', b)
- default:
- if b < 32 || b > 127 { // unprintable
- var buf [3]byte
- bufs := strconv.AppendInt(buf[:0], int64(b), 10)
- s = append(s, '\\')
- for i := 0; i < 3-len(bufs); i++ {
- s = append(s, '0')
- }
- for _, r := range bufs {
- s = append(s, r)
- }
- } else {
- s = append(s, b)
- }
- }
- }
- off += 1 + l
- return string(s), off, nil
-}
-
-func packString(s string, msg []byte, off int) (int, error) {
- txtTmp := make([]byte, 256*4+1)
- off, err := packTxtString(s, msg, off, txtTmp)
- if err != nil {
- return len(msg), err
- }
- return off, nil
-}
-
-func unpackStringBase32(msg []byte, off, end int) (string, int, error) {
- if end > len(msg) {
- return "", len(msg), &Error{err: "overflow unpacking base32"}
- }
- s := toBase32(msg[off:end])
- return s, end, nil
-}
-
-func packStringBase32(s string, msg []byte, off int) (int, error) {
- b32, err := fromBase32([]byte(s))
- if err != nil {
- return len(msg), err
- }
- if off+len(b32) > len(msg) {
- return len(msg), &Error{err: "overflow packing base32"}
- }
- copy(msg[off:off+len(b32)], b32)
- off += len(b32)
- return off, nil
-}
-
-func unpackStringBase64(msg []byte, off, end int) (string, int, error) {
- // Rest of the RR is base64 encoded value, so we don't need an explicit length
- // to be set. Thus far all RR's that have base64 encoded fields have those as their
- // last one. What we do need is the end of the RR!
- if end > len(msg) {
- return "", len(msg), &Error{err: "overflow unpacking base64"}
- }
- s := toBase64(msg[off:end])
- return s, end, nil
-}
-
-func packStringBase64(s string, msg []byte, off int) (int, error) {
- b64, err := fromBase64([]byte(s))
- if err != nil {
- return len(msg), err
- }
- if off+len(b64) > len(msg) {
- return len(msg), &Error{err: "overflow packing base64"}
- }
- copy(msg[off:off+len(b64)], b64)
- off += len(b64)
- return off, nil
-}
-
-func unpackStringHex(msg []byte, off, end int) (string, int, error) {
- // Rest of the RR is hex encoded value, so we don't need an explicit length
- // to be set. NSEC and TSIG have hex fields with a length field.
- // What we do need is the end of the RR!
- if end > len(msg) {
- return "", len(msg), &Error{err: "overflow unpacking hex"}
- }
-
- s := hex.EncodeToString(msg[off:end])
- return s, end, nil
-}
-
-func packStringHex(s string, msg []byte, off int) (int, error) {
- h, err := hex.DecodeString(s)
- if err != nil {
- return len(msg), err
- }
- if off+(len(h)) > len(msg) {
- return len(msg), &Error{err: "overflow packing hex"}
- }
- copy(msg[off:off+len(h)], h)
- off += len(h)
- return off, nil
-}
-
-func unpackStringTxt(msg []byte, off int) ([]string, int, error) {
- txt, off, err := unpackTxt(msg, off)
- if err != nil {
- return nil, len(msg), err
- }
- return txt, off, nil
-}
-
-func packStringTxt(s []string, msg []byte, off int) (int, error) {
- txtTmp := make([]byte, 256*4+1) // If the whole string consists out of \DDD we need this many.
- off, err := packTxt(s, msg, off, txtTmp)
- if err != nil {
- return len(msg), err
- }
- return off, nil
-}
-
-func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) {
- var edns []EDNS0
-Option:
- code := uint16(0)
- if off+4 > len(msg) {
- return nil, len(msg), &Error{err: "overflow unpacking opt"}
- }
- code = binary.BigEndian.Uint16(msg[off:])
- off += 2
- optlen := binary.BigEndian.Uint16(msg[off:])
- off += 2
- if off+int(optlen) > len(msg) {
- return nil, len(msg), &Error{err: "overflow unpacking opt"}
- }
- switch code {
- case EDNS0NSID:
- e := new(EDNS0_NSID)
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- case EDNS0SUBNET, EDNS0SUBNETDRAFT:
- e := new(EDNS0_SUBNET)
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- if code == EDNS0SUBNETDRAFT {
- e.DraftOption = true
- }
- case EDNS0COOKIE:
- e := new(EDNS0_COOKIE)
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- case EDNS0UL:
- e := new(EDNS0_UL)
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- case EDNS0LLQ:
- e := new(EDNS0_LLQ)
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- case EDNS0DAU:
- e := new(EDNS0_DAU)
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- case EDNS0DHU:
- e := new(EDNS0_DHU)
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- case EDNS0N3U:
- e := new(EDNS0_N3U)
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- default:
- e := new(EDNS0_LOCAL)
- e.Code = code
- if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
- return nil, len(msg), err
- }
- edns = append(edns, e)
- off += int(optlen)
- }
-
- if off < len(msg) {
- goto Option
- }
-
- return edns, off, nil
-}
-
-func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) {
- for _, el := range options {
- b, err := el.pack()
- if err != nil || off+3 > len(msg) {
- return len(msg), &Error{err: "overflow packing opt"}
- }
- binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code
- binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length
- off += 4
- if off+len(b) > len(msg) {
- copy(msg[off:], b)
- off = len(msg)
- continue
- }
- // Actual data
- copy(msg[off:off+len(b)], b)
- off += len(b)
- }
- return off, nil
-}
-
-func unpackStringOctet(msg []byte, off int) (string, int, error) {
- s := string(msg[off:])
- return s, len(msg), nil
-}
-
-func packStringOctet(s string, msg []byte, off int) (int, error) {
- txtTmp := make([]byte, 256*4+1)
- off, err := packOctetString(s, msg, off, txtTmp)
- if err != nil {
- return len(msg), err
- }
- return off, nil
-}
-
-func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
- var nsec []uint16
- length, window, lastwindow := 0, 0, -1
- for off < len(msg) {
- if off+2 > len(msg) {
- return nsec, len(msg), &Error{err: "overflow unpacking nsecx"}
- }
- window = int(msg[off])
- length = int(msg[off+1])
- off += 2
- if window <= lastwindow {
- // RFC 4034: Blocks are present in the NSEC RR RDATA in
- // increasing numerical order.
- return nsec, len(msg), &Error{err: "out of order NSEC block"}
- }
- if length == 0 {
- // RFC 4034: Blocks with no types present MUST NOT be included.
- return nsec, len(msg), &Error{err: "empty NSEC block"}
- }
- if length > 32 {
- return nsec, len(msg), &Error{err: "NSEC block too long"}
- }
- if off+length > len(msg) {
- return nsec, len(msg), &Error{err: "overflowing NSEC block"}
- }
-
- // Walk the bytes in the window and extract the type bits
- for j := 0; j < length; j++ {
- b := msg[off+j]
- // Check the bits one by one, and set the type
- if b&0x80 == 0x80 {
- nsec = append(nsec, uint16(window*256+j*8+0))
- }
- if b&0x40 == 0x40 {
- nsec = append(nsec, uint16(window*256+j*8+1))
- }
- if b&0x20 == 0x20 {
- nsec = append(nsec, uint16(window*256+j*8+2))
- }
- if b&0x10 == 0x10 {
- nsec = append(nsec, uint16(window*256+j*8+3))
- }
- if b&0x8 == 0x8 {
- nsec = append(nsec, uint16(window*256+j*8+4))
- }
- if b&0x4 == 0x4 {
- nsec = append(nsec, uint16(window*256+j*8+5))
- }
- if b&0x2 == 0x2 {
- nsec = append(nsec, uint16(window*256+j*8+6))
- }
- if b&0x1 == 0x1 {
- nsec = append(nsec, uint16(window*256+j*8+7))
- }
- }
- off += length
- lastwindow = window
- }
- return nsec, off, nil
-}
-
-func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
- if len(bitmap) == 0 {
- return off, nil
- }
- var lastwindow, lastlength uint16
- for j := 0; j < len(bitmap); j++ {
- t := bitmap[j]
- window := t / 256
- length := (t-window*256)/8 + 1
- if window > lastwindow && lastlength != 0 { // New window, jump to the new offset
- off += int(lastlength) + 2
- lastlength = 0
- }
- if window < lastwindow || length < lastlength {
- return len(msg), &Error{err: "nsec bits out of order"}
- }
- if off+2+int(length) > len(msg) {
- return len(msg), &Error{err: "overflow packing nsec"}
- }
- // Setting the window #
- msg[off] = byte(window)
- // Setting the octets length
- msg[off+1] = byte(length)
- // Setting the bit value for the type in the right octet
- msg[off+1+int(length)] |= byte(1 << (7 - (t % 8)))
- lastwindow, lastlength = window, length
- }
- off += int(lastlength) + 2
- return off, nil
-}
-
-func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) {
- var (
- servers []string
- s string
- err error
- )
- if end > len(msg) {
- return nil, len(msg), &Error{err: "overflow unpacking domain names"}
- }
- for off < end {
- s, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return servers, len(msg), err
- }
- servers = append(servers, s)
- }
- return servers, off, nil
-}
-
-func packDataDomainNames(names []string, msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- var err error
- for j := 0; j < len(names); j++ {
- off, err = PackDomainName(names[j], msg, off, compression, false && compress)
- if err != nil {
- return len(msg), err
- }
- }
- return off, nil
-}
diff --git a/vendor/github.com/miekg/dns/msg_test.go b/vendor/github.com/miekg/dns/msg_test.go
deleted file mode 100644
index 2dbef6260..000000000
--- a/vendor/github.com/miekg/dns/msg_test.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package dns
-
-import (
- "fmt"
- "regexp"
- "strconv"
- "strings"
- "testing"
-)
-
-const (
- maxPrintableLabel = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789x"
- tooLongLabel = maxPrintableLabel + "x"
-)
-
-var (
- longDomain = maxPrintableLabel[:53] + strings.TrimSuffix(
- strings.Join([]string{".", ".", ".", ".", "."}, maxPrintableLabel[:49]), ".")
- reChar = regexp.MustCompile(`.`)
- i = -1
- maxUnprintableLabel = reChar.ReplaceAllStringFunc(maxPrintableLabel, func(ch string) string {
- if i++; i >= 32 {
- i = 0
- }
- return fmt.Sprintf("\\%03d", i)
- })
-)
-
-func TestUnpackDomainName(t *testing.T) {
- var cases = []struct {
- label string
- input string
- expectedOutput string
- expectedError string
- }{
- {"empty domain",
- "\x00",
- ".",
- ""},
- {"long label",
- string(63) + maxPrintableLabel + "\x00",
- maxPrintableLabel + ".",
- ""},
- {"unprintable label",
- string(63) + regexp.MustCompile(`\\[0-9]+`).ReplaceAllStringFunc(maxUnprintableLabel,
- func(escape string) string {
- n, _ := strconv.ParseInt(escape[1:], 10, 8)
- return string(n)
- }) + "\x00",
- maxUnprintableLabel + ".",
- ""},
- {"long domain",
- string(53) + strings.Replace(longDomain, ".", string(49), -1) + "\x00",
- longDomain + ".",
- ""},
- {"compression pointer",
- // an unrealistic but functional test referencing an offset _inside_ a label
- "\x03foo" + "\x05\x03com\x00" + "\x07example" + "\xC0\x05",
- "foo.\\003com\\000.example.com.",
- ""},
-
- {"too long domain",
- string(54) + "x" + strings.Replace(longDomain, ".", string(49), -1) + "\x00",
- "x" + longDomain + ".",
- ErrLongDomain.Error()},
- {"too long by pointer",
- // a matryoshka doll name to get over 255 octets after expansion via internal pointers
- string([]byte{
- // 11 length values, first to last
- 40, 37, 34, 31, 28, 25, 22, 19, 16, 13, 0,
- // 12 filler values
- 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
- // 10 pointers, last to first
- 192, 10, 192, 9, 192, 8, 192, 7, 192, 6, 192, 5, 192, 4, 192, 3, 192, 2, 192, 1,
- }),
- "",
- ErrLongDomain.Error()},
- {"long by pointer",
- // a matryoshka doll name _not_ exceeding 255 octets after expansion
- string([]byte{
- // 11 length values, first to last
- 37, 34, 31, 28, 25, 22, 19, 16, 13, 10, 0,
- // 9 filler values
- 120, 120, 120, 120, 120, 120, 120, 120, 120,
- // 10 pointers, last to first
- 192, 10, 192, 9, 192, 8, 192, 7, 192, 6, 192, 5, 192, 4, 192, 3, 192, 2, 192, 1,
- }),
- "" +
- (`\"\031\028\025\022\019\016\013\010\000xxxxxxxxx` +
- `\192\010\192\009\192\008\192\007\192\006\192\005\192\004\192\003\192\002.`) +
- (`\031\028\025\022\019\016\013\010\000xxxxxxxxx` +
- `\192\010\192\009\192\008\192\007\192\006\192\005\192\004\192\003.`) +
- (`\028\025\022\019\016\013\010\000xxxxxxxxx` +
- `\192\010\192\009\192\008\192\007\192\006\192\005\192\004.`) +
- (`\025\022\019\016\013\010\000xxxxxxxxx` +
- `\192\010\192\009\192\008\192\007\192\006\192\005.`) +
- `\022\019\016\013\010\000xxxxxxxxx\192\010\192\009\192\008\192\007\192\006.` +
- `\019\016\013\010\000xxxxxxxxx\192\010\192\009\192\008\192\007.` +
- `\016\013\010\000xxxxxxxxx\192\010\192\009\192\008.` +
- `\013\010\000xxxxxxxxx\192\010\192\009.` +
- `\010\000xxxxxxxxx\192\010.` +
- `\000xxxxxxxxx.`,
- ""},
- {"truncated name", "\x07example\x03", "", "dns: buffer size too small"},
- {"non-absolute name", "\x07example\x03com", "", "dns: buffer size too small"},
- {"compression pointer cycle",
- "\x03foo" + "\x03bar" + "\x07example" + "\xC0\x04",
- "",
- "dns: too many compression pointers"},
- {"reserved compression pointer 0b10", "\x07example\x80", "", "dns: bad rdata"},
- {"reserved compression pointer 0b01", "\x07example\x40", "", "dns: bad rdata"},
- }
- for _, test := range cases {
- output, idx, err := UnpackDomainName([]byte(test.input), 0)
- if test.expectedOutput != "" && output != test.expectedOutput {
- t.Errorf("%s: expected %s, got %s", test.label, test.expectedOutput, output)
- }
- if test.expectedError == "" && err != nil {
- t.Errorf("%s: expected no error, got %d %v", test.label, idx, err)
- } else if test.expectedError != "" && (err == nil || err.Error() != test.expectedError) {
- t.Errorf("%s: expected error %s, got %d %v", test.label, test.expectedError, idx, err)
- }
- }
-}
diff --git a/vendor/github.com/miekg/dns/nsecx.go b/vendor/github.com/miekg/dns/nsecx.go
deleted file mode 100644
index 9b908c447..000000000
--- a/vendor/github.com/miekg/dns/nsecx.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package dns
-
-import (
- "crypto/sha1"
- "hash"
- "strings"
-)
-
-type saltWireFmt struct {
- Salt string `dns:"size-hex"`
-}
-
-// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
-func HashName(label string, ha uint8, iter uint16, salt string) string {
- saltwire := new(saltWireFmt)
- saltwire.Salt = salt
- wire := make([]byte, DefaultMsgSize)
- n, err := packSaltWire(saltwire, wire)
- if err != nil {
- return ""
- }
- wire = wire[:n]
- name := make([]byte, 255)
- off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
- if err != nil {
- return ""
- }
- name = name[:off]
- var s hash.Hash
- switch ha {
- case SHA1:
- s = sha1.New()
- default:
- return ""
- }
-
- // k = 0
- s.Write(name)
- s.Write(wire)
- nsec3 := s.Sum(nil)
- // k > 0
- for k := uint16(0); k < iter; k++ {
- s.Reset()
- s.Write(nsec3)
- s.Write(wire)
- nsec3 = s.Sum(nsec3[:0])
- }
- return toBase32(nsec3)
-}
-
-// Cover returns true if a name is covered by the NSEC3 record
-func (rr *NSEC3) Cover(name string) bool {
- nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
- owner := strings.ToUpper(rr.Hdr.Name)
- labelIndices := Split(owner)
- if len(labelIndices) < 2 {
- return false
- }
- ownerHash := owner[:labelIndices[1]-1]
- ownerZone := owner[labelIndices[1]:]
- if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
- return false
- }
-
- nextHash := rr.NextDomain
- if ownerHash == nextHash { // empty interval
- return false
- }
- if ownerHash > nextHash { // end of zone
- if nameHash > ownerHash { // covered since there is nothing after ownerHash
- return true
- }
- return nameHash < nextHash // if nameHash is before beginning of zone it is covered
- }
- if nameHash < ownerHash { // nameHash is before ownerHash, not covered
- return false
- }
- return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
-}
-
-// Match returns true if a name matches the NSEC3 record
-func (rr *NSEC3) Match(name string) bool {
- nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
- owner := strings.ToUpper(rr.Hdr.Name)
- labelIndices := Split(owner)
- if len(labelIndices) < 2 {
- return false
- }
- ownerHash := owner[:labelIndices[1]-1]
- ownerZone := owner[labelIndices[1]:]
- if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
- return false
- }
- if ownerHash == nameHash {
- return true
- }
- return false
-}
-
-func packSaltWire(sw *saltWireFmt, msg []byte) (int, error) {
- off, err := packStringHex(sw.Salt, msg, 0)
- if err != nil {
- return off, err
- }
- return off, nil
-}
diff --git a/vendor/github.com/miekg/dns/nsecx_test.go b/vendor/github.com/miekg/dns/nsecx_test.go
deleted file mode 100644
index 8d5f71797..000000000
--- a/vendor/github.com/miekg/dns/nsecx_test.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package dns
-
-import "testing"
-
-func TestPackNsec3(t *testing.T) {
- nsec3 := HashName("dnsex.nl.", SHA1, 0, "DEAD")
- if nsec3 != "ROCCJAE8BJJU7HN6T7NG3TNM8ACRS87J" {
- t.Error(nsec3)
- }
-
- nsec3 = HashName("a.b.c.example.org.", SHA1, 2, "DEAD")
- if nsec3 != "6LQ07OAHBTOOEU2R9ANI2AT70K5O0RCG" {
- t.Error(nsec3)
- }
-}
-
-func TestNsec3(t *testing.T) {
- nsec3, _ := NewRR("sk4e8fj94u78smusb40o1n0oltbblu2r.nl. IN NSEC3 1 1 5 F10E9F7EA83FC8F3 SK4F38CQ0ATIEI8MH3RGD0P5I4II6QAN NS SOA TXT RRSIG DNSKEY NSEC3PARAM")
- if !nsec3.(*NSEC3).Match("nl.") { // name hash = sk4e8fj94u78smusb40o1n0oltbblu2r
- t.Fatal("sk4e8fj94u78smusb40o1n0oltbblu2r.nl. should match sk4e8fj94u78smusb40o1n0oltbblu2r.nl.")
- }
- if !nsec3.(*NSEC3).Match("NL.") { // name hash = sk4e8fj94u78smusb40o1n0oltbblu2r
- t.Fatal("sk4e8fj94u78smusb40o1n0oltbblu2r.NL. should match sk4e8fj94u78smusb40o1n0oltbblu2r.nl.")
- }
- if nsec3.(*NSEC3).Match("com.") { //
- t.Fatal("com. is not in the zone nl.")
- }
- if nsec3.(*NSEC3).Match("test.nl.") { // name hash = gd0ptr5bnfpimpu2d3v6gd4n0bai7s0q
- t.Fatal("gd0ptr5bnfpimpu2d3v6gd4n0bai7s0q.nl. should not match sk4e8fj94u78smusb40o1n0oltbblu2r.nl.")
- }
- nsec3, _ = NewRR("nl. IN NSEC3 1 1 5 F10E9F7EA83FC8F3 SK4F38CQ0ATIEI8MH3RGD0P5I4II6QAN NS SOA TXT RRSIG DNSKEY NSEC3PARAM")
- if nsec3.(*NSEC3).Match("nl.") {
- t.Fatal("sk4e8fj94u78smusb40o1n0oltbblu2r.nl. should not match a record without a owner hash")
- }
-
- for _, tc := range []struct {
- rr *NSEC3
- name string
- covers bool
- }{
- // positive tests
- { // name hash between owner hash and next hash
- rr: &NSEC3{
- Hdr: RR_Header{Name: "2N1TB3VAIRUOBL6RKDVII42N9TFMIALP.com."},
- Hash: 1,
- Flags: 1,
- Iterations: 5,
- Salt: "F10E9F7EA83FC8F3",
- NextDomain: "PT3RON8N7PM3A0OE989IB84OOSADP7O8",
- },
- name: "bsd.com.",
- covers: true,
- },
- { // end of zone, name hash is after owner hash
- rr: &NSEC3{
- Hdr: RR_Header{Name: "3v62ulr0nre83v0rja2vjgtlif9v6rab.com."},
- Hash: 1,
- Flags: 1,
- Iterations: 5,
- Salt: "F10E9F7EA83FC8F3",
- NextDomain: "2N1TB3VAIRUOBL6RKDVII42N9TFMIALP",
- },
- name: "csd.com.",
- covers: true,
- },
- { // end of zone, name hash is before beginning of zone
- rr: &NSEC3{
- Hdr: RR_Header{Name: "PT3RON8N7PM3A0OE989IB84OOSADP7O8.com."},
- Hash: 1,
- Flags: 1,
- Iterations: 5,
- Salt: "F10E9F7EA83FC8F3",
- NextDomain: "3V62ULR0NRE83V0RJA2VJGTLIF9V6RAB",
- },
- name: "asd.com.",
- covers: true,
- },
- // negative tests
- { // too short owner name
- rr: &NSEC3{
- Hdr: RR_Header{Name: "nl."},
- Hash: 1,
- Flags: 1,
- Iterations: 5,
- Salt: "F10E9F7EA83FC8F3",
- NextDomain: "39P99DCGG0MDLARTCRMCF6OFLLUL7PR6",
- },
- name: "asd.com.",
- covers: false,
- },
- { // outside of zone
- rr: &NSEC3{
- Hdr: RR_Header{Name: "39p91242oslggest5e6a7cci4iaeqvnk.nl."},
- Hash: 1,
- Flags: 1,
- Iterations: 5,
- Salt: "F10E9F7EA83FC8F3",
- NextDomain: "39P99DCGG0MDLARTCRMCF6OFLLUL7PR6",
- },
- name: "asd.com.",
- covers: false,
- },
- { // empty interval
- rr: &NSEC3{
- Hdr: RR_Header{Name: "2n1tb3vairuobl6rkdvii42n9tfmialp.com."},
- Hash: 1,
- Flags: 1,
- Iterations: 5,
- Salt: "F10E9F7EA83FC8F3",
- NextDomain: "2N1TB3VAIRUOBL6RKDVII42N9TFMIALP",
- },
- name: "asd.com.",
- covers: false,
- },
- { // name hash is before owner hash, not covered
- rr: &NSEC3{
- Hdr: RR_Header{Name: "3V62ULR0NRE83V0RJA2VJGTLIF9V6RAB.com."},
- Hash: 1,
- Flags: 1,
- Iterations: 5,
- Salt: "F10E9F7EA83FC8F3",
- NextDomain: "PT3RON8N7PM3A0OE989IB84OOSADP7O8",
- },
- name: "asd.com.",
- covers: false,
- },
- } {
- covers := tc.rr.Cover(tc.name)
- if tc.covers != covers {
- t.Fatalf("Cover failed for %s: expected %t, got %t [record: %s]", tc.name, tc.covers, covers, tc.rr)
- }
- }
-}
diff --git a/vendor/github.com/miekg/dns/parse_test.go b/vendor/github.com/miekg/dns/parse_test.go
deleted file mode 100644
index fc5bdaf5d..000000000
--- a/vendor/github.com/miekg/dns/parse_test.go
+++ /dev/null
@@ -1,1540 +0,0 @@
-package dns
-
-import (
- "bytes"
- "crypto/rsa"
- "encoding/hex"
- "fmt"
- "math/rand"
- "net"
- "reflect"
- "strconv"
- "strings"
- "testing"
- "testing/quick"
- "time"
-)
-
-func TestDotInName(t *testing.T) {
- buf := make([]byte, 20)
- PackDomainName("aa\\.bb.nl.", buf, 0, nil, false)
- // index 3 must be a real dot
- if buf[3] != '.' {
- t.Error("dot should be a real dot")
- }
-
- if buf[6] != 2 {
- t.Error("this must have the value 2")
- }
- dom, _, _ := UnpackDomainName(buf, 0)
- // printing it should yield the backspace again
- if dom != "aa\\.bb.nl." {
- t.Error("dot should have been escaped: ", dom)
- }
-}
-
-func TestDotLastInLabel(t *testing.T) {
- sample := "aa\\..au."
- buf := make([]byte, 20)
- _, err := PackDomainName(sample, buf, 0, nil, false)
- if err != nil {
- t.Fatalf("unexpected error packing domain: %v", err)
- }
- dom, _, _ := UnpackDomainName(buf, 0)
- if dom != sample {
- t.Fatalf("unpacked domain `%s' doesn't match packed domain", dom)
- }
-}
-
-func TestTooLongDomainName(t *testing.T) {
- l := "aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt."
- dom := l + l + l + l + l + l + l
- _, err := NewRR(dom + " IN A 127.0.0.1")
- if err == nil {
- t.Error("should be too long")
- } else {
- t.Logf("error is %v", err)
- }
- _, err = NewRR("..com. IN A 127.0.0.1")
- if err == nil {
- t.Error("should fail")
- } else {
- t.Logf("error is %v", err)
- }
-}
-
-func TestDomainName(t *testing.T) {
- tests := []string{"r\\.gieben.miek.nl.", "www\\.www.miek.nl.",
- "www.*.miek.nl.", "www.*.miek.nl.",
- }
- dbuff := make([]byte, 40)
-
- for _, ts := range tests {
- if _, err := PackDomainName(ts, dbuff, 0, nil, false); err != nil {
- t.Error("not a valid domain name")
- continue
- }
- n, _, err := UnpackDomainName(dbuff, 0)
- if err != nil {
- t.Error("failed to unpack packed domain name")
- continue
- }
- if ts != n {
- t.Errorf("must be equal: in: %s, out: %s", ts, n)
- }
- }
-}
-
-func TestDomainNameAndTXTEscapes(t *testing.T) {
- tests := []byte{'.', '(', ')', ';', ' ', '@', '"', '\\', 9, 13, 10, 0, 255}
- for _, b := range tests {
- rrbytes := []byte{
- 1, b, 0, // owner
- byte(TypeTXT >> 8), byte(TypeTXT),
- byte(ClassINET >> 8), byte(ClassINET),
- 0, 0, 0, 1, // TTL
- 0, 2, 1, b, // Data
- }
- rr1, _, err := UnpackRR(rrbytes, 0)
- if err != nil {
- panic(err)
- }
- s := rr1.String()
- rr2, err := NewRR(s)
- if err != nil {
- t.Errorf("Error parsing unpacked RR's string: %v", err)
- t.Errorf(" Bytes: %v", rrbytes)
- t.Errorf("String: %v", s)
- }
- repacked := make([]byte, len(rrbytes))
- if _, err := PackRR(rr2, repacked, 0, nil, false); err != nil {
- t.Errorf("error packing parsed RR: %v", err)
- t.Errorf(" original Bytes: %v", rrbytes)
- t.Errorf("unpacked Struct: %v", rr1)
- t.Errorf(" parsed Struct: %v", rr2)
- }
- if !bytes.Equal(repacked, rrbytes) {
- t.Error("packed bytes don't match original bytes")
- t.Errorf(" original bytes: %v", rrbytes)
- t.Errorf(" packed bytes: %v", repacked)
- t.Errorf("unpacked struct: %v", rr1)
- t.Errorf(" parsed struct: %v", rr2)
- }
- }
-}
-
-func TestTXTEscapeParsing(t *testing.T) {
- test := [][]string{
- {`";"`, `";"`},
- {`\;`, `";"`},
- {`"\t"`, `"t"`},
- {`"\r"`, `"r"`},
- {`"\ "`, `" "`},
- {`"\;"`, `";"`},
- {`"\;\""`, `";\""`},
- {`"\(a\)"`, `"(a)"`},
- {`"\(a)"`, `"(a)"`},
- {`"(a\)"`, `"(a)"`},
- {`"(a)"`, `"(a)"`},
- {`"\048"`, `"0"`},
- {`"\` + "\t" + `"`, `"\009"`},
- {`"\` + "\n" + `"`, `"\010"`},
- {`"\` + "\r" + `"`, `"\013"`},
- {`"\` + "\x11" + `"`, `"\017"`},
- {`"\'"`, `"'"`},
- }
- for _, s := range test {
- rr, err := NewRR(fmt.Sprintf("example.com. IN TXT %v", s[0]))
- if err != nil {
- t.Errorf("could not parse %v TXT: %s", s[0], err)
- continue
- }
-
- txt := sprintTxt(rr.(*TXT).Txt)
- if txt != s[1] {
- t.Errorf("mismatch after parsing `%v` TXT record: `%v` != `%v`", s[0], txt, s[1])
- }
- }
-}
-
-func GenerateDomain(r *rand.Rand, size int) []byte {
- dnLen := size % 70 // artificially limit size so there's less to intrepret if a failure occurs
- var dn []byte
- done := false
- for i := 0; i < dnLen && !done; {
- max := dnLen - i
- if max > 63 {
- max = 63
- }
- lLen := max
- if lLen != 0 {
- lLen = int(r.Int31()) % max
- }
- done = lLen == 0
- if done {
- continue
- }
- l := make([]byte, lLen+1)
- l[0] = byte(lLen)
- for j := 0; j < lLen; j++ {
- l[j+1] = byte(rand.Int31())
- }
- dn = append(dn, l...)
- i += 1 + lLen
- }
- return append(dn, 0)
-}
-
-func TestDomainQuick(t *testing.T) {
- r := rand.New(rand.NewSource(0))
- f := func(l int) bool {
- db := GenerateDomain(r, l)
- ds, _, err := UnpackDomainName(db, 0)
- if err != nil {
- panic(err)
- }
- buf := make([]byte, 255)
- off, err := PackDomainName(ds, buf, 0, nil, false)
- if err != nil {
- t.Errorf("error packing domain: %v", err)
- t.Errorf(" bytes: %v", db)
- t.Errorf("string: %v", ds)
- return false
- }
- if !bytes.Equal(db, buf[:off]) {
- t.Errorf("repacked domain doesn't match original:")
- t.Errorf("src bytes: %v", db)
- t.Errorf(" string: %v", ds)
- t.Errorf("out bytes: %v", buf[:off])
- return false
- }
- return true
- }
- if err := quick.Check(f, nil); err != nil {
- t.Error(err)
- }
-}
-
-func GenerateTXT(r *rand.Rand, size int) []byte {
- rdLen := size % 300 // artificially limit size so there's less to intrepret if a failure occurs
- var rd []byte
- for i := 0; i < rdLen; {
- max := rdLen - 1
- if max > 255 {
- max = 255
- }
- sLen := max
- if max != 0 {
- sLen = int(r.Int31()) % max
- }
- s := make([]byte, sLen+1)
- s[0] = byte(sLen)
- for j := 0; j < sLen; j++ {
- s[j+1] = byte(rand.Int31())
- }
- rd = append(rd, s...)
- i += 1 + sLen
- }
- return rd
-}
-
-// Ok, 2 things. 1) this test breaks with the new functionality of splitting up larger txt
-// chunks into 255 byte pieces. 2) I don't like the random nature of this thing, because I can't
-// place the quotes where they need to be.
-// So either add some code the places the quotes in just the right spots, make this non random
-// or do something else.
-// Disabled for now. (miek)
-func testTXTRRQuick(t *testing.T) {
- s := rand.NewSource(0)
- r := rand.New(s)
- typeAndClass := []byte{
- byte(TypeTXT >> 8), byte(TypeTXT),
- byte(ClassINET >> 8), byte(ClassINET),
- 0, 0, 0, 1, // TTL
- }
- f := func(l int) bool {
- owner := GenerateDomain(r, l)
- rdata := GenerateTXT(r, l)
- rrbytes := make([]byte, 0, len(owner)+2+2+4+2+len(rdata))
- rrbytes = append(rrbytes, owner...)
- rrbytes = append(rrbytes, typeAndClass...)
- rrbytes = append(rrbytes, byte(len(rdata)>>8))
- rrbytes = append(rrbytes, byte(len(rdata)))
- rrbytes = append(rrbytes, rdata...)
- rr, _, err := UnpackRR(rrbytes, 0)
- if err != nil {
- panic(err)
- }
- buf := make([]byte, len(rrbytes)*3)
- off, err := PackRR(rr, buf, 0, nil, false)
- if err != nil {
- t.Errorf("pack Error: %v\nRR: %v", err, rr)
- return false
- }
- buf = buf[:off]
- if !bytes.Equal(buf, rrbytes) {
- t.Errorf("packed bytes don't match original bytes")
- t.Errorf("src bytes: %v", rrbytes)
- t.Errorf(" struct: %v", rr)
- t.Errorf("out bytes: %v", buf)
- return false
- }
- if len(rdata) == 0 {
- // string'ing won't produce any data to parse
- return true
- }
- rrString := rr.String()
- rr2, err := NewRR(rrString)
- if err != nil {
- t.Errorf("error parsing own output: %v", err)
- t.Errorf("struct: %v", rr)
- t.Errorf("string: %v", rrString)
- return false
- }
- if rr2.String() != rrString {
- t.Errorf("parsed rr.String() doesn't match original string")
- t.Errorf("original: %v", rrString)
- t.Errorf(" parsed: %v", rr2.String())
- return false
- }
-
- buf = make([]byte, len(rrbytes)*3)
- off, err = PackRR(rr2, buf, 0, nil, false)
- if err != nil {
- t.Errorf("error packing parsed rr: %v", err)
- t.Errorf("unpacked Struct: %v", rr)
- t.Errorf(" string: %v", rrString)
- t.Errorf(" parsed Struct: %v", rr2)
- return false
- }
- buf = buf[:off]
- if !bytes.Equal(buf, rrbytes) {
- t.Errorf("parsed packed bytes don't match original bytes")
- t.Errorf(" source bytes: %v", rrbytes)
- t.Errorf("unpacked struct: %v", rr)
- t.Errorf(" string: %v", rrString)
- t.Errorf(" parsed struct: %v", rr2)
- t.Errorf(" repacked bytes: %v", buf)
- return false
- }
- return true
- }
- c := &quick.Config{MaxCountScale: 10}
- if err := quick.Check(f, c); err != nil {
- t.Error(err)
- }
-}
-
-func TestParseDirectiveMisc(t *testing.T) {
- tests := map[string]string{
- "$ORIGIN miek.nl.\na IN NS b": "a.miek.nl.\t3600\tIN\tNS\tb.miek.nl.",
- "$TTL 2H\nmiek.nl. IN NS b.": "miek.nl.\t7200\tIN\tNS\tb.",
- "miek.nl. 1D IN NS b.": "miek.nl.\t86400\tIN\tNS\tb.",
- `name. IN SOA a6.nstld.com. hostmaster.nic.name. (
- 203362132 ; serial
- 5m ; refresh (5 minutes)
- 5m ; retry (5 minutes)
- 2w ; expire (2 weeks)
- 300 ; minimum (5 minutes)
-)`: "name.\t3600\tIN\tSOA\ta6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300",
- ". 3600000 IN NS ONE.MY-ROOTS.NET.": ".\t3600000\tIN\tNS\tONE.MY-ROOTS.NET.",
- "ONE.MY-ROOTS.NET. 3600000 IN A 192.168.1.1": "ONE.MY-ROOTS.NET.\t3600000\tIN\tA\t192.168.1.1",
- }
- for i, o := range tests {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestNSEC(t *testing.T) {
- nsectests := map[string]string{
- "nl. IN NSEC3PARAM 1 0 5 30923C44C6CBBB8F": "nl.\t3600\tIN\tNSEC3PARAM\t1 0 5 30923C44C6CBBB8F",
- "p2209hipbpnm681knjnu0m1febshlv4e.nl. IN NSEC3 1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM": "p2209hipbpnm681knjnu0m1febshlv4e.nl.\t3600\tIN\tNSEC3\t1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM",
- "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC",
- "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC TYPE65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534",
- "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSec Type65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534",
- "44ohaq2njb0idnvolt9ggthvsk1e1uv8.skydns.test. NSEC3 1 0 0 - 44OHAQ2NJB0IDNVOLT9GGTHVSK1E1UVA": "44ohaq2njb0idnvolt9ggthvsk1e1uv8.skydns.test.\t3600\tIN\tNSEC3\t1 0 0 - 44OHAQ2NJB0IDNVOLT9GGTHVSK1E1UVA",
- }
- for i, o := range nsectests {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseLOC(t *testing.T) {
- lt := map[string]string{
- "SW1A2AA.find.me.uk. LOC 51 30 12.748 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 30 12.748 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m",
- "SW1A2AA.find.me.uk. LOC 51 0 0.0 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 00 0.000 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m",
- }
- for i, o := range lt {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseDS(t *testing.T) {
- dt := map[string]string{
- "example.net. 3600 IN DS 40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B 2071398F": "example.net.\t3600\tIN\tDS\t40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B2071398F",
- }
- for i, o := range dt {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestQuotes(t *testing.T) {
- tests := map[string]string{
- `t.example.com. IN TXT "a bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a bc\"",
- `t.example.com. IN TXT "a
- bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a\\010 bc\"",
- `t.example.com. IN TXT ""`: "t.example.com.\t3600\tIN\tTXT\t\"\"",
- `t.example.com. IN TXT "a"`: "t.example.com.\t3600\tIN\tTXT\t\"a\"",
- `t.example.com. IN TXT "aa"`: "t.example.com.\t3600\tIN\tTXT\t\"aa\"",
- `t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
- `t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
- `t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
- `t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
- `t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\" \"aaa\"",
- `t.example.com. IN TXT aaa aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\" \"aaa\"",
- `t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
- "cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.",
- "cid.urn.arpa. NAPTR 100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.",
- "cid.urn.arpa. NAPTR 100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.",
- "cid.urn.arpa. NAPTR 100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .",
- }
- for i, o := range tests {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is\n`%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseClass(t *testing.T) {
- tests := map[string]string{
- "t.example.com. IN A 127.0.0.1": "t.example.com. 3600 IN A 127.0.0.1",
- "t.example.com. CS A 127.0.0.1": "t.example.com. 3600 CS A 127.0.0.1",
- "t.example.com. CH A 127.0.0.1": "t.example.com. 3600 CH A 127.0.0.1",
- // ClassANY can not occur in zone files
- // "t.example.com. ANY A 127.0.0.1": "t.example.com. 3600 ANY A 127.0.0.1",
- "t.example.com. NONE A 127.0.0.1": "t.example.com. 3600 NONE A 127.0.0.1",
- }
- for i, o := range tests {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is\n`%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestBrace(t *testing.T) {
- tests := map[string]string{
- "(miek.nl.) 3600 IN A 127.0.1.1": "miek.nl.\t3600\tIN\tA\t127.0.1.1",
- "miek.nl. (3600) IN MX (10) elektron.atoom.net.": "miek.nl.\t3600\tIN\tMX\t10 elektron.atoom.net.",
- `miek.nl. IN (
- 3600 A 127.0.0.1)`: "miek.nl.\t3600\tIN\tA\t127.0.0.1",
- "(miek.nl.) (A) (127.0.2.1)": "miek.nl.\t3600\tIN\tA\t127.0.2.1",
- "miek.nl A 127.0.3.1": "miek.nl.\t3600\tIN\tA\t127.0.3.1",
- "_ssh._tcp.local. 60 IN (PTR) stora._ssh._tcp.local.": "_ssh._tcp.local.\t60\tIN\tPTR\tstora._ssh._tcp.local.",
- "miek.nl. NS ns.miek.nl": "miek.nl.\t3600\tIN\tNS\tns.miek.nl.",
- `(miek.nl.) (
- (IN)
- (AAAA)
- (::1) )`: "miek.nl.\t3600\tIN\tAAAA\t::1",
- `(miek.nl.) (
- (IN)
- (AAAA)
- (::1))`: "miek.nl.\t3600\tIN\tAAAA\t::1",
- "miek.nl. IN AAAA ::2": "miek.nl.\t3600\tIN\tAAAA\t::2",
- `((m)(i)ek.(n)l.) (SOA) (soa.) (soa.) (
- 2009032802 ; serial
- 21600 ; refresh (6 hours)
- 7(2)00 ; retry (2 hours)
- 604()800 ; expire (1 week)
- 3600 ; minimum (1 hour)
- )`: "miek.nl.\t3600\tIN\tSOA\tsoa. soa. 2009032802 21600 7200 604800 3600",
- "miek\\.nl. IN A 127.0.0.10": "miek\\.nl.\t3600\tIN\tA\t127.0.0.10",
- "miek.nl. IN A 127.0.0.11": "miek.nl.\t3600\tIN\tA\t127.0.0.11",
- "miek.nl. A 127.0.0.12": "miek.nl.\t3600\tIN\tA\t127.0.0.12",
- `miek.nl. 86400 IN SOA elektron.atoom.net. miekg.atoom.net. (
- 2009032802 ; serial
- 21600 ; refresh (6 hours)
- 7200 ; retry (2 hours)
- 604800 ; expire (1 week)
- 3600 ; minimum (1 hour)
- )`: "miek.nl.\t86400\tIN\tSOA\telektron.atoom.net. miekg.atoom.net. 2009032802 21600 7200 604800 3600",
- }
- for i, o := range tests {
- rr, err := NewRR(i)
- if err != nil {
- t.Errorf("failed to parse RR: %v\n\t%s", err, i)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseFailure(t *testing.T) {
- tests := []string{"miek.nl. IN A 327.0.0.1",
- "miek.nl. IN AAAA ::x",
- "miek.nl. IN MX a0 miek.nl.",
- "miek.nl aap IN MX mx.miek.nl.",
- "miek.nl 200 IN mxx 10 mx.miek.nl.",
- "miek.nl. inn MX 10 mx.miek.nl.",
- // "miek.nl. IN CNAME ", // actually valid nowadays, zero size rdata
- "miek.nl. IN CNAME ..",
- "miek.nl. PA MX 10 miek.nl.",
- "miek.nl. ) IN MX 10 miek.nl.",
- }
-
- for _, s := range tests {
- _, err := NewRR(s)
- if err == nil {
- t.Errorf("should have triggered an error: \"%s\"", s)
- }
- }
-}
-
-func TestZoneParsing(t *testing.T) {
- // parse_test.db
- db := `
-a.example.com. IN A 127.0.0.1
-8db7._openpgpkey.example.com. IN OPENPGPKEY mQCNAzIG
-$ORIGIN a.example.com.
-test IN A 127.0.0.1
- IN SSHFP 1 2 (
- BC6533CDC95A79078A39A56EA7635984ED655318ADA9
- B6159E30723665DA95BB )
-$ORIGIN b.example.com.
-test IN CNAME test.a.example.com.
-`
- start := time.Now().UnixNano()
- to := ParseZone(strings.NewReader(db), "", "parse_test.db")
- var i int
- for x := range to {
- i++
- if x.Error != nil {
- t.Error(x.Error)
- continue
- }
- t.Log(x.RR)
- }
- delta := time.Now().UnixNano() - start
- t.Logf("%d RRs parsed in %.2f s (%.2f RR/s)", i, float32(delta)/1e9, float32(i)/(float32(delta)/1e9))
-}
-
-func ExampleParseZone() {
- zone := `$ORIGIN .
-$TTL 3600 ; 1 hour
-name IN SOA a6.nstld.com. hostmaster.nic.name. (
- 203362132 ; serial
- 300 ; refresh (5 minutes)
- 300 ; retry (5 minutes)
- 1209600 ; expire (2 weeks)
- 300 ; minimum (5 minutes)
- )
-$TTL 10800 ; 3 hours
-name. 10800 IN NS name.
- IN NS g6.nstld.com.
- 7200 NS h6.nstld.com.
- 3600 IN NS j6.nstld.com.
- IN 3600 NS k6.nstld.com.
- NS l6.nstld.com.
- NS a6.nstld.com.
- NS c6.nstld.com.
- NS d6.nstld.com.
- NS f6.nstld.com.
- NS m6.nstld.com.
-(
- NS m7.nstld.com.
-)
-$ORIGIN name.
-0-0onlus NS ns7.ehiweb.it.
- NS ns8.ehiweb.it.
-0-g MX 10 mx01.nic
- MX 10 mx02.nic
- MX 10 mx03.nic
- MX 10 mx04.nic
-$ORIGIN 0-g.name
-moutamassey NS ns01.yahoodomains.jp.
- NS ns02.yahoodomains.jp.
-`
- to := ParseZone(strings.NewReader(zone), "", "testzone")
- for x := range to {
- fmt.Println(x.RR)
- }
- // Output:
- // name. 3600 IN SOA a6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300
- // name. 10800 IN NS name.
- // name. 10800 IN NS g6.nstld.com.
- // name. 7200 IN NS h6.nstld.com.
- // name. 3600 IN NS j6.nstld.com.
- // name. 3600 IN NS k6.nstld.com.
- // name. 10800 IN NS l6.nstld.com.
- // name. 10800 IN NS a6.nstld.com.
- // name. 10800 IN NS c6.nstld.com.
- // name. 10800 IN NS d6.nstld.com.
- // name. 10800 IN NS f6.nstld.com.
- // name. 10800 IN NS m6.nstld.com.
- // name. 10800 IN NS m7.nstld.com.
- // 0-0onlus.name. 10800 IN NS ns7.ehiweb.it.
- // 0-0onlus.name. 10800 IN NS ns8.ehiweb.it.
- // 0-g.name. 10800 IN MX 10 mx01.nic.name.
- // 0-g.name. 10800 IN MX 10 mx02.nic.name.
- // 0-g.name. 10800 IN MX 10 mx03.nic.name.
- // 0-g.name. 10800 IN MX 10 mx04.nic.name.
- // moutamassey.0-g.name.name. 10800 IN NS ns01.yahoodomains.jp.
- // moutamassey.0-g.name.name. 10800 IN NS ns02.yahoodomains.jp.
-}
-
-func ExampleHIP() {
- h := `www.example.com IN HIP ( 2 200100107B1A74DF365639CC39F1D578
- AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
-9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ
-b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
- rvs.example.com. )`
- if hip, err := NewRR(h); err == nil {
- fmt.Println(hip.String())
- }
- // Output:
- // www.example.com. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
-}
-
-func TestHIP(t *testing.T) {
- h := `www.example.com. IN HIP ( 2 200100107B1A74DF365639CC39F1D578
- AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
-9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ
-b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
- rvs1.example.com.
- rvs2.example.com. )`
- rr, err := NewRR(h)
- if err != nil {
- t.Fatalf("failed to parse RR: %v", err)
- }
- t.Logf("RR: %s", rr)
- msg := new(Msg)
- msg.Answer = []RR{rr, rr}
- bytes, err := msg.Pack()
- if err != nil {
- t.Fatalf("failed to pack msg: %v", err)
- }
- if err := msg.Unpack(bytes); err != nil {
- t.Fatalf("failed to unpack msg: %v", err)
- }
- if len(msg.Answer) != 2 {
- t.Fatalf("2 answers expected: %v", msg)
- }
- for i, rr := range msg.Answer {
- rr := rr.(*HIP)
- t.Logf("RR: %s", rr)
- if l := len(rr.RendezvousServers); l != 2 {
- t.Fatalf("2 servers expected, only %d in record %d:\n%v", l, i, msg)
- }
- for j, s := range []string{"rvs1.example.com.", "rvs2.example.com."} {
- if rr.RendezvousServers[j] != s {
- t.Fatalf("expected server %d of record %d to be %s:\n%v", j, i, s, msg)
- }
- }
- }
-}
-
-func ExampleSOA() {
- s := "example.com. 1000 SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100"
- if soa, err := NewRR(s); err == nil {
- fmt.Println(soa.String())
- }
- // Output:
- // example.com. 1000 IN SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100
-}
-
-func TestLineNumberError(t *testing.T) {
- s := "example.com. 1000 SOA master.example.com. admin.example.com. monkey 4294967294 4294967293 4294967295 100"
- if _, err := NewRR(s); err != nil {
- if err.Error() != "dns: bad SOA zone parameter: \"monkey\" at line: 1:68" {
- t.Error("not expecting this error: ", err)
- }
- }
-}
-
-// Test with no known RR on the line
-func TestLineNumberError2(t *testing.T) {
- tests := map[string]string{
- "example.com. 1000 SO master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100": "dns: expecting RR type or class, not this...: \"SO\" at line: 1:21",
- "example.com 1000 IN TALINK a.example.com. b..example.com.": "dns: bad TALINK NextName: \"b..example.com.\" at line: 1:57",
- "example.com 1000 IN TALINK ( a.example.com. b..example.com. )": "dns: bad TALINK NextName: \"b..example.com.\" at line: 1:60",
- `example.com 1000 IN TALINK ( a.example.com.
- bb..example.com. )`: "dns: bad TALINK NextName: \"bb..example.com.\" at line: 2:18",
- // This is a bug, it should report an error on line 1, but the new is already processed.
- `example.com 1000 IN TALINK ( a.example.com. b...example.com.
- )`: "dns: bad TALINK NextName: \"b...example.com.\" at line: 2:1"}
-
- for in, errStr := range tests {
- _, err := NewRR(in)
- if err == nil {
- t.Error("err is nil")
- } else {
- if err.Error() != errStr {
- t.Errorf("%s: error should be %s is %v", in, errStr, err)
- }
- }
- }
-}
-
-// Test if the calculations are correct
-func TestRfc1982(t *testing.T) {
- // If the current time and the timestamp are more than 68 years apart
- // it means the date has wrapped. 0 is 1970
-
- // fall in the current 68 year span
- strtests := []string{"20120525134203", "19700101000000", "20380119031408"}
- for _, v := range strtests {
- if x, _ := StringToTime(v); v != TimeToString(x) {
- t.Errorf("1982 arithmetic string failure %s (%s:%d)", v, TimeToString(x), x)
- }
- }
-
- inttests := map[uint32]string{0: "19700101000000",
- 1 << 31: "20380119031408",
- 1<<32 - 1: "21060207062815",
- }
- for i, v := range inttests {
- if TimeToString(i) != v {
- t.Errorf("1982 arithmetic int failure %d:%s (%s)", i, v, TimeToString(i))
- }
- }
-
- // Future tests, these dates get parsed to a date within the current 136 year span
- future := map[string]string{"22680119031408": "20631123173144",
- "19010101121212": "20370206184028",
- "19210101121212": "20570206184028",
- "19500101121212": "20860206184028",
- "19700101000000": "19700101000000",
- "19690101000000": "21050207062816",
- "29210101121212": "21040522212236",
- }
- for from, to := range future {
- x, _ := StringToTime(from)
- y := TimeToString(x)
- if y != to {
- t.Errorf("1982 arithmetic future failure %s:%s (%s)", from, to, y)
- }
- }
-}
-
-func TestEmpty(t *testing.T) {
- for range ParseZone(strings.NewReader(""), "", "") {
- t.Errorf("should be empty")
- }
-}
-
-func TestLowercaseTokens(t *testing.T) {
- var testrecords = []string{
- "example.org. 300 IN a 1.2.3.4",
- "example.org. 300 in A 1.2.3.4",
- "example.org. 300 in a 1.2.3.4",
- "example.org. 300 a 1.2.3.4",
- "example.org. 300 A 1.2.3.4",
- "example.org. IN a 1.2.3.4",
- "example.org. in A 1.2.3.4",
- "example.org. in a 1.2.3.4",
- "example.org. a 1.2.3.4",
- "example.org. A 1.2.3.4",
- "example.org. a 1.2.3.4",
- "$ORIGIN example.org.\n a 1.2.3.4",
- "$Origin example.org.\n a 1.2.3.4",
- "$origin example.org.\n a 1.2.3.4",
- "example.org. Class1 Type1 1.2.3.4",
- }
- for _, testrr := range testrecords {
- _, err := NewRR(testrr)
- if err != nil {
- t.Errorf("failed to parse %#v, got %v", testrr, err)
- }
- }
-}
-
-func ExampleParseZone_generate() {
- // From the manual: http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2566761
- zone := "$GENERATE 1-2 0 NS SERVER$.EXAMPLE.\n$GENERATE 1-8 $ CNAME $.0"
- to := ParseZone(strings.NewReader(zone), "0.0.192.IN-ADDR.ARPA.", "")
- for x := range to {
- if x.Error == nil {
- fmt.Println(x.RR.String())
- }
- }
- // Output:
- // 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER1.EXAMPLE.
- // 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER2.EXAMPLE.
- // 1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.
- // 2.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 2.0.0.0.192.IN-ADDR.ARPA.
- // 3.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 3.0.0.0.192.IN-ADDR.ARPA.
- // 4.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 4.0.0.0.192.IN-ADDR.ARPA.
- // 5.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 5.0.0.0.192.IN-ADDR.ARPA.
- // 6.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 6.0.0.0.192.IN-ADDR.ARPA.
- // 7.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 7.0.0.0.192.IN-ADDR.ARPA.
- // 8.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 8.0.0.0.192.IN-ADDR.ARPA.
-}
-
-func TestSRVPacking(t *testing.T) {
- msg := Msg{}
-
- things := []string{"1.2.3.4:8484",
- "45.45.45.45:8484",
- "84.84.84.84:8484",
- }
-
- for i, n := range things {
- h, p, err := net.SplitHostPort(n)
- if err != nil {
- continue
- }
- port, _ := strconv.ParseUint(p, 10, 16)
-
- rr := &SRV{
- Hdr: RR_Header{Name: "somename.",
- Rrtype: TypeSRV,
- Class: ClassINET,
- Ttl: 5},
- Priority: uint16(i),
- Weight: 5,
- Port: uint16(port),
- Target: h + ".",
- }
-
- msg.Answer = append(msg.Answer, rr)
- }
-
- _, err := msg.Pack()
- if err != nil {
- t.Fatalf("couldn't pack %v: %v", msg, err)
- }
-}
-
-func TestParseBackslash(t *testing.T) {
- if r, err := NewRR("nul\\000gap.test.globnix.net. 600 IN A 192.0.2.10"); err != nil {
- t.Errorf("could not create RR with \\000 in it")
- } else {
- t.Logf("parsed %s", r.String())
- }
- if r, err := NewRR(`nul\000gap.test.globnix.net. 600 IN TXT "Hello\123"`); err != nil {
- t.Errorf("could not create RR with \\000 in it")
- } else {
- t.Logf("parsed %s", r.String())
- }
- if r, err := NewRR(`m\ @\ iek.nl. IN 3600 A 127.0.0.1`); err != nil {
- t.Errorf("could not create RR with \\ and \\@ in it")
- } else {
- t.Logf("parsed %s", r.String())
- }
-}
-
-func TestILNP(t *testing.T) {
- tests := []string{
- "host1.example.com.\t3600\tIN\tNID\t10 0014:4fff:ff20:ee64",
- "host1.example.com.\t3600\tIN\tNID\t20 0015:5fff:ff21:ee65",
- "host2.example.com.\t3600\tIN\tNID\t10 0016:6fff:ff22:ee66",
- "host1.example.com.\t3600\tIN\tL32\t10 10.1.2.0",
- "host1.example.com.\t3600\tIN\tL32\t20 10.1.4.0",
- "host2.example.com.\t3600\tIN\tL32\t10 10.1.8.0",
- "host1.example.com.\t3600\tIN\tL64\t10 2001:0DB8:1140:1000",
- "host1.example.com.\t3600\tIN\tL64\t20 2001:0DB8:2140:2000",
- "host2.example.com.\t3600\tIN\tL64\t10 2001:0DB8:4140:4000",
- "host1.example.com.\t3600\tIN\tLP\t10 l64-subnet1.example.com.",
- "host1.example.com.\t3600\tIN\tLP\t10 l64-subnet2.example.com.",
- "host1.example.com.\t3600\tIN\tLP\t20 l32-subnet1.example.com.",
- }
- for _, t1 := range tests {
- r, err := NewRR(t1)
- if err != nil {
- t.Fatalf("an error occurred: %v", err)
- } else {
- if t1 != r.String() {
- t.Fatalf("strings should be equal %s %s", t1, r.String())
- }
- }
- }
-}
-
-func TestGposEidNimloc(t *testing.T) {
- dt := map[string]string{
- "444433332222111199990123000000ff. NSAP-PTR foo.bar.com.": "444433332222111199990123000000ff.\t3600\tIN\tNSAP-PTR\tfoo.bar.com.",
- "lillee. IN GPOS -32.6882 116.8652 10.0": "lillee.\t3600\tIN\tGPOS\t-32.6882 116.8652 10.0",
- "hinault. IN GPOS -22.6882 116.8652 250.0": "hinault.\t3600\tIN\tGPOS\t-22.6882 116.8652 250.0",
- "VENERA. IN NIMLOC 75234159EAC457800920": "VENERA.\t3600\tIN\tNIMLOC\t75234159EAC457800920",
- "VAXA. IN EID 3141592653589793": "VAXA.\t3600\tIN\tEID\t3141592653589793",
- }
- for i, o := range dt {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestPX(t *testing.T) {
- dt := map[string]string{
- "*.net2.it. IN PX 10 net2.it. PRMD-net2.ADMD-p400.C-it.": "*.net2.it.\t3600\tIN\tPX\t10 net2.it. PRMD-net2.ADMD-p400.C-it.",
- "ab.net2.it. IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.": "ab.net2.it.\t3600\tIN\tPX\t10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.",
- }
- for i, o := range dt {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestComment(t *testing.T) {
- // Comments we must see
- comments := map[string]bool{"; this is comment 1": true,
- "; this is comment 4": true, "; this is comment 6": true,
- "; this is comment 7": true, "; this is comment 8": true}
- zone := `
-foo. IN A 10.0.0.1 ; this is comment 1
-foo. IN A (
- 10.0.0.2 ; this is comment2
-)
-; this is comment3
-foo. IN A 10.0.0.3
-foo. IN A ( 10.0.0.4 ); this is comment 4
-
-foo. IN A 10.0.0.5
-; this is comment5
-
-foo. IN A 10.0.0.6
-
-foo. IN DNSKEY 256 3 5 AwEAAb+8l ; this is comment 6
-foo. IN NSEC miek.nl. TXT RRSIG NSEC; this is comment 7
-foo. IN TXT "THIS IS TEXT MAN"; this is comment 8
-`
- for x := range ParseZone(strings.NewReader(zone), ".", "") {
- if x.Error == nil {
- if x.Comment != "" {
- if _, ok := comments[x.Comment]; !ok {
- t.Errorf("wrong comment %s", x.Comment)
- }
- }
- }
- }
-}
-
-func TestEUIxx(t *testing.T) {
- tests := map[string]string{
- "host.example. IN EUI48 00-00-5e-90-01-2a": "host.example.\t3600\tIN\tEUI48\t00-00-5e-90-01-2a",
- "host.example. IN EUI64 00-00-5e-ef-00-00-00-2a": "host.example.\t3600\tIN\tEUI64\t00-00-5e-ef-00-00-00-2a",
- }
- for i, o := range tests {
- r, err := NewRR(i)
- if err != nil {
- t.Errorf("failed to parse %s: %v", i, err)
- }
- if r.String() != o {
- t.Errorf("want %s, got %s", o, r.String())
- }
- }
-}
-
-func TestUserRR(t *testing.T) {
- tests := map[string]string{
- "host.example. IN UID 1234": "host.example.\t3600\tIN\tUID\t1234",
- "host.example. IN GID 1234556": "host.example.\t3600\tIN\tGID\t1234556",
- "host.example. IN UINFO \"Miek Gieben\"": "host.example.\t3600\tIN\tUINFO\t\"Miek Gieben\"",
- }
- for i, o := range tests {
- r, err := NewRR(i)
- if err != nil {
- t.Errorf("failed to parse %s: %v", i, err)
- }
- if r.String() != o {
- t.Errorf("want %s, got %s", o, r.String())
- }
- }
-}
-
-func TestTXT(t *testing.T) {
- // Test single entry TXT record
- rr, err := NewRR(`_raop._tcp.local. 60 IN TXT "single value"`)
- if err != nil {
- t.Error("failed to parse single value TXT record", err)
- } else if rr, ok := rr.(*TXT); !ok {
- t.Error("wrong type, record should be of type TXT")
- } else {
- if len(rr.Txt) != 1 {
- t.Error("bad size of TXT value:", len(rr.Txt))
- } else if rr.Txt[0] != "single value" {
- t.Error("bad single value")
- }
- if rr.String() != `_raop._tcp.local. 60 IN TXT "single value"` {
- t.Error("bad representation of TXT record:", rr.String())
- }
- if rr.len() != 28+1+12 {
- t.Error("bad size of serialized record:", rr.len())
- }
- }
-
- // Test multi entries TXT record
- rr, err = NewRR(`_raop._tcp.local. 60 IN TXT "a=1" "b=2" "c=3" "d=4"`)
- if err != nil {
- t.Error("failed to parse multi-values TXT record", err)
- } else if rr, ok := rr.(*TXT); !ok {
- t.Error("wrong type, record should be of type TXT")
- } else {
- if len(rr.Txt) != 4 {
- t.Error("bad size of TXT multi-value:", len(rr.Txt))
- } else if rr.Txt[0] != "a=1" || rr.Txt[1] != "b=2" || rr.Txt[2] != "c=3" || rr.Txt[3] != "d=4" {
- t.Error("bad values in TXT records")
- }
- if rr.String() != `_raop._tcp.local. 60 IN TXT "a=1" "b=2" "c=3" "d=4"` {
- t.Error("bad representation of TXT multi value record:", rr.String())
- }
- if rr.len() != 28+1+3+1+3+1+3+1+3 {
- t.Error("bad size of serialized multi value record:", rr.len())
- }
- }
-
- // Test empty-string in TXT record
- rr, err = NewRR(`_raop._tcp.local. 60 IN TXT ""`)
- if err != nil {
- t.Error("failed to parse empty-string TXT record", err)
- } else if rr, ok := rr.(*TXT); !ok {
- t.Error("wrong type, record should be of type TXT")
- } else {
- if len(rr.Txt) != 1 {
- t.Error("bad size of TXT empty-string value:", len(rr.Txt))
- } else if rr.Txt[0] != "" {
- t.Error("bad value for empty-string TXT record")
- }
- if rr.String() != `_raop._tcp.local. 60 IN TXT ""` {
- t.Error("bad representation of empty-string TXT record:", rr.String())
- }
- if rr.len() != 28+1 {
- t.Error("bad size of serialized record:", rr.len())
- }
- }
-
- // Test TXT record with chunk larger than 255 bytes, they should be split up, by the parser
- s := ""
- for i := 0; i < 255; i++ {
- s += "a"
- }
- s += "b"
- rr, err = NewRR(`test.local. 60 IN TXT "` + s + `"`)
- if err != nil {
- t.Error("failed to parse empty-string TXT record", err)
- }
- if rr.(*TXT).Txt[1] != "b" {
- t.Errorf("Txt should have two chunk, last one my be 'b', but is %s", rr.(*TXT).Txt[1])
- }
- t.Log(rr.String())
-}
-
-func TestTypeXXXX(t *testing.T) {
- _, err := NewRR("example.com IN TYPE1234 \\# 4 aabbccdd")
- if err != nil {
- t.Errorf("failed to parse TYPE1234 RR: %v", err)
- }
- _, err = NewRR("example.com IN TYPE655341 \\# 8 aabbccddaabbccdd")
- if err == nil {
- t.Errorf("this should not work, for TYPE655341")
- }
- _, err = NewRR("example.com IN TYPE1 \\# 4 0a000001")
- if err == nil {
- t.Errorf("this should not work")
- }
-}
-
-func TestPTR(t *testing.T) {
- _, err := NewRR("144.2.0.192.in-addr.arpa. 900 IN PTR ilouse03146p0\\(.example.com.")
- if err != nil {
- t.Error("failed to parse ", err)
- }
-}
-
-func TestDigit(t *testing.T) {
- tests := map[string]byte{
- "miek\\000.nl. 100 IN TXT \"A\"": 0,
- "miek\\001.nl. 100 IN TXT \"A\"": 1,
- "miek\\254.nl. 100 IN TXT \"A\"": 254,
- "miek\\255.nl. 100 IN TXT \"A\"": 255,
- "miek\\256.nl. 100 IN TXT \"A\"": 0,
- "miek\\257.nl. 100 IN TXT \"A\"": 1,
- "miek\\004.nl. 100 IN TXT \"A\"": 4,
- }
- for s, i := range tests {
- r, err := NewRR(s)
- buf := make([]byte, 40)
- if err != nil {
- t.Fatalf("failed to parse %v", err)
- }
- PackRR(r, buf, 0, nil, false)
- t.Log(buf)
- if buf[5] != i {
- t.Fatalf("5 pos must be %d, is %d", i, buf[5])
- }
- r1, _, _ := UnpackRR(buf, 0)
- if r1.Header().Ttl != 100 {
- t.Fatalf("TTL should %d, is %d", 100, r1.Header().Ttl)
- }
- }
-}
-
-func TestParseRRSIGTimestamp(t *testing.T) {
- tests := map[string]bool{
- `miek.nl. IN RRSIG SOA 8 2 43200 20140210031301 20140111031301 12051 miek.nl. MVZUyrYwq0iZhMFDDnVXD2BvuNiUJjSYlJAgzyAE6CF875BMvvZa+Sb0 RlSCL7WODQSQHhCx/fegHhVVF+Iz8N8kOLrmXD1+jO3Bm6Prl5UhcsPx WTBsg/kmxbp8sR1kvH4oZJtVfakG3iDerrxNaf0sQwhZzyfJQAqpC7pcBoc=`: true,
- `miek.nl. IN RRSIG SOA 8 2 43200 315565800 4102477800 12051 miek.nl. MVZUyrYwq0iZhMFDDnVXD2BvuNiUJjSYlJAgzyAE6CF875BMvvZa+Sb0 RlSCL7WODQSQHhCx/fegHhVVF+Iz8N8kOLrmXD1+jO3Bm6Prl5UhcsPx WTBsg/kmxbp8sR1kvH4oZJtVfakG3iDerrxNaf0sQwhZzyfJQAqpC7pcBoc=`: true,
- }
- for r := range tests {
- _, err := NewRR(r)
- if err != nil {
- t.Error(err)
- }
- }
-}
-
-func TestTxtEqual(t *testing.T) {
- rr1 := new(TXT)
- rr1.Hdr = RR_Header{Name: ".", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
- rr1.Txt = []string{"a\"a", "\"", "b"}
- rr2, _ := NewRR(rr1.String())
- if rr1.String() != rr2.String() {
- // This is not an error, but keep this test.
- t.Errorf("these two TXT records should match:\n%s\n%s", rr1.String(), rr2.String())
- }
- t.Logf("%s\n%s", rr1.String(), rr2.String())
-}
-
-func TestTxtLong(t *testing.T) {
- rr1 := new(TXT)
- rr1.Hdr = RR_Header{Name: ".", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
- // Make a long txt record, this breaks when sending the packet,
- // but not earlier.
- rr1.Txt = []string{"start-"}
- for i := 0; i < 200; i++ {
- rr1.Txt[0] += "start-"
- }
- str := rr1.String()
- if len(str) < len(rr1.Txt[0]) {
- t.Error("string conversion should work")
- }
-}
-
-// Basically, don't crash.
-func TestMalformedPackets(t *testing.T) {
- var packets = []string{
- "0021641c0000000100000000000078787878787878787878787303636f6d0000100001",
- }
-
- // com = 63 6f 6d
- for _, packet := range packets {
- data, _ := hex.DecodeString(packet)
- // for _, v := range data {
- // t.Log(v)
- // }
- var msg Msg
- msg.Unpack(data)
- // println(msg.String())
- }
-}
-
-type algorithm struct {
- name uint8
- bits int
-}
-
-func TestNewPrivateKey(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- algorithms := []algorithm{
- {ECDSAP256SHA256, 256},
- {ECDSAP384SHA384, 384},
- {RSASHA1, 1024},
- {RSASHA256, 2048},
- {DSA, 1024},
- }
-
- for _, algo := range algorithms {
- key := new(DNSKEY)
- key.Hdr.Rrtype = TypeDNSKEY
- key.Hdr.Name = "miek.nl."
- key.Hdr.Class = ClassINET
- key.Hdr.Ttl = 14400
- key.Flags = 256
- key.Protocol = 3
- key.Algorithm = algo.name
- privkey, err := key.Generate(algo.bits)
- if err != nil {
- t.Fatal(err)
- }
-
- newPrivKey, err := key.NewPrivateKey(key.PrivateKeyString(privkey))
- if err != nil {
- t.Error(key.String())
- t.Error(key.PrivateKeyString(privkey))
- t.Fatal(err)
- }
-
- switch newPrivKey := newPrivKey.(type) {
- case *rsa.PrivateKey:
- newPrivKey.Precompute()
- }
-
- if !reflect.DeepEqual(privkey, newPrivKey) {
- t.Errorf("[%v] Private keys differ:\n%#v\n%#v", AlgorithmToString[algo.name], privkey, newPrivKey)
- }
- }
-}
-
-// special input test
-func TestNewRRSpecial(t *testing.T) {
- var (
- rr RR
- err error
- expect string
- )
-
- rr, err = NewRR("; comment")
- expect = ""
- if err != nil {
- t.Errorf("unexpected err: %v", err)
- }
- if rr != nil {
- t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
- }
-
- rr, err = NewRR("")
- expect = ""
- if err != nil {
- t.Errorf("unexpected err: %v", err)
- }
- if rr != nil {
- t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
- }
-
- rr, err = NewRR("$ORIGIN foo.")
- expect = ""
- if err != nil {
- t.Errorf("unexpected err: %v", err)
- }
- if rr != nil {
- t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
- }
-
- rr, err = NewRR(" ")
- expect = ""
- if err != nil {
- t.Errorf("unexpected err: %v", err)
- }
- if rr != nil {
- t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
- }
-
- rr, err = NewRR("\n")
- expect = ""
- if err != nil {
- t.Errorf("unexpected err: %v", err)
- }
- if rr != nil {
- t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
- }
-
- rr, err = NewRR("foo. A 1.1.1.1\nbar. A 2.2.2.2")
- expect = "foo.\t3600\tIN\tA\t1.1.1.1"
- if err != nil {
- t.Errorf("unexpected err: %v", err)
- }
- if rr == nil || rr.String() != expect {
- t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
- }
-}
-
-func TestPrintfVerbsRdata(t *testing.T) {
- x, _ := NewRR("www.miek.nl. IN MX 20 mx.miek.nl.")
- if Field(x, 1) != "20" {
- t.Errorf("should be 20")
- }
- if Field(x, 2) != "mx.miek.nl." {
- t.Errorf("should be mx.miek.nl.")
- }
-
- x, _ = NewRR("www.miek.nl. IN A 127.0.0.1")
- if Field(x, 1) != "127.0.0.1" {
- t.Errorf("should be 127.0.0.1")
- }
-
- x, _ = NewRR("www.miek.nl. IN AAAA ::1")
- if Field(x, 1) != "::1" {
- t.Errorf("should be ::1")
- }
-
- x, _ = NewRR("www.miek.nl. IN NSEC a.miek.nl. A NS SOA MX AAAA")
- if Field(x, 1) != "a.miek.nl." {
- t.Errorf("should be a.miek.nl.")
- }
- if Field(x, 2) != "A NS SOA MX AAAA" {
- t.Errorf("should be A NS SOA MX AAAA")
- }
-
- x, _ = NewRR("www.miek.nl. IN TXT \"first\" \"second\"")
- if Field(x, 1) != "first second" {
- t.Errorf("should be first second")
- }
- if Field(x, 0) != "" {
- t.Errorf("should be empty")
- }
-}
-
-func TestParseTokenOverflow(t *testing.T) {
- _, err := NewRR("_443._tcp.example.org. IN TLSA 0 0 0 308205e8308204d0a00302010202100411de8f53b462f6a5a861b712ec6b59300d06092a864886f70d01010b05003070310b300906035504061302555331153013060355040a130c446967694365727420496e6331193017060355040b13107777772e64696769636572742e636f6d312f302d06035504031326446967694365727420534841322048696768204173737572616e636520536572766572204341301e170d3134313130363030303030305a170d3135313131333132303030305a3081a5310b3009060355040613025553311330110603550408130a43616c69666f726e6961311430120603550407130b4c6f7320416e67656c6573313c303a060355040a1333496e7465726e657420436f72706f726174696f6e20666f722041737369676e6564204e616d657320616e64204e756d6265727331133011060355040b130a546563686e6f6c6f6779311830160603550403130f7777772e6578616d706c652e6f726730820122300d06092a864886f70d01010105000382010f003082010a02820101009e663f52a3d18cb67cdfed547408a4e47e4036538988da2798da3b6655f7240d693ed1cb3fe6d6ad3a9e657ff6efa86b83b0cad24e5d31ff2bf70ec3b78b213f1b4bf61bdc669cbbc07d67154128ca92a9b3cbb4213a836fb823ddd4d7cc04918314d25f06086fa9970ba17e357cca9b458c27eb71760ab95e3f9bc898ae89050ae4d09ba2f7e4259d9ff1e072a6971b18355a8b9e53670c3d5dbdbd283f93a764e71b3a4140ca0746090c08510e2e21078d7d07844bf9c03865b531a0bf2ee766bc401f6451c5a1e6f6fb5d5c1d6a97a0abe91ae8b02e89241e07353909ccd5b41c46de207c06801e08f20713603827f2ae3e68cf15ef881d7e0608f70742e30203010001a382024630820242301f0603551d230418301680145168ff90af0207753cccd9656462a212b859723b301d0603551d0e04160414b000a7f422e9b1ce216117c4c46e7164c8e60c553081810603551d11047a3078820f7777772e6578616d706c652e6f7267820b6578616d706c652e636f6d820b6578616d706c652e656475820b6578616d706c652e6e6574820b6578616d706c652e6f7267820f7777772e6578616d706c652e636f6d820f7777772e6578616d706c652e656475820f7777772e6578616d706c652e6e6574300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b0601050507030230750603551d1f046e306c3034a032a030862e687474703a2f2f63726c332e64696769636572742e636f6d2f736861322d68612d7365727665722d67332e63726c3034a032a030862e687474703a2f2f63726c342e64696769636572742e636f6d2f736861322d68612d7365727665722d67332e63726c30420603551d20043b3039303706096086480186fd6c0101302a302806082b06010505070201161c68747470733a2f2f7777772e64696769636572742e636f6d2f43505330818306082b0601050507010104773075302406082b060105050730018618687474703a2f2f6f6373702e64696769636572742e636f6d304d06082b060105050730028641687474703a2f2f636163657274732e64696769636572742e636f6d2f446967694365727453484132486967684173737572616e636553657276657243412e637274300c0603551d130101ff04023000300d06092a864886f70d01010b050003820101005eac2124dedb3978a86ff3608406acb542d3cb54cb83facd63aec88144d6a1bf15dbf1f215c4a73e241e582365cba9ea50dd306541653b3513af1a0756c1b2720e8d112b34fb67181efad9c4609bdc670fb025fa6e6d42188161b026cf3089a08369c2f3609fc84bcc3479140c1922ede430ca8dbac2b2a3cdacb305ba15dc7361c4c3a5e6daa99cb446cb221b28078a7a944efba70d96f31ac143d959bccd2fd50e30c325ea2624fb6b6dbe9344dbcf133bfbd5b4e892d635dbf31596451672c6b65ba5ac9b3cddea92b35dab1065cae3c8cb6bb450a62ea2f72ea7c6bdc7b65fa09b012392543734083c7687d243f8d0375304d99ccd2e148966a8637a6797")
- if err == nil {
- t.Fatalf("token overflow should return an error")
- }
- t.Logf("err: %s\n", err)
-}
-
-func TestParseTLSA(t *testing.T) {
- lt := []string{
- "_443._tcp.example.org.\t3600\tIN\tTLSA\t1 1 1 c22be239f483c08957bc106219cc2d3ac1a308dfbbdd0a365f17b9351234cf00",
- "_443._tcp.example.org.\t3600\tIN\tTLSA\t2 1 2 4e85f45179e9cd6e0e68e2eb5be2e85ec9b92d91c609caf3ef0315213e3f92ece92c38397a607214de95c7fadc0ad0f1c604a469a0387959745032c0d51492f3",
- "_443._tcp.example.org.\t3600\tIN\tTLSA\t3 0 2 69ec8d2277360b215d0cd956b0e2747108dff34b27d461a41c800629e38ee6c2d1230cc9e8e36711330adc6766e6ff7c5fbb37f106f248337c1a20ad682888d2",
- }
- for _, o := range lt {
- rr, err := NewRR(o)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", o, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseSMIMEA(t *testing.T) {
- lt := map[string]string{
- "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t1 1 2 bd80f334566928fc18f58df7e4928c1886f48f71ca3fd41cd9b1854aca7c2180aaacad2819612ed68e7bd3701cc39be7f2529b017c0bc6a53e8fb3f0c7d48070": "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t1 1 2 bd80f334566928fc18f58df7e4928c1886f48f71ca3fd41cd9b1854aca7c2180aaacad2819612ed68e7bd3701cc39be7f2529b017c0bc6a53e8fb3f0c7d48070",
- "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t0 0 1 cdcf0fc66b182928c5217ddd42c826983f5a4b94160ee6c1c9be62d38199f710": "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t0 0 1 cdcf0fc66b182928c5217ddd42c826983f5a4b94160ee6c1c9be62d38199f710",
- "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t3 0 2 499a1eda2af8828b552cdb9d80c3744a25872fddd73f3898d8e4afa3549595d2dd4340126e759566fe8c26b251fa0c887ba4869f011a65f7e79967c2eb729f5b": "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t3 0 2 499a1eda2af8828b552cdb9d80c3744a25872fddd73f3898d8e4afa3549595d2dd4340126e759566fe8c26b251fa0c887ba4869f011a65f7e79967c2eb729f5b",
- "2e85e1db3e62be6eb._smimecert.example.com.\t3600\tIN\tSMIMEA\t3 0 2 499a1eda2af8828b552cdb9d80c3744a25872fddd73f3898d8e4afa3549595d2dd4340126e759566fe8 c26b251fa0c887ba4869f01 1a65f7e79967c2eb729f5b": "2e85e1db3e62be6eb._smimecert.example.com.\t3600\tIN\tSMIMEA\t3 0 2 499a1eda2af8828b552cdb9d80c3744a25872fddd73f3898d8e4afa3549595d2dd4340126e759566fe8c26b251fa0c887ba4869f011a65f7e79967c2eb729f5b",
- }
- for i, o := range lt {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", o, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseSSHFP(t *testing.T) {
- lt := []string{
- "test.example.org.\t300\tSSHFP\t1 2 (\n" +
- "\t\t\t\t\tBC6533CDC95A79078A39A56EA7635984ED655318ADA9\n" +
- "\t\t\t\t\tB6159E30723665DA95BB )",
- "test.example.org.\t300\tSSHFP\t1 2 ( BC6533CDC 95A79078A39A56EA7635984ED655318AD A9B6159E3072366 5DA95BB )",
- }
- result := "test.example.org.\t300\tIN\tSSHFP\t1 2 BC6533CDC95A79078A39A56EA7635984ED655318ADA9B6159E30723665DA95BB"
- for _, o := range lt {
- rr, err := NewRR(o)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != result {
- t.Errorf("`%s' should be equal to\n\n`%s', but is \n`%s'", o, result, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseHINFO(t *testing.T) {
- dt := map[string]string{
- "example.net. HINFO A B": "example.net. 3600 IN HINFO \"A\" \"B\"",
- "example.net. HINFO \"A\" \"B\"": "example.net. 3600 IN HINFO \"A\" \"B\"",
- "example.net. HINFO A B C D E F": "example.net. 3600 IN HINFO \"A\" \"B C D E F\"",
- "example.net. HINFO AB": "example.net. 3600 IN HINFO \"AB\" \"\"",
- // "example.net. HINFO PC-Intel-700mhz \"Redhat Linux 7.1\"": "example.net. 3600 IN HINFO \"PC-Intel-700mhz\" \"Redhat Linux 7.1\"",
- // This one is recommended in Pro Bind book http://www.zytrax.com/books/dns/ch8/hinfo.html
- // but effectively, even Bind would replace it to correctly formed text when you AXFR
- // TODO: remove this set of comments or figure support for quoted/unquoted combinations in endingToTxtSlice function
- }
- for i, o := range dt {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseCAA(t *testing.T) {
- lt := map[string]string{
- "example.net. CAA 0 issue \"symantec.com\"": "example.net.\t3600\tIN\tCAA\t0 issue \"symantec.com\"",
- "example.net. CAA 0 issuewild \"symantec.com; stuff\"": "example.net.\t3600\tIN\tCAA\t0 issuewild \"symantec.com; stuff\"",
- "example.net. CAA 128 tbs \"critical\"": "example.net.\t3600\tIN\tCAA\t128 tbs \"critical\"",
- "example.net. CAA 2 auth \"0>09\\006\\010+\\006\\001\\004\\001\\214y\\002\\003\\001\\006\\009`\\134H\\001e\\003\\004\\002\\001\\004 y\\209\\012\\221r\\220\\156Q\\218\\150\\150{\\166\\245:\\231\\182%\\157:\\133\\179}\\1923r\\238\\151\\255\\128q\\145\\002\\001\\000\"": "example.net.\t3600\tIN\tCAA\t2 auth \"0>09\\006\\010+\\006\\001\\004\\001\\214y\\002\\003\\001\\006\\009`\\134H\\001e\\003\\004\\002\\001\\004 y\\209\\012\\221r\\220\\156Q\\218\\150\\150{\\166\\245:\\231\\182%\\157:\\133\\179}\\1923r\\238\\151\\255\\128q\\145\\002\\001\\000\"",
- "example.net. TYPE257 0 issue \"symantec.com\"": "example.net.\t3600\tIN\tCAA\t0 issue \"symantec.com\"",
- }
- for i, o := range lt {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestPackCAA(t *testing.T) {
- m := new(Msg)
- record := new(CAA)
- record.Hdr = RR_Header{Name: "example.com.", Rrtype: TypeCAA, Class: ClassINET, Ttl: 0}
- record.Tag = "issue"
- record.Value = "symantec.com"
- record.Flag = 1
-
- m.Answer = append(m.Answer, record)
- bytes, err := m.Pack()
- if err != nil {
- t.Fatalf("failed to pack msg: %v", err)
- }
- if err := m.Unpack(bytes); err != nil {
- t.Fatalf("failed to unpack msg: %v", err)
- }
- if len(m.Answer) != 1 {
- t.Fatalf("incorrect number of answers unpacked")
- }
- rr := m.Answer[0].(*CAA)
- if rr.Tag != "issue" {
- t.Fatalf("invalid tag for unpacked answer")
- } else if rr.Value != "symantec.com" {
- t.Fatalf("invalid value for unpacked answer")
- } else if rr.Flag != 1 {
- t.Fatalf("invalid flag for unpacked answer")
- }
-}
-
-func TestParseURI(t *testing.T) {
- lt := map[string]string{
- "_http._tcp. IN URI 10 1 \"http://www.example.com/path\"": "_http._tcp.\t3600\tIN\tURI\t10 1 \"http://www.example.com/path\"",
- "_http._tcp. IN URI 10 1 \"\"": "_http._tcp.\t3600\tIN\tURI\t10 1 \"\"",
- }
- for i, o := range lt {
- rr, err := NewRR(i)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestParseAVC(t *testing.T) {
- avcs := map[string]string{
- `example.org. IN AVC "app-name:WOLFGANG|app-class:OAM|business=yes"`: `example.org. 3600 IN AVC "app-name:WOLFGANG|app-class:OAM|business=yes"`,
- }
- for avc, o := range avcs {
- rr, err := NewRR(avc)
- if err != nil {
- t.Error("failed to parse RR: ", err)
- continue
- }
- if rr.String() != o {
- t.Errorf("`%s' should be equal to\n`%s', but is `%s'", avc, o, rr.String())
- } else {
- t.Logf("RR is OK: `%s'", rr.String())
- }
- }
-}
-
-func TestUnbalancedParens(t *testing.T) {
- sig := `example.com. 3600 IN RRSIG MX 15 2 3600 (
- 1440021600 1438207200 3613 example.com. (
- oL9krJun7xfBOIWcGHi7mag5/hdZrKWw15jPGrHpjQeRAvTdszaPD+QLs3f
- x8A4M3e23mRZ9VrbpMngwcrqNAg== )`
- _, err := NewRR(sig)
- if err == nil {
- t.Fatalf("Failed to detect extra opening brace")
- }
-}
diff --git a/vendor/github.com/miekg/dns/privaterr.go b/vendor/github.com/miekg/dns/privaterr.go
deleted file mode 100644
index 6b08e6e95..000000000
--- a/vendor/github.com/miekg/dns/privaterr.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package dns
-
-import (
- "fmt"
- "strings"
-)
-
-// PrivateRdata is an interface used for implementing "Private Use" RR types, see
-// RFC 6895. This allows one to experiment with new RR types, without requesting an
-// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
-type PrivateRdata interface {
- // String returns the text presentaton of the Rdata of the Private RR.
- String() string
- // Parse parses the Rdata of the private RR.
- Parse([]string) error
- // Pack is used when packing a private RR into a buffer.
- Pack([]byte) (int, error)
- // Unpack is used when unpacking a private RR from a buffer.
- // TODO(miek): diff. signature than Pack, see edns0.go for instance.
- Unpack([]byte) (int, error)
- // Copy copies the Rdata.
- Copy(PrivateRdata) error
- // Len returns the length in octets of the Rdata.
- Len() int
-}
-
-// PrivateRR represents an RR that uses a PrivateRdata user-defined type.
-// It mocks normal RRs and implements dns.RR interface.
-type PrivateRR struct {
- Hdr RR_Header
- Data PrivateRdata
-}
-
-func mkPrivateRR(rrtype uint16) *PrivateRR {
- // Panics if RR is not an instance of PrivateRR.
- rrfunc, ok := TypeToRR[rrtype]
- if !ok {
- panic(fmt.Sprintf("dns: invalid operation with Private RR type %d", rrtype))
- }
-
- anyrr := rrfunc()
- switch rr := anyrr.(type) {
- case *PrivateRR:
- return rr
- }
- panic(fmt.Sprintf("dns: RR is not a PrivateRR, TypeToRR[%d] generator returned %T", rrtype, anyrr))
-}
-
-// Header return the RR header of r.
-func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
-
-func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }
-
-// Private len and copy parts to satisfy RR interface.
-func (r *PrivateRR) len() int { return r.Hdr.len() + r.Data.Len() }
-func (r *PrivateRR) copy() RR {
- // make new RR like this:
- rr := mkPrivateRR(r.Hdr.Rrtype)
- newh := r.Hdr.copyHeader()
- rr.Hdr = *newh
-
- err := r.Data.Copy(rr.Data)
- if err != nil {
- panic("dns: got value that could not be used to copy Private rdata")
- }
- return rr
-}
-func (r *PrivateRR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := r.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- n, err := r.Data.Pack(msg[off:])
- if err != nil {
- return len(msg), err
- }
- off += n
- r.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-// PrivateHandle registers a private resource record type. It requires
-// string and numeric representation of private RR type and generator function as argument.
-func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
- rtypestr = strings.ToUpper(rtypestr)
-
- TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator()} }
- TypeToString[rtype] = rtypestr
- StringToType[rtypestr] = rtype
-
- typeToUnpack[rtype] = func(h RR_Header, msg []byte, off int) (RR, int, error) {
- if noRdata(h) {
- return &h, off, nil
- }
- var err error
-
- rr := mkPrivateRR(h.Rrtype)
- rr.Hdr = h
-
- off1, err := rr.Data.Unpack(msg[off:])
- off += off1
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
- }
-
- setPrivateRR := func(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := mkPrivateRR(h.Rrtype)
- rr.Hdr = h
-
- var l lex
- text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
- Fetch:
- for {
- // TODO(miek): we could also be returning _QUOTE, this might or might not
- // be an issue (basically parsing TXT becomes hard)
- switch l = <-c; l.value {
- case zNewline, zEOF:
- break Fetch
- case zString:
- text = append(text, l.token)
- }
- }
-
- err := rr.Data.Parse(text)
- if err != nil {
- return nil, &ParseError{f, err.Error(), l}, ""
- }
-
- return rr, nil, ""
- }
-
- typeToparserFunc[rtype] = parserFunc{setPrivateRR, true}
-}
-
-// PrivateHandleRemove removes defenitions required to support private RR type.
-func PrivateHandleRemove(rtype uint16) {
- rtypestr, ok := TypeToString[rtype]
- if ok {
- delete(TypeToRR, rtype)
- delete(TypeToString, rtype)
- delete(typeToparserFunc, rtype)
- delete(StringToType, rtypestr)
- delete(typeToUnpack, rtype)
- }
- return
-}
diff --git a/vendor/github.com/miekg/dns/privaterr_test.go b/vendor/github.com/miekg/dns/privaterr_test.go
deleted file mode 100644
index 72ec8f5c0..000000000
--- a/vendor/github.com/miekg/dns/privaterr_test.go
+++ /dev/null
@@ -1,171 +0,0 @@
-package dns_test
-
-import (
- "strings"
- "testing"
-
- "github.com/miekg/dns"
-)
-
-const TypeISBN uint16 = 0xFF00
-
-// A crazy new RR type :)
-type ISBN struct {
- x string // rdata with 10 or 13 numbers, dashes or spaces allowed
-}
-
-func NewISBN() dns.PrivateRdata { return &ISBN{""} }
-
-func (rd *ISBN) Len() int { return len([]byte(rd.x)) }
-func (rd *ISBN) String() string { return rd.x }
-
-func (rd *ISBN) Parse(txt []string) error {
- rd.x = strings.TrimSpace(strings.Join(txt, " "))
- return nil
-}
-
-func (rd *ISBN) Pack(buf []byte) (int, error) {
- b := []byte(rd.x)
- n := copy(buf, b)
- if n != len(b) {
- return n, dns.ErrBuf
- }
- return n, nil
-}
-
-func (rd *ISBN) Unpack(buf []byte) (int, error) {
- rd.x = string(buf)
- return len(buf), nil
-}
-
-func (rd *ISBN) Copy(dest dns.PrivateRdata) error {
- isbn, ok := dest.(*ISBN)
- if !ok {
- return dns.ErrRdata
- }
- isbn.x = rd.x
- return nil
-}
-
-var testrecord = strings.Join([]string{"example.org.", "3600", "IN", "ISBN", "12-3 456789-0-123"}, "\t")
-
-func TestPrivateText(t *testing.T) {
- dns.PrivateHandle("ISBN", TypeISBN, NewISBN)
- defer dns.PrivateHandleRemove(TypeISBN)
-
- rr, err := dns.NewRR(testrecord)
- if err != nil {
- t.Fatal(err)
- }
- if rr.String() != testrecord {
- t.Errorf("record string representation did not match original %#v != %#v", rr.String(), testrecord)
- } else {
- t.Log(rr.String())
- }
-}
-
-func TestPrivateByteSlice(t *testing.T) {
- dns.PrivateHandle("ISBN", TypeISBN, NewISBN)
- defer dns.PrivateHandleRemove(TypeISBN)
-
- rr, err := dns.NewRR(testrecord)
- if err != nil {
- t.Fatal(err)
- }
-
- buf := make([]byte, 100)
- off, err := dns.PackRR(rr, buf, 0, nil, false)
- if err != nil {
- t.Errorf("got error packing ISBN: %v", err)
- }
-
- custrr := rr.(*dns.PrivateRR)
- if ln := custrr.Data.Len() + len(custrr.Header().Name) + 11; ln != off {
- t.Errorf("offset is not matching to length of Private RR: %d!=%d", off, ln)
- }
-
- rr1, off1, err := dns.UnpackRR(buf[:off], 0)
- if err != nil {
- t.Errorf("got error unpacking ISBN: %v", err)
- return
- }
-
- if off1 != off {
- t.Errorf("offset after unpacking differs: %d != %d", off1, off)
- }
-
- if rr1.String() != testrecord {
- t.Errorf("record string representation did not match original %#v != %#v", rr1.String(), testrecord)
- } else {
- t.Log(rr1.String())
- }
-}
-
-const TypeVERSION uint16 = 0xFF01
-
-type VERSION struct {
- x string
-}
-
-func NewVersion() dns.PrivateRdata { return &VERSION{""} }
-
-func (rd *VERSION) String() string { return rd.x }
-func (rd *VERSION) Parse(txt []string) error {
- rd.x = strings.TrimSpace(strings.Join(txt, " "))
- return nil
-}
-
-func (rd *VERSION) Pack(buf []byte) (int, error) {
- b := []byte(rd.x)
- n := copy(buf, b)
- if n != len(b) {
- return n, dns.ErrBuf
- }
- return n, nil
-}
-
-func (rd *VERSION) Unpack(buf []byte) (int, error) {
- rd.x = string(buf)
- return len(buf), nil
-}
-
-func (rd *VERSION) Copy(dest dns.PrivateRdata) error {
- isbn, ok := dest.(*VERSION)
- if !ok {
- return dns.ErrRdata
- }
- isbn.x = rd.x
- return nil
-}
-
-func (rd *VERSION) Len() int {
- return len([]byte(rd.x))
-}
-
-var smallzone = `$ORIGIN example.org.
-@ SOA sns.dns.icann.org. noc.dns.icann.org. (
- 2014091518 7200 3600 1209600 3600
-)
- A 1.2.3.4
-ok ISBN 1231-92110-12
-go VERSION (
- 1.3.1 ; comment
-)
-www ISBN 1231-92110-16
-* CNAME @
-`
-
-func TestPrivateZoneParser(t *testing.T) {
- dns.PrivateHandle("ISBN", TypeISBN, NewISBN)
- dns.PrivateHandle("VERSION", TypeVERSION, NewVersion)
- defer dns.PrivateHandleRemove(TypeISBN)
- defer dns.PrivateHandleRemove(TypeVERSION)
-
- r := strings.NewReader(smallzone)
- for x := range dns.ParseZone(r, ".", "") {
- if err := x.Error; err != nil {
- t.Fatal(err)
- }
- t.Log(x.RR)
- }
-}
diff --git a/vendor/github.com/miekg/dns/rawmsg.go b/vendor/github.com/miekg/dns/rawmsg.go
deleted file mode 100644
index 6e21fba7e..000000000
--- a/vendor/github.com/miekg/dns/rawmsg.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package dns
-
-import "encoding/binary"
-
-// rawSetRdlength sets the rdlength in the header of
-// the RR. The offset 'off' must be positioned at the
-// start of the header of the RR, 'end' must be the
-// end of the RR.
-func rawSetRdlength(msg []byte, off, end int) bool {
- l := len(msg)
-Loop:
- for {
- if off+1 > l {
- return false
- }
- c := int(msg[off])
- off++
- switch c & 0xC0 {
- case 0x00:
- if c == 0x00 {
- // End of the domainname
- break Loop
- }
- if off+c > l {
- return false
- }
- off += c
-
- case 0xC0:
- // pointer, next byte included, ends domainname
- off++
- break Loop
- }
- }
- // The domainname has been seen, we at the start of the fixed part in the header.
- // Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length.
- off += 2 + 2 + 4
- if off+2 > l {
- return false
- }
- //off+1 is the end of the header, 'end' is the end of the rr
- //so 'end' - 'off+2' is the length of the rdata
- rdatalen := end - (off + 2)
- if rdatalen > 0xFFFF {
- return false
- }
- binary.BigEndian.PutUint16(msg[off:], uint16(rdatalen))
- return true
-}
diff --git a/vendor/github.com/miekg/dns/remote_test.go b/vendor/github.com/miekg/dns/remote_test.go
deleted file mode 100644
index 4cf701fe4..000000000
--- a/vendor/github.com/miekg/dns/remote_test.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package dns
-
-import "testing"
-
-const LinodeAddr = "176.58.119.54:53"
-
-func TestClientRemote(t *testing.T) {
- m := new(Msg)
- m.SetQuestion("go.dns.miek.nl.", TypeTXT)
-
- c := new(Client)
- r, _, err := c.Exchange(m, LinodeAddr)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
- if r != nil && r.Rcode != RcodeSuccess {
- t.Errorf("failed to get an valid answer\n%v", r)
- }
-}
diff --git a/vendor/github.com/miekg/dns/reverse.go b/vendor/github.com/miekg/dns/reverse.go
deleted file mode 100644
index f6e7a47a6..000000000
--- a/vendor/github.com/miekg/dns/reverse.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package dns
-
-// StringToType is the reverse of TypeToString, needed for string parsing.
-var StringToType = reverseInt16(TypeToString)
-
-// StringToClass is the reverse of ClassToString, needed for string parsing.
-var StringToClass = reverseInt16(ClassToString)
-
-// StringToOpcode is a map of opcodes to strings.
-var StringToOpcode = reverseInt(OpcodeToString)
-
-// StringToRcode is a map of rcodes to strings.
-var StringToRcode = reverseInt(RcodeToString)
-
-// Reverse a map
-func reverseInt8(m map[uint8]string) map[string]uint8 {
- n := make(map[string]uint8, len(m))
- for u, s := range m {
- n[s] = u
- }
- return n
-}
-
-func reverseInt16(m map[uint16]string) map[string]uint16 {
- n := make(map[string]uint16, len(m))
- for u, s := range m {
- n[s] = u
- }
- return n
-}
-
-func reverseInt(m map[int]string) map[string]int {
- n := make(map[string]int, len(m))
- for u, s := range m {
- n[s] = u
- }
- return n
-}
diff --git a/vendor/github.com/miekg/dns/sanitize.go b/vendor/github.com/miekg/dns/sanitize.go
deleted file mode 100644
index b489f3f05..000000000
--- a/vendor/github.com/miekg/dns/sanitize.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package dns
-
-// Dedup removes identical RRs from rrs. It preserves the original ordering.
-// The lowest TTL of any duplicates is used in the remaining one. Dedup modifies
-// rrs.
-// m is used to store the RRs temporay. If it is nil a new map will be allocated.
-func Dedup(rrs []RR, m map[string]RR) []RR {
- if m == nil {
- m = make(map[string]RR)
- }
- // Save the keys, so we don't have to call normalizedString twice.
- keys := make([]*string, 0, len(rrs))
-
- for _, r := range rrs {
- key := normalizedString(r)
- keys = append(keys, &key)
- if _, ok := m[key]; ok {
- // Shortest TTL wins.
- if m[key].Header().Ttl > r.Header().Ttl {
- m[key].Header().Ttl = r.Header().Ttl
- }
- continue
- }
-
- m[key] = r
- }
- // If the length of the result map equals the amount of RRs we got,
- // it means they were all different. We can then just return the original rrset.
- if len(m) == len(rrs) {
- return rrs
- }
-
- j := 0
- for i, r := range rrs {
- // If keys[i] lives in the map, we should copy and remove it.
- if _, ok := m[*keys[i]]; ok {
- delete(m, *keys[i])
- rrs[j] = r
- j++
- }
-
- if len(m) == 0 {
- break
- }
- }
-
- return rrs[:j]
-}
-
-// normalizedString returns a normalized string from r. The TTL
-// is removed and the domain name is lowercased. We go from this:
-// DomainName<TAB>TTL<TAB>CLASS<TAB>TYPE<TAB>RDATA to:
-// lowercasename<TAB>CLASS<TAB>TYPE...
-func normalizedString(r RR) string {
- // A string Go DNS makes has: domainname<TAB>TTL<TAB>...
- b := []byte(r.String())
-
- // find the first non-escaped tab, then another, so we capture where the TTL lives.
- esc := false
- ttlStart, ttlEnd := 0, 0
- for i := 0; i < len(b) && ttlEnd == 0; i++ {
- switch {
- case b[i] == '\\':
- esc = !esc
- case b[i] == '\t' && !esc:
- if ttlStart == 0 {
- ttlStart = i
- continue
- }
- if ttlEnd == 0 {
- ttlEnd = i
- }
- case b[i] >= 'A' && b[i] <= 'Z' && !esc:
- b[i] += 32
- default:
- esc = false
- }
- }
-
- // remove TTL.
- copy(b[ttlStart:], b[ttlEnd:])
- cut := ttlEnd - ttlStart
- return string(b[:len(b)-cut])
-}
diff --git a/vendor/github.com/miekg/dns/sanitize_test.go b/vendor/github.com/miekg/dns/sanitize_test.go
deleted file mode 100644
index 2ba3fe9a3..000000000
--- a/vendor/github.com/miekg/dns/sanitize_test.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package dns
-
-import "testing"
-
-func TestDedup(t *testing.T) {
- // make it []string
- testcases := map[[3]RR][]string{
- [...]RR{
- newRR(t, "mIek.nl. IN A 127.0.0.1"),
- newRR(t, "mieK.nl. IN A 127.0.0.1"),
- newRR(t, "miek.Nl. IN A 127.0.0.1"),
- }: {"mIek.nl.\t3600\tIN\tA\t127.0.0.1"},
- [...]RR{
- newRR(t, "miEk.nl. 2000 IN A 127.0.0.1"),
- newRR(t, "mieK.Nl. 1000 IN A 127.0.0.1"),
- newRR(t, "Miek.nL. 500 IN A 127.0.0.1"),
- }: {"miEk.nl.\t500\tIN\tA\t127.0.0.1"},
- [...]RR{
- newRR(t, "miek.nl. IN A 127.0.0.1"),
- newRR(t, "miek.nl. CH A 127.0.0.1"),
- newRR(t, "miek.nl. IN A 127.0.0.1"),
- }: {"miek.nl.\t3600\tIN\tA\t127.0.0.1",
- "miek.nl.\t3600\tCH\tA\t127.0.0.1",
- },
- [...]RR{
- newRR(t, "miek.nl. CH A 127.0.0.1"),
- newRR(t, "miek.nl. IN A 127.0.0.1"),
- newRR(t, "miek.de. IN A 127.0.0.1"),
- }: {"miek.nl.\t3600\tCH\tA\t127.0.0.1",
- "miek.nl.\t3600\tIN\tA\t127.0.0.1",
- "miek.de.\t3600\tIN\tA\t127.0.0.1",
- },
- [...]RR{
- newRR(t, "miek.de. IN A 127.0.0.1"),
- newRR(t, "miek.nl. 200 IN A 127.0.0.1"),
- newRR(t, "miek.nl. 300 IN A 127.0.0.1"),
- }: {"miek.de.\t3600\tIN\tA\t127.0.0.1",
- "miek.nl.\t200\tIN\tA\t127.0.0.1",
- },
- }
-
- for rr, expected := range testcases {
- out := Dedup([]RR{rr[0], rr[1], rr[2]}, nil)
- for i, o := range out {
- if o.String() != expected[i] {
- t.Fatalf("expected %v, got %v", expected[i], o.String())
- }
- }
- }
-}
-
-func BenchmarkDedup(b *testing.B) {
- rrs := []RR{
- newRR(nil, "miEk.nl. 2000 IN A 127.0.0.1"),
- newRR(nil, "mieK.Nl. 1000 IN A 127.0.0.1"),
- newRR(nil, "Miek.nL. 500 IN A 127.0.0.1"),
- }
- m := make(map[string]RR)
- for i := 0; i < b.N; i++ {
- Dedup(rrs, m)
- }
-}
-
-func TestNormalizedString(t *testing.T) {
- tests := map[RR]string{
- newRR(t, "mIEk.Nl. 3600 IN A 127.0.0.1"): "miek.nl.\tIN\tA\t127.0.0.1",
- newRR(t, "m\\ iek.nL. 3600 IN A 127.0.0.1"): "m\\ iek.nl.\tIN\tA\t127.0.0.1",
- newRR(t, "m\\\tIeK.nl. 3600 in A 127.0.0.1"): "m\\009iek.nl.\tIN\tA\t127.0.0.1",
- }
- for tc, expected := range tests {
- n := normalizedString(tc)
- if n != expected {
- t.Errorf("expected %s, got %s", expected, n)
- }
- }
-}
-
-func newRR(t *testing.T, s string) RR {
- r, err := NewRR(s)
- if err != nil {
- t.Logf("newRR: %v", err)
- }
- return r
-}
diff --git a/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/miekg/dns/scan.go
deleted file mode 100644
index 8d4773c3e..000000000
--- a/vendor/github.com/miekg/dns/scan.go
+++ /dev/null
@@ -1,987 +0,0 @@
-package dns
-
-import (
- "io"
- "log"
- "os"
- "strconv"
- "strings"
-)
-
-type debugging bool
-
-const debug debugging = false
-
-func (d debugging) Printf(format string, args ...interface{}) {
- if d {
- log.Printf(format, args...)
- }
-}
-
-const maxTok = 2048 // Largest token we can return.
-const maxUint16 = 1<<16 - 1
-
-// Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
-// * Add ownernames if they are left blank;
-// * Suppress sequences of spaces;
-// * Make each RR fit on one line (_NEWLINE is send as last)
-// * Handle comments: ;
-// * Handle braces - anywhere.
-const (
- // Zonefile
- zEOF = iota
- zString
- zBlank
- zQuote
- zNewline
- zRrtpe
- zOwner
- zClass
- zDirOrigin // $ORIGIN
- zDirTtl // $TTL
- zDirInclude // $INCLUDE
- zDirGenerate // $GENERATE
-
- // Privatekey file
- zValue
- zKey
-
- zExpectOwnerDir // Ownername
- zExpectOwnerBl // Whitespace after the ownername
- zExpectAny // Expect rrtype, ttl or class
- zExpectAnyNoClass // Expect rrtype or ttl
- zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS
- zExpectAnyNoTtl // Expect rrtype or class
- zExpectAnyNoTtlBl // Whitespace after _EXPECT_ANY_NOTTL
- zExpectRrtype // Expect rrtype
- zExpectRrtypeBl // Whitespace BEFORE rrtype
- zExpectRdata // The first element of the rdata
- zExpectDirTtlBl // Space after directive $TTL
- zExpectDirTtl // Directive $TTL
- zExpectDirOriginBl // Space after directive $ORIGIN
- zExpectDirOrigin // Directive $ORIGIN
- zExpectDirIncludeBl // Space after directive $INCLUDE
- zExpectDirInclude // Directive $INCLUDE
- zExpectDirGenerate // Directive $GENERATE
- zExpectDirGenerateBl // Space after directive $GENERATE
-)
-
-// ParseError is a parsing error. It contains the parse error and the location in the io.Reader
-// where the error occurred.
-type ParseError struct {
- file string
- err string
- lex lex
-}
-
-func (e *ParseError) Error() (s string) {
- if e.file != "" {
- s = e.file + ": "
- }
- s += "dns: " + e.err + ": " + strconv.QuoteToASCII(e.lex.token) + " at line: " +
- strconv.Itoa(e.lex.line) + ":" + strconv.Itoa(e.lex.column)
- return
-}
-
-type lex struct {
- token string // text of the token
- tokenUpper string // uppercase text of the token
- length int // length of the token
- err bool // when true, token text has lexer error
- value uint8 // value: zString, _BLANK, etc.
- line int // line in the file
- column int // column in the file
- torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
- comment string // any comment text seen
-}
-
-// Token holds the token that are returned when a zone file is parsed.
-type Token struct {
- // The scanned resource record when error is not nil.
- RR
- // When an error occurred, this has the error specifics.
- Error *ParseError
- // A potential comment positioned after the RR and on the same line.
- Comment string
-}
-
-// NewRR reads the RR contained in the string s. Only the first RR is
-// returned. If s contains no RR, return nil with no error. The class
-// defaults to IN and TTL defaults to 3600. The full zone file syntax
-// like $TTL, $ORIGIN, etc. is supported. All fields of the returned
-// RR are set, except RR.Header().Rdlength which is set to 0.
-func NewRR(s string) (RR, error) {
- if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
- return ReadRR(strings.NewReader(s+"\n"), "")
- }
- return ReadRR(strings.NewReader(s), "")
-}
-
-// ReadRR reads the RR contained in q.
-// See NewRR for more documentation.
-func ReadRR(q io.Reader, filename string) (RR, error) {
- r := <-parseZoneHelper(q, ".", filename, 1)
- if r == nil {
- return nil, nil
- }
-
- if r.Error != nil {
- return nil, r.Error
- }
- return r.RR, nil
-}
-
-// ParseZone reads a RFC 1035 style zonefile from r. It returns *Tokens on the
-// returned channel, which consist out the parsed RR, a potential comment or an error.
-// If there is an error the RR is nil. The string file is only used
-// in error reporting. The string origin is used as the initial origin, as
-// if the file would start with: $ORIGIN origin .
-// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported.
-// The channel t is closed by ParseZone when the end of r is reached.
-//
-// Basic usage pattern when reading from a string (z) containing the
-// zone data:
-//
-// for x := range dns.ParseZone(strings.NewReader(z), "", "") {
-// if x.Error != nil {
-// // log.Println(x.Error)
-// } else {
-// // Do something with x.RR
-// }
-// }
-//
-// Comments specified after an RR (and on the same line!) are returned too:
-//
-// foo. IN A 10.0.0.1 ; this is a comment
-//
-// The text "; this is comment" is returned in Token.Comment. Comments inside the
-// RR are discarded. Comments on a line by themselves are discarded too.
-func ParseZone(r io.Reader, origin, file string) chan *Token {
- return parseZoneHelper(r, origin, file, 10000)
-}
-
-func parseZoneHelper(r io.Reader, origin, file string, chansize int) chan *Token {
- t := make(chan *Token, chansize)
- go parseZone(r, origin, file, t, 0)
- return t
-}
-
-func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
- defer func() {
- if include == 0 {
- close(t)
- }
- }()
- s := scanInit(r)
- c := make(chan lex)
- // Start the lexer
- go zlexer(s, c)
- // 6 possible beginnings of a line, _ is a space
- // 0. zRRTYPE -> all omitted until the rrtype
- // 1. zOwner _ zRrtype -> class/ttl omitted
- // 2. zOwner _ zString _ zRrtype -> class omitted
- // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class
- // 4. zOwner _ zClass _ zRrtype -> ttl omitted
- // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed)
- // After detecting these, we know the zRrtype so we can jump to functions
- // handling the rdata for each of these types.
-
- if origin == "" {
- origin = "."
- }
- origin = Fqdn(origin)
- if _, ok := IsDomainName(origin); !ok {
- t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
- return
- }
-
- st := zExpectOwnerDir // initial state
- var h RR_Header
- var defttl uint32 = defaultTtl
- var prevName string
- for l := range c {
- // Lexer spotted an error already
- if l.err == true {
- t <- &Token{Error: &ParseError{f, l.token, l}}
- return
-
- }
- switch st {
- case zExpectOwnerDir:
- // We can also expect a directive, like $TTL or $ORIGIN
- h.Ttl = defttl
- h.Class = ClassINET
- switch l.value {
- case zNewline:
- st = zExpectOwnerDir
- case zOwner:
- h.Name = l.token
- if l.token[0] == '@' {
- h.Name = origin
- prevName = h.Name
- st = zExpectOwnerBl
- break
- }
- if h.Name[l.length-1] != '.' {
- h.Name = appendOrigin(h.Name, origin)
- }
- _, ok := IsDomainName(l.token)
- if !ok {
- t <- &Token{Error: &ParseError{f, "bad owner name", l}}
- return
- }
- prevName = h.Name
- st = zExpectOwnerBl
- case zDirTtl:
- st = zExpectDirTtlBl
- case zDirOrigin:
- st = zExpectDirOriginBl
- case zDirInclude:
- st = zExpectDirIncludeBl
- case zDirGenerate:
- st = zExpectDirGenerateBl
- case zRrtpe:
- h.Name = prevName
- h.Rrtype = l.torc
- st = zExpectRdata
- case zClass:
- h.Name = prevName
- h.Class = l.torc
- st = zExpectAnyNoClassBl
- case zBlank:
- // Discard, can happen when there is nothing on the
- // line except the RR type
- case zString:
- ttl, ok := stringToTtl(l.token)
- if !ok {
- t <- &Token{Error: &ParseError{f, "not a TTL", l}}
- return
- }
- h.Ttl = ttl
- // Don't about the defttl, we should take the $TTL value
- // defttl = ttl
- st = zExpectAnyNoTtlBl
-
- default:
- t <- &Token{Error: &ParseError{f, "syntax error at beginning", l}}
- return
- }
- case zExpectDirIncludeBl:
- if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after $INCLUDE-directive", l}}
- return
- }
- st = zExpectDirInclude
- case zExpectDirInclude:
- if l.value != zString {
- t <- &Token{Error: &ParseError{f, "expecting $INCLUDE value, not this...", l}}
- return
- }
- neworigin := origin // There may be optionally a new origin set after the filename, if not use current one
- l := <-c
- switch l.value {
- case zBlank:
- l := <-c
- if l.value == zString {
- if _, ok := IsDomainName(l.token); !ok || l.length == 0 || l.err {
- t <- &Token{Error: &ParseError{f, "bad origin name", l}}
- return
- }
- // a new origin is specified.
- if l.token[l.length-1] != '.' {
- if origin != "." { // Prevent .. endings
- neworigin = l.token + "." + origin
- } else {
- neworigin = l.token + origin
- }
- } else {
- neworigin = l.token
- }
- }
- case zNewline, zEOF:
- // Ok
- default:
- t <- &Token{Error: &ParseError{f, "garbage after $INCLUDE", l}}
- return
- }
- // Start with the new file
- r1, e1 := os.Open(l.token)
- if e1 != nil {
- t <- &Token{Error: &ParseError{f, "failed to open `" + l.token + "'", l}}
- return
- }
- if include+1 > 7 {
- t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}}
- return
- }
- parseZone(r1, l.token, neworigin, t, include+1)
- st = zExpectOwnerDir
- case zExpectDirTtlBl:
- if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after $TTL-directive", l}}
- return
- }
- st = zExpectDirTtl
- case zExpectDirTtl:
- if l.value != zString {
- t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
- return
- }
- if e, _ := slurpRemainder(c, f); e != nil {
- t <- &Token{Error: e}
- return
- }
- ttl, ok := stringToTtl(l.token)
- if !ok {
- t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
- return
- }
- defttl = ttl
- st = zExpectOwnerDir
- case zExpectDirOriginBl:
- if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after $ORIGIN-directive", l}}
- return
- }
- st = zExpectDirOrigin
- case zExpectDirOrigin:
- if l.value != zString {
- t <- &Token{Error: &ParseError{f, "expecting $ORIGIN value, not this...", l}}
- return
- }
- if e, _ := slurpRemainder(c, f); e != nil {
- t <- &Token{Error: e}
- }
- if _, ok := IsDomainName(l.token); !ok {
- t <- &Token{Error: &ParseError{f, "bad origin name", l}}
- return
- }
- if l.token[l.length-1] != '.' {
- if origin != "." { // Prevent .. endings
- origin = l.token + "." + origin
- } else {
- origin = l.token + origin
- }
- } else {
- origin = l.token
- }
- st = zExpectOwnerDir
- case zExpectDirGenerateBl:
- if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after $GENERATE-directive", l}}
- return
- }
- st = zExpectDirGenerate
- case zExpectDirGenerate:
- if l.value != zString {
- t <- &Token{Error: &ParseError{f, "expecting $GENERATE value, not this...", l}}
- return
- }
- if errMsg := generate(l, c, t, origin); errMsg != "" {
- t <- &Token{Error: &ParseError{f, errMsg, l}}
- return
- }
- st = zExpectOwnerDir
- case zExpectOwnerBl:
- if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank after owner", l}}
- return
- }
- st = zExpectAny
- case zExpectAny:
- switch l.value {
- case zRrtpe:
- h.Rrtype = l.torc
- st = zExpectRdata
- case zClass:
- h.Class = l.torc
- st = zExpectAnyNoClassBl
- case zString:
- ttl, ok := stringToTtl(l.token)
- if !ok {
- t <- &Token{Error: &ParseError{f, "not a TTL", l}}
- return
- }
- h.Ttl = ttl
- // defttl = ttl // don't set the defttl here
- st = zExpectAnyNoTtlBl
- default:
- t <- &Token{Error: &ParseError{f, "expecting RR type, TTL or class, not this...", l}}
- return
- }
- case zExpectAnyNoClassBl:
- if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank before class", l}}
- return
- }
- st = zExpectAnyNoClass
- case zExpectAnyNoTtlBl:
- if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank before TTL", l}}
- return
- }
- st = zExpectAnyNoTtl
- case zExpectAnyNoTtl:
- switch l.value {
- case zClass:
- h.Class = l.torc
- st = zExpectRrtypeBl
- case zRrtpe:
- h.Rrtype = l.torc
- st = zExpectRdata
- default:
- t <- &Token{Error: &ParseError{f, "expecting RR type or class, not this...", l}}
- return
- }
- case zExpectAnyNoClass:
- switch l.value {
- case zString:
- ttl, ok := stringToTtl(l.token)
- if !ok {
- t <- &Token{Error: &ParseError{f, "not a TTL", l}}
- return
- }
- h.Ttl = ttl
- // defttl = ttl // don't set the def ttl anymore
- st = zExpectRrtypeBl
- case zRrtpe:
- h.Rrtype = l.torc
- st = zExpectRdata
- default:
- t <- &Token{Error: &ParseError{f, "expecting RR type or TTL, not this...", l}}
- return
- }
- case zExpectRrtypeBl:
- if l.value != zBlank {
- t <- &Token{Error: &ParseError{f, "no blank before RR type", l}}
- return
- }
- st = zExpectRrtype
- case zExpectRrtype:
- if l.value != zRrtpe {
- t <- &Token{Error: &ParseError{f, "unknown RR type", l}}
- return
- }
- h.Rrtype = l.torc
- st = zExpectRdata
- case zExpectRdata:
- r, e, c1 := setRR(h, c, origin, f)
- if e != nil {
- // If e.lex is nil than we have encounter a unknown RR type
- // in that case we substitute our current lex token
- if e.lex.token == "" && e.lex.value == 0 {
- e.lex = l // Uh, dirty
- }
- t <- &Token{Error: e}
- return
- }
- t <- &Token{RR: r, Comment: c1}
- st = zExpectOwnerDir
- }
- }
- // If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this
- // is not an error, because an empty zone file is still a zone file.
-}
-
-// zlexer scans the sourcefile and returns tokens on the channel c.
-func zlexer(s *scan, c chan lex) {
- var l lex
- str := make([]byte, maxTok) // Should be enough for any token
- stri := 0 // Offset in str (0 means empty)
- com := make([]byte, maxTok) // Hold comment text
- comi := 0
- quote := false
- escape := false
- space := false
- commt := false
- rrtype := false
- owner := true
- brace := 0
- x, err := s.tokenText()
- defer close(c)
- for err == nil {
- l.column = s.position.Column
- l.line = s.position.Line
- if stri >= maxTok {
- l.token = "token length insufficient for parsing"
- l.err = true
- debug.Printf("[%+v]", l.token)
- c <- l
- return
- }
- if comi >= maxTok {
- l.token = "comment length insufficient for parsing"
- l.err = true
- debug.Printf("[%+v]", l.token)
- c <- l
- return
- }
-
- switch x {
- case ' ', '\t':
- if escape {
- escape = false
- str[stri] = x
- stri++
- break
- }
- if quote {
- // Inside quotes this is legal
- str[stri] = x
- stri++
- break
- }
- if commt {
- com[comi] = x
- comi++
- break
- }
- if stri == 0 {
- // Space directly in the beginning, handled in the grammar
- } else if owner {
- // If we have a string and its the first, make it an owner
- l.value = zOwner
- l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
- // escape $... start with a \ not a $, so this will work
- switch l.tokenUpper {
- case "$TTL":
- l.value = zDirTtl
- case "$ORIGIN":
- l.value = zDirOrigin
- case "$INCLUDE":
- l.value = zDirInclude
- case "$GENERATE":
- l.value = zDirGenerate
- }
- debug.Printf("[7 %+v]", l.token)
- c <- l
- } else {
- l.value = zString
- l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
- if !rrtype {
- if t, ok := StringToType[l.tokenUpper]; ok {
- l.value = zRrtpe
- l.torc = t
- rrtype = true
- } else {
- if strings.HasPrefix(l.tokenUpper, "TYPE") {
- t, ok := typeToInt(l.token)
- if !ok {
- l.token = "unknown RR type"
- l.err = true
- c <- l
- return
- }
- l.value = zRrtpe
- l.torc = t
- }
- }
- if t, ok := StringToClass[l.tokenUpper]; ok {
- l.value = zClass
- l.torc = t
- } else {
- if strings.HasPrefix(l.tokenUpper, "CLASS") {
- t, ok := classToInt(l.token)
- if !ok {
- l.token = "unknown class"
- l.err = true
- c <- l
- return
- }
- l.value = zClass
- l.torc = t
- }
- }
- }
- debug.Printf("[6 %+v]", l.token)
- c <- l
- }
- stri = 0
- // I reverse space stuff here
- if !space && !commt {
- l.value = zBlank
- l.token = " "
- l.length = 1
- debug.Printf("[5 %+v]", l.token)
- c <- l
- }
- owner = false
- space = true
- case ';':
- if escape {
- escape = false
- str[stri] = x
- stri++
- break
- }
- if quote {
- // Inside quotes this is legal
- str[stri] = x
- stri++
- break
- }
- if stri > 0 {
- l.value = zString
- l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
- debug.Printf("[4 %+v]", l.token)
- c <- l
- stri = 0
- }
- commt = true
- com[comi] = ';'
- comi++
- case '\r':
- escape = false
- if quote {
- str[stri] = x
- stri++
- break
- }
- // discard if outside of quotes
- case '\n':
- escape = false
- // Escaped newline
- if quote {
- str[stri] = x
- stri++
- break
- }
- // inside quotes this is legal
- if commt {
- // Reset a comment
- commt = false
- rrtype = false
- stri = 0
- // If not in a brace this ends the comment AND the RR
- if brace == 0 {
- owner = true
- owner = true
- l.value = zNewline
- l.token = "\n"
- l.tokenUpper = l.token
- l.length = 1
- l.comment = string(com[:comi])
- debug.Printf("[3 %+v %+v]", l.token, l.comment)
- c <- l
- l.comment = ""
- comi = 0
- break
- }
- com[comi] = ' ' // convert newline to space
- comi++
- break
- }
-
- if brace == 0 {
- // If there is previous text, we should output it here
- if stri != 0 {
- l.value = zString
- l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
-
- l.length = stri
- if !rrtype {
- if t, ok := StringToType[l.tokenUpper]; ok {
- l.value = zRrtpe
- l.torc = t
- rrtype = true
- }
- }
- debug.Printf("[2 %+v]", l.token)
- c <- l
- }
- l.value = zNewline
- l.token = "\n"
- l.tokenUpper = l.token
- l.length = 1
- debug.Printf("[1 %+v]", l.token)
- c <- l
- stri = 0
- commt = false
- rrtype = false
- owner = true
- comi = 0
- }
- case '\\':
- // comments do not get escaped chars, everything is copied
- if commt {
- com[comi] = x
- comi++
- break
- }
- // something already escaped must be in string
- if escape {
- str[stri] = x
- stri++
- escape = false
- break
- }
- // something escaped outside of string gets added to string
- str[stri] = x
- stri++
- escape = true
- case '"':
- if commt {
- com[comi] = x
- comi++
- break
- }
- if escape {
- str[stri] = x
- stri++
- escape = false
- break
- }
- space = false
- // send previous gathered text and the quote
- if stri != 0 {
- l.value = zString
- l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
-
- debug.Printf("[%+v]", l.token)
- c <- l
- stri = 0
- }
-
- // send quote itself as separate token
- l.value = zQuote
- l.token = "\""
- l.tokenUpper = l.token
- l.length = 1
- c <- l
- quote = !quote
- case '(', ')':
- if commt {
- com[comi] = x
- comi++
- break
- }
- if escape {
- str[stri] = x
- stri++
- escape = false
- break
- }
- if quote {
- str[stri] = x
- stri++
- break
- }
- switch x {
- case ')':
- brace--
- if brace < 0 {
- l.token = "extra closing brace"
- l.tokenUpper = l.token
- l.err = true
- debug.Printf("[%+v]", l.token)
- c <- l
- return
- }
- case '(':
- brace++
- }
- default:
- escape = false
- if commt {
- com[comi] = x
- comi++
- break
- }
- str[stri] = x
- stri++
- space = false
- }
- x, err = s.tokenText()
- }
- if stri > 0 {
- // Send remainder
- l.token = string(str[:stri])
- l.tokenUpper = strings.ToUpper(l.token)
- l.length = stri
- l.value = zString
- debug.Printf("[%+v]", l.token)
- c <- l
- }
- if brace != 0 {
- l.token = "unbalanced brace"
- l.tokenUpper = l.token
- l.err = true
- c <- l
- }
-}
-
-// Extract the class number from CLASSxx
-func classToInt(token string) (uint16, bool) {
- offset := 5
- if len(token) < offset+1 {
- return 0, false
- }
- class, err := strconv.ParseUint(token[offset:], 10, 16)
- if err != nil {
- return 0, false
- }
- return uint16(class), true
-}
-
-// Extract the rr number from TYPExxx
-func typeToInt(token string) (uint16, bool) {
- offset := 4
- if len(token) < offset+1 {
- return 0, false
- }
- typ, err := strconv.ParseUint(token[offset:], 10, 16)
- if err != nil {
- return 0, false
- }
- return uint16(typ), true
-}
-
-// Parse things like 2w, 2m, etc, Return the time in seconds.
-func stringToTtl(token string) (uint32, bool) {
- s := uint32(0)
- i := uint32(0)
- for _, c := range token {
- switch c {
- case 's', 'S':
- s += i
- i = 0
- case 'm', 'M':
- s += i * 60
- i = 0
- case 'h', 'H':
- s += i * 60 * 60
- i = 0
- case 'd', 'D':
- s += i * 60 * 60 * 24
- i = 0
- case 'w', 'W':
- s += i * 60 * 60 * 24 * 7
- i = 0
- case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- i *= 10
- i += uint32(c) - '0'
- default:
- return 0, false
- }
- }
- return s + i, true
-}
-
-// Parse LOC records' <digits>[.<digits>][mM] into a
-// mantissa exponent format. Token should contain the entire
-// string (i.e. no spaces allowed)
-func stringToCm(token string) (e, m uint8, ok bool) {
- if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' {
- token = token[0 : len(token)-1]
- }
- s := strings.SplitN(token, ".", 2)
- var meters, cmeters, val int
- var err error
- switch len(s) {
- case 2:
- if cmeters, err = strconv.Atoi(s[1]); err != nil {
- return
- }
- fallthrough
- case 1:
- if meters, err = strconv.Atoi(s[0]); err != nil {
- return
- }
- case 0:
- // huh?
- return 0, 0, false
- }
- ok = true
- if meters > 0 {
- e = 2
- val = meters
- } else {
- e = 0
- val = cmeters
- }
- for val > 10 {
- e++
- val /= 10
- }
- if e > 9 {
- ok = false
- }
- m = uint8(val)
- return
-}
-
-func appendOrigin(name, origin string) string {
- if origin == "." {
- return name + origin
- }
- return name + "." + origin
-}
-
-// LOC record helper function
-func locCheckNorth(token string, latitude uint32) (uint32, bool) {
- switch token {
- case "n", "N":
- return LOC_EQUATOR + latitude, true
- case "s", "S":
- return LOC_EQUATOR - latitude, true
- }
- return latitude, false
-}
-
-// LOC record helper function
-func locCheckEast(token string, longitude uint32) (uint32, bool) {
- switch token {
- case "e", "E":
- return LOC_EQUATOR + longitude, true
- case "w", "W":
- return LOC_EQUATOR - longitude, true
- }
- return longitude, false
-}
-
-// "Eat" the rest of the "line". Return potential comments
-func slurpRemainder(c chan lex, f string) (*ParseError, string) {
- l := <-c
- com := ""
- switch l.value {
- case zBlank:
- l = <-c
- com = l.comment
- if l.value != zNewline && l.value != zEOF {
- return &ParseError{f, "garbage after rdata", l}, ""
- }
- case zNewline:
- com = l.comment
- case zEOF:
- default:
- return &ParseError{f, "garbage after rdata", l}, ""
- }
- return nil, com
-}
-
-// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64"
-// Used for NID and L64 record.
-func stringToNodeID(l lex) (uint64, *ParseError) {
- if len(l.token) < 19 {
- return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
- }
- // There must be three colons at fixes postitions, if not its a parse error
- if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' {
- return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
- }
- s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19]
- u, err := strconv.ParseUint(s, 16, 64)
- if err != nil {
- return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
- }
- return u, nil
-}
diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go
deleted file mode 100644
index b8b18fd77..000000000
--- a/vendor/github.com/miekg/dns/scan_rr.go
+++ /dev/null
@@ -1,2184 +0,0 @@
-package dns
-
-import (
- "encoding/base64"
- "net"
- "strconv"
- "strings"
-)
-
-type parserFunc struct {
- // Func defines the function that parses the tokens and returns the RR
- // or an error. The last string contains any comments in the line as
- // they returned by the lexer as well.
- Func func(h RR_Header, c chan lex, origin string, file string) (RR, *ParseError, string)
- // Signals if the RR ending is of variable length, like TXT or records
- // that have Hexadecimal or Base64 as their last element in the Rdata. Records
- // that have a fixed ending or for instance A, AAAA, SOA and etc.
- Variable bool
-}
-
-// Parse the rdata of each rrtype.
-// All data from the channel c is either zString or zBlank.
-// After the rdata there may come a zBlank and then a zNewline
-// or immediately a zNewline. If this is not the case we flag
-// an *ParseError: garbage after rdata.
-func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- parserfunc, ok := typeToparserFunc[h.Rrtype]
- if ok {
- r, e, cm := parserfunc.Func(h, c, o, f)
- if parserfunc.Variable {
- return r, e, cm
- }
- if e != nil {
- return nil, e, ""
- }
- e, cm = slurpRemainder(c, f)
- if e != nil {
- return nil, e, ""
- }
- return r, nil, cm
- }
- // RFC3957 RR (Unknown RR handling)
- return setRFC3597(h, c, o, f)
-}
-
-// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces)
-// or an error
-func endingToString(c chan lex, errstr, f string) (string, *ParseError, string) {
- s := ""
- l := <-c // zString
- for l.value != zNewline && l.value != zEOF {
- if l.err {
- return s, &ParseError{f, errstr, l}, ""
- }
- switch l.value {
- case zString:
- s += l.token
- case zBlank: // Ok
- default:
- return "", &ParseError{f, errstr, l}, ""
- }
- l = <-c
- }
- return s, nil, l.comment
-}
-
-// A remainder of the rdata with embedded spaces, split on unquoted whitespace
-// and return the parsed string slice or an error
-func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) {
- // Get the remaining data until we see a zNewline
- l := <-c
- if l.err {
- return nil, &ParseError{f, errstr, l}, ""
- }
-
- // Build the slice
- s := make([]string, 0)
- quote := false
- empty := false
- for l.value != zNewline && l.value != zEOF {
- if l.err {
- return nil, &ParseError{f, errstr, l}, ""
- }
- switch l.value {
- case zString:
- empty = false
- if len(l.token) > 255 {
- // split up tokens that are larger than 255 into 255-chunks
- sx := []string{}
- p, i := 0, 255
- for {
- if i <= len(l.token) {
- sx = append(sx, l.token[p:i])
- } else {
- sx = append(sx, l.token[p:])
- break
-
- }
- p, i = p+255, i+255
- }
- s = append(s, sx...)
- break
- }
-
- s = append(s, l.token)
- case zBlank:
- if quote {
- // zBlank can only be seen in between txt parts.
- return nil, &ParseError{f, errstr, l}, ""
- }
- case zQuote:
- if empty && quote {
- s = append(s, "")
- }
- quote = !quote
- empty = true
- default:
- return nil, &ParseError{f, errstr, l}, ""
- }
- l = <-c
- }
- if quote {
- return nil, &ParseError{f, errstr, l}, ""
- }
- return s, nil, l.comment
-}
-
-func setA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(A)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 { // Dynamic updates.
- return rr, nil, ""
- }
- rr.A = net.ParseIP(l.token)
- if rr.A == nil || l.err {
- return nil, &ParseError{f, "bad A A", l}, ""
- }
- return rr, nil, ""
-}
-
-func setAAAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(AAAA)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- rr.AAAA = net.ParseIP(l.token)
- if rr.AAAA == nil || l.err {
- return nil, &ParseError{f, "bad AAAA AAAA", l}, ""
- }
- return rr, nil, ""
-}
-
-func setNS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NS)
- rr.Hdr = h
-
- l := <-c
- rr.Ns = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Ns = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad NS Ns", l}, ""
- }
- if rr.Ns[l.length-1] != '.' {
- rr.Ns = appendOrigin(rr.Ns, o)
- }
- return rr, nil, ""
-}
-
-func setPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(PTR)
- rr.Hdr = h
-
- l := <-c
- rr.Ptr = l.token
- if l.length == 0 { // dynamic update rr.
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Ptr = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad PTR Ptr", l}, ""
- }
- if rr.Ptr[l.length-1] != '.' {
- rr.Ptr = appendOrigin(rr.Ptr, o)
- }
- return rr, nil, ""
-}
-
-func setNSAPPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NSAPPTR)
- rr.Hdr = h
-
- l := <-c
- rr.Ptr = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Ptr = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad NSAP-PTR Ptr", l}, ""
- }
- if rr.Ptr[l.length-1] != '.' {
- rr.Ptr = appendOrigin(rr.Ptr, o)
- }
- return rr, nil, ""
-}
-
-func setRP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(RP)
- rr.Hdr = h
-
- l := <-c
- rr.Mbox = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Mbox = o
- } else {
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad RP Mbox", l}, ""
- }
- if rr.Mbox[l.length-1] != '.' {
- rr.Mbox = appendOrigin(rr.Mbox, o)
- }
- }
- <-c // zBlank
- l = <-c
- rr.Txt = l.token
- if l.token == "@" {
- rr.Txt = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad RP Txt", l}, ""
- }
- if rr.Txt[l.length-1] != '.' {
- rr.Txt = appendOrigin(rr.Txt, o)
- }
- return rr, nil, ""
-}
-
-func setMR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(MR)
- rr.Hdr = h
-
- l := <-c
- rr.Mr = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Mr = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad MR Mr", l}, ""
- }
- if rr.Mr[l.length-1] != '.' {
- rr.Mr = appendOrigin(rr.Mr, o)
- }
- return rr, nil, ""
-}
-
-func setMB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(MB)
- rr.Hdr = h
-
- l := <-c
- rr.Mb = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Mb = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad MB Mb", l}, ""
- }
- if rr.Mb[l.length-1] != '.' {
- rr.Mb = appendOrigin(rr.Mb, o)
- }
- return rr, nil, ""
-}
-
-func setMG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(MG)
- rr.Hdr = h
-
- l := <-c
- rr.Mg = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Mg = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad MG Mg", l}, ""
- }
- if rr.Mg[l.length-1] != '.' {
- rr.Mg = appendOrigin(rr.Mg, o)
- }
- return rr, nil, ""
-}
-
-func setHINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(HINFO)
- rr.Hdr = h
-
- chunks, e, c1 := endingToTxtSlice(c, "bad HINFO Fields", f)
- if e != nil {
- return nil, e, c1
- }
-
- if ln := len(chunks); ln == 0 {
- return rr, nil, ""
- } else if ln == 1 {
- // Can we split it?
- if out := strings.Fields(chunks[0]); len(out) > 1 {
- chunks = out
- } else {
- chunks = append(chunks, "")
- }
- }
-
- rr.Cpu = chunks[0]
- rr.Os = strings.Join(chunks[1:], " ")
-
- return rr, nil, ""
-}
-
-func setMINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(MINFO)
- rr.Hdr = h
-
- l := <-c
- rr.Rmail = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Rmail = o
- } else {
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad MINFO Rmail", l}, ""
- }
- if rr.Rmail[l.length-1] != '.' {
- rr.Rmail = appendOrigin(rr.Rmail, o)
- }
- }
- <-c // zBlank
- l = <-c
- rr.Email = l.token
- if l.token == "@" {
- rr.Email = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad MINFO Email", l}, ""
- }
- if rr.Email[l.length-1] != '.' {
- rr.Email = appendOrigin(rr.Email, o)
- }
- return rr, nil, ""
-}
-
-func setMF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(MF)
- rr.Hdr = h
-
- l := <-c
- rr.Mf = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Mf = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad MF Mf", l}, ""
- }
- if rr.Mf[l.length-1] != '.' {
- rr.Mf = appendOrigin(rr.Mf, o)
- }
- return rr, nil, ""
-}
-
-func setMD(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(MD)
- rr.Hdr = h
-
- l := <-c
- rr.Md = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Md = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad MD Md", l}, ""
- }
- if rr.Md[l.length-1] != '.' {
- rr.Md = appendOrigin(rr.Md, o)
- }
- return rr, nil, ""
-}
-
-func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(MX)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad MX Pref", l}, ""
- }
- rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
- rr.Mx = l.token
- if l.token == "@" {
- rr.Mx = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad MX Mx", l}, ""
- }
- if rr.Mx[l.length-1] != '.' {
- rr.Mx = appendOrigin(rr.Mx, o)
- }
- return rr, nil, ""
-}
-
-func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(RT)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil {
- return nil, &ParseError{f, "bad RT Preference", l}, ""
- }
- rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
- rr.Host = l.token
- if l.token == "@" {
- rr.Host = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad RT Host", l}, ""
- }
- if rr.Host[l.length-1] != '.' {
- rr.Host = appendOrigin(rr.Host, o)
- }
- return rr, nil, ""
-}
-
-func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(AFSDB)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad AFSDB Subtype", l}, ""
- }
- rr.Subtype = uint16(i)
- <-c // zBlank
- l = <-c // zString
- rr.Hostname = l.token
- if l.token == "@" {
- rr.Hostname = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad AFSDB Hostname", l}, ""
- }
- if rr.Hostname[l.length-1] != '.' {
- rr.Hostname = appendOrigin(rr.Hostname, o)
- }
- return rr, nil, ""
-}
-
-func setX25(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(X25)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.err {
- return nil, &ParseError{f, "bad X25 PSDNAddress", l}, ""
- }
- rr.PSDNAddress = l.token
- return rr, nil, ""
-}
-
-func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(KX)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad KX Pref", l}, ""
- }
- rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
- rr.Exchanger = l.token
- if l.token == "@" {
- rr.Exchanger = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad KX Exchanger", l}, ""
- }
- if rr.Exchanger[l.length-1] != '.' {
- rr.Exchanger = appendOrigin(rr.Exchanger, o)
- }
- return rr, nil, ""
-}
-
-func setCNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(CNAME)
- rr.Hdr = h
-
- l := <-c
- rr.Target = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Target = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad CNAME Target", l}, ""
- }
- if rr.Target[l.length-1] != '.' {
- rr.Target = appendOrigin(rr.Target, o)
- }
- return rr, nil, ""
-}
-
-func setDNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(DNAME)
- rr.Hdr = h
-
- l := <-c
- rr.Target = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Target = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad CNAME Target", l}, ""
- }
- if rr.Target[l.length-1] != '.' {
- rr.Target = appendOrigin(rr.Target, o)
- }
- return rr, nil, ""
-}
-
-func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(SOA)
- rr.Hdr = h
-
- l := <-c
- rr.Ns = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- <-c // zBlank
- if l.token == "@" {
- rr.Ns = o
- } else {
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad SOA Ns", l}, ""
- }
- if rr.Ns[l.length-1] != '.' {
- rr.Ns = appendOrigin(rr.Ns, o)
- }
- }
-
- l = <-c
- rr.Mbox = l.token
- if l.token == "@" {
- rr.Mbox = o
- } else {
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad SOA Mbox", l}, ""
- }
- if rr.Mbox[l.length-1] != '.' {
- rr.Mbox = appendOrigin(rr.Mbox, o)
- }
- }
- <-c // zBlank
-
- var (
- v uint32
- ok bool
- )
- for i := 0; i < 5; i++ {
- l = <-c
- if l.err {
- return nil, &ParseError{f, "bad SOA zone parameter", l}, ""
- }
- if j, e := strconv.ParseUint(l.token, 10, 32); e != nil {
- if i == 0 {
- // Serial should be a number
- return nil, &ParseError{f, "bad SOA zone parameter", l}, ""
- }
- if v, ok = stringToTtl(l.token); !ok {
- return nil, &ParseError{f, "bad SOA zone parameter", l}, ""
-
- }
- } else {
- v = uint32(j)
- }
- switch i {
- case 0:
- rr.Serial = v
- <-c // zBlank
- case 1:
- rr.Refresh = v
- <-c // zBlank
- case 2:
- rr.Retry = v
- <-c // zBlank
- case 3:
- rr.Expire = v
- <-c // zBlank
- case 4:
- rr.Minttl = v
- }
- }
- return rr, nil, ""
-}
-
-func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(SRV)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad SRV Priority", l}, ""
- }
- rr.Priority = uint16(i)
- <-c // zBlank
- l = <-c // zString
- i, e = strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad SRV Weight", l}, ""
- }
- rr.Weight = uint16(i)
- <-c // zBlank
- l = <-c // zString
- i, e = strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad SRV Port", l}, ""
- }
- rr.Port = uint16(i)
- <-c // zBlank
- l = <-c // zString
- rr.Target = l.token
- if l.token == "@" {
- rr.Target = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad SRV Target", l}, ""
- }
- if rr.Target[l.length-1] != '.' {
- rr.Target = appendOrigin(rr.Target, o)
- }
- return rr, nil, ""
-}
-
-func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NAPTR)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NAPTR Order", l}, ""
- }
- rr.Order = uint16(i)
- <-c // zBlank
- l = <-c // zString
- i, e = strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NAPTR Preference", l}, ""
- }
- rr.Preference = uint16(i)
- // Flags
- <-c // zBlank
- l = <-c // _QUOTE
- if l.value != zQuote {
- return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
- }
- l = <-c // Either String or Quote
- if l.value == zString {
- rr.Flags = l.token
- l = <-c // _QUOTE
- if l.value != zQuote {
- return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
- }
- } else if l.value == zQuote {
- rr.Flags = ""
- } else {
- return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
- }
-
- // Service
- <-c // zBlank
- l = <-c // _QUOTE
- if l.value != zQuote {
- return nil, &ParseError{f, "bad NAPTR Service", l}, ""
- }
- l = <-c // Either String or Quote
- if l.value == zString {
- rr.Service = l.token
- l = <-c // _QUOTE
- if l.value != zQuote {
- return nil, &ParseError{f, "bad NAPTR Service", l}, ""
- }
- } else if l.value == zQuote {
- rr.Service = ""
- } else {
- return nil, &ParseError{f, "bad NAPTR Service", l}, ""
- }
-
- // Regexp
- <-c // zBlank
- l = <-c // _QUOTE
- if l.value != zQuote {
- return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
- }
- l = <-c // Either String or Quote
- if l.value == zString {
- rr.Regexp = l.token
- l = <-c // _QUOTE
- if l.value != zQuote {
- return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
- }
- } else if l.value == zQuote {
- rr.Regexp = ""
- } else {
- return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
- }
- // After quote no space??
- <-c // zBlank
- l = <-c // zString
- rr.Replacement = l.token
- if l.token == "@" {
- rr.Replacement = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad NAPTR Replacement", l}, ""
- }
- if rr.Replacement[l.length-1] != '.' {
- rr.Replacement = appendOrigin(rr.Replacement, o)
- }
- return rr, nil, ""
-}
-
-func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(TALINK)
- rr.Hdr = h
-
- l := <-c
- rr.PreviousName = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.PreviousName = o
- } else {
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad TALINK PreviousName", l}, ""
- }
- if rr.PreviousName[l.length-1] != '.' {
- rr.PreviousName = appendOrigin(rr.PreviousName, o)
- }
- }
- <-c // zBlank
- l = <-c
- rr.NextName = l.token
- if l.token == "@" {
- rr.NextName = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad TALINK NextName", l}, ""
- }
- if rr.NextName[l.length-1] != '.' {
- rr.NextName = appendOrigin(rr.NextName, o)
- }
- return rr, nil, ""
-}
-
-func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(LOC)
- rr.Hdr = h
- // Non zero defaults for LOC record, see RFC 1876, Section 3.
- rr.HorizPre = 165 // 10000
- rr.VertPre = 162 // 10
- rr.Size = 18 // 1
- ok := false
- // North
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 32)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad LOC Latitude", l}, ""
- }
- rr.Latitude = 1000 * 60 * 60 * uint32(i)
-
- <-c // zBlank
- // Either number, 'N' or 'S'
- l = <-c
- if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
- goto East
- }
- i, e = strconv.ParseUint(l.token, 10, 32)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad LOC Latitude minutes", l}, ""
- }
- rr.Latitude += 1000 * 60 * uint32(i)
-
- <-c // zBlank
- l = <-c
- if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err {
- return nil, &ParseError{f, "bad LOC Latitude seconds", l}, ""
- } else {
- rr.Latitude += uint32(1000 * i)
- }
- <-c // zBlank
- // Either number, 'N' or 'S'
- l = <-c
- if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
- goto East
- }
- // If still alive, flag an error
- return nil, &ParseError{f, "bad LOC Latitude North/South", l}, ""
-
-East:
- // East
- <-c // zBlank
- l = <-c
- if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err {
- return nil, &ParseError{f, "bad LOC Longitude", l}, ""
- } else {
- rr.Longitude = 1000 * 60 * 60 * uint32(i)
- }
- <-c // zBlank
- // Either number, 'E' or 'W'
- l = <-c
- if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
- goto Altitude
- }
- if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err {
- return nil, &ParseError{f, "bad LOC Longitude minutes", l}, ""
- } else {
- rr.Longitude += 1000 * 60 * uint32(i)
- }
- <-c // zBlank
- l = <-c
- if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err {
- return nil, &ParseError{f, "bad LOC Longitude seconds", l}, ""
- } else {
- rr.Longitude += uint32(1000 * i)
- }
- <-c // zBlank
- // Either number, 'E' or 'W'
- l = <-c
- if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
- goto Altitude
- }
- // If still alive, flag an error
- return nil, &ParseError{f, "bad LOC Longitude East/West", l}, ""
-
-Altitude:
- <-c // zBlank
- l = <-c
- if l.length == 0 || l.err {
- return nil, &ParseError{f, "bad LOC Altitude", l}, ""
- }
- if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' {
- l.token = l.token[0 : len(l.token)-1]
- }
- if i, e := strconv.ParseFloat(l.token, 32); e != nil {
- return nil, &ParseError{f, "bad LOC Altitude", l}, ""
- } else {
- rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5)
- }
-
- // And now optionally the other values
- l = <-c
- count := 0
- for l.value != zNewline && l.value != zEOF {
- switch l.value {
- case zString:
- switch count {
- case 0: // Size
- e, m, ok := stringToCm(l.token)
- if !ok {
- return nil, &ParseError{f, "bad LOC Size", l}, ""
- }
- rr.Size = (e & 0x0f) | (m << 4 & 0xf0)
- case 1: // HorizPre
- e, m, ok := stringToCm(l.token)
- if !ok {
- return nil, &ParseError{f, "bad LOC HorizPre", l}, ""
- }
- rr.HorizPre = (e & 0x0f) | (m << 4 & 0xf0)
- case 2: // VertPre
- e, m, ok := stringToCm(l.token)
- if !ok {
- return nil, &ParseError{f, "bad LOC VertPre", l}, ""
- }
- rr.VertPre = (e & 0x0f) | (m << 4 & 0xf0)
- }
- count++
- case zBlank:
- // Ok
- default:
- return nil, &ParseError{f, "bad LOC Size, HorizPre or VertPre", l}, ""
- }
- l = <-c
- }
- return rr, nil, ""
-}
-
-func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(HIP)
- rr.Hdr = h
-
- // HitLength is not represented
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, e := strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad HIP PublicKeyAlgorithm", l}, ""
- }
- rr.PublicKeyAlgorithm = uint8(i)
- <-c // zBlank
- l = <-c // zString
- if l.length == 0 || l.err {
- return nil, &ParseError{f, "bad HIP Hit", l}, ""
- }
- rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6.
- rr.HitLength = uint8(len(rr.Hit)) / 2
-
- <-c // zBlank
- l = <-c // zString
- if l.length == 0 || l.err {
- return nil, &ParseError{f, "bad HIP PublicKey", l}, ""
- }
- rr.PublicKey = l.token // This cannot contain spaces
- rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey)))
-
- // RendezvousServers (if any)
- l = <-c
- var xs []string
- for l.value != zNewline && l.value != zEOF {
- switch l.value {
- case zString:
- if l.token == "@" {
- xs = append(xs, o)
- l = <-c
- continue
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad HIP RendezvousServers", l}, ""
- }
- if l.token[l.length-1] != '.' {
- l.token = appendOrigin(l.token, o)
- }
- xs = append(xs, l.token)
- case zBlank:
- // Ok
- default:
- return nil, &ParseError{f, "bad HIP RendezvousServers", l}, ""
- }
- l = <-c
- }
- rr.RendezvousServers = xs
- return rr, nil, l.comment
-}
-
-func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(CERT)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- if v, ok := StringToCertType[l.token]; ok {
- rr.Type = v
- } else if i, e := strconv.ParseUint(l.token, 10, 16); e != nil {
- return nil, &ParseError{f, "bad CERT Type", l}, ""
- } else {
- rr.Type = uint16(i)
- }
- <-c // zBlank
- l = <-c // zString
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad CERT KeyTag", l}, ""
- }
- rr.KeyTag = uint16(i)
- <-c // zBlank
- l = <-c // zString
- if v, ok := StringToAlgorithm[l.token]; ok {
- rr.Algorithm = v
- } else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
- return nil, &ParseError{f, "bad CERT Algorithm", l}, ""
- } else {
- rr.Algorithm = uint8(i)
- }
- s, e1, c1 := endingToString(c, "bad CERT Certificate", f)
- if e1 != nil {
- return nil, e1, c1
- }
- rr.Certificate = s
- return rr, nil, c1
-}
-
-func setOPENPGPKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(OPENPGPKEY)
- rr.Hdr = h
-
- s, e, c1 := endingToString(c, "bad OPENPGPKEY PublicKey", f)
- if e != nil {
- return nil, e, c1
- }
- rr.PublicKey = s
- return rr, nil, c1
-}
-
-func setSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- r, e, s := setRRSIG(h, c, o, f)
- if r != nil {
- return &SIG{*r.(*RRSIG)}, e, s
- }
- return nil, e, s
-}
-
-func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(RRSIG)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- if t, ok := StringToType[l.tokenUpper]; !ok {
- if strings.HasPrefix(l.tokenUpper, "TYPE") {
- t, ok = typeToInt(l.tokenUpper)
- if !ok {
- return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
- }
- rr.TypeCovered = t
- } else {
- return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
- }
- } else {
- rr.TypeCovered = t
- }
- <-c // zBlank
- l = <-c
- i, err := strconv.ParseUint(l.token, 10, 8)
- if err != nil || l.err {
- return nil, &ParseError{f, "bad RRSIG Algorithm", l}, ""
- }
- rr.Algorithm = uint8(i)
- <-c // zBlank
- l = <-c
- i, err = strconv.ParseUint(l.token, 10, 8)
- if err != nil || l.err {
- return nil, &ParseError{f, "bad RRSIG Labels", l}, ""
- }
- rr.Labels = uint8(i)
- <-c // zBlank
- l = <-c
- i, err = strconv.ParseUint(l.token, 10, 32)
- if err != nil || l.err {
- return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, ""
- }
- rr.OrigTtl = uint32(i)
- <-c // zBlank
- l = <-c
- if i, err := StringToTime(l.token); err != nil {
- // Try to see if all numeric and use it as epoch
- if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
- // TODO(miek): error out on > MAX_UINT32, same below
- rr.Expiration = uint32(i)
- } else {
- return nil, &ParseError{f, "bad RRSIG Expiration", l}, ""
- }
- } else {
- rr.Expiration = i
- }
- <-c // zBlank
- l = <-c
- if i, err := StringToTime(l.token); err != nil {
- if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
- rr.Inception = uint32(i)
- } else {
- return nil, &ParseError{f, "bad RRSIG Inception", l}, ""
- }
- } else {
- rr.Inception = i
- }
- <-c // zBlank
- l = <-c
- i, err = strconv.ParseUint(l.token, 10, 16)
- if err != nil || l.err {
- return nil, &ParseError{f, "bad RRSIG KeyTag", l}, ""
- }
- rr.KeyTag = uint16(i)
- <-c // zBlank
- l = <-c
- rr.SignerName = l.token
- if l.token == "@" {
- rr.SignerName = o
- } else {
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad RRSIG SignerName", l}, ""
- }
- if rr.SignerName[l.length-1] != '.' {
- rr.SignerName = appendOrigin(rr.SignerName, o)
- }
- }
- s, e, c1 := endingToString(c, "bad RRSIG Signature", f)
- if e != nil {
- return nil, e, c1
- }
- rr.Signature = s
- return rr, nil, c1
-}
-
-func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NSEC)
- rr.Hdr = h
-
- l := <-c
- rr.NextDomain = l.token
- if l.length == 0 {
- return rr, nil, l.comment
- }
- if l.token == "@" {
- rr.NextDomain = o
- } else {
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad NSEC NextDomain", l}, ""
- }
- if rr.NextDomain[l.length-1] != '.' {
- rr.NextDomain = appendOrigin(rr.NextDomain, o)
- }
- }
-
- rr.TypeBitMap = make([]uint16, 0)
- var (
- k uint16
- ok bool
- )
- l = <-c
- for l.value != zNewline && l.value != zEOF {
- switch l.value {
- case zBlank:
- // Ok
- case zString:
- if k, ok = StringToType[l.tokenUpper]; !ok {
- if k, ok = typeToInt(l.tokenUpper); !ok {
- return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
- }
- }
- rr.TypeBitMap = append(rr.TypeBitMap, k)
- default:
- return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
- }
- l = <-c
- }
- return rr, nil, l.comment
-}
-
-func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NSEC3)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, e := strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NSEC3 Hash", l}, ""
- }
- rr.Hash = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NSEC3 Flags", l}, ""
- }
- rr.Flags = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NSEC3 Iterations", l}, ""
- }
- rr.Iterations = uint16(i)
- <-c
- l = <-c
- if len(l.token) == 0 || l.err {
- return nil, &ParseError{f, "bad NSEC3 Salt", l}, ""
- }
- rr.SaltLength = uint8(len(l.token)) / 2
- rr.Salt = l.token
-
- <-c
- l = <-c
- if len(l.token) == 0 || l.err {
- return nil, &ParseError{f, "bad NSEC3 NextDomain", l}, ""
- }
- rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
- rr.NextDomain = l.token
-
- rr.TypeBitMap = make([]uint16, 0)
- var (
- k uint16
- ok bool
- )
- l = <-c
- for l.value != zNewline && l.value != zEOF {
- switch l.value {
- case zBlank:
- // Ok
- case zString:
- if k, ok = StringToType[l.tokenUpper]; !ok {
- if k, ok = typeToInt(l.tokenUpper); !ok {
- return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
- }
- }
- rr.TypeBitMap = append(rr.TypeBitMap, k)
- default:
- return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
- }
- l = <-c
- }
- return rr, nil, l.comment
-}
-
-func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NSEC3PARAM)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, ""
- }
- rr.Hash = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, ""
- }
- rr.Flags = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, ""
- }
- rr.Iterations = uint16(i)
- <-c
- l = <-c
- rr.SaltLength = uint8(len(l.token))
- rr.Salt = l.token
- return rr, nil, ""
-}
-
-func setEUI48(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(EUI48)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.length != 17 || l.err {
- return nil, &ParseError{f, "bad EUI48 Address", l}, ""
- }
- addr := make([]byte, 12)
- dash := 0
- for i := 0; i < 10; i += 2 {
- addr[i] = l.token[i+dash]
- addr[i+1] = l.token[i+1+dash]
- dash++
- if l.token[i+1+dash] != '-' {
- return nil, &ParseError{f, "bad EUI48 Address", l}, ""
- }
- }
- addr[10] = l.token[15]
- addr[11] = l.token[16]
-
- i, e := strconv.ParseUint(string(addr), 16, 48)
- if e != nil {
- return nil, &ParseError{f, "bad EUI48 Address", l}, ""
- }
- rr.Address = i
- return rr, nil, ""
-}
-
-func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(EUI64)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.length != 23 || l.err {
- return nil, &ParseError{f, "bad EUI64 Address", l}, ""
- }
- addr := make([]byte, 16)
- dash := 0
- for i := 0; i < 14; i += 2 {
- addr[i] = l.token[i+dash]
- addr[i+1] = l.token[i+1+dash]
- dash++
- if l.token[i+1+dash] != '-' {
- return nil, &ParseError{f, "bad EUI64 Address", l}, ""
- }
- }
- addr[14] = l.token[21]
- addr[15] = l.token[22]
-
- i, e := strconv.ParseUint(string(addr), 16, 64)
- if e != nil {
- return nil, &ParseError{f, "bad EUI68 Address", l}, ""
- }
- rr.Address = uint64(i)
- return rr, nil, ""
-}
-
-func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(SSHFP)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad SSHFP Algorithm", l}, ""
- }
- rr.Algorithm = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad SSHFP Type", l}, ""
- }
- rr.Type = uint8(i)
- <-c // zBlank
- s, e1, c1 := endingToString(c, "bad SSHFP Fingerprint", f)
- if e1 != nil {
- return nil, e1, c1
- }
- rr.FingerPrint = s
- return rr, nil, ""
-}
-
-func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) {
- rr := new(DNSKEY)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad " + typ + " Flags", l}, ""
- }
- rr.Flags = uint16(i)
- <-c // zBlank
- l = <-c // zString
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad " + typ + " Protocol", l}, ""
- }
- rr.Protocol = uint8(i)
- <-c // zBlank
- l = <-c // zString
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
- }
- rr.Algorithm = uint8(i)
- s, e1, c1 := endingToString(c, "bad "+typ+" PublicKey", f)
- if e1 != nil {
- return nil, e1, c1
- }
- rr.PublicKey = s
- return rr, nil, c1
-}
-
-func setKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- r, e, s := setDNSKEYs(h, c, o, f, "KEY")
- if r != nil {
- return &KEY{*r.(*DNSKEY)}, e, s
- }
- return nil, e, s
-}
-
-func setDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- r, e, s := setDNSKEYs(h, c, o, f, "DNSKEY")
- return r, e, s
-}
-
-func setCDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- r, e, s := setDNSKEYs(h, c, o, f, "CDNSKEY")
- if r != nil {
- return &CDNSKEY{*r.(*DNSKEY)}, e, s
- }
- return nil, e, s
-}
-
-func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(RKEY)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad RKEY Flags", l}, ""
- }
- rr.Flags = uint16(i)
- <-c // zBlank
- l = <-c // zString
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad RKEY Protocol", l}, ""
- }
- rr.Protocol = uint8(i)
- <-c // zBlank
- l = <-c // zString
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad RKEY Algorithm", l}, ""
- }
- rr.Algorithm = uint8(i)
- s, e1, c1 := endingToString(c, "bad RKEY PublicKey", f)
- if e1 != nil {
- return nil, e1, c1
- }
- rr.PublicKey = s
- return rr, nil, c1
-}
-
-func setEID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(EID)
- rr.Hdr = h
- s, e, c1 := endingToString(c, "bad EID Endpoint", f)
- if e != nil {
- return nil, e, c1
- }
- rr.Endpoint = s
- return rr, nil, c1
-}
-
-func setNIMLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NIMLOC)
- rr.Hdr = h
- s, e, c1 := endingToString(c, "bad NIMLOC Locator", f)
- if e != nil {
- return nil, e, c1
- }
- rr.Locator = s
- return rr, nil, c1
-}
-
-func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(GPOS)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- _, e := strconv.ParseFloat(l.token, 64)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad GPOS Longitude", l}, ""
- }
- rr.Longitude = l.token
- <-c // zBlank
- l = <-c
- _, e = strconv.ParseFloat(l.token, 64)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad GPOS Latitude", l}, ""
- }
- rr.Latitude = l.token
- <-c // zBlank
- l = <-c
- _, e = strconv.ParseFloat(l.token, 64)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad GPOS Altitude", l}, ""
- }
- rr.Altitude = l.token
- return rr, nil, ""
-}
-
-func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) {
- rr := new(DS)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, ""
- }
- rr.KeyTag = uint16(i)
- <-c // zBlank
- l = <-c
- if i, e = strconv.ParseUint(l.token, 10, 8); e != nil {
- i, ok := StringToAlgorithm[l.tokenUpper]
- if !ok || l.err {
- return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
- }
- rr.Algorithm = i
- } else {
- rr.Algorithm = uint8(i)
- }
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad " + typ + " DigestType", l}, ""
- }
- rr.DigestType = uint8(i)
- s, e1, c1 := endingToString(c, "bad "+typ+" Digest", f)
- if e1 != nil {
- return nil, e1, c1
- }
- rr.Digest = s
- return rr, nil, c1
-}
-
-func setDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- r, e, s := setDSs(h, c, o, f, "DS")
- return r, e, s
-}
-
-func setDLV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- r, e, s := setDSs(h, c, o, f, "DLV")
- if r != nil {
- return &DLV{*r.(*DS)}, e, s
- }
- return nil, e, s
-}
-
-func setCDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- r, e, s := setDSs(h, c, o, f, "CDS")
- if r != nil {
- return &CDS{*r.(*DS)}, e, s
- }
- return nil, e, s
-}
-
-func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(TA)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad TA KeyTag", l}, ""
- }
- rr.KeyTag = uint16(i)
- <-c // zBlank
- l = <-c
- if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
- i, ok := StringToAlgorithm[l.tokenUpper]
- if !ok || l.err {
- return nil, &ParseError{f, "bad TA Algorithm", l}, ""
- }
- rr.Algorithm = i
- } else {
- rr.Algorithm = uint8(i)
- }
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad TA DigestType", l}, ""
- }
- rr.DigestType = uint8(i)
- s, e, c1 := endingToString(c, "bad TA Digest", f)
- if e != nil {
- return nil, e.(*ParseError), c1
- }
- rr.Digest = s
- return rr, nil, c1
-}
-
-func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(TLSA)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, e := strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad TLSA Usage", l}, ""
- }
- rr.Usage = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad TLSA Selector", l}, ""
- }
- rr.Selector = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad TLSA MatchingType", l}, ""
- }
- rr.MatchingType = uint8(i)
- // So this needs be e2 (i.e. different than e), because...??t
- s, e2, c1 := endingToString(c, "bad TLSA Certificate", f)
- if e2 != nil {
- return nil, e2, c1
- }
- rr.Certificate = s
- return rr, nil, c1
-}
-
-func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(SMIMEA)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, e := strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad SMIMEA Usage", l}, ""
- }
- rr.Usage = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad SMIMEA Selector", l}, ""
- }
- rr.Selector = uint8(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 8)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad SMIMEA MatchingType", l}, ""
- }
- rr.MatchingType = uint8(i)
- // So this needs be e2 (i.e. different than e), because...??t
- s, e2, c1 := endingToString(c, "bad SMIMEA Certificate", f)
- if e2 != nil {
- return nil, e2, c1
- }
- rr.Certificate = s
- return rr, nil, c1
-}
-
-func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(RFC3597)
- rr.Hdr = h
- l := <-c
- if l.token != "\\#" {
- return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
- }
- <-c // zBlank
- l = <-c
- rdlength, e := strconv.Atoi(l.token)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad RFC3597 Rdata ", l}, ""
- }
-
- s, e1, c1 := endingToString(c, "bad RFC3597 Rdata", f)
- if e1 != nil {
- return nil, e1, c1
- }
- if rdlength*2 != len(s) {
- return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
- }
- rr.Rdata = s
- return rr, nil, c1
-}
-
-func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(SPF)
- rr.Hdr = h
-
- s, e, c1 := endingToTxtSlice(c, "bad SPF Txt", f)
- if e != nil {
- return nil, e, ""
- }
- rr.Txt = s
- return rr, nil, c1
-}
-
-func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(AVC)
- rr.Hdr = h
-
- s, e, c1 := endingToTxtSlice(c, "bad AVC Txt", f)
- if e != nil {
- return nil, e, ""
- }
- rr.Txt = s
- return rr, nil, c1
-}
-
-func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(TXT)
- rr.Hdr = h
-
- // no zBlank reading here, because all this rdata is TXT
- s, e, c1 := endingToTxtSlice(c, "bad TXT Txt", f)
- if e != nil {
- return nil, e, ""
- }
- rr.Txt = s
- return rr, nil, c1
-}
-
-// identical to setTXT
-func setNINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NINFO)
- rr.Hdr = h
-
- s, e, c1 := endingToTxtSlice(c, "bad NINFO ZSData", f)
- if e != nil {
- return nil, e, ""
- }
- rr.ZSData = s
- return rr, nil, c1
-}
-
-func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(URI)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 { // Dynamic updates.
- return rr, nil, ""
- }
-
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad URI Priority", l}, ""
- }
- rr.Priority = uint16(i)
- <-c // zBlank
- l = <-c
- i, e = strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad URI Weight", l}, ""
- }
- rr.Weight = uint16(i)
-
- <-c // zBlank
- s, err, c1 := endingToTxtSlice(c, "bad URI Target", f)
- if err != nil {
- return nil, err, ""
- }
- if len(s) > 1 {
- return nil, &ParseError{f, "bad URI Target", l}, ""
- }
- rr.Target = s[0]
- return rr, nil, c1
-}
-
-func setDHCID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- // awesome record to parse!
- rr := new(DHCID)
- rr.Hdr = h
-
- s, e, c1 := endingToString(c, "bad DHCID Digest", f)
- if e != nil {
- return nil, e, c1
- }
- rr.Digest = s
- return rr, nil, c1
-}
-
-func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(NID)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad NID Preference", l}, ""
- }
- rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
- u, err := stringToNodeID(l)
- if err != nil || l.err {
- return nil, err, ""
- }
- rr.NodeID = u
- return rr, nil, ""
-}
-
-func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(L32)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad L32 Preference", l}, ""
- }
- rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
- rr.Locator32 = net.ParseIP(l.token)
- if rr.Locator32 == nil || l.err {
- return nil, &ParseError{f, "bad L32 Locator", l}, ""
- }
- return rr, nil, ""
-}
-
-func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(LP)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad LP Preference", l}, ""
- }
- rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
- rr.Fqdn = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Fqdn = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad LP Fqdn", l}, ""
- }
- if rr.Fqdn[l.length-1] != '.' {
- rr.Fqdn = appendOrigin(rr.Fqdn, o)
- }
- return rr, nil, ""
-}
-
-func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(L64)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad L64 Preference", l}, ""
- }
- rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
- u, err := stringToNodeID(l)
- if err != nil || l.err {
- return nil, err, ""
- }
- rr.Locator64 = u
- return rr, nil, ""
-}
-
-func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(UID)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 32)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad UID Uid", l}, ""
- }
- rr.Uid = uint32(i)
- return rr, nil, ""
-}
-
-func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(GID)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 32)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad GID Gid", l}, ""
- }
- rr.Gid = uint32(i)
- return rr, nil, ""
-}
-
-func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(UINFO)
- rr.Hdr = h
- s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f)
- if e != nil {
- return nil, e, c1
- }
- if ln := len(s); ln == 0 {
- return rr, nil, c1
- }
- rr.Uinfo = s[0] // silently discard anything after the first character-string
- return rr, nil, c1
-}
-
-func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(PX)
- rr.Hdr = h
-
- l := <-c
- if l.length == 0 {
- return rr, nil, ""
- }
- i, e := strconv.ParseUint(l.token, 10, 16)
- if e != nil || l.err {
- return nil, &ParseError{f, "bad PX Preference", l}, ""
- }
- rr.Preference = uint16(i)
- <-c // zBlank
- l = <-c // zString
- rr.Map822 = l.token
- if l.length == 0 {
- return rr, nil, ""
- }
- if l.token == "@" {
- rr.Map822 = o
- return rr, nil, ""
- }
- _, ok := IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad PX Map822", l}, ""
- }
- if rr.Map822[l.length-1] != '.' {
- rr.Map822 = appendOrigin(rr.Map822, o)
- }
- <-c // zBlank
- l = <-c // zString
- rr.Mapx400 = l.token
- if l.token == "@" {
- rr.Mapx400 = o
- return rr, nil, ""
- }
- _, ok = IsDomainName(l.token)
- if !ok || l.length == 0 || l.err {
- return nil, &ParseError{f, "bad PX Mapx400", l}, ""
- }
- if rr.Mapx400[l.length-1] != '.' {
- rr.Mapx400 = appendOrigin(rr.Mapx400, o)
- }
- return rr, nil, ""
-}
-
-func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
- rr := new(CAA)
- rr.Hdr = h
- l := <-c
- if l.length == 0 {
- return rr, nil, l.comment
- }
- i, err := strconv.ParseUint(l.token, 10, 8)
- if err != nil || l.err {
- return nil, &ParseError{f, "bad CAA Flag", l}, ""
- }
- rr.Flag = uint8(i)
-
- <-c // zBlank
- l = <-c // zString
- if l.value != zString {
- return nil, &ParseError{f, "bad CAA Tag", l}, ""
- }
- rr.Tag = l.token
-
- <-c // zBlank
- s, e, c1 := endingToTxtSlice(c, "bad CAA Value", f)
- if e != nil {
- return nil, e, ""
- }
- if len(s) > 1 {
- return nil, &ParseError{f, "bad CAA Value", l}, ""
- }
- rr.Value = s[0]
- return rr, nil, c1
-}
-
-var typeToparserFunc = map[uint16]parserFunc{
- TypeAAAA: {setAAAA, false},
- TypeAFSDB: {setAFSDB, false},
- TypeA: {setA, false},
- TypeCAA: {setCAA, true},
- TypeCDS: {setCDS, true},
- TypeCDNSKEY: {setCDNSKEY, true},
- TypeCERT: {setCERT, true},
- TypeCNAME: {setCNAME, false},
- TypeDHCID: {setDHCID, true},
- TypeDLV: {setDLV, true},
- TypeDNAME: {setDNAME, false},
- TypeKEY: {setKEY, true},
- TypeDNSKEY: {setDNSKEY, true},
- TypeDS: {setDS, true},
- TypeEID: {setEID, true},
- TypeEUI48: {setEUI48, false},
- TypeEUI64: {setEUI64, false},
- TypeGID: {setGID, false},
- TypeGPOS: {setGPOS, false},
- TypeHINFO: {setHINFO, true},
- TypeHIP: {setHIP, true},
- TypeKX: {setKX, false},
- TypeL32: {setL32, false},
- TypeL64: {setL64, false},
- TypeLOC: {setLOC, true},
- TypeLP: {setLP, false},
- TypeMB: {setMB, false},
- TypeMD: {setMD, false},
- TypeMF: {setMF, false},
- TypeMG: {setMG, false},
- TypeMINFO: {setMINFO, false},
- TypeMR: {setMR, false},
- TypeMX: {setMX, false},
- TypeNAPTR: {setNAPTR, false},
- TypeNID: {setNID, false},
- TypeNIMLOC: {setNIMLOC, true},
- TypeNINFO: {setNINFO, true},
- TypeNSAPPTR: {setNSAPPTR, false},
- TypeNSEC3PARAM: {setNSEC3PARAM, false},
- TypeNSEC3: {setNSEC3, true},
- TypeNSEC: {setNSEC, true},
- TypeNS: {setNS, false},
- TypeOPENPGPKEY: {setOPENPGPKEY, true},
- TypePTR: {setPTR, false},
- TypePX: {setPX, false},
- TypeSIG: {setSIG, true},
- TypeRKEY: {setRKEY, true},
- TypeRP: {setRP, false},
- TypeRRSIG: {setRRSIG, true},
- TypeRT: {setRT, false},
- TypeSMIMEA: {setSMIMEA, true},
- TypeSOA: {setSOA, false},
- TypeSPF: {setSPF, true},
- TypeAVC: {setAVC, true},
- TypeSRV: {setSRV, false},
- TypeSSHFP: {setSSHFP, true},
- TypeTALINK: {setTALINK, false},
- TypeTA: {setTA, true},
- TypeTLSA: {setTLSA, true},
- TypeTXT: {setTXT, true},
- TypeUID: {setUID, false},
- TypeUINFO: {setUINFO, true},
- TypeURI: {setURI, true},
- TypeX25: {setX25, false},
-}
diff --git a/vendor/github.com/miekg/dns/scanner.go b/vendor/github.com/miekg/dns/scanner.go
deleted file mode 100644
index c29bc2f38..000000000
--- a/vendor/github.com/miekg/dns/scanner.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package dns
-
-// Implement a simple scanner, return a byte stream from an io reader.
-
-import (
- "bufio"
- "io"
- "text/scanner"
-)
-
-type scan struct {
- src *bufio.Reader
- position scanner.Position
- eof bool // Have we just seen a eof
-}
-
-func scanInit(r io.Reader) *scan {
- s := new(scan)
- s.src = bufio.NewReader(r)
- s.position.Line = 1
- return s
-}
-
-// tokenText returns the next byte from the input
-func (s *scan) tokenText() (byte, error) {
- c, err := s.src.ReadByte()
- if err != nil {
- return c, err
- }
- // delay the newline handling until the next token is delivered,
- // fixes off-by-one errors when reporting a parse error.
- if s.eof == true {
- s.position.Line++
- s.position.Column = 0
- s.eof = false
- }
- if c == '\n' {
- s.eof = true
- return c, nil
- }
- s.position.Column++
- return c, nil
-}
diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go
deleted file mode 100644
index 0ca6e008c..000000000
--- a/vendor/github.com/miekg/dns/server.go
+++ /dev/null
@@ -1,734 +0,0 @@
-// DNS server implementation.
-
-package dns
-
-import (
- "bytes"
- "crypto/tls"
- "encoding/binary"
- "io"
- "net"
- "sync"
- "time"
-)
-
-// Maximum number of TCP queries before we close the socket.
-const maxTCPQueries = 128
-
-// Handler is implemented by any value that implements ServeDNS.
-type Handler interface {
- ServeDNS(w ResponseWriter, r *Msg)
-}
-
-// A ResponseWriter interface is used by an DNS handler to
-// construct an DNS response.
-type ResponseWriter interface {
- // LocalAddr returns the net.Addr of the server
- LocalAddr() net.Addr
- // RemoteAddr returns the net.Addr of the client that sent the current request.
- RemoteAddr() net.Addr
- // WriteMsg writes a reply back to the client.
- WriteMsg(*Msg) error
- // Write writes a raw buffer back to the client.
- Write([]byte) (int, error)
- // Close closes the connection.
- Close() error
- // TsigStatus returns the status of the Tsig.
- TsigStatus() error
- // TsigTimersOnly sets the tsig timers only boolean.
- TsigTimersOnly(bool)
- // Hijack lets the caller take over the connection.
- // After a call to Hijack(), the DNS package will not do anything with the connection.
- Hijack()
-}
-
-type response struct {
- hijacked bool // connection has been hijacked by handler
- tsigStatus error
- tsigTimersOnly bool
- tsigRequestMAC string
- tsigSecret map[string]string // the tsig secrets
- udp *net.UDPConn // i/o connection if UDP was used
- tcp net.Conn // i/o connection if TCP was used
- udpSession *SessionUDP // oob data to get egress interface right
- remoteAddr net.Addr // address of the client
- writer Writer // writer to output the raw DNS bits
-}
-
-// ServeMux is an DNS request multiplexer. It matches the
-// zone name of each incoming request against a list of
-// registered patterns add calls the handler for the pattern
-// that most closely matches the zone name. ServeMux is DNSSEC aware, meaning
-// that queries for the DS record are redirected to the parent zone (if that
-// is also registered), otherwise the child gets the query.
-// ServeMux is also safe for concurrent access from multiple goroutines.
-type ServeMux struct {
- z map[string]Handler
- m *sync.RWMutex
-}
-
-// NewServeMux allocates and returns a new ServeMux.
-func NewServeMux() *ServeMux { return &ServeMux{z: make(map[string]Handler), m: new(sync.RWMutex)} }
-
-// DefaultServeMux is the default ServeMux used by Serve.
-var DefaultServeMux = NewServeMux()
-
-// The HandlerFunc type is an adapter to allow the use of
-// ordinary functions as DNS handlers. If f is a function
-// with the appropriate signature, HandlerFunc(f) is a
-// Handler object that calls f.
-type HandlerFunc func(ResponseWriter, *Msg)
-
-// ServeDNS calls f(w, r).
-func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
- f(w, r)
-}
-
-// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets.
-func HandleFailed(w ResponseWriter, r *Msg) {
- m := new(Msg)
- m.SetRcode(r, RcodeServerFailure)
- // does not matter if this write fails
- w.WriteMsg(m)
-}
-
-func failedHandler() Handler { return HandlerFunc(HandleFailed) }
-
-// ListenAndServe Starts a server on address and network specified Invoke handler
-// for incoming queries.
-func ListenAndServe(addr string, network string, handler Handler) error {
- server := &Server{Addr: addr, Net: network, Handler: handler}
- return server.ListenAndServe()
-}
-
-// ListenAndServeTLS acts like http.ListenAndServeTLS, more information in
-// http://golang.org/pkg/net/http/#ListenAndServeTLS
-func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
- cert, err := tls.LoadX509KeyPair(certFile, keyFile)
- if err != nil {
- return err
- }
-
- config := tls.Config{
- Certificates: []tls.Certificate{cert},
- }
-
- server := &Server{
- Addr: addr,
- Net: "tcp-tls",
- TLSConfig: &config,
- Handler: handler,
- }
-
- return server.ListenAndServe()
-}
-
-// ActivateAndServe activates a server with a listener from systemd,
-// l and p should not both be non-nil.
-// If both l and p are not nil only p will be used.
-// Invoke handler for incoming queries.
-func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error {
- server := &Server{Listener: l, PacketConn: p, Handler: handler}
- return server.ActivateAndServe()
-}
-
-func (mux *ServeMux) match(q string, t uint16) Handler {
- mux.m.RLock()
- defer mux.m.RUnlock()
- var handler Handler
- b := make([]byte, len(q)) // worst case, one label of length q
- off := 0
- end := false
- for {
- l := len(q[off:])
- for i := 0; i < l; i++ {
- b[i] = q[off+i]
- if b[i] >= 'A' && b[i] <= 'Z' {
- b[i] |= ('a' - 'A')
- }
- }
- if h, ok := mux.z[string(b[:l])]; ok { // causes garbage, might want to change the map key
- if t != TypeDS {
- return h
- }
- // Continue for DS to see if we have a parent too, if so delegeate to the parent
- handler = h
- }
- off, end = NextLabel(q, off)
- if end {
- break
- }
- }
- // Wildcard match, if we have found nothing try the root zone as a last resort.
- if h, ok := mux.z["."]; ok {
- return h
- }
- return handler
-}
-
-// Handle adds a handler to the ServeMux for pattern.
-func (mux *ServeMux) Handle(pattern string, handler Handler) {
- if pattern == "" {
- panic("dns: invalid pattern " + pattern)
- }
- mux.m.Lock()
- mux.z[Fqdn(pattern)] = handler
- mux.m.Unlock()
-}
-
-// HandleFunc adds a handler function to the ServeMux for pattern.
-func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
- mux.Handle(pattern, HandlerFunc(handler))
-}
-
-// HandleRemove deregistrars the handler specific for pattern from the ServeMux.
-func (mux *ServeMux) HandleRemove(pattern string) {
- if pattern == "" {
- panic("dns: invalid pattern " + pattern)
- }
- mux.m.Lock()
- delete(mux.z, Fqdn(pattern))
- mux.m.Unlock()
-}
-
-// ServeDNS dispatches the request to the handler whose
-// pattern most closely matches the request message. If DefaultServeMux
-// is used the correct thing for DS queries is done: a possible parent
-// is sought.
-// If no handler is found a standard SERVFAIL message is returned
-// If the request message does not have exactly one question in the
-// question section a SERVFAIL is returned, unlesss Unsafe is true.
-func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg) {
- var h Handler
- if len(request.Question) < 1 { // allow more than one question
- h = failedHandler()
- } else {
- if h = mux.match(request.Question[0].Name, request.Question[0].Qtype); h == nil {
- h = failedHandler()
- }
- }
- h.ServeDNS(w, request)
-}
-
-// Handle registers the handler with the given pattern
-// in the DefaultServeMux. The documentation for
-// ServeMux explains how patterns are matched.
-func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
-
-// HandleRemove deregisters the handle with the given pattern
-// in the DefaultServeMux.
-func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) }
-
-// HandleFunc registers the handler function with the given pattern
-// in the DefaultServeMux.
-func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
- DefaultServeMux.HandleFunc(pattern, handler)
-}
-
-// Writer writes raw DNS messages; each call to Write should send an entire message.
-type Writer interface {
- io.Writer
-}
-
-// Reader reads raw DNS messages; each call to ReadTCP or ReadUDP should return an entire message.
-type Reader interface {
- // ReadTCP reads a raw message from a TCP connection. Implementations may alter
- // connection properties, for example the read-deadline.
- ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error)
- // ReadUDP reads a raw message from a UDP connection. Implementations may alter
- // connection properties, for example the read-deadline.
- ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error)
-}
-
-// defaultReader is an adapter for the Server struct that implements the Reader interface
-// using the readTCP and readUDP func of the embedded Server.
-type defaultReader struct {
- *Server
-}
-
-func (dr *defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
- return dr.readTCP(conn, timeout)
-}
-
-func (dr *defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
- return dr.readUDP(conn, timeout)
-}
-
-// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader.
-// Implementations should never return a nil Reader.
-type DecorateReader func(Reader) Reader
-
-// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer.
-// Implementations should never return a nil Writer.
-type DecorateWriter func(Writer) Writer
-
-// A Server defines parameters for running an DNS server.
-type Server struct {
- // Address to listen on, ":dns" if empty.
- Addr string
- // if "tcp" or "tcp-tls" (DNS over TLS) it will invoke a TCP listener, otherwise an UDP one
- Net string
- // TCP Listener to use, this is to aid in systemd's socket activation.
- Listener net.Listener
- // TLS connection configuration
- TLSConfig *tls.Config
- // UDP "Listener" to use, this is to aid in systemd's socket activation.
- PacketConn net.PacketConn
- // Handler to invoke, dns.DefaultServeMux if nil.
- Handler Handler
- // Default buffer size to use to read incoming UDP messages. If not set
- // it defaults to MinMsgSize (512 B).
- UDPSize int
- // The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second.
- ReadTimeout time.Duration
- // The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second.
- WriteTimeout time.Duration
- // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
- IdleTimeout func() time.Duration
- // Secret(s) for Tsig map[<zonename>]<base64 secret>.
- TsigSecret map[string]string
- // Unsafe instructs the server to disregard any sanity checks and directly hand the message to
- // the handler. It will specifically not check if the query has the QR bit not set.
- Unsafe bool
- // If NotifyStartedFunc is set it is called once the server has started listening.
- NotifyStartedFunc func()
- // DecorateReader is optional, allows customization of the process that reads raw DNS messages.
- DecorateReader DecorateReader
- // DecorateWriter is optional, allows customization of the process that writes raw DNS messages.
- DecorateWriter DecorateWriter
-
- // Graceful shutdown handling
-
- inFlight sync.WaitGroup
-
- lock sync.RWMutex
- started bool
-}
-
-// ListenAndServe starts a nameserver on the configured address in *Server.
-func (srv *Server) ListenAndServe() error {
- srv.lock.Lock()
- defer srv.lock.Unlock()
- if srv.started {
- return &Error{err: "server already started"}
- }
- addr := srv.Addr
- if addr == "" {
- addr = ":domain"
- }
- if srv.UDPSize == 0 {
- srv.UDPSize = MinMsgSize
- }
- switch srv.Net {
- case "tcp", "tcp4", "tcp6":
- a, err := net.ResolveTCPAddr(srv.Net, addr)
- if err != nil {
- return err
- }
- l, err := net.ListenTCP(srv.Net, a)
- if err != nil {
- return err
- }
- srv.Listener = l
- srv.started = true
- srv.lock.Unlock()
- err = srv.serveTCP(l)
- srv.lock.Lock() // to satisfy the defer at the top
- return err
- case "tcp-tls", "tcp4-tls", "tcp6-tls":
- network := "tcp"
- if srv.Net == "tcp4-tls" {
- network = "tcp4"
- } else if srv.Net == "tcp6-tls" {
- network = "tcp6"
- }
-
- l, err := tls.Listen(network, addr, srv.TLSConfig)
- if err != nil {
- return err
- }
- srv.Listener = l
- srv.started = true
- srv.lock.Unlock()
- err = srv.serveTCP(l)
- srv.lock.Lock() // to satisfy the defer at the top
- return err
- case "udp", "udp4", "udp6":
- a, err := net.ResolveUDPAddr(srv.Net, addr)
- if err != nil {
- return err
- }
- l, err := net.ListenUDP(srv.Net, a)
- if err != nil {
- return err
- }
- if e := setUDPSocketOptions(l); e != nil {
- return e
- }
- srv.PacketConn = l
- srv.started = true
- srv.lock.Unlock()
- err = srv.serveUDP(l)
- srv.lock.Lock() // to satisfy the defer at the top
- return err
- }
- return &Error{err: "bad network"}
-}
-
-// ActivateAndServe starts a nameserver with the PacketConn or Listener
-// configured in *Server. Its main use is to start a server from systemd.
-func (srv *Server) ActivateAndServe() error {
- srv.lock.Lock()
- defer srv.lock.Unlock()
- if srv.started {
- return &Error{err: "server already started"}
- }
- pConn := srv.PacketConn
- l := srv.Listener
- if pConn != nil {
- if srv.UDPSize == 0 {
- srv.UDPSize = MinMsgSize
- }
- // Check PacketConn interface's type is valid and value
- // is not nil
- if t, ok := pConn.(*net.UDPConn); ok && t != nil {
- if e := setUDPSocketOptions(t); e != nil {
- return e
- }
- srv.started = true
- srv.lock.Unlock()
- e := srv.serveUDP(t)
- srv.lock.Lock() // to satisfy the defer at the top
- return e
- }
- }
- if l != nil {
- srv.started = true
- srv.lock.Unlock()
- e := srv.serveTCP(l)
- srv.lock.Lock() // to satisfy the defer at the top
- return e
- }
- return &Error{err: "bad listeners"}
-}
-
-// Shutdown gracefully shuts down a server. After a call to Shutdown, ListenAndServe and
-// ActivateAndServe will return. All in progress queries are completed before the server
-// is taken down. If the Shutdown is taking longer than the reading timeout an error
-// is returned.
-func (srv *Server) Shutdown() error {
- srv.lock.Lock()
- if !srv.started {
- srv.lock.Unlock()
- return &Error{err: "server not started"}
- }
- srv.started = false
- srv.lock.Unlock()
-
- if srv.PacketConn != nil {
- srv.PacketConn.Close()
- }
- if srv.Listener != nil {
- srv.Listener.Close()
- }
-
- fin := make(chan bool)
- go func() {
- srv.inFlight.Wait()
- fin <- true
- }()
-
- select {
- case <-time.After(srv.getReadTimeout()):
- return &Error{err: "server shutdown is pending"}
- case <-fin:
- return nil
- }
-}
-
-// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
-func (srv *Server) getReadTimeout() time.Duration {
- rtimeout := dnsTimeout
- if srv.ReadTimeout != 0 {
- rtimeout = srv.ReadTimeout
- }
- return rtimeout
-}
-
-// serveTCP starts a TCP listener for the server.
-// Each request is handled in a separate goroutine.
-func (srv *Server) serveTCP(l net.Listener) error {
- defer l.Close()
-
- if srv.NotifyStartedFunc != nil {
- srv.NotifyStartedFunc()
- }
-
- reader := Reader(&defaultReader{srv})
- if srv.DecorateReader != nil {
- reader = srv.DecorateReader(reader)
- }
-
- handler := srv.Handler
- if handler == nil {
- handler = DefaultServeMux
- }
- rtimeout := srv.getReadTimeout()
- // deadline is not used here
- for {
- rw, err := l.Accept()
- if err != nil {
- if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
- continue
- }
- return err
- }
- m, err := reader.ReadTCP(rw, rtimeout)
- srv.lock.RLock()
- if !srv.started {
- srv.lock.RUnlock()
- return nil
- }
- srv.lock.RUnlock()
- if err != nil {
- continue
- }
- srv.inFlight.Add(1)
- go srv.serve(rw.RemoteAddr(), handler, m, nil, nil, rw)
- }
-}
-
-// serveUDP starts a UDP listener for the server.
-// Each request is handled in a separate goroutine.
-func (srv *Server) serveUDP(l *net.UDPConn) error {
- defer l.Close()
-
- if srv.NotifyStartedFunc != nil {
- srv.NotifyStartedFunc()
- }
-
- reader := Reader(&defaultReader{srv})
- if srv.DecorateReader != nil {
- reader = srv.DecorateReader(reader)
- }
-
- handler := srv.Handler
- if handler == nil {
- handler = DefaultServeMux
- }
- rtimeout := srv.getReadTimeout()
- // deadline is not used here
- for {
- m, s, err := reader.ReadUDP(l, rtimeout)
- srv.lock.RLock()
- if !srv.started {
- srv.lock.RUnlock()
- return nil
- }
- srv.lock.RUnlock()
- if err != nil {
- continue
- }
- srv.inFlight.Add(1)
- go srv.serve(s.RemoteAddr(), handler, m, l, s, nil)
- }
-}
-
-// Serve a new connection.
-func (srv *Server) serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, s *SessionUDP, t net.Conn) {
- defer srv.inFlight.Done()
-
- w := &response{tsigSecret: srv.TsigSecret, udp: u, tcp: t, remoteAddr: a, udpSession: s}
- if srv.DecorateWriter != nil {
- w.writer = srv.DecorateWriter(w)
- } else {
- w.writer = w
- }
-
- q := 0 // counter for the amount of TCP queries we get
-
- reader := Reader(&defaultReader{srv})
- if srv.DecorateReader != nil {
- reader = srv.DecorateReader(reader)
- }
-Redo:
- req := new(Msg)
- err := req.Unpack(m)
- if err != nil { // Send a FormatError back
- x := new(Msg)
- x.SetRcodeFormatError(req)
- w.WriteMsg(x)
- goto Exit
- }
- if !srv.Unsafe && req.Response {
- goto Exit
- }
-
- w.tsigStatus = nil
- if w.tsigSecret != nil {
- if t := req.IsTsig(); t != nil {
- secret := t.Hdr.Name
- if _, ok := w.tsigSecret[secret]; !ok {
- w.tsigStatus = ErrKeyAlg
- }
- w.tsigStatus = TsigVerify(m, w.tsigSecret[secret], "", false)
- w.tsigTimersOnly = false
- w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC
- }
- }
- h.ServeDNS(w, req) // Writes back to the client
-
-Exit:
- if w.tcp == nil {
- return
- }
- // TODO(miek): make this number configurable?
- if q > maxTCPQueries { // close socket after this many queries
- w.Close()
- return
- }
-
- if w.hijacked {
- return // client calls Close()
- }
- if u != nil { // UDP, "close" and return
- w.Close()
- return
- }
- idleTimeout := tcpIdleTimeout
- if srv.IdleTimeout != nil {
- idleTimeout = srv.IdleTimeout()
- }
- m, err = reader.ReadTCP(w.tcp, idleTimeout)
- if err == nil {
- q++
- goto Redo
- }
- w.Close()
- return
-}
-
-func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
- conn.SetReadDeadline(time.Now().Add(timeout))
- l := make([]byte, 2)
- n, err := conn.Read(l)
- if err != nil || n != 2 {
- if err != nil {
- return nil, err
- }
- return nil, ErrShortRead
- }
- length := binary.BigEndian.Uint16(l)
- if length == 0 {
- return nil, ErrShortRead
- }
- m := make([]byte, int(length))
- n, err = conn.Read(m[:int(length)])
- if err != nil || n == 0 {
- if err != nil {
- return nil, err
- }
- return nil, ErrShortRead
- }
- i := n
- for i < int(length) {
- j, err := conn.Read(m[i:int(length)])
- if err != nil {
- return nil, err
- }
- i += j
- }
- n = i
- m = m[:n]
- return m, nil
-}
-
-func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
- conn.SetReadDeadline(time.Now().Add(timeout))
- m := make([]byte, srv.UDPSize)
- n, s, err := ReadFromSessionUDP(conn, m)
- if err != nil || n == 0 {
- if err != nil {
- return nil, nil, err
- }
- return nil, nil, ErrShortRead
- }
- m = m[:n]
- return m, s, nil
-}
-
-// WriteMsg implements the ResponseWriter.WriteMsg method.
-func (w *response) WriteMsg(m *Msg) (err error) {
- var data []byte
- if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check)
- if t := m.IsTsig(); t != nil {
- data, w.tsigRequestMAC, err = TsigGenerate(m, w.tsigSecret[t.Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly)
- if err != nil {
- return err
- }
- _, err = w.writer.Write(data)
- return err
- }
- }
- data, err = m.Pack()
- if err != nil {
- return err
- }
- _, err = w.writer.Write(data)
- return err
-}
-
-// Write implements the ResponseWriter.Write method.
-func (w *response) Write(m []byte) (int, error) {
- switch {
- case w.udp != nil:
- n, err := WriteToSessionUDP(w.udp, m, w.udpSession)
- return n, err
- case w.tcp != nil:
- lm := len(m)
- if lm < 2 {
- return 0, io.ErrShortBuffer
- }
- if lm > MaxMsgSize {
- return 0, &Error{err: "message too large"}
- }
- l := make([]byte, 2, 2+lm)
- binary.BigEndian.PutUint16(l, uint16(lm))
- m = append(l, m...)
-
- n, err := io.Copy(w.tcp, bytes.NewReader(m))
- return int(n), err
- }
- panic("not reached")
-}
-
-// LocalAddr implements the ResponseWriter.LocalAddr method.
-func (w *response) LocalAddr() net.Addr {
- if w.tcp != nil {
- return w.tcp.LocalAddr()
- }
- return w.udp.LocalAddr()
-}
-
-// RemoteAddr implements the ResponseWriter.RemoteAddr method.
-func (w *response) RemoteAddr() net.Addr { return w.remoteAddr }
-
-// TsigStatus implements the ResponseWriter.TsigStatus method.
-func (w *response) TsigStatus() error { return w.tsigStatus }
-
-// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method.
-func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b }
-
-// Hijack implements the ResponseWriter.Hijack method.
-func (w *response) Hijack() { w.hijacked = true }
-
-// Close implements the ResponseWriter.Close method
-func (w *response) Close() error {
- // Can't close the udp conn, as that is actually the listener.
- if w.tcp != nil {
- e := w.tcp.Close()
- w.tcp = nil
- return e
- }
- return nil
-}
diff --git a/vendor/github.com/miekg/dns/server_test.go b/vendor/github.com/miekg/dns/server_test.go
deleted file mode 100644
index f17a2f90f..000000000
--- a/vendor/github.com/miekg/dns/server_test.go
+++ /dev/null
@@ -1,719 +0,0 @@
-package dns
-
-import (
- "crypto/tls"
- "fmt"
- "io"
- "net"
- "runtime"
- "sync"
- "testing"
- "time"
-)
-
-func HelloServer(w ResponseWriter, req *Msg) {
- m := new(Msg)
- m.SetReply(req)
-
- m.Extra = make([]RR, 1)
- m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
- w.WriteMsg(m)
-}
-
-func HelloServerBadID(w ResponseWriter, req *Msg) {
- m := new(Msg)
- m.SetReply(req)
- m.Id++
-
- m.Extra = make([]RR, 1)
- m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
- w.WriteMsg(m)
-}
-
-func AnotherHelloServer(w ResponseWriter, req *Msg) {
- m := new(Msg)
- m.SetReply(req)
-
- m.Extra = make([]RR, 1)
- m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello example"}}
- w.WriteMsg(m)
-}
-
-func RunLocalUDPServer(laddr string) (*Server, string, error) {
- server, l, _, err := RunLocalUDPServerWithFinChan(laddr)
-
- return server, l, err
-}
-
-func RunLocalUDPServerWithFinChan(laddr string) (*Server, string, chan struct{}, error) {
- pc, err := net.ListenPacket("udp", laddr)
- if err != nil {
- return nil, "", nil, err
- }
- server := &Server{PacketConn: pc, ReadTimeout: time.Hour, WriteTimeout: time.Hour}
-
- waitLock := sync.Mutex{}
- waitLock.Lock()
- server.NotifyStartedFunc = waitLock.Unlock
-
- fin := make(chan struct{}, 0)
-
- go func() {
- server.ActivateAndServe()
- close(fin)
- pc.Close()
- }()
-
- waitLock.Lock()
- return server, pc.LocalAddr().String(), fin, nil
-}
-
-func RunLocalUDPServerUnsafe(laddr string) (*Server, string, error) {
- pc, err := net.ListenPacket("udp", laddr)
- if err != nil {
- return nil, "", err
- }
- server := &Server{PacketConn: pc, Unsafe: true,
- ReadTimeout: time.Hour, WriteTimeout: time.Hour}
-
- waitLock := sync.Mutex{}
- waitLock.Lock()
- server.NotifyStartedFunc = waitLock.Unlock
-
- go func() {
- server.ActivateAndServe()
- pc.Close()
- }()
-
- waitLock.Lock()
- return server, pc.LocalAddr().String(), nil
-}
-
-func RunLocalTCPServer(laddr string) (*Server, string, error) {
- l, err := net.Listen("tcp", laddr)
- if err != nil {
- return nil, "", err
- }
-
- server := &Server{Listener: l, ReadTimeout: time.Hour, WriteTimeout: time.Hour}
-
- waitLock := sync.Mutex{}
- waitLock.Lock()
- server.NotifyStartedFunc = waitLock.Unlock
-
- go func() {
- server.ActivateAndServe()
- l.Close()
- }()
-
- waitLock.Lock()
- return server, l.Addr().String(), nil
-}
-
-func RunLocalTLSServer(laddr string, config *tls.Config) (*Server, string, error) {
- l, err := tls.Listen("tcp", laddr, config)
- if err != nil {
- return nil, "", err
- }
-
- server := &Server{Listener: l, ReadTimeout: time.Hour, WriteTimeout: time.Hour}
-
- waitLock := sync.Mutex{}
- waitLock.Lock()
- server.NotifyStartedFunc = waitLock.Unlock
-
- go func() {
- server.ActivateAndServe()
- l.Close()
- }()
-
- waitLock.Lock()
- return server, l.Addr().String(), nil
-}
-
-func TestServing(t *testing.T) {
- HandleFunc("miek.nl.", HelloServer)
- HandleFunc("example.com.", AnotherHelloServer)
- defer HandleRemove("miek.nl.")
- defer HandleRemove("example.com.")
-
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- c := new(Client)
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeTXT)
- r, _, err := c.Exchange(m, addrstr)
- if err != nil || len(r.Extra) == 0 {
- t.Fatal("failed to exchange miek.nl", err)
- }
- txt := r.Extra[0].(*TXT).Txt[0]
- if txt != "Hello world" {
- t.Error("unexpected result for miek.nl", txt, "!= Hello world")
- }
-
- m.SetQuestion("example.com.", TypeTXT)
- r, _, err = c.Exchange(m, addrstr)
- if err != nil {
- t.Fatal("failed to exchange example.com", err)
- }
- txt = r.Extra[0].(*TXT).Txt[0]
- if txt != "Hello example" {
- t.Error("unexpected result for example.com", txt, "!= Hello example")
- }
-
- // Test Mixes cased as noticed by Ask.
- m.SetQuestion("eXaMplE.cOm.", TypeTXT)
- r, _, err = c.Exchange(m, addrstr)
- if err != nil {
- t.Error("failed to exchange eXaMplE.cOm", err)
- }
- txt = r.Extra[0].(*TXT).Txt[0]
- if txt != "Hello example" {
- t.Error("unexpected result for example.com", txt, "!= Hello example")
- }
-}
-
-func TestServingTLS(t *testing.T) {
- HandleFunc("miek.nl.", HelloServer)
- HandleFunc("example.com.", AnotherHelloServer)
- defer HandleRemove("miek.nl.")
- defer HandleRemove("example.com.")
-
- cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock)
- if err != nil {
- t.Fatalf("unable to build certificate: %v", err)
- }
-
- config := tls.Config{
- Certificates: []tls.Certificate{cert},
- }
-
- s, addrstr, err := RunLocalTLSServer("127.0.0.1:0", &config)
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- c := new(Client)
- c.Net = "tcp-tls"
- c.TLSConfig = &tls.Config{
- InsecureSkipVerify: true,
- }
-
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeTXT)
- r, _, err := c.Exchange(m, addrstr)
- if err != nil || len(r.Extra) == 0 {
- t.Fatal("failed to exchange miek.nl", err)
- }
- txt := r.Extra[0].(*TXT).Txt[0]
- if txt != "Hello world" {
- t.Error("unexpected result for miek.nl", txt, "!= Hello world")
- }
-
- m.SetQuestion("example.com.", TypeTXT)
- r, _, err = c.Exchange(m, addrstr)
- if err != nil {
- t.Fatal("failed to exchange example.com", err)
- }
- txt = r.Extra[0].(*TXT).Txt[0]
- if txt != "Hello example" {
- t.Error("unexpected result for example.com", txt, "!= Hello example")
- }
-
- // Test Mixes cased as noticed by Ask.
- m.SetQuestion("eXaMplE.cOm.", TypeTXT)
- r, _, err = c.Exchange(m, addrstr)
- if err != nil {
- t.Error("failed to exchange eXaMplE.cOm", err)
- }
- txt = r.Extra[0].(*TXT).Txt[0]
- if txt != "Hello example" {
- t.Error("unexpected result for example.com", txt, "!= Hello example")
- }
-}
-
-func BenchmarkServe(b *testing.B) {
- b.StopTimer()
- HandleFunc("miek.nl.", HelloServer)
- defer HandleRemove("miek.nl.")
- a := runtime.GOMAXPROCS(4)
-
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- b.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- c := new(Client)
- m := new(Msg)
- m.SetQuestion("miek.nl", TypeSOA)
-
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- c.Exchange(m, addrstr)
- }
- runtime.GOMAXPROCS(a)
-}
-
-func benchmarkServe6(b *testing.B) {
- b.StopTimer()
- HandleFunc("miek.nl.", HelloServer)
- defer HandleRemove("miek.nl.")
- a := runtime.GOMAXPROCS(4)
- s, addrstr, err := RunLocalUDPServer("[::1]:0")
- if err != nil {
- b.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- c := new(Client)
- m := new(Msg)
- m.SetQuestion("miek.nl", TypeSOA)
-
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- c.Exchange(m, addrstr)
- }
- runtime.GOMAXPROCS(a)
-}
-
-func HelloServerCompress(w ResponseWriter, req *Msg) {
- m := new(Msg)
- m.SetReply(req)
- m.Extra = make([]RR, 1)
- m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
- m.Compress = true
- w.WriteMsg(m)
-}
-
-func BenchmarkServeCompress(b *testing.B) {
- b.StopTimer()
- HandleFunc("miek.nl.", HelloServerCompress)
- defer HandleRemove("miek.nl.")
- a := runtime.GOMAXPROCS(4)
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- b.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- c := new(Client)
- m := new(Msg)
- m.SetQuestion("miek.nl", TypeSOA)
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- c.Exchange(m, addrstr)
- }
- runtime.GOMAXPROCS(a)
-}
-
-func TestDotAsCatchAllWildcard(t *testing.T) {
- mux := NewServeMux()
- mux.Handle(".", HandlerFunc(HelloServer))
- mux.Handle("example.com.", HandlerFunc(AnotherHelloServer))
-
- handler := mux.match("www.miek.nl.", TypeTXT)
- if handler == nil {
- t.Error("wildcard match failed")
- }
-
- handler = mux.match("www.example.com.", TypeTXT)
- if handler == nil {
- t.Error("example.com match failed")
- }
-
- handler = mux.match("a.www.example.com.", TypeTXT)
- if handler == nil {
- t.Error("a.www.example.com match failed")
- }
-
- handler = mux.match("boe.", TypeTXT)
- if handler == nil {
- t.Error("boe. match failed")
- }
-}
-
-func TestCaseFolding(t *testing.T) {
- mux := NewServeMux()
- mux.Handle("_udp.example.com.", HandlerFunc(HelloServer))
-
- handler := mux.match("_dns._udp.example.com.", TypeSRV)
- if handler == nil {
- t.Error("case sensitive characters folded")
- }
-
- handler = mux.match("_DNS._UDP.EXAMPLE.COM.", TypeSRV)
- if handler == nil {
- t.Error("case insensitive characters not folded")
- }
-}
-
-func TestRootServer(t *testing.T) {
- mux := NewServeMux()
- mux.Handle(".", HandlerFunc(HelloServer))
-
- handler := mux.match(".", TypeNS)
- if handler == nil {
- t.Error("root match failed")
- }
-}
-
-type maxRec struct {
- max int
- sync.RWMutex
-}
-
-var M = new(maxRec)
-
-func HelloServerLargeResponse(resp ResponseWriter, req *Msg) {
- m := new(Msg)
- m.SetReply(req)
- m.Authoritative = true
- m1 := 0
- M.RLock()
- m1 = M.max
- M.RUnlock()
- for i := 0; i < m1; i++ {
- aRec := &A{
- Hdr: RR_Header{
- Name: req.Question[0].Name,
- Rrtype: TypeA,
- Class: ClassINET,
- Ttl: 0,
- },
- A: net.ParseIP(fmt.Sprintf("127.0.0.%d", i+1)).To4(),
- }
- m.Answer = append(m.Answer, aRec)
- }
- resp.WriteMsg(m)
-}
-
-func TestServingLargeResponses(t *testing.T) {
- HandleFunc("example.", HelloServerLargeResponse)
- defer HandleRemove("example.")
-
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- // Create request
- m := new(Msg)
- m.SetQuestion("web.service.example.", TypeANY)
-
- c := new(Client)
- c.Net = "udp"
- M.Lock()
- M.max = 2
- M.Unlock()
- _, _, err = c.Exchange(m, addrstr)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
- // This must fail
- M.Lock()
- M.max = 20
- M.Unlock()
- _, _, err = c.Exchange(m, addrstr)
- if err == nil {
- t.Error("failed to fail exchange, this should generate packet error")
- }
- // But this must work again
- c.UDPSize = 7000
- _, _, err = c.Exchange(m, addrstr)
- if err != nil {
- t.Errorf("failed to exchange: %v", err)
- }
-}
-
-func TestServingResponse(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- HandleFunc("miek.nl.", HelloServer)
- s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
-
- c := new(Client)
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeTXT)
- m.Response = false
- _, _, err = c.Exchange(m, addrstr)
- if err != nil {
- t.Fatal("failed to exchange", err)
- }
- m.Response = true
- _, _, err = c.Exchange(m, addrstr)
- if err == nil {
- t.Fatal("exchanged response message")
- }
-
- s.Shutdown()
- s, addrstr, err = RunLocalUDPServerUnsafe("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- defer s.Shutdown()
-
- m.Response = true
- _, _, err = c.Exchange(m, addrstr)
- if err != nil {
- t.Fatal("could exchanged response message in Unsafe mode")
- }
-}
-
-func TestShutdownTCP(t *testing.T) {
- s, _, err := RunLocalTCPServer("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- err = s.Shutdown()
- if err != nil {
- t.Errorf("could not shutdown test TCP server, %v", err)
- }
-}
-
-func TestShutdownTLS(t *testing.T) {
- cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock)
- if err != nil {
- t.Fatalf("unable to build certificate: %v", err)
- }
-
- config := tls.Config{
- Certificates: []tls.Certificate{cert},
- }
-
- s, _, err := RunLocalTLSServer("127.0.0.1:0", &config)
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- err = s.Shutdown()
- if err != nil {
- t.Errorf("could not shutdown test TLS server, %v", err)
- }
-}
-
-type trigger struct {
- done bool
- sync.RWMutex
-}
-
-func (t *trigger) Set() {
- t.Lock()
- defer t.Unlock()
- t.done = true
-}
-func (t *trigger) Get() bool {
- t.RLock()
- defer t.RUnlock()
- return t.done
-}
-
-func TestHandlerCloseTCP(t *testing.T) {
-
- ln, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- panic(err)
- }
- addr := ln.Addr().String()
-
- server := &Server{Addr: addr, Net: "tcp", Listener: ln}
-
- hname := "testhandlerclosetcp."
- triggered := &trigger{}
- HandleFunc(hname, func(w ResponseWriter, r *Msg) {
- triggered.Set()
- w.Close()
- })
- defer HandleRemove(hname)
-
- go func() {
- defer server.Shutdown()
- c := &Client{Net: "tcp"}
- m := new(Msg).SetQuestion(hname, 1)
- tries := 0
- exchange:
- _, _, err := c.Exchange(m, addr)
- if err != nil && err != io.EOF {
- t.Logf("exchange failed: %s\n", err)
- if tries == 3 {
- return
- }
- time.Sleep(time.Second / 10)
- tries++
- goto exchange
- }
- }()
- server.ActivateAndServe()
- if !triggered.Get() {
- t.Fatalf("handler never called")
- }
-}
-
-func TestShutdownUDP(t *testing.T) {
- s, _, fin, err := RunLocalUDPServerWithFinChan("127.0.0.1:0")
- if err != nil {
- t.Fatalf("unable to run test server: %v", err)
- }
- err = s.Shutdown()
- if err != nil {
- t.Errorf("could not shutdown test UDP server, %v", err)
- }
- select {
- case <-fin:
- case <-time.After(2 * time.Second):
- t.Error("Could not shutdown test UDP server. Gave up waiting")
- }
-}
-
-type ExampleFrameLengthWriter struct {
- Writer
-}
-
-func (e *ExampleFrameLengthWriter) Write(m []byte) (int, error) {
- fmt.Println("writing raw DNS message of length", len(m))
- return e.Writer.Write(m)
-}
-
-func ExampleDecorateWriter() {
- // instrument raw DNS message writing
- wf := DecorateWriter(func(w Writer) Writer {
- return &ExampleFrameLengthWriter{w}
- })
-
- // simple UDP server
- pc, err := net.ListenPacket("udp", "127.0.0.1:0")
- if err != nil {
- fmt.Println(err.Error())
- return
- }
- server := &Server{
- PacketConn: pc,
- DecorateWriter: wf,
- ReadTimeout: time.Hour, WriteTimeout: time.Hour,
- }
-
- waitLock := sync.Mutex{}
- waitLock.Lock()
- server.NotifyStartedFunc = waitLock.Unlock
- defer server.Shutdown()
-
- go func() {
- server.ActivateAndServe()
- pc.Close()
- }()
-
- waitLock.Lock()
-
- HandleFunc("miek.nl.", HelloServer)
-
- c := new(Client)
- m := new(Msg)
- m.SetQuestion("miek.nl.", TypeTXT)
- _, _, err = c.Exchange(m, pc.LocalAddr().String())
- if err != nil {
- fmt.Println("failed to exchange", err.Error())
- return
- }
- // Output: writing raw DNS message of length 56
-}
-
-var (
- // CertPEMBlock is a X509 data used to test TLS servers (used with tls.X509KeyPair)
- CertPEMBlock = []byte(`-----BEGIN CERTIFICATE-----
-MIIDAzCCAeugAwIBAgIRAJFYMkcn+b8dpU15wjf++GgwDQYJKoZIhvcNAQELBQAw
-EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjAxMDgxMjAzNTNaFw0xNzAxMDcxMjAz
-NTNaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDXjqO6skvP03k58CNjQggd9G/mt+Wa+xRU+WXiKCCHttawM8x+slq5
-yfsHCwxlwsGn79HmJqecNqgHb2GWBXAvVVokFDTcC1hUP4+gp2gu9Ny27UHTjlLm
-O0l/xZ5MN8tfKyYlFw18tXu3fkaPyHj8v/D1RDkuo4ARdFvGSe8TqisbhLk2+9ow
-xfIGbEM9Fdiw8qByC2+d+FfvzIKz3GfQVwn0VoRom8L6NBIANq1IGrB5JefZB6nv
-DnfuxkBmY7F1513HKuEJ8KsLWWZWV9OPU4j4I4Rt+WJNlKjbD2srHxyrS2RDsr91
-8nCkNoWVNO3sZq0XkWKecdc921vL4ginAgMBAAGjVDBSMA4GA1UdDwEB/wQEAwIC
-pDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MBoGA1UdEQQT
-MBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAGcU3iyLBIVZj
-aDzSvEDHUd1bnLBl1C58Xu/CyKlPqVU7mLfK0JcgEaYQTSX6fCJVNLbbCrcGLsPJ
-fbjlBbyeLjTV413fxPVuona62pBFjqdtbli2Qe8FRH2KBdm41JUJGdo+SdsFu7nc
-BFOcubdw6LLIXvsTvwndKcHWx1rMX709QU1Vn1GAIsbJV/DWI231Jyyb+lxAUx/C
-8vce5uVxiKcGS+g6OjsN3D3TtiEQGSXLh013W6Wsih8td8yMCMZ3w8LQ38br1GUe
-ahLIgUJ9l6HDguM17R7kGqxNvbElsMUHfTtXXP7UDQUiYXDakg8xDP6n9DCDhJ8Y
-bSt7OLB7NQ==
------END CERTIFICATE-----`)
-
- // KeyPEMBlock is a X509 data used to test TLS servers (used with tls.X509KeyPair)
- KeyPEMBlock = []byte(`-----BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEA146jurJLz9N5OfAjY0IIHfRv5rflmvsUVPll4iggh7bWsDPM
-frJaucn7BwsMZcLBp+/R5iannDaoB29hlgVwL1VaJBQ03AtYVD+PoKdoLvTctu1B
-045S5jtJf8WeTDfLXysmJRcNfLV7t35Gj8h4/L/w9UQ5LqOAEXRbxknvE6orG4S5
-NvvaMMXyBmxDPRXYsPKgcgtvnfhX78yCs9xn0FcJ9FaEaJvC+jQSADatSBqweSXn
-2Qep7w537sZAZmOxdeddxyrhCfCrC1lmVlfTj1OI+COEbfliTZSo2w9rKx8cq0tk
-Q7K/dfJwpDaFlTTt7GatF5FinnHXPdtby+IIpwIDAQABAoIBAAJK4RDmPooqTJrC
-JA41MJLo+5uvjwCT9QZmVKAQHzByUFw1YNJkITTiognUI0CdzqNzmH7jIFs39ZeG
-proKusO2G6xQjrNcZ4cV2fgyb5g4QHStl0qhs94A+WojduiGm2IaumAgm6Mc5wDv
-ld6HmknN3Mku/ZCyanVFEIjOVn2WB7ZQLTBs6ZYaebTJG2Xv6p9t2YJW7pPQ9Xce
-s9ohAWohyM4X/OvfnfnLtQp2YLw/BxwehBsCR5SXM3ibTKpFNtxJC8hIfTuWtxZu
-2ywrmXShYBRB1WgtZt5k04bY/HFncvvcHK3YfI1+w4URKtwdaQgPUQRbVwDwuyBn
-flfkCJECgYEA/eWt01iEyE/lXkGn6V9lCocUU7lCU6yk5UT8VXVUc5If4KZKPfCk
-p4zJDOqwn2eM673aWz/mG9mtvAvmnugaGjcaVCyXOp/D/GDmKSoYcvW5B/yjfkLy
-dK6Yaa5LDRVYlYgyzcdCT5/9Qc626NzFwKCZNI4ncIU8g7ViATRxWJ8CgYEA2Ver
-vZ0M606sfgC0H3NtwNBxmuJ+lIF5LNp/wDi07lDfxRR1rnZMX5dnxjcpDr/zvm8J
-WtJJX3xMgqjtHuWKL3yKKony9J5ZPjichSbSbhrzfovgYIRZLxLLDy4MP9L3+CX/
-yBXnqMWuSnFX+M5fVGxdDWiYF3V+wmeOv9JvavkCgYEAiXAPDFzaY+R78O3xiu7M
-r0o3wqqCMPE/wav6O/hrYrQy9VSO08C0IM6g9pEEUwWmzuXSkZqhYWoQFb8Lc/GI
-T7CMXAxXQLDDUpbRgG79FR3Wr3AewHZU8LyiXHKwxcBMV4WGmsXGK3wbh8fyU1NO
-6NsGk+BvkQVOoK1LBAPzZ1kCgYEAsBSmD8U33T9s4dxiEYTrqyV0lH3g/SFz8ZHH
-pAyNEPI2iC1ONhyjPWKlcWHpAokiyOqeUpVBWnmSZtzC1qAydsxYB6ShT+sl9BHb
-RMix/QAauzBJhQhUVJ3OIys0Q1UBDmqCsjCE8SfOT4NKOUnA093C+YT+iyrmmktZ
-zDCJkckCgYEAndqM5KXGk5xYo+MAA1paZcbTUXwaWwjLU+XSRSSoyBEi5xMtfvUb
-7+a1OMhLwWbuz+pl64wFKrbSUyimMOYQpjVE/1vk/kb99pxbgol27hdKyTH1d+ov
-kFsxKCqxAnBVGEWAvVZAiiTOxleQFjz5RnL0BQp9Lg2cQe+dvuUmIAA=
------END RSA PRIVATE KEY-----`)
-)
-
-func testShutdownBindPort(t *testing.T, protocol string, port string) {
- handler := NewServeMux()
- handler.HandleFunc(".", func(w ResponseWriter, r *Msg) {})
- startedCh := make(chan struct{})
- s := &Server{
- Addr: net.JoinHostPort("127.0.0.1", port),
- Net: protocol,
- Handler: handler,
- NotifyStartedFunc: func() {
- startedCh <- struct{}{}
- },
- }
- go func() {
- if err := s.ListenAndServe(); err != nil {
- t.Log(err)
- }
- }()
- <-startedCh
- t.Logf("DNS server is started on: %s", s.Addr)
- if err := s.Shutdown(); err != nil {
- t.Fatal(err)
- }
- time.Sleep(100 * time.Millisecond)
- go func() {
- if err := s.ListenAndServe(); err != nil {
- t.Fatal(err)
- }
- }()
- <-startedCh
- t.Logf("DNS server is started on: %s", s.Addr)
-}
-
-func TestShutdownBindPortUDP(t *testing.T) {
- testShutdownBindPort(t, "udp", "1153")
-}
-
-func TestShutdownBindPortTCP(t *testing.T) {
- testShutdownBindPort(t, "tcp", "1154")
-}
diff --git a/vendor/github.com/miekg/dns/sig0.go b/vendor/github.com/miekg/dns/sig0.go
deleted file mode 100644
index f31e9e684..000000000
--- a/vendor/github.com/miekg/dns/sig0.go
+++ /dev/null
@@ -1,218 +0,0 @@
-package dns
-
-import (
- "crypto"
- "crypto/dsa"
- "crypto/ecdsa"
- "crypto/rsa"
- "encoding/binary"
- "math/big"
- "strings"
- "time"
-)
-
-// Sign signs a dns.Msg. It fills the signature with the appropriate data.
-// The SIG record should have the SignerName, KeyTag, Algorithm, Inception
-// and Expiration set.
-func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
- if k == nil {
- return nil, ErrPrivKey
- }
- if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
- return nil, ErrKey
- }
- rr.Header().Rrtype = TypeSIG
- rr.Header().Class = ClassANY
- rr.Header().Ttl = 0
- rr.Header().Name = "."
- rr.OrigTtl = 0
- rr.TypeCovered = 0
- rr.Labels = 0
-
- buf := make([]byte, m.Len()+rr.len())
- mbuf, err := m.PackBuffer(buf)
- if err != nil {
- return nil, err
- }
- if &buf[0] != &mbuf[0] {
- return nil, ErrBuf
- }
- off, err := PackRR(rr, buf, len(mbuf), nil, false)
- if err != nil {
- return nil, err
- }
- buf = buf[:off:cap(buf)]
-
- hash, ok := AlgorithmToHash[rr.Algorithm]
- if !ok {
- return nil, ErrAlg
- }
-
- hasher := hash.New()
- // Write SIG rdata
- hasher.Write(buf[len(mbuf)+1+2+2+4+2:])
- // Write message
- hasher.Write(buf[:len(mbuf)])
-
- signature, err := sign(k, hasher.Sum(nil), hash, rr.Algorithm)
- if err != nil {
- return nil, err
- }
-
- rr.Signature = toBase64(signature)
-
- buf = append(buf, signature...)
- if len(buf) > int(^uint16(0)) {
- return nil, ErrBuf
- }
- // Adjust sig data length
- rdoff := len(mbuf) + 1 + 2 + 2 + 4
- rdlen := binary.BigEndian.Uint16(buf[rdoff:])
- rdlen += uint16(len(signature))
- binary.BigEndian.PutUint16(buf[rdoff:], rdlen)
- // Adjust additional count
- adc := binary.BigEndian.Uint16(buf[10:])
- adc++
- binary.BigEndian.PutUint16(buf[10:], adc)
- return buf, nil
-}
-
-// Verify validates the message buf using the key k.
-// It's assumed that buf is a valid message from which rr was unpacked.
-func (rr *SIG) Verify(k *KEY, buf []byte) error {
- if k == nil {
- return ErrKey
- }
- if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
- return ErrKey
- }
-
- var hash crypto.Hash
- switch rr.Algorithm {
- case DSA, RSASHA1:
- hash = crypto.SHA1
- case RSASHA256, ECDSAP256SHA256:
- hash = crypto.SHA256
- case ECDSAP384SHA384:
- hash = crypto.SHA384
- case RSASHA512:
- hash = crypto.SHA512
- default:
- return ErrAlg
- }
- hasher := hash.New()
-
- buflen := len(buf)
- qdc := binary.BigEndian.Uint16(buf[4:])
- anc := binary.BigEndian.Uint16(buf[6:])
- auc := binary.BigEndian.Uint16(buf[8:])
- adc := binary.BigEndian.Uint16(buf[10:])
- offset := 12
- var err error
- for i := uint16(0); i < qdc && offset < buflen; i++ {
- _, offset, err = UnpackDomainName(buf, offset)
- if err != nil {
- return err
- }
- // Skip past Type and Class
- offset += 2 + 2
- }
- for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ {
- _, offset, err = UnpackDomainName(buf, offset)
- if err != nil {
- return err
- }
- // Skip past Type, Class and TTL
- offset += 2 + 2 + 4
- if offset+1 >= buflen {
- continue
- }
- var rdlen uint16
- rdlen = binary.BigEndian.Uint16(buf[offset:])
- offset += 2
- offset += int(rdlen)
- }
- if offset >= buflen {
- return &Error{err: "overflowing unpacking signed message"}
- }
-
- // offset should be just prior to SIG
- bodyend := offset
- // owner name SHOULD be root
- _, offset, err = UnpackDomainName(buf, offset)
- if err != nil {
- return err
- }
- // Skip Type, Class, TTL, RDLen
- offset += 2 + 2 + 4 + 2
- sigstart := offset
- // Skip Type Covered, Algorithm, Labels, Original TTL
- offset += 2 + 1 + 1 + 4
- if offset+4+4 >= buflen {
- return &Error{err: "overflow unpacking signed message"}
- }
- expire := binary.BigEndian.Uint32(buf[offset:])
- offset += 4
- incept := binary.BigEndian.Uint32(buf[offset:])
- offset += 4
- now := uint32(time.Now().Unix())
- if now < incept || now > expire {
- return ErrTime
- }
- // Skip key tag
- offset += 2
- var signername string
- signername, offset, err = UnpackDomainName(buf, offset)
- if err != nil {
- return err
- }
- // If key has come from the DNS name compression might
- // have mangled the case of the name
- if strings.ToLower(signername) != strings.ToLower(k.Header().Name) {
- return &Error{err: "signer name doesn't match key name"}
- }
- sigend := offset
- hasher.Write(buf[sigstart:sigend])
- hasher.Write(buf[:10])
- hasher.Write([]byte{
- byte((adc - 1) << 8),
- byte(adc - 1),
- })
- hasher.Write(buf[12:bodyend])
-
- hashed := hasher.Sum(nil)
- sig := buf[sigend:]
- switch k.Algorithm {
- case DSA:
- pk := k.publicKeyDSA()
- sig = sig[1:]
- r := big.NewInt(0)
- r.SetBytes(sig[:len(sig)/2])
- s := big.NewInt(0)
- s.SetBytes(sig[len(sig)/2:])
- if pk != nil {
- if dsa.Verify(pk, hashed, r, s) {
- return nil
- }
- return ErrSig
- }
- case RSASHA1, RSASHA256, RSASHA512:
- pk := k.publicKeyRSA()
- if pk != nil {
- return rsa.VerifyPKCS1v15(pk, hash, hashed, sig)
- }
- case ECDSAP256SHA256, ECDSAP384SHA384:
- pk := k.publicKeyECDSA()
- r := big.NewInt(0)
- r.SetBytes(sig[:len(sig)/2])
- s := big.NewInt(0)
- s.SetBytes(sig[len(sig)/2:])
- if pk != nil {
- if ecdsa.Verify(pk, hashed, r, s) {
- return nil
- }
- return ErrSig
- }
- }
- return ErrKeyAlg
-}
diff --git a/vendor/github.com/miekg/dns/sig0_test.go b/vendor/github.com/miekg/dns/sig0_test.go
deleted file mode 100644
index 122de6a8e..000000000
--- a/vendor/github.com/miekg/dns/sig0_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package dns
-
-import (
- "crypto"
- "testing"
- "time"
-)
-
-func TestSIG0(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping test in short mode.")
- }
- m := new(Msg)
- m.SetQuestion("example.org.", TypeSOA)
- for _, alg := range []uint8{ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256, RSASHA512} {
- algstr := AlgorithmToString[alg]
- keyrr := new(KEY)
- keyrr.Hdr.Name = algstr + "."
- keyrr.Hdr.Rrtype = TypeKEY
- keyrr.Hdr.Class = ClassINET
- keyrr.Algorithm = alg
- keysize := 1024
- switch alg {
- case ECDSAP256SHA256:
- keysize = 256
- case ECDSAP384SHA384:
- keysize = 384
- }
- pk, err := keyrr.Generate(keysize)
- if err != nil {
- t.Errorf("failed to generate key for “%s”: %v", algstr, err)
- continue
- }
- now := uint32(time.Now().Unix())
- sigrr := new(SIG)
- sigrr.Hdr.Name = "."
- sigrr.Hdr.Rrtype = TypeSIG
- sigrr.Hdr.Class = ClassANY
- sigrr.Algorithm = alg
- sigrr.Expiration = now + 300
- sigrr.Inception = now - 300
- sigrr.KeyTag = keyrr.KeyTag()
- sigrr.SignerName = keyrr.Hdr.Name
- mb, err := sigrr.Sign(pk.(crypto.Signer), m)
- if err != nil {
- t.Errorf("failed to sign message using “%s”: %v", algstr, err)
- continue
- }
- m := new(Msg)
- if err := m.Unpack(mb); err != nil {
- t.Errorf("failed to unpack message signed using “%s”: %v", algstr, err)
- continue
- }
- if len(m.Extra) != 1 {
- t.Errorf("missing SIG for message signed using “%s”", algstr)
- continue
- }
- var sigrrwire *SIG
- switch rr := m.Extra[0].(type) {
- case *SIG:
- sigrrwire = rr
- default:
- t.Errorf("expected SIG RR, instead: %v", rr)
- continue
- }
- for _, rr := range []*SIG{sigrr, sigrrwire} {
- id := "sigrr"
- if rr == sigrrwire {
- id = "sigrrwire"
- }
- if err := rr.Verify(keyrr, mb); err != nil {
- t.Errorf("failed to verify “%s” signed SIG(%s): %v", algstr, id, err)
- continue
- }
- }
- mb[13]++
- if err := sigrr.Verify(keyrr, mb); err == nil {
- t.Errorf("verify succeeded on an altered message using “%s”", algstr)
- continue
- }
- sigrr.Expiration = 2
- sigrr.Inception = 1
- mb, _ = sigrr.Sign(pk.(crypto.Signer), m)
- if err := sigrr.Verify(keyrr, mb); err == nil {
- t.Errorf("verify succeeded on an expired message using “%s”", algstr)
- continue
- }
- }
-}
diff --git a/vendor/github.com/miekg/dns/singleinflight.go b/vendor/github.com/miekg/dns/singleinflight.go
deleted file mode 100644
index 9573c7d0b..000000000
--- a/vendor/github.com/miekg/dns/singleinflight.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Adapted for dns package usage by Miek Gieben.
-
-package dns
-
-import "sync"
-import "time"
-
-// call is an in-flight or completed singleflight.Do call
-type call struct {
- wg sync.WaitGroup
- val *Msg
- rtt time.Duration
- err error
- dups int
-}
-
-// singleflight represents a class of work and forms a namespace in
-// which units of work can be executed with duplicate suppression.
-type singleflight struct {
- sync.Mutex // protects m
- m map[string]*call // lazily initialized
-}
-
-// Do executes and returns the results of the given function, making
-// sure that only one execution is in-flight for a given key at a
-// time. If a duplicate comes in, the duplicate caller waits for the
-// original to complete and receives the same results.
-// The return value shared indicates whether v was given to multiple callers.
-func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) {
- g.Lock()
- if g.m == nil {
- g.m = make(map[string]*call)
- }
- if c, ok := g.m[key]; ok {
- c.dups++
- g.Unlock()
- c.wg.Wait()
- return c.val, c.rtt, c.err, true
- }
- c := new(call)
- c.wg.Add(1)
- g.m[key] = c
- g.Unlock()
-
- c.val, c.rtt, c.err = fn()
- c.wg.Done()
-
- g.Lock()
- delete(g.m, key)
- g.Unlock()
-
- return c.val, c.rtt, c.err, c.dups > 0
-}
diff --git a/vendor/github.com/miekg/dns/smimea.go b/vendor/github.com/miekg/dns/smimea.go
deleted file mode 100644
index 4e7ded4b3..000000000
--- a/vendor/github.com/miekg/dns/smimea.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package dns
-
-import (
- "crypto/sha256"
- "crypto/x509"
- "encoding/hex"
-)
-
-// Sign creates a SMIMEA record from an SSL certificate.
-func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
- r.Hdr.Rrtype = TypeSMIMEA
- r.Usage = uint8(usage)
- r.Selector = uint8(selector)
- r.MatchingType = uint8(matchingType)
-
- r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
- if err != nil {
- return err
- }
- return nil
-}
-
-// Verify verifies a SMIMEA record against an SSL certificate. If it is OK
-// a nil error is returned.
-func (r *SMIMEA) Verify(cert *x509.Certificate) error {
- c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
- if err != nil {
- return err // Not also ErrSig?
- }
- if r.Certificate == c {
- return nil
- }
- return ErrSig // ErrSig, really?
-}
-
-// SMIMEAName returns the ownername of a SMIMEA resource record as per the
-// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3
-func SMIMEAName(email, domain string) (string, error) {
- hasher := sha256.New()
- hasher.Write([]byte(email))
-
- // RFC Section 3: "The local-part is hashed using the SHA2-256
- // algorithm with the hash truncated to 28 octets and
- // represented in its hexadecimal representation to become the
- // left-most label in the prepared domain name"
- return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain, nil
-}
diff --git a/vendor/github.com/miekg/dns/tlsa.go b/vendor/github.com/miekg/dns/tlsa.go
deleted file mode 100644
index 431e2fb5a..000000000
--- a/vendor/github.com/miekg/dns/tlsa.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package dns
-
-import (
- "crypto/x509"
- "net"
- "strconv"
-)
-
-// Sign creates a TLSA record from an SSL certificate.
-func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
- r.Hdr.Rrtype = TypeTLSA
- r.Usage = uint8(usage)
- r.Selector = uint8(selector)
- r.MatchingType = uint8(matchingType)
-
- r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
- if err != nil {
- return err
- }
- return nil
-}
-
-// Verify verifies a TLSA record against an SSL certificate. If it is OK
-// a nil error is returned.
-func (r *TLSA) Verify(cert *x509.Certificate) error {
- c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
- if err != nil {
- return err // Not also ErrSig?
- }
- if r.Certificate == c {
- return nil
- }
- return ErrSig // ErrSig, really?
-}
-
-// TLSAName returns the ownername of a TLSA resource record as per the
-// rules specified in RFC 6698, Section 3.
-func TLSAName(name, service, network string) (string, error) {
- if !IsFqdn(name) {
- return "", ErrFqdn
- }
- p, err := net.LookupPort(network, service)
- if err != nil {
- return "", err
- }
- return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil
-}
diff --git a/vendor/github.com/miekg/dns/tsig.go b/vendor/github.com/miekg/dns/tsig.go
deleted file mode 100644
index 24013096b..000000000
--- a/vendor/github.com/miekg/dns/tsig.go
+++ /dev/null
@@ -1,383 +0,0 @@
-package dns
-
-import (
- "crypto/hmac"
- "crypto/md5"
- "crypto/sha1"
- "crypto/sha256"
- "crypto/sha512"
- "encoding/binary"
- "encoding/hex"
- "hash"
- "strconv"
- "strings"
- "time"
-)
-
-// HMAC hashing codes. These are transmitted as domain names.
-const (
- HmacMD5 = "hmac-md5.sig-alg.reg.int."
- HmacSHA1 = "hmac-sha1."
- HmacSHA256 = "hmac-sha256."
- HmacSHA512 = "hmac-sha512."
-)
-
-// TSIG is the RR the holds the transaction signature of a message.
-// See RFC 2845 and RFC 4635.
-type TSIG struct {
- Hdr RR_Header
- Algorithm string `dns:"domain-name"`
- TimeSigned uint64 `dns:"uint48"`
- Fudge uint16
- MACSize uint16
- MAC string `dns:"size-hex:MACSize"`
- OrigId uint16
- Error uint16
- OtherLen uint16
- OtherData string `dns:"size-hex:OtherLen"`
-}
-
-// TSIG has no official presentation format, but this will suffice.
-
-func (rr *TSIG) String() string {
- s := "\n;; TSIG PSEUDOSECTION:\n"
- s += rr.Hdr.String() +
- " " + rr.Algorithm +
- " " + tsigTimeToString(rr.TimeSigned) +
- " " + strconv.Itoa(int(rr.Fudge)) +
- " " + strconv.Itoa(int(rr.MACSize)) +
- " " + strings.ToUpper(rr.MAC) +
- " " + strconv.Itoa(int(rr.OrigId)) +
- " " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR
- " " + strconv.Itoa(int(rr.OtherLen)) +
- " " + rr.OtherData
- return s
-}
-
-// The following values must be put in wireformat, so that the MAC can be calculated.
-// RFC 2845, section 3.4.2. TSIG Variables.
-type tsigWireFmt struct {
- // From RR_Header
- Name string `dns:"domain-name"`
- Class uint16
- Ttl uint32
- // Rdata of the TSIG
- Algorithm string `dns:"domain-name"`
- TimeSigned uint64 `dns:"uint48"`
- Fudge uint16
- // MACSize, MAC and OrigId excluded
- Error uint16
- OtherLen uint16
- OtherData string `dns:"size-hex:OtherLen"`
-}
-
-// If we have the MAC use this type to convert it to wiredata. Section 3.4.3. Request MAC
-type macWireFmt struct {
- MACSize uint16
- MAC string `dns:"size-hex:MACSize"`
-}
-
-// 3.3. Time values used in TSIG calculations
-type timerWireFmt struct {
- TimeSigned uint64 `dns:"uint48"`
- Fudge uint16
-}
-
-// TsigGenerate fills out the TSIG record attached to the message.
-// The message should contain
-// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
-// time fudge (defaults to 300 seconds) and the current time
-// The TSIG MAC is saved in that Tsig RR.
-// When TsigGenerate is called for the first time requestMAC is set to the empty string and
-// timersOnly is false.
-// If something goes wrong an error is returned, otherwise it is nil.
-func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
- if m.IsTsig() == nil {
- panic("dns: TSIG not last RR in additional")
- }
- // If we barf here, the caller is to blame
- rawsecret, err := fromBase64([]byte(secret))
- if err != nil {
- return nil, "", err
- }
-
- rr := m.Extra[len(m.Extra)-1].(*TSIG)
- m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg
- mbuf, err := m.Pack()
- if err != nil {
- return nil, "", err
- }
- buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
-
- t := new(TSIG)
- var h hash.Hash
- switch strings.ToLower(rr.Algorithm) {
- case HmacMD5:
- h = hmac.New(md5.New, []byte(rawsecret))
- case HmacSHA1:
- h = hmac.New(sha1.New, []byte(rawsecret))
- case HmacSHA256:
- h = hmac.New(sha256.New, []byte(rawsecret))
- case HmacSHA512:
- h = hmac.New(sha512.New, []byte(rawsecret))
- default:
- return nil, "", ErrKeyAlg
- }
- h.Write(buf)
- t.MAC = hex.EncodeToString(h.Sum(nil))
- t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
-
- t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
- t.Fudge = rr.Fudge
- t.TimeSigned = rr.TimeSigned
- t.Algorithm = rr.Algorithm
- t.OrigId = m.Id
-
- tbuf := make([]byte, t.len())
- if off, err := PackRR(t, tbuf, 0, nil, false); err == nil {
- tbuf = tbuf[:off] // reset to actual size used
- } else {
- return nil, "", err
- }
- mbuf = append(mbuf, tbuf...)
- // Update the ArCount directly in the buffer.
- binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1))
-
- return mbuf, t.MAC, nil
-}
-
-// TsigVerify verifies the TSIG on a message.
-// If the signature does not validate err contains the
-// error, otherwise it is nil.
-func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
- rawsecret, err := fromBase64([]byte(secret))
- if err != nil {
- return err
- }
- // Strip the TSIG from the incoming msg
- stripped, tsig, err := stripTsig(msg)
- if err != nil {
- return err
- }
-
- msgMAC, err := hex.DecodeString(tsig.MAC)
- if err != nil {
- return err
- }
-
- buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
-
- // Fudge factor works both ways. A message can arrive before it was signed because
- // of clock skew.
- now := uint64(time.Now().Unix())
- ti := now - tsig.TimeSigned
- if now < tsig.TimeSigned {
- ti = tsig.TimeSigned - now
- }
- if uint64(tsig.Fudge) < ti {
- return ErrTime
- }
-
- var h hash.Hash
- switch strings.ToLower(tsig.Algorithm) {
- case HmacMD5:
- h = hmac.New(md5.New, rawsecret)
- case HmacSHA1:
- h = hmac.New(sha1.New, rawsecret)
- case HmacSHA256:
- h = hmac.New(sha256.New, rawsecret)
- case HmacSHA512:
- h = hmac.New(sha512.New, rawsecret)
- default:
- return ErrKeyAlg
- }
- h.Write(buf)
- if !hmac.Equal(h.Sum(nil), msgMAC) {
- return ErrSig
- }
- return nil
-}
-
-// Create a wiredata buffer for the MAC calculation.
-func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []byte {
- var buf []byte
- if rr.TimeSigned == 0 {
- rr.TimeSigned = uint64(time.Now().Unix())
- }
- if rr.Fudge == 0 {
- rr.Fudge = 300 // Standard (RFC) default.
- }
-
- if requestMAC != "" {
- m := new(macWireFmt)
- m.MACSize = uint16(len(requestMAC) / 2)
- m.MAC = requestMAC
- buf = make([]byte, len(requestMAC)) // long enough
- n, _ := packMacWire(m, buf)
- buf = buf[:n]
- }
-
- tsigvar := make([]byte, DefaultMsgSize)
- if timersOnly {
- tsig := new(timerWireFmt)
- tsig.TimeSigned = rr.TimeSigned
- tsig.Fudge = rr.Fudge
- n, _ := packTimerWire(tsig, tsigvar)
- tsigvar = tsigvar[:n]
- } else {
- tsig := new(tsigWireFmt)
- tsig.Name = strings.ToLower(rr.Hdr.Name)
- tsig.Class = ClassANY
- tsig.Ttl = rr.Hdr.Ttl
- tsig.Algorithm = strings.ToLower(rr.Algorithm)
- tsig.TimeSigned = rr.TimeSigned
- tsig.Fudge = rr.Fudge
- tsig.Error = rr.Error
- tsig.OtherLen = rr.OtherLen
- tsig.OtherData = rr.OtherData
- n, _ := packTsigWire(tsig, tsigvar)
- tsigvar = tsigvar[:n]
- }
-
- if requestMAC != "" {
- x := append(buf, msgbuf...)
- buf = append(x, tsigvar...)
- } else {
- buf = append(msgbuf, tsigvar...)
- }
- return buf
-}
-
-// Strip the TSIG from the raw message.
-func stripTsig(msg []byte) ([]byte, *TSIG, error) {
- // Copied from msg.go's Unpack() Header, but modified.
- var (
- dh Header
- err error
- )
- off, tsigoff := 0, 0
-
- if dh, off, err = unpackMsgHdr(msg, off); err != nil {
- return nil, nil, err
- }
- if dh.Arcount == 0 {
- return nil, nil, ErrNoSig
- }
-
- // Rcode, see msg.go Unpack()
- if int(dh.Bits&0xF) == RcodeNotAuth {
- return nil, nil, ErrAuth
- }
-
- for i := 0; i < int(dh.Qdcount); i++ {
- _, off, err = unpackQuestion(msg, off)
- if err != nil {
- return nil, nil, err
- }
- }
-
- _, off, err = unpackRRslice(int(dh.Ancount), msg, off)
- if err != nil {
- return nil, nil, err
- }
- _, off, err = unpackRRslice(int(dh.Nscount), msg, off)
- if err != nil {
- return nil, nil, err
- }
-
- rr := new(TSIG)
- var extra RR
- for i := 0; i < int(dh.Arcount); i++ {
- tsigoff = off
- extra, off, err = UnpackRR(msg, off)
- if err != nil {
- return nil, nil, err
- }
- if extra.Header().Rrtype == TypeTSIG {
- rr = extra.(*TSIG)
- // Adjust Arcount.
- arcount := binary.BigEndian.Uint16(msg[10:])
- binary.BigEndian.PutUint16(msg[10:], arcount-1)
- break
- }
- }
- if rr == nil {
- return nil, nil, ErrNoSig
- }
- return msg[:tsigoff], rr, nil
-}
-
-// Translate the TSIG time signed into a date. There is no
-// need for RFC1982 calculations as this date is 48 bits.
-func tsigTimeToString(t uint64) string {
- ti := time.Unix(int64(t), 0).UTC()
- return ti.Format("20060102150405")
-}
-
-func packTsigWire(tw *tsigWireFmt, msg []byte) (int, error) {
- // copied from zmsg.go TSIG packing
- // RR_Header
- off, err := PackDomainName(tw.Name, msg, 0, nil, false)
- if err != nil {
- return off, err
- }
- off, err = packUint16(tw.Class, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(tw.Ttl, msg, off)
- if err != nil {
- return off, err
- }
-
- off, err = PackDomainName(tw.Algorithm, msg, off, nil, false)
- if err != nil {
- return off, err
- }
- off, err = packUint48(tw.TimeSigned, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(tw.Fudge, msg, off)
- if err != nil {
- return off, err
- }
-
- off, err = packUint16(tw.Error, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(tw.OtherLen, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(tw.OtherData, msg, off)
- if err != nil {
- return off, err
- }
- return off, nil
-}
-
-func packMacWire(mw *macWireFmt, msg []byte) (int, error) {
- off, err := packUint16(mw.MACSize, msg, 0)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(mw.MAC, msg, off)
- if err != nil {
- return off, err
- }
- return off, nil
-}
-
-func packTimerWire(tw *timerWireFmt, msg []byte) (int, error) {
- off, err := packUint48(tw.TimeSigned, msg, 0)
- if err != nil {
- return off, err
- }
- off, err = packUint16(tw.Fudge, msg, off)
- if err != nil {
- return off, err
- }
- return off, nil
-}
diff --git a/vendor/github.com/miekg/dns/tsig_test.go b/vendor/github.com/miekg/dns/tsig_test.go
deleted file mode 100644
index 48b9988b6..000000000
--- a/vendor/github.com/miekg/dns/tsig_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package dns
-
-import (
- "testing"
- "time"
-)
-
-func newTsig(algo string) *Msg {
- m := new(Msg)
- m.SetQuestion("example.org.", TypeA)
- m.SetTsig("example.", algo, 300, time.Now().Unix())
- return m
-}
-
-func TestTsig(t *testing.T) {
- m := newTsig(HmacMD5)
- buf, _, err := TsigGenerate(m, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false)
- if err != nil {
- t.Fatal(err)
- }
- err = TsigVerify(buf, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false)
- if err != nil {
- t.Fatal(err)
- }
-}
-
-func TestTsigCase(t *testing.T) {
- m := newTsig("HmAc-mD5.sig-ALg.rEg.int.") // HmacMD5
- buf, _, err := TsigGenerate(m, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false)
- if err != nil {
- t.Fatal(err)
- }
- err = TsigVerify(buf, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false)
- if err != nil {
- t.Fatal(err)
- }
-}
diff --git a/vendor/github.com/miekg/dns/types.go b/vendor/github.com/miekg/dns/types.go
deleted file mode 100644
index 53da4755c..000000000
--- a/vendor/github.com/miekg/dns/types.go
+++ /dev/null
@@ -1,1287 +0,0 @@
-package dns
-
-import (
- "fmt"
- "net"
- "strconv"
- "strings"
- "time"
-)
-
-type (
- // Type is a DNS type.
- Type uint16
- // Class is a DNS class.
- Class uint16
- // Name is a DNS domain name.
- Name string
-)
-
-// Packet formats
-
-// Wire constants and supported types.
-const (
- // valid RR_Header.Rrtype and Question.qtype
-
- TypeNone uint16 = 0
- TypeA uint16 = 1
- TypeNS uint16 = 2
- TypeMD uint16 = 3
- TypeMF uint16 = 4
- TypeCNAME uint16 = 5
- TypeSOA uint16 = 6
- TypeMB uint16 = 7
- TypeMG uint16 = 8
- TypeMR uint16 = 9
- TypeNULL uint16 = 10
- TypePTR uint16 = 12
- TypeHINFO uint16 = 13
- TypeMINFO uint16 = 14
- TypeMX uint16 = 15
- TypeTXT uint16 = 16
- TypeRP uint16 = 17
- TypeAFSDB uint16 = 18
- TypeX25 uint16 = 19
- TypeISDN uint16 = 20
- TypeRT uint16 = 21
- TypeNSAPPTR uint16 = 23
- TypeSIG uint16 = 24
- TypeKEY uint16 = 25
- TypePX uint16 = 26
- TypeGPOS uint16 = 27
- TypeAAAA uint16 = 28
- TypeLOC uint16 = 29
- TypeNXT uint16 = 30
- TypeEID uint16 = 31
- TypeNIMLOC uint16 = 32
- TypeSRV uint16 = 33
- TypeATMA uint16 = 34
- TypeNAPTR uint16 = 35
- TypeKX uint16 = 36
- TypeCERT uint16 = 37
- TypeDNAME uint16 = 39
- TypeOPT uint16 = 41 // EDNS
- TypeDS uint16 = 43
- TypeSSHFP uint16 = 44
- TypeRRSIG uint16 = 46
- TypeNSEC uint16 = 47
- TypeDNSKEY uint16 = 48
- TypeDHCID uint16 = 49
- TypeNSEC3 uint16 = 50
- TypeNSEC3PARAM uint16 = 51
- TypeTLSA uint16 = 52
- TypeSMIMEA uint16 = 53
- TypeHIP uint16 = 55
- TypeNINFO uint16 = 56
- TypeRKEY uint16 = 57
- TypeTALINK uint16 = 58
- TypeCDS uint16 = 59
- TypeCDNSKEY uint16 = 60
- TypeOPENPGPKEY uint16 = 61
- TypeSPF uint16 = 99
- TypeUINFO uint16 = 100
- TypeUID uint16 = 101
- TypeGID uint16 = 102
- TypeUNSPEC uint16 = 103
- TypeNID uint16 = 104
- TypeL32 uint16 = 105
- TypeL64 uint16 = 106
- TypeLP uint16 = 107
- TypeEUI48 uint16 = 108
- TypeEUI64 uint16 = 109
- TypeURI uint16 = 256
- TypeCAA uint16 = 257
- TypeAVC uint16 = 258
-
- TypeTKEY uint16 = 249
- TypeTSIG uint16 = 250
-
- // valid Question.Qtype only
- TypeIXFR uint16 = 251
- TypeAXFR uint16 = 252
- TypeMAILB uint16 = 253
- TypeMAILA uint16 = 254
- TypeANY uint16 = 255
-
- TypeTA uint16 = 32768
- TypeDLV uint16 = 32769
- TypeReserved uint16 = 65535
-
- // valid Question.Qclass
- ClassINET = 1
- ClassCSNET = 2
- ClassCHAOS = 3
- ClassHESIOD = 4
- ClassNONE = 254
- ClassANY = 255
-
- // Message Response Codes.
- RcodeSuccess = 0
- RcodeFormatError = 1
- RcodeServerFailure = 2
- RcodeNameError = 3
- RcodeNotImplemented = 4
- RcodeRefused = 5
- RcodeYXDomain = 6
- RcodeYXRrset = 7
- RcodeNXRrset = 8
- RcodeNotAuth = 9
- RcodeNotZone = 10
- RcodeBadSig = 16 // TSIG
- RcodeBadVers = 16 // EDNS0
- RcodeBadKey = 17
- RcodeBadTime = 18
- RcodeBadMode = 19 // TKEY
- RcodeBadName = 20
- RcodeBadAlg = 21
- RcodeBadTrunc = 22 // TSIG
- RcodeBadCookie = 23 // DNS Cookies
-
- // Message Opcodes. There is no 3.
- OpcodeQuery = 0
- OpcodeIQuery = 1
- OpcodeStatus = 2
- OpcodeNotify = 4
- OpcodeUpdate = 5
-)
-
-// Header is the wire format for the DNS packet header.
-type Header struct {
- Id uint16
- Bits uint16
- Qdcount, Ancount, Nscount, Arcount uint16
-}
-
-const (
- headerSize = 12
-
- // Header.Bits
- _QR = 1 << 15 // query/response (response=1)
- _AA = 1 << 10 // authoritative
- _TC = 1 << 9 // truncated
- _RD = 1 << 8 // recursion desired
- _RA = 1 << 7 // recursion available
- _Z = 1 << 6 // Z
- _AD = 1 << 5 // authticated data
- _CD = 1 << 4 // checking disabled
-
- LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2.
- LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2.
-
- LOC_HOURS = 60 * 1000
- LOC_DEGREES = 60 * LOC_HOURS
-
- LOC_ALTITUDEBASE = 100000
-)
-
-// Different Certificate Types, see RFC 4398, Section 2.1
-const (
- CertPKIX = 1 + iota
- CertSPKI
- CertPGP
- CertIPIX
- CertISPKI
- CertIPGP
- CertACPKIX
- CertIACPKIX
- CertURI = 253
- CertOID = 254
-)
-
-// CertTypeToString converts the Cert Type to its string representation.
-// See RFC 4398 and RFC 6944.
-var CertTypeToString = map[uint16]string{
- CertPKIX: "PKIX",
- CertSPKI: "SPKI",
- CertPGP: "PGP",
- CertIPIX: "IPIX",
- CertISPKI: "ISPKI",
- CertIPGP: "IPGP",
- CertACPKIX: "ACPKIX",
- CertIACPKIX: "IACPKIX",
- CertURI: "URI",
- CertOID: "OID",
-}
-
-// StringToCertType is the reverseof CertTypeToString.
-var StringToCertType = reverseInt16(CertTypeToString)
-
-//go:generate go run types_generate.go
-
-// Question holds a DNS question. There can be multiple questions in the
-// question section of a message. Usually there is just one.
-type Question struct {
- Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed)
- Qtype uint16
- Qclass uint16
-}
-
-func (q *Question) len() int {
- return len(q.Name) + 1 + 2 + 2
-}
-
-func (q *Question) String() (s string) {
- // prefix with ; (as in dig)
- s = ";" + sprintName(q.Name) + "\t"
- s += Class(q.Qclass).String() + "\t"
- s += " " + Type(q.Qtype).String()
- return s
-}
-
-// ANY is a wildcard record. See RFC 1035, Section 3.2.3. ANY
-// is named "*" there.
-type ANY struct {
- Hdr RR_Header
- // Does not have any rdata
-}
-
-func (rr *ANY) String() string { return rr.Hdr.String() }
-
-type CNAME struct {
- Hdr RR_Header
- Target string `dns:"cdomain-name"`
-}
-
-func (rr *CNAME) String() string { return rr.Hdr.String() + sprintName(rr.Target) }
-
-type HINFO struct {
- Hdr RR_Header
- Cpu string
- Os string
-}
-
-func (rr *HINFO) String() string {
- return rr.Hdr.String() + sprintTxt([]string{rr.Cpu, rr.Os})
-}
-
-type MB struct {
- Hdr RR_Header
- Mb string `dns:"cdomain-name"`
-}
-
-func (rr *MB) String() string { return rr.Hdr.String() + sprintName(rr.Mb) }
-
-type MG struct {
- Hdr RR_Header
- Mg string `dns:"cdomain-name"`
-}
-
-func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) }
-
-type MINFO struct {
- Hdr RR_Header
- Rmail string `dns:"cdomain-name"`
- Email string `dns:"cdomain-name"`
-}
-
-func (rr *MINFO) String() string {
- return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email)
-}
-
-type MR struct {
- Hdr RR_Header
- Mr string `dns:"cdomain-name"`
-}
-
-func (rr *MR) String() string {
- return rr.Hdr.String() + sprintName(rr.Mr)
-}
-
-type MF struct {
- Hdr RR_Header
- Mf string `dns:"cdomain-name"`
-}
-
-func (rr *MF) String() string {
- return rr.Hdr.String() + sprintName(rr.Mf)
-}
-
-type MD struct {
- Hdr RR_Header
- Md string `dns:"cdomain-name"`
-}
-
-func (rr *MD) String() string {
- return rr.Hdr.String() + sprintName(rr.Md)
-}
-
-type MX struct {
- Hdr RR_Header
- Preference uint16
- Mx string `dns:"cdomain-name"`
-}
-
-func (rr *MX) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx)
-}
-
-type AFSDB struct {
- Hdr RR_Header
- Subtype uint16
- Hostname string `dns:"cdomain-name"`
-}
-
-func (rr *AFSDB) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname)
-}
-
-type X25 struct {
- Hdr RR_Header
- PSDNAddress string
-}
-
-func (rr *X25) String() string {
- return rr.Hdr.String() + rr.PSDNAddress
-}
-
-type RT struct {
- Hdr RR_Header
- Preference uint16
- Host string `dns:"cdomain-name"`
-}
-
-func (rr *RT) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host)
-}
-
-type NS struct {
- Hdr RR_Header
- Ns string `dns:"cdomain-name"`
-}
-
-func (rr *NS) String() string {
- return rr.Hdr.String() + sprintName(rr.Ns)
-}
-
-type PTR struct {
- Hdr RR_Header
- Ptr string `dns:"cdomain-name"`
-}
-
-func (rr *PTR) String() string {
- return rr.Hdr.String() + sprintName(rr.Ptr)
-}
-
-type RP struct {
- Hdr RR_Header
- Mbox string `dns:"domain-name"`
- Txt string `dns:"domain-name"`
-}
-
-func (rr *RP) String() string {
- return rr.Hdr.String() + rr.Mbox + " " + sprintTxt([]string{rr.Txt})
-}
-
-type SOA struct {
- Hdr RR_Header
- Ns string `dns:"cdomain-name"`
- Mbox string `dns:"cdomain-name"`
- Serial uint32
- Refresh uint32
- Retry uint32
- Expire uint32
- Minttl uint32
-}
-
-func (rr *SOA) String() string {
- return rr.Hdr.String() + sprintName(rr.Ns) + " " + sprintName(rr.Mbox) +
- " " + strconv.FormatInt(int64(rr.Serial), 10) +
- " " + strconv.FormatInt(int64(rr.Refresh), 10) +
- " " + strconv.FormatInt(int64(rr.Retry), 10) +
- " " + strconv.FormatInt(int64(rr.Expire), 10) +
- " " + strconv.FormatInt(int64(rr.Minttl), 10)
-}
-
-type TXT struct {
- Hdr RR_Header
- Txt []string `dns:"txt"`
-}
-
-func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
-
-func sprintName(s string) string {
- src := []byte(s)
- dst := make([]byte, 0, len(src))
- for i := 0; i < len(src); {
- if i+1 < len(src) && src[i] == '\\' && src[i+1] == '.' {
- dst = append(dst, src[i:i+2]...)
- i += 2
- } else {
- b, n := nextByte(src, i)
- if n == 0 {
- i++ // dangling back slash
- } else if b == '.' {
- dst = append(dst, b)
- } else {
- dst = appendDomainNameByte(dst, b)
- }
- i += n
- }
- }
- return string(dst)
-}
-
-func sprintTxtOctet(s string) string {
- src := []byte(s)
- dst := make([]byte, 0, len(src))
- dst = append(dst, '"')
- for i := 0; i < len(src); {
- if i+1 < len(src) && src[i] == '\\' && src[i+1] == '.' {
- dst = append(dst, src[i:i+2]...)
- i += 2
- } else {
- b, n := nextByte(src, i)
- if n == 0 {
- i++ // dangling back slash
- } else if b == '.' {
- dst = append(dst, b)
- } else {
- if b < ' ' || b > '~' {
- dst = appendByte(dst, b)
- } else {
- dst = append(dst, b)
- }
- }
- i += n
- }
- }
- dst = append(dst, '"')
- return string(dst)
-}
-
-func sprintTxt(txt []string) string {
- var out []byte
- for i, s := range txt {
- if i > 0 {
- out = append(out, ` "`...)
- } else {
- out = append(out, '"')
- }
- bs := []byte(s)
- for j := 0; j < len(bs); {
- b, n := nextByte(bs, j)
- if n == 0 {
- break
- }
- out = appendTXTStringByte(out, b)
- j += n
- }
- out = append(out, '"')
- }
- return string(out)
-}
-
-func appendDomainNameByte(s []byte, b byte) []byte {
- switch b {
- case '.', ' ', '\'', '@', ';', '(', ')': // additional chars to escape
- return append(s, '\\', b)
- }
- return appendTXTStringByte(s, b)
-}
-
-func appendTXTStringByte(s []byte, b byte) []byte {
- switch b {
- case '"', '\\':
- return append(s, '\\', b)
- }
- if b < ' ' || b > '~' {
- return appendByte(s, b)
- }
- return append(s, b)
-}
-
-func appendByte(s []byte, b byte) []byte {
- var buf [3]byte
- bufs := strconv.AppendInt(buf[:0], int64(b), 10)
- s = append(s, '\\')
- for i := 0; i < 3-len(bufs); i++ {
- s = append(s, '0')
- }
- for _, r := range bufs {
- s = append(s, r)
- }
- return s
-}
-
-func nextByte(b []byte, offset int) (byte, int) {
- if offset >= len(b) {
- return 0, 0
- }
- if b[offset] != '\\' {
- // not an escape sequence
- return b[offset], 1
- }
- switch len(b) - offset {
- case 1: // dangling escape
- return 0, 0
- case 2, 3: // too short to be \ddd
- default: // maybe \ddd
- if isDigit(b[offset+1]) && isDigit(b[offset+2]) && isDigit(b[offset+3]) {
- return dddToByte(b[offset+1:]), 4
- }
- }
- // not \ddd, just an RFC 1035 "quoted" character
- return b[offset+1], 2
-}
-
-type SPF struct {
- Hdr RR_Header
- Txt []string `dns:"txt"`
-}
-
-func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
-
-type AVC struct {
- Hdr RR_Header
- Txt []string `dns:"txt"`
-}
-
-func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
-
-type SRV struct {
- Hdr RR_Header
- Priority uint16
- Weight uint16
- Port uint16
- Target string `dns:"domain-name"`
-}
-
-func (rr *SRV) String() string {
- return rr.Hdr.String() +
- strconv.Itoa(int(rr.Priority)) + " " +
- strconv.Itoa(int(rr.Weight)) + " " +
- strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target)
-}
-
-type NAPTR struct {
- Hdr RR_Header
- Order uint16
- Preference uint16
- Flags string
- Service string
- Regexp string
- Replacement string `dns:"domain-name"`
-}
-
-func (rr *NAPTR) String() string {
- return rr.Hdr.String() +
- strconv.Itoa(int(rr.Order)) + " " +
- strconv.Itoa(int(rr.Preference)) + " " +
- "\"" + rr.Flags + "\" " +
- "\"" + rr.Service + "\" " +
- "\"" + rr.Regexp + "\" " +
- rr.Replacement
-}
-
-// The CERT resource record, see RFC 4398.
-type CERT struct {
- Hdr RR_Header
- Type uint16
- KeyTag uint16
- Algorithm uint8
- Certificate string `dns:"base64"`
-}
-
-func (rr *CERT) String() string {
- var (
- ok bool
- certtype, algorithm string
- )
- if certtype, ok = CertTypeToString[rr.Type]; !ok {
- certtype = strconv.Itoa(int(rr.Type))
- }
- if algorithm, ok = AlgorithmToString[rr.Algorithm]; !ok {
- algorithm = strconv.Itoa(int(rr.Algorithm))
- }
- return rr.Hdr.String() + certtype +
- " " + strconv.Itoa(int(rr.KeyTag)) +
- " " + algorithm +
- " " + rr.Certificate
-}
-
-// The DNAME resource record, see RFC 2672.
-type DNAME struct {
- Hdr RR_Header
- Target string `dns:"domain-name"`
-}
-
-func (rr *DNAME) String() string {
- return rr.Hdr.String() + sprintName(rr.Target)
-}
-
-type A struct {
- Hdr RR_Header
- A net.IP `dns:"a"`
-}
-
-func (rr *A) String() string {
- if rr.A == nil {
- return rr.Hdr.String()
- }
- return rr.Hdr.String() + rr.A.String()
-}
-
-type AAAA struct {
- Hdr RR_Header
- AAAA net.IP `dns:"aaaa"`
-}
-
-func (rr *AAAA) String() string {
- if rr.AAAA == nil {
- return rr.Hdr.String()
- }
- return rr.Hdr.String() + rr.AAAA.String()
-}
-
-type PX struct {
- Hdr RR_Header
- Preference uint16
- Map822 string `dns:"domain-name"`
- Mapx400 string `dns:"domain-name"`
-}
-
-func (rr *PX) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400)
-}
-
-type GPOS struct {
- Hdr RR_Header
- Longitude string
- Latitude string
- Altitude string
-}
-
-func (rr *GPOS) String() string {
- return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude
-}
-
-type LOC struct {
- Hdr RR_Header
- Version uint8
- Size uint8
- HorizPre uint8
- VertPre uint8
- Latitude uint32
- Longitude uint32
- Altitude uint32
-}
-
-// cmToM takes a cm value expressed in RFC1876 SIZE mantissa/exponent
-// format and returns a string in m (two decimals for the cm)
-func cmToM(m, e uint8) string {
- if e < 2 {
- if e == 1 {
- m *= 10
- }
-
- return fmt.Sprintf("0.%02d", m)
- }
-
- s := fmt.Sprintf("%d", m)
- for e > 2 {
- s += "0"
- e--
- }
- return s
-}
-
-func (rr *LOC) String() string {
- s := rr.Hdr.String()
-
- lat := rr.Latitude
- ns := "N"
- if lat > LOC_EQUATOR {
- lat = lat - LOC_EQUATOR
- } else {
- ns = "S"
- lat = LOC_EQUATOR - lat
- }
- h := lat / LOC_DEGREES
- lat = lat % LOC_DEGREES
- m := lat / LOC_HOURS
- lat = lat % LOC_HOURS
- s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float64(lat) / 1000), ns)
-
- lon := rr.Longitude
- ew := "E"
- if lon > LOC_PRIMEMERIDIAN {
- lon = lon - LOC_PRIMEMERIDIAN
- } else {
- ew = "W"
- lon = LOC_PRIMEMERIDIAN - lon
- }
- h = lon / LOC_DEGREES
- lon = lon % LOC_DEGREES
- m = lon / LOC_HOURS
- lon = lon % LOC_HOURS
- s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float64(lon) / 1000), ew)
-
- var alt = float64(rr.Altitude) / 100
- alt -= LOC_ALTITUDEBASE
- if rr.Altitude%100 != 0 {
- s += fmt.Sprintf("%.2fm ", alt)
- } else {
- s += fmt.Sprintf("%.0fm ", alt)
- }
-
- s += cmToM((rr.Size&0xf0)>>4, rr.Size&0x0f) + "m "
- s += cmToM((rr.HorizPre&0xf0)>>4, rr.HorizPre&0x0f) + "m "
- s += cmToM((rr.VertPre&0xf0)>>4, rr.VertPre&0x0f) + "m"
-
- return s
-}
-
-// SIG is identical to RRSIG and nowadays only used for SIG(0), RFC2931.
-type SIG struct {
- RRSIG
-}
-
-type RRSIG struct {
- Hdr RR_Header
- TypeCovered uint16
- Algorithm uint8
- Labels uint8
- OrigTtl uint32
- Expiration uint32
- Inception uint32
- KeyTag uint16
- SignerName string `dns:"domain-name"`
- Signature string `dns:"base64"`
-}
-
-func (rr *RRSIG) String() string {
- s := rr.Hdr.String()
- s += Type(rr.TypeCovered).String()
- s += " " + strconv.Itoa(int(rr.Algorithm)) +
- " " + strconv.Itoa(int(rr.Labels)) +
- " " + strconv.FormatInt(int64(rr.OrigTtl), 10) +
- " " + TimeToString(rr.Expiration) +
- " " + TimeToString(rr.Inception) +
- " " + strconv.Itoa(int(rr.KeyTag)) +
- " " + sprintName(rr.SignerName) +
- " " + rr.Signature
- return s
-}
-
-type NSEC struct {
- Hdr RR_Header
- NextDomain string `dns:"domain-name"`
- TypeBitMap []uint16 `dns:"nsec"`
-}
-
-func (rr *NSEC) String() string {
- s := rr.Hdr.String() + sprintName(rr.NextDomain)
- for i := 0; i < len(rr.TypeBitMap); i++ {
- s += " " + Type(rr.TypeBitMap[i]).String()
- }
- return s
-}
-
-func (rr *NSEC) len() int {
- l := rr.Hdr.len() + len(rr.NextDomain) + 1
- lastwindow := uint32(2 ^ 32 + 1)
- for _, t := range rr.TypeBitMap {
- window := t / 256
- if uint32(window) != lastwindow {
- l += 1 + 32
- }
- lastwindow = uint32(window)
- }
- return l
-}
-
-type DLV struct {
- DS
-}
-
-type CDS struct {
- DS
-}
-
-type DS struct {
- Hdr RR_Header
- KeyTag uint16
- Algorithm uint8
- DigestType uint8
- Digest string `dns:"hex"`
-}
-
-func (rr *DS) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
- " " + strconv.Itoa(int(rr.Algorithm)) +
- " " + strconv.Itoa(int(rr.DigestType)) +
- " " + strings.ToUpper(rr.Digest)
-}
-
-type KX struct {
- Hdr RR_Header
- Preference uint16
- Exchanger string `dns:"domain-name"`
-}
-
-func (rr *KX) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
- " " + sprintName(rr.Exchanger)
-}
-
-type TA struct {
- Hdr RR_Header
- KeyTag uint16
- Algorithm uint8
- DigestType uint8
- Digest string `dns:"hex"`
-}
-
-func (rr *TA) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
- " " + strconv.Itoa(int(rr.Algorithm)) +
- " " + strconv.Itoa(int(rr.DigestType)) +
- " " + strings.ToUpper(rr.Digest)
-}
-
-type TALINK struct {
- Hdr RR_Header
- PreviousName string `dns:"domain-name"`
- NextName string `dns:"domain-name"`
-}
-
-func (rr *TALINK) String() string {
- return rr.Hdr.String() +
- sprintName(rr.PreviousName) + " " + sprintName(rr.NextName)
-}
-
-type SSHFP struct {
- Hdr RR_Header
- Algorithm uint8
- Type uint8
- FingerPrint string `dns:"hex"`
-}
-
-func (rr *SSHFP) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Algorithm)) +
- " " + strconv.Itoa(int(rr.Type)) +
- " " + strings.ToUpper(rr.FingerPrint)
-}
-
-type KEY struct {
- DNSKEY
-}
-
-type CDNSKEY struct {
- DNSKEY
-}
-
-type DNSKEY struct {
- Hdr RR_Header
- Flags uint16
- Protocol uint8
- Algorithm uint8
- PublicKey string `dns:"base64"`
-}
-
-func (rr *DNSKEY) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) +
- " " + strconv.Itoa(int(rr.Protocol)) +
- " " + strconv.Itoa(int(rr.Algorithm)) +
- " " + rr.PublicKey
-}
-
-type RKEY struct {
- Hdr RR_Header
- Flags uint16
- Protocol uint8
- Algorithm uint8
- PublicKey string `dns:"base64"`
-}
-
-func (rr *RKEY) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) +
- " " + strconv.Itoa(int(rr.Protocol)) +
- " " + strconv.Itoa(int(rr.Algorithm)) +
- " " + rr.PublicKey
-}
-
-type NSAPPTR struct {
- Hdr RR_Header
- Ptr string `dns:"domain-name"`
-}
-
-func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) }
-
-type NSEC3 struct {
- Hdr RR_Header
- Hash uint8
- Flags uint8
- Iterations uint16
- SaltLength uint8
- Salt string `dns:"size-hex:SaltLength"`
- HashLength uint8
- NextDomain string `dns:"size-base32:HashLength"`
- TypeBitMap []uint16 `dns:"nsec"`
-}
-
-func (rr *NSEC3) String() string {
- s := rr.Hdr.String()
- s += strconv.Itoa(int(rr.Hash)) +
- " " + strconv.Itoa(int(rr.Flags)) +
- " " + strconv.Itoa(int(rr.Iterations)) +
- " " + saltToString(rr.Salt) +
- " " + rr.NextDomain
- for i := 0; i < len(rr.TypeBitMap); i++ {
- s += " " + Type(rr.TypeBitMap[i]).String()
- }
- return s
-}
-
-func (rr *NSEC3) len() int {
- l := rr.Hdr.len() + 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1
- lastwindow := uint32(2 ^ 32 + 1)
- for _, t := range rr.TypeBitMap {
- window := t / 256
- if uint32(window) != lastwindow {
- l += 1 + 32
- }
- lastwindow = uint32(window)
- }
- return l
-}
-
-type NSEC3PARAM struct {
- Hdr RR_Header
- Hash uint8
- Flags uint8
- Iterations uint16
- SaltLength uint8
- Salt string `dns:"size-hex:SaltLength"`
-}
-
-func (rr *NSEC3PARAM) String() string {
- s := rr.Hdr.String()
- s += strconv.Itoa(int(rr.Hash)) +
- " " + strconv.Itoa(int(rr.Flags)) +
- " " + strconv.Itoa(int(rr.Iterations)) +
- " " + saltToString(rr.Salt)
- return s
-}
-
-type TKEY struct {
- Hdr RR_Header
- Algorithm string `dns:"domain-name"`
- Inception uint32
- Expiration uint32
- Mode uint16
- Error uint16
- KeySize uint16
- Key string
- OtherLen uint16
- OtherData string
-}
-
-func (rr *TKEY) String() string {
- // It has no presentation format
- return ""
-}
-
-// RFC3597 represents an unknown/generic RR.
-type RFC3597 struct {
- Hdr RR_Header
- Rdata string `dns:"hex"`
-}
-
-func (rr *RFC3597) String() string {
- // Let's call it a hack
- s := rfc3597Header(rr.Hdr)
-
- s += "\\# " + strconv.Itoa(len(rr.Rdata)/2) + " " + rr.Rdata
- return s
-}
-
-func rfc3597Header(h RR_Header) string {
- var s string
-
- s += sprintName(h.Name) + "\t"
- s += strconv.FormatInt(int64(h.Ttl), 10) + "\t"
- s += "CLASS" + strconv.Itoa(int(h.Class)) + "\t"
- s += "TYPE" + strconv.Itoa(int(h.Rrtype)) + "\t"
- return s
-}
-
-type URI struct {
- Hdr RR_Header
- Priority uint16
- Weight uint16
- Target string `dns:"octet"`
-}
-
-func (rr *URI) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Priority)) +
- " " + strconv.Itoa(int(rr.Weight)) + " " + sprintTxtOctet(rr.Target)
-}
-
-type DHCID struct {
- Hdr RR_Header
- Digest string `dns:"base64"`
-}
-
-func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest }
-
-type TLSA struct {
- Hdr RR_Header
- Usage uint8
- Selector uint8
- MatchingType uint8
- Certificate string `dns:"hex"`
-}
-
-func (rr *TLSA) String() string {
- return rr.Hdr.String() +
- strconv.Itoa(int(rr.Usage)) +
- " " + strconv.Itoa(int(rr.Selector)) +
- " " + strconv.Itoa(int(rr.MatchingType)) +
- " " + rr.Certificate
-}
-
-type SMIMEA struct {
- Hdr RR_Header
- Usage uint8
- Selector uint8
- MatchingType uint8
- Certificate string `dns:"hex"`
-}
-
-func (rr *SMIMEA) String() string {
- s := rr.Hdr.String() +
- strconv.Itoa(int(rr.Usage)) +
- " " + strconv.Itoa(int(rr.Selector)) +
- " " + strconv.Itoa(int(rr.MatchingType))
-
- // Every Nth char needs a space on this output. If we output
- // this as one giant line, we can't read it can in because in some cases
- // the cert length overflows scan.maxTok (2048).
- sx := splitN(rr.Certificate, 1024) // conservative value here
- s += " " + strings.Join(sx, " ")
- return s
-}
-
-type HIP struct {
- Hdr RR_Header
- HitLength uint8
- PublicKeyAlgorithm uint8
- PublicKeyLength uint16
- Hit string `dns:"size-hex:HitLength"`
- PublicKey string `dns:"size-base64:PublicKeyLength"`
- RendezvousServers []string `dns:"domain-name"`
-}
-
-func (rr *HIP) String() string {
- s := rr.Hdr.String() +
- strconv.Itoa(int(rr.PublicKeyAlgorithm)) +
- " " + rr.Hit +
- " " + rr.PublicKey
- for _, d := range rr.RendezvousServers {
- s += " " + sprintName(d)
- }
- return s
-}
-
-type NINFO struct {
- Hdr RR_Header
- ZSData []string `dns:"txt"`
-}
-
-func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) }
-
-type NID struct {
- Hdr RR_Header
- Preference uint16
- NodeID uint64
-}
-
-func (rr *NID) String() string {
- s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
- node := fmt.Sprintf("%0.16x", rr.NodeID)
- s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
- return s
-}
-
-type L32 struct {
- Hdr RR_Header
- Preference uint16
- Locator32 net.IP `dns:"a"`
-}
-
-func (rr *L32) String() string {
- if rr.Locator32 == nil {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
- }
- return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
- " " + rr.Locator32.String()
-}
-
-type L64 struct {
- Hdr RR_Header
- Preference uint16
- Locator64 uint64
-}
-
-func (rr *L64) String() string {
- s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
- node := fmt.Sprintf("%0.16X", rr.Locator64)
- s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
- return s
-}
-
-type LP struct {
- Hdr RR_Header
- Preference uint16
- Fqdn string `dns:"domain-name"`
-}
-
-func (rr *LP) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn)
-}
-
-type EUI48 struct {
- Hdr RR_Header
- Address uint64 `dns:"uint48"`
-}
-
-func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) }
-
-type EUI64 struct {
- Hdr RR_Header
- Address uint64
-}
-
-func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) }
-
-type CAA struct {
- Hdr RR_Header
- Flag uint8
- Tag string
- Value string `dns:"octet"`
-}
-
-func (rr *CAA) String() string {
- return rr.Hdr.String() + strconv.Itoa(int(rr.Flag)) + " " + rr.Tag + " " + sprintTxtOctet(rr.Value)
-}
-
-type UID struct {
- Hdr RR_Header
- Uid uint32
-}
-
-func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) }
-
-type GID struct {
- Hdr RR_Header
- Gid uint32
-}
-
-func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) }
-
-type UINFO struct {
- Hdr RR_Header
- Uinfo string
-}
-
-func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) }
-
-type EID struct {
- Hdr RR_Header
- Endpoint string `dns:"hex"`
-}
-
-func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) }
-
-type NIMLOC struct {
- Hdr RR_Header
- Locator string `dns:"hex"`
-}
-
-func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) }
-
-type OPENPGPKEY struct {
- Hdr RR_Header
- PublicKey string `dns:"base64"`
-}
-
-func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey }
-
-// TimeToString translates the RRSIG's incep. and expir. times to the
-// string representation used when printing the record.
-// It takes serial arithmetic (RFC 1982) into account.
-func TimeToString(t uint32) string {
- mod := ((int64(t) - time.Now().Unix()) / year68) - 1
- if mod < 0 {
- mod = 0
- }
- ti := time.Unix(int64(t)-(mod*year68), 0).UTC()
- return ti.Format("20060102150405")
-}
-
-// StringToTime translates the RRSIG's incep. and expir. times from
-// string values like "20110403154150" to an 32 bit integer.
-// It takes serial arithmetic (RFC 1982) into account.
-func StringToTime(s string) (uint32, error) {
- t, err := time.Parse("20060102150405", s)
- if err != nil {
- return 0, err
- }
- mod := (t.Unix() / year68) - 1
- if mod < 0 {
- mod = 0
- }
- return uint32(t.Unix() - (mod * year68)), nil
-}
-
-// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty.
-func saltToString(s string) string {
- if len(s) == 0 {
- return "-"
- }
- return strings.ToUpper(s)
-}
-
-func euiToString(eui uint64, bits int) (hex string) {
- switch bits {
- case 64:
- hex = fmt.Sprintf("%16.16x", eui)
- hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] +
- "-" + hex[8:10] + "-" + hex[10:12] + "-" + hex[12:14] + "-" + hex[14:16]
- case 48:
- hex = fmt.Sprintf("%12.12x", eui)
- hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] +
- "-" + hex[8:10] + "-" + hex[10:12]
- }
- return
-}
-
-// copyIP returns a copy of ip.
-func copyIP(ip net.IP) net.IP {
- p := make(net.IP, len(ip))
- copy(p, ip)
- return p
-}
-
-// SplitN splits a string into N sized string chunks.
-// This might become an exported function once.
-func splitN(s string, n int) []string {
- if len(s) < n {
- return []string{s}
- }
- sx := []string{}
- p, i := 0, n
- for {
- if i <= len(s) {
- sx = append(sx, s[p:i])
- } else {
- sx = append(sx, s[p:])
- break
-
- }
- p, i = p+n, i+n
- }
-
- return sx
-}
diff --git a/vendor/github.com/miekg/dns/types_generate.go b/vendor/github.com/miekg/dns/types_generate.go
deleted file mode 100644
index dd1310942..000000000
--- a/vendor/github.com/miekg/dns/types_generate.go
+++ /dev/null
@@ -1,271 +0,0 @@
-//+build ignore
-
-// types_generate.go is meant to run with go generate. It will use
-// go/{importer,types} to track down all the RR struct types. Then for each type
-// it will generate conversion tables (TypeToRR and TypeToString) and banal
-// methods (len, Header, copy) based on the struct tags. The generated source is
-// written to ztypes.go, and is meant to be checked into git.
-package main
-
-import (
- "bytes"
- "fmt"
- "go/format"
- "go/importer"
- "go/types"
- "log"
- "os"
- "strings"
- "text/template"
-)
-
-var skipLen = map[string]struct{}{
- "NSEC": {},
- "NSEC3": {},
- "OPT": {},
-}
-
-var packageHdr = `
-// *** DO NOT MODIFY ***
-// AUTOGENERATED BY go generate from type_generate.go
-
-package dns
-
-import (
- "encoding/base64"
- "net"
-)
-
-`
-
-var TypeToRR = template.Must(template.New("TypeToRR").Parse(`
-// TypeToRR is a map of constructors for each RR type.
-var TypeToRR = map[uint16]func() RR{
-{{range .}}{{if ne . "RFC3597"}} Type{{.}}: func() RR { return new({{.}}) },
-{{end}}{{end}} }
-
-`))
-
-var typeToString = template.Must(template.New("typeToString").Parse(`
-// TypeToString is a map of strings for each RR type.
-var TypeToString = map[uint16]string{
-{{range .}}{{if ne . "NSAPPTR"}} Type{{.}}: "{{.}}",
-{{end}}{{end}} TypeNSAPPTR: "NSAP-PTR",
-}
-
-`))
-
-var headerFunc = template.Must(template.New("headerFunc").Parse(`
-// Header() functions
-{{range .}} func (rr *{{.}}) Header() *RR_Header { return &rr.Hdr }
-{{end}}
-
-`))
-
-// getTypeStruct will take a type and the package scope, and return the
-// (innermost) struct if the type is considered a RR type (currently defined as
-// those structs beginning with a RR_Header, could be redefined as implementing
-// the RR interface). The bool return value indicates if embedded structs were
-// resolved.
-func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) {
- st, ok := t.Underlying().(*types.Struct)
- if !ok {
- return nil, false
- }
- if st.Field(0).Type() == scope.Lookup("RR_Header").Type() {
- return st, false
- }
- if st.Field(0).Anonymous() {
- st, _ := getTypeStruct(st.Field(0).Type(), scope)
- return st, true
- }
- return nil, false
-}
-
-func main() {
- // Import and type-check the package
- pkg, err := importer.Default().Import("github.com/miekg/dns")
- fatalIfErr(err)
- scope := pkg.Scope()
-
- // Collect constants like TypeX
- var numberedTypes []string
- for _, name := range scope.Names() {
- o := scope.Lookup(name)
- if o == nil || !o.Exported() {
- continue
- }
- b, ok := o.Type().(*types.Basic)
- if !ok || b.Kind() != types.Uint16 {
- continue
- }
- if !strings.HasPrefix(o.Name(), "Type") {
- continue
- }
- name := strings.TrimPrefix(o.Name(), "Type")
- if name == "PrivateRR" {
- continue
- }
- numberedTypes = append(numberedTypes, name)
- }
-
- // Collect actual types (*X)
- var namedTypes []string
- for _, name := range scope.Names() {
- o := scope.Lookup(name)
- if o == nil || !o.Exported() {
- continue
- }
- if st, _ := getTypeStruct(o.Type(), scope); st == nil {
- continue
- }
- if name == "PrivateRR" {
- continue
- }
-
- // Check if corresponding TypeX exists
- if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" {
- log.Fatalf("Constant Type%s does not exist.", o.Name())
- }
-
- namedTypes = append(namedTypes, o.Name())
- }
-
- b := &bytes.Buffer{}
- b.WriteString(packageHdr)
-
- // Generate TypeToRR
- fatalIfErr(TypeToRR.Execute(b, namedTypes))
-
- // Generate typeToString
- fatalIfErr(typeToString.Execute(b, numberedTypes))
-
- // Generate headerFunc
- fatalIfErr(headerFunc.Execute(b, namedTypes))
-
- // Generate len()
- fmt.Fprint(b, "// len() functions\n")
- for _, name := range namedTypes {
- if _, ok := skipLen[name]; ok {
- continue
- }
- o := scope.Lookup(name)
- st, isEmbedded := getTypeStruct(o.Type(), scope)
- if isEmbedded {
- continue
- }
- fmt.Fprintf(b, "func (rr *%s) len() int {\n", name)
- fmt.Fprintf(b, "l := rr.Hdr.len()\n")
- for i := 1; i < st.NumFields(); i++ {
- o := func(s string) { fmt.Fprintf(b, s, st.Field(i).Name()) }
-
- if _, ok := st.Field(i).Type().(*types.Slice); ok {
- switch st.Tag(i) {
- case `dns:"-"`:
- // ignored
- case `dns:"cdomain-name"`, `dns:"domain-name"`, `dns:"txt"`:
- o("for _, x := range rr.%s { l += len(x) + 1 }\n")
- default:
- log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
- }
- continue
- }
-
- switch {
- case st.Tag(i) == `dns:"-"`:
- // ignored
- case st.Tag(i) == `dns:"cdomain-name"`, st.Tag(i) == `dns:"domain-name"`:
- o("l += len(rr.%s) + 1\n")
- case st.Tag(i) == `dns:"octet"`:
- o("l += len(rr.%s)\n")
- case strings.HasPrefix(st.Tag(i), `dns:"size-base64`):
- fallthrough
- case st.Tag(i) == `dns:"base64"`:
- o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n")
- case strings.HasPrefix(st.Tag(i), `dns:"size-hex`):
- fallthrough
- case st.Tag(i) == `dns:"hex"`:
- o("l += len(rr.%s)/2 + 1\n")
- case st.Tag(i) == `dns:"a"`:
- o("l += net.IPv4len // %s\n")
- case st.Tag(i) == `dns:"aaaa"`:
- o("l += net.IPv6len // %s\n")
- case st.Tag(i) == `dns:"txt"`:
- o("for _, t := range rr.%s { l += len(t) + 1 }\n")
- case st.Tag(i) == `dns:"uint48"`:
- o("l += 6 // %s\n")
- case st.Tag(i) == "":
- switch st.Field(i).Type().(*types.Basic).Kind() {
- case types.Uint8:
- o("l++ // %s\n")
- case types.Uint16:
- o("l += 2 // %s\n")
- case types.Uint32:
- o("l += 4 // %s\n")
- case types.Uint64:
- o("l += 8 // %s\n")
- case types.String:
- o("l += len(rr.%s) + 1\n")
- default:
- log.Fatalln(name, st.Field(i).Name())
- }
- default:
- log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
- }
- }
- fmt.Fprintf(b, "return l }\n")
- }
-
- // Generate copy()
- fmt.Fprint(b, "// copy() functions\n")
- for _, name := range namedTypes {
- o := scope.Lookup(name)
- st, isEmbedded := getTypeStruct(o.Type(), scope)
- if isEmbedded {
- continue
- }
- fmt.Fprintf(b, "func (rr *%s) copy() RR {\n", name)
- fields := []string{"*rr.Hdr.copyHeader()"}
- for i := 1; i < st.NumFields(); i++ {
- f := st.Field(i).Name()
- if sl, ok := st.Field(i).Type().(*types.Slice); ok {
- t := sl.Underlying().String()
- t = strings.TrimPrefix(t, "[]")
- if strings.Contains(t, ".") {
- splits := strings.Split(t, ".")
- t = splits[len(splits)-1]
- }
- fmt.Fprintf(b, "%s := make([]%s, len(rr.%s)); copy(%s, rr.%s)\n",
- f, t, f, f, f)
- fields = append(fields, f)
- continue
- }
- if st.Field(i).Type().String() == "net.IP" {
- fields = append(fields, "copyIP(rr."+f+")")
- continue
- }
- fields = append(fields, "rr."+f)
- }
- fmt.Fprintf(b, "return &%s{%s}\n", name, strings.Join(fields, ","))
- fmt.Fprintf(b, "}\n")
- }
-
- // gofmt
- res, err := format.Source(b.Bytes())
- if err != nil {
- b.WriteTo(os.Stderr)
- log.Fatal(err)
- }
-
- // write result
- f, err := os.Create("ztypes.go")
- fatalIfErr(err)
- defer f.Close()
- f.Write(res)
-}
-
-func fatalIfErr(err error) {
- if err != nil {
- log.Fatal(err)
- }
-}
diff --git a/vendor/github.com/miekg/dns/types_test.go b/vendor/github.com/miekg/dns/types_test.go
deleted file mode 100644
index c117cfbc7..000000000
--- a/vendor/github.com/miekg/dns/types_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package dns
-
-import (
- "testing"
-)
-
-func TestCmToM(t *testing.T) {
- s := cmToM(0, 0)
- if s != "0.00" {
- t.Error("0, 0")
- }
-
- s = cmToM(1, 0)
- if s != "0.01" {
- t.Error("1, 0")
- }
-
- s = cmToM(3, 1)
- if s != "0.30" {
- t.Error("3, 1")
- }
-
- s = cmToM(4, 2)
- if s != "4" {
- t.Error("4, 2")
- }
-
- s = cmToM(5, 3)
- if s != "50" {
- t.Error("5, 3")
- }
-
- s = cmToM(7, 5)
- if s != "7000" {
- t.Error("7, 5")
- }
-
- s = cmToM(9, 9)
- if s != "90000000" {
- t.Error("9, 9")
- }
-}
-
-func TestSplitN(t *testing.T) {
- xs := splitN("abc", 5)
- if len(xs) != 1 && xs[0] != "abc" {
- t.Errorf("Failure to split abc")
- }
-
- s := ""
- for i := 0; i < 255; i++ {
- s += "a"
- }
-
- xs = splitN(s, 255)
- if len(xs) != 1 && xs[0] != s {
- t.Errorf("failure to split 255 char long string")
- }
-
- s += "b"
- xs = splitN(s, 255)
- if len(xs) != 2 || xs[1] != "b" {
- t.Errorf("failure to split 256 char long string: %d", len(xs))
- }
-
- // Make s longer
- for i := 0; i < 255; i++ {
- s += "a"
- }
- xs = splitN(s, 255)
- if len(xs) != 3 || xs[2] != "a" {
- t.Errorf("failure to split 510 char long string: %d", len(xs))
- }
-}
diff --git a/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/miekg/dns/udp.go
deleted file mode 100644
index af111b9a8..000000000
--- a/vendor/github.com/miekg/dns/udp.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// +build !windows
-
-package dns
-
-import (
- "net"
-)
-
-// SessionUDP holds the remote address and the associated
-// out-of-band data.
-type SessionUDP struct {
- raddr *net.UDPAddr
- context []byte
-}
-
-// RemoteAddr returns the remote network address.
-func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
-
-// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
-// net.UDPAddr.
-func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
- oob := make([]byte, 40)
- n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob)
- if err != nil {
- return n, nil, err
- }
- return n, &SessionUDP{raddr, oob[:oobn]}, err
-}
-
-// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
-func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
- n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr)
- return n, err
-}
diff --git a/vendor/github.com/miekg/dns/udp_linux.go b/vendor/github.com/miekg/dns/udp_linux.go
deleted file mode 100644
index 033df4239..000000000
--- a/vendor/github.com/miekg/dns/udp_linux.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// +build linux,!appengine
-
-package dns
-
-// See:
-// * http://stackoverflow.com/questions/3062205/setting-the-source-ip-for-a-udp-socket and
-// * http://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/
-//
-// Why do we need this: When listening on 0.0.0.0 with UDP so kernel decides what is the outgoing
-// interface, this might not always be the correct one. This code will make sure the egress
-// packet's interface matched the ingress' one.
-
-import (
- "net"
- "syscall"
-)
-
-// setUDPSocketOptions sets the UDP socket options.
-// This function is implemented on a per platform basis. See udp_*.go for more details
-func setUDPSocketOptions(conn *net.UDPConn) error {
- sa, err := getUDPSocketName(conn)
- if err != nil {
- return err
- }
- switch sa.(type) {
- case *syscall.SockaddrInet6:
- v6only, err := getUDPSocketOptions6Only(conn)
- if err != nil {
- return err
- }
- setUDPSocketOptions6(conn)
- if !v6only {
- setUDPSocketOptions4(conn)
- }
- case *syscall.SockaddrInet4:
- setUDPSocketOptions4(conn)
- }
- return nil
-}
-
-// setUDPSocketOptions4 prepares the v4 socket for sessions.
-func setUDPSocketOptions4(conn *net.UDPConn) error {
- file, err := conn.File()
- if err != nil {
- return err
- }
- if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil {
- file.Close()
- return err
- }
- // Calling File() above results in the connection becoming blocking, we must fix that.
- // See https://github.com/miekg/dns/issues/279
- err = syscall.SetNonblock(int(file.Fd()), true)
- if err != nil {
- file.Close()
- return err
- }
- file.Close()
- return nil
-}
-
-// setUDPSocketOptions6 prepares the v6 socket for sessions.
-func setUDPSocketOptions6(conn *net.UDPConn) error {
- file, err := conn.File()
- if err != nil {
- return err
- }
- if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil {
- file.Close()
- return err
- }
- err = syscall.SetNonblock(int(file.Fd()), true)
- if err != nil {
- file.Close()
- return err
- }
- file.Close()
- return nil
-}
-
-// getUDPSocketOption6Only return true if the socket is v6 only and false when it is v4/v6 combined
-// (dualstack).
-func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) {
- file, err := conn.File()
- if err != nil {
- return false, err
- }
- // dual stack. See http://stackoverflow.com/questions/1618240/how-to-support-both-ipv4-and-ipv6-connections
- v6only, err := syscall.GetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY)
- if err != nil {
- file.Close()
- return false, err
- }
- file.Close()
- return v6only == 1, nil
-}
-
-func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) {
- file, err := conn.File()
- if err != nil {
- return nil, err
- }
- defer file.Close()
- return syscall.Getsockname(int(file.Fd()))
-}
diff --git a/vendor/github.com/miekg/dns/udp_other.go b/vendor/github.com/miekg/dns/udp_other.go
deleted file mode 100644
index 488a282b2..000000000
--- a/vendor/github.com/miekg/dns/udp_other.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// +build !linux appengine
-
-package dns
-
-import (
- "net"
-)
-
-// These do nothing. See udp_linux.go for an example of how to implement this.
-
-// We tried to adhire to some kind of naming scheme.
-func setUDPSocketOptions(conn *net.UDPConn) error { return nil }
-func setUDPSocketOptions4(conn *net.UDPConn) error { return nil }
-func setUDPSocketOptions6(conn *net.UDPConn) error { return nil }
-func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil }
diff --git a/vendor/github.com/miekg/dns/udp_windows.go b/vendor/github.com/miekg/dns/udp_windows.go
deleted file mode 100644
index 51e532ac2..000000000
--- a/vendor/github.com/miekg/dns/udp_windows.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// +build windows
-
-package dns
-
-import "net"
-
-type SessionUDP struct {
- raddr *net.UDPAddr
-}
-
-func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
-
-// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
-// net.UDPAddr.
-func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
- n, raddr, err := conn.ReadFrom(b)
- if err != nil {
- return n, nil, err
- }
- session := &SessionUDP{raddr.(*net.UDPAddr)}
- return n, session, err
-}
-
-// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
-func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
- n, err := conn.WriteTo(b, session.raddr)
- return n, err
-}
-
diff --git a/vendor/github.com/miekg/dns/update.go b/vendor/github.com/miekg/dns/update.go
deleted file mode 100644
index e90c5c968..000000000
--- a/vendor/github.com/miekg/dns/update.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package dns
-
-// NameUsed sets the RRs in the prereq section to
-// "Name is in use" RRs. RFC 2136 section 2.4.4.
-func (u *Msg) NameUsed(rr []RR) {
- if u.Answer == nil {
- u.Answer = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}})
- }
-}
-
-// NameNotUsed sets the RRs in the prereq section to
-// "Name is in not use" RRs. RFC 2136 section 2.4.5.
-func (u *Msg) NameNotUsed(rr []RR) {
- if u.Answer == nil {
- u.Answer = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassNONE}})
- }
-}
-
-// Used sets the RRs in the prereq section to
-// "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2.
-func (u *Msg) Used(rr []RR) {
- if len(u.Question) == 0 {
- panic("dns: empty question section")
- }
- if u.Answer == nil {
- u.Answer = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- r.Header().Class = u.Question[0].Qclass
- u.Answer = append(u.Answer, r)
- }
-}
-
-// RRsetUsed sets the RRs in the prereq section to
-// "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1.
-func (u *Msg) RRsetUsed(rr []RR) {
- if u.Answer == nil {
- u.Answer = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}})
- }
-}
-
-// RRsetNotUsed sets the RRs in the prereq section to
-// "RRset does not exist" RRs. RFC 2136 section 2.4.3.
-func (u *Msg) RRsetNotUsed(rr []RR) {
- if u.Answer == nil {
- u.Answer = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassNONE}})
- }
-}
-
-// Insert creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1.
-func (u *Msg) Insert(rr []RR) {
- if len(u.Question) == 0 {
- panic("dns: empty question section")
- }
- if u.Ns == nil {
- u.Ns = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- r.Header().Class = u.Question[0].Qclass
- u.Ns = append(u.Ns, r)
- }
-}
-
-// RemoveRRset creates a dynamic update packet that deletes an RRset, see RFC 2136 section 2.5.2.
-func (u *Msg) RemoveRRset(rr []RR) {
- if u.Ns == nil {
- u.Ns = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}})
- }
-}
-
-// RemoveName creates a dynamic update packet that deletes all RRsets of a name, see RFC 2136 section 2.5.3
-func (u *Msg) RemoveName(rr []RR) {
- if u.Ns == nil {
- u.Ns = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}})
- }
-}
-
-// Remove creates a dynamic update packet deletes RR from a RRSset, see RFC 2136 section 2.5.4
-func (u *Msg) Remove(rr []RR) {
- if u.Ns == nil {
- u.Ns = make([]RR, 0, len(rr))
- }
- for _, r := range rr {
- r.Header().Class = ClassNONE
- r.Header().Ttl = 0
- u.Ns = append(u.Ns, r)
- }
-}
diff --git a/vendor/github.com/miekg/dns/update_test.go b/vendor/github.com/miekg/dns/update_test.go
deleted file mode 100644
index 12760a1ee..000000000
--- a/vendor/github.com/miekg/dns/update_test.go
+++ /dev/null
@@ -1,145 +0,0 @@
-package dns
-
-import (
- "bytes"
- "testing"
-)
-
-func TestDynamicUpdateParsing(t *testing.T) {
- prefix := "example.com. IN "
- for _, typ := range TypeToString {
- if typ == "OPT" || typ == "AXFR" || typ == "IXFR" || typ == "ANY" || typ == "TKEY" ||
- typ == "TSIG" || typ == "ISDN" || typ == "UNSPEC" || typ == "NULL" || typ == "ATMA" ||
- typ == "Reserved" || typ == "None" || typ == "NXT" || typ == "MAILB" || typ == "MAILA" {
- continue
- }
- r, err := NewRR(prefix + typ)
- if err != nil {
- t.Errorf("failure to parse: %s %s: %v", prefix, typ, err)
- } else {
- t.Logf("parsed: %s", r.String())
- }
- }
-}
-
-func TestDynamicUpdateUnpack(t *testing.T) {
- // From https://github.com/miekg/dns/issues/150#issuecomment-62296803
- // It should be an update message for the zone "example.",
- // deleting the A RRset "example." and then adding an A record at "example.".
- // class ANY, TYPE A
- buf := []byte{171, 68, 40, 0, 0, 1, 0, 0, 0, 2, 0, 0, 7, 101, 120, 97, 109, 112, 108, 101, 0, 0, 6, 0, 1, 192, 12, 0, 1, 0, 255, 0, 0, 0, 0, 0, 0, 192, 12, 0, 1, 0, 1, 0, 0, 0, 0, 0, 4, 127, 0, 0, 1}
- msg := new(Msg)
- err := msg.Unpack(buf)
- if err != nil {
- t.Errorf("failed to unpack: %v\n%s", err, msg.String())
- }
-}
-
-func TestDynamicUpdateZeroRdataUnpack(t *testing.T) {
- m := new(Msg)
- rr := &RR_Header{Name: ".", Rrtype: 0, Class: 1, Ttl: ^uint32(0), Rdlength: 0}
- m.Answer = []RR{rr, rr, rr, rr, rr}
- m.Ns = m.Answer
- for n, s := range TypeToString {
- rr.Rrtype = n
- bytes, err := m.Pack()
- if err != nil {
- t.Errorf("failed to pack %s: %v", s, err)
- continue
- }
- if err := new(Msg).Unpack(bytes); err != nil {
- t.Errorf("failed to unpack %s: %v", s, err)
- }
- }
-}
-
-func TestRemoveRRset(t *testing.T) {
- // Should add a zero data RR in Class ANY with a TTL of 0
- // for each set mentioned in the RRs provided to it.
- rr, err := NewRR(". 100 IN A 127.0.0.1")
- if err != nil {
- t.Fatalf("error constructing RR: %v", err)
- }
- m := new(Msg)
- m.Ns = []RR{&RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY, Ttl: 0, Rdlength: 0}}
- expectstr := m.String()
- expect, err := m.Pack()
- if err != nil {
- t.Fatalf("error packing expected msg: %v", err)
- }
-
- m.Ns = nil
- m.RemoveRRset([]RR{rr})
- actual, err := m.Pack()
- if err != nil {
- t.Fatalf("error packing actual msg: %v", err)
- }
- if !bytes.Equal(actual, expect) {
- tmp := new(Msg)
- if err := tmp.Unpack(actual); err != nil {
- t.Fatalf("error unpacking actual msg: %v\nexpected: %v\ngot: %v\n", err, expect, actual)
- }
- t.Errorf("expected msg:\n%s", expectstr)
- t.Errorf("actual msg:\n%v", tmp)
- }
-}
-
-func TestPreReqAndRemovals(t *testing.T) {
- // Build a list of multiple prereqs and then somes removes followed by an insert.
- // We should be able to add multiple prereqs and updates.
- m := new(Msg)
- m.SetUpdate("example.org.")
- m.Id = 1234
-
- // Use a full set of RRs each time, so we are sure the rdata is stripped.
- rrName1, _ := NewRR("name_used. 3600 IN A 127.0.0.1")
- rrName2, _ := NewRR("name_not_used. 3600 IN A 127.0.0.1")
- rrRemove1, _ := NewRR("remove1. 3600 IN A 127.0.0.1")
- rrRemove2, _ := NewRR("remove2. 3600 IN A 127.0.0.1")
- rrRemove3, _ := NewRR("remove3. 3600 IN A 127.0.0.1")
- rrInsert, _ := NewRR("insert. 3600 IN A 127.0.0.1")
- rrRrset1, _ := NewRR("rrset_used1. 3600 IN A 127.0.0.1")
- rrRrset2, _ := NewRR("rrset_used2. 3600 IN A 127.0.0.1")
- rrRrset3, _ := NewRR("rrset_not_used. 3600 IN A 127.0.0.1")
-
- // Handle the prereqs.
- m.NameUsed([]RR{rrName1})
- m.NameNotUsed([]RR{rrName2})
- m.RRsetUsed([]RR{rrRrset1})
- m.Used([]RR{rrRrset2})
- m.RRsetNotUsed([]RR{rrRrset3})
-
- // and now the updates.
- m.RemoveName([]RR{rrRemove1})
- m.RemoveRRset([]RR{rrRemove2})
- m.Remove([]RR{rrRemove3})
- m.Insert([]RR{rrInsert})
-
- // This test function isn't a Example function because we print these RR with tabs at the
- // end and the Example function trim these, thus they never match.
- // TODO(miek): don't print these tabs and make this into an Example function.
- expect := `;; opcode: UPDATE, status: NOERROR, id: 1234
-;; flags:; QUERY: 1, ANSWER: 5, AUTHORITY: 4, ADDITIONAL: 0
-
-;; QUESTION SECTION:
-;example.org. IN SOA
-
-;; ANSWER SECTION:
-name_used. 0 ANY ANY
-name_not_used. 0 NONE ANY
-rrset_used1. 0 ANY A
-rrset_used2. 3600 IN A 127.0.0.1
-rrset_not_used. 0 NONE A
-
-;; AUTHORITY SECTION:
-remove1. 0 ANY ANY
-remove2. 0 ANY A
-remove3. 0 NONE A 127.0.0.1
-insert. 3600 IN A 127.0.0.1
-`
-
- if m.String() != expect {
- t.Errorf("expected msg:\n%s", expect)
- t.Errorf("actual msg:\n%v", m.String())
- }
-}
diff --git a/vendor/github.com/miekg/dns/xfr.go b/vendor/github.com/miekg/dns/xfr.go
deleted file mode 100644
index 576c5590a..000000000
--- a/vendor/github.com/miekg/dns/xfr.go
+++ /dev/null
@@ -1,255 +0,0 @@
-package dns
-
-import (
- "fmt"
- "time"
-)
-
-// Envelope is used when doing a zone transfer with a remote server.
-type Envelope struct {
- RR []RR // The set of RRs in the answer section of the xfr reply message.
- Error error // If something went wrong, this contains the error.
-}
-
-// A Transfer defines parameters that are used during a zone transfer.
-type Transfer struct {
- *Conn
- DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds
- ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
- WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
- TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
- tsigTimersOnly bool
-}
-
-// Think we need to away to stop the transfer
-
-// In performs an incoming transfer with the server in a.
-// If you would like to set the source IP, or some other attribute
-// of a Dialer for a Transfer, you can do so by specifying the attributes
-// in the Transfer.Conn:
-//
-// d := net.Dialer{LocalAddr: transfer_source}
-// con, err := d.Dial("tcp", master)
-// dnscon := &dns.Conn{Conn:con}
-// transfer = &dns.Transfer{Conn: dnscon}
-// channel, err := transfer.In(message, master)
-//
-func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
- timeout := dnsTimeout
- if t.DialTimeout != 0 {
- timeout = t.DialTimeout
- }
- if t.Conn == nil {
- t.Conn, err = DialTimeout("tcp", a, timeout)
- if err != nil {
- return nil, err
- }
- }
- if err := t.WriteMsg(q); err != nil {
- return nil, err
- }
- env = make(chan *Envelope)
- go func() {
- if q.Question[0].Qtype == TypeAXFR {
- go t.inAxfr(q.Id, env)
- return
- }
- if q.Question[0].Qtype == TypeIXFR {
- go t.inIxfr(q.Id, env)
- return
- }
- }()
- return env, nil
-}
-
-func (t *Transfer) inAxfr(id uint16, c chan *Envelope) {
- first := true
- defer t.Close()
- defer close(c)
- timeout := dnsTimeout
- if t.ReadTimeout != 0 {
- timeout = t.ReadTimeout
- }
- for {
- t.Conn.SetReadDeadline(time.Now().Add(timeout))
- in, err := t.ReadMsg()
- if err != nil {
- c <- &Envelope{nil, err}
- return
- }
- if id != in.Id {
- c <- &Envelope{in.Answer, ErrId}
- return
- }
- if first {
- if in.Rcode != RcodeSuccess {
- c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
- return
- }
- if !isSOAFirst(in) {
- c <- &Envelope{in.Answer, ErrSoa}
- return
- }
- first = !first
- // only one answer that is SOA, receive more
- if len(in.Answer) == 1 {
- t.tsigTimersOnly = true
- c <- &Envelope{in.Answer, nil}
- continue
- }
- }
-
- if !first {
- t.tsigTimersOnly = true // Subsequent envelopes use this.
- if isSOALast(in) {
- c <- &Envelope{in.Answer, nil}
- return
- }
- c <- &Envelope{in.Answer, nil}
- }
- }
-}
-
-func (t *Transfer) inIxfr(id uint16, c chan *Envelope) {
- serial := uint32(0) // The first serial seen is the current server serial
- first := true
- defer t.Close()
- defer close(c)
- timeout := dnsTimeout
- if t.ReadTimeout != 0 {
- timeout = t.ReadTimeout
- }
- for {
- t.SetReadDeadline(time.Now().Add(timeout))
- in, err := t.ReadMsg()
- if err != nil {
- c <- &Envelope{nil, err}
- return
- }
- if id != in.Id {
- c <- &Envelope{in.Answer, ErrId}
- return
- }
- if first {
- if in.Rcode != RcodeSuccess {
- c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
- return
- }
- // A single SOA RR signals "no changes"
- if len(in.Answer) == 1 && isSOAFirst(in) {
- c <- &Envelope{in.Answer, nil}
- return
- }
-
- // Check if the returned answer is ok
- if !isSOAFirst(in) {
- c <- &Envelope{in.Answer, ErrSoa}
- return
- }
- // This serial is important
- serial = in.Answer[0].(*SOA).Serial
- first = !first
- }
-
- // Now we need to check each message for SOA records, to see what we need to do
- if !first {
- t.tsigTimersOnly = true
- // If the last record in the IXFR contains the servers' SOA, we should quit
- if v, ok := in.Answer[len(in.Answer)-1].(*SOA); ok {
- if v.Serial == serial {
- c <- &Envelope{in.Answer, nil}
- return
- }
- }
- c <- &Envelope{in.Answer, nil}
- }
- }
-}
-
-// Out performs an outgoing transfer with the client connecting in w.
-// Basic use pattern:
-//
-// ch := make(chan *dns.Envelope)
-// tr := new(dns.Transfer)
-// go tr.Out(w, r, ch)
-// ch <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}}
-// close(ch)
-// w.Hijack()
-// // w.Close() // Client closes connection
-//
-// The server is responsible for sending the correct sequence of RRs through the
-// channel ch.
-func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error {
- for x := range ch {
- r := new(Msg)
- // Compress?
- r.SetReply(q)
- r.Authoritative = true
- // assume it fits TODO(miek): fix
- r.Answer = append(r.Answer, x.RR...)
- if err := w.WriteMsg(r); err != nil {
- return err
- }
- }
- w.TsigTimersOnly(true)
- return nil
-}
-
-// ReadMsg reads a message from the transfer connection t.
-func (t *Transfer) ReadMsg() (*Msg, error) {
- m := new(Msg)
- p := make([]byte, MaxMsgSize)
- n, err := t.Read(p)
- if err != nil && n == 0 {
- return nil, err
- }
- p = p[:n]
- if err := m.Unpack(p); err != nil {
- return nil, err
- }
- if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil {
- if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
- return m, ErrSecret
- }
- // Need to work on the original message p, as that was used to calculate the tsig.
- err = TsigVerify(p, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
- t.tsigRequestMAC = ts.MAC
- }
- return m, err
-}
-
-// WriteMsg writes a message through the transfer connection t.
-func (t *Transfer) WriteMsg(m *Msg) (err error) {
- var out []byte
- if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil {
- if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
- return ErrSecret
- }
- out, t.tsigRequestMAC, err = TsigGenerate(m, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
- } else {
- out, err = m.Pack()
- }
- if err != nil {
- return err
- }
- if _, err = t.Write(out); err != nil {
- return err
- }
- return nil
-}
-
-func isSOAFirst(in *Msg) bool {
- if len(in.Answer) > 0 {
- return in.Answer[0].Header().Rrtype == TypeSOA
- }
- return false
-}
-
-func isSOALast(in *Msg) bool {
- if len(in.Answer) > 0 {
- return in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA
- }
- return false
-}
-
-const errXFR = "bad xfr rcode: %d"
diff --git a/vendor/github.com/miekg/dns/xfr_test.go b/vendor/github.com/miekg/dns/xfr_test.go
deleted file mode 100644
index a478963a3..000000000
--- a/vendor/github.com/miekg/dns/xfr_test.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// +build net
-
-package dns
-
-import (
- "net"
- "strings"
- "testing"
- "time"
-)
-
-func getIP(s string) string {
- a, err := net.LookupAddr(s)
- if err != nil {
- return ""
- }
- return a[0]
-}
-
-// flaky, need to setup local server and test from that.
-func TestAXFR_Miek(t *testing.T) {
- // This test runs against a server maintained by Miek
- if testing.Short() {
- return
- }
- m := new(Msg)
- m.SetAxfr("miek.nl.")
-
- server := getIP("linode.atoom.net")
-
- tr := new(Transfer)
-
- if a, err := tr.In(m, net.JoinHostPort(server, "53")); err != nil {
- t.Fatal("failed to setup axfr: ", err)
- } else {
- for ex := range a {
- if ex.Error != nil {
- t.Errorf("error %v", ex.Error)
- break
- }
- for _, rr := range ex.RR {
- t.Log(rr.String())
- }
- }
- }
-}
-
-// fails.
-func TestAXFR_NLNL_MultipleEnvelopes(t *testing.T) {
- // This test runs against a server maintained by NLnet Labs
- if testing.Short() {
- return
- }
- m := new(Msg)
- m.SetAxfr("nlnetlabs.nl.")
-
- server := getIP("open.nlnetlabs.nl.")
-
- tr := new(Transfer)
- if a, err := tr.In(m, net.JoinHostPort(server, "53")); err != nil {
- t.Fatalf("failed to setup axfr %v for server: %v", err, server)
- } else {
- for ex := range a {
- if ex.Error != nil {
- t.Errorf("error %v", ex.Error)
- break
- }
- }
- }
-}
-
-func TestAXFR_Miek_Tsig(t *testing.T) {
- // This test runs against a server maintained by Miek
- if testing.Short() {
- return
- }
- m := new(Msg)
- m.SetAxfr("example.nl.")
- m.SetTsig("axfr.", HmacMD5, 300, time.Now().Unix())
-
- tr := new(Transfer)
- tr.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
-
- if a, err := tr.In(m, "176.58.119.54:53"); err != nil {
- t.Fatal("failed to setup axfr: ", err)
- } else {
- for ex := range a {
- if ex.Error != nil {
- t.Errorf("error %v", ex.Error)
- break
- }
- for _, rr := range ex.RR {
- t.Log(rr.String())
- }
- }
- }
-}
-
-func TestAXFR_SIDN_NSD3_NONE(t *testing.T) { testAXFRSIDN(t, "nsd", "") }
-func TestAXFR_SIDN_NSD3_MD5(t *testing.T) { testAXFRSIDN(t, "nsd", HmacMD5) }
-func TestAXFR_SIDN_NSD3_SHA1(t *testing.T) { testAXFRSIDN(t, "nsd", HmacSHA1) }
-func TestAXFR_SIDN_NSD3_SHA256(t *testing.T) { testAXFRSIDN(t, "nsd", HmacSHA256) }
-
-func TestAXFR_SIDN_NSD4_NONE(t *testing.T) { testAXFRSIDN(t, "nsd4", "") }
-func TestAXFR_SIDN_NSD4_MD5(t *testing.T) { testAXFRSIDN(t, "nsd4", HmacMD5) }
-func TestAXFR_SIDN_NSD4_SHA1(t *testing.T) { testAXFRSIDN(t, "nsd4", HmacSHA1) }
-func TestAXFR_SIDN_NSD4_SHA256(t *testing.T) { testAXFRSIDN(t, "nsd4", HmacSHA256) }
-
-func TestAXFR_SIDN_BIND9_NONE(t *testing.T) { testAXFRSIDN(t, "bind9", "") }
-func TestAXFR_SIDN_BIND9_MD5(t *testing.T) { testAXFRSIDN(t, "bind9", HmacMD5) }
-func TestAXFR_SIDN_BIND9_SHA1(t *testing.T) { testAXFRSIDN(t, "bind9", HmacSHA1) }
-func TestAXFR_SIDN_BIND9_SHA256(t *testing.T) { testAXFRSIDN(t, "bind9", HmacSHA256) }
-
-func TestAXFR_SIDN_KNOT_NONE(t *testing.T) { testAXFRSIDN(t, "knot", "") }
-func TestAXFR_SIDN_KNOT_MD5(t *testing.T) { testAXFRSIDN(t, "knot", HmacMD5) }
-func TestAXFR_SIDN_KNOT_SHA1(t *testing.T) { testAXFRSIDN(t, "knot", HmacSHA1) }
-func TestAXFR_SIDN_KNOT_SHA256(t *testing.T) { testAXFRSIDN(t, "knot", HmacSHA256) }
-
-func TestAXFR_SIDN_POWERDNS_NONE(t *testing.T) { testAXFRSIDN(t, "powerdns", "") }
-func TestAXFR_SIDN_POWERDNS_MD5(t *testing.T) { testAXFRSIDN(t, "powerdns", HmacMD5) }
-func TestAXFR_SIDN_POWERDNS_SHA1(t *testing.T) { testAXFRSIDN(t, "powerdns", HmacSHA1) }
-func TestAXFR_SIDN_POWERDNS_SHA256(t *testing.T) { testAXFRSIDN(t, "powerdns", HmacSHA256) }
-
-func TestAXFR_SIDN_YADIFA_NONE(t *testing.T) { testAXFRSIDN(t, "yadifa", "") }
-func TestAXFR_SIDN_YADIFA_MD5(t *testing.T) { testAXFRSIDN(t, "yadifa", HmacMD5) }
-func TestAXFR_SIDN_YADIFA_SHA1(t *testing.T) { testAXFRSIDN(t, "yadifa", HmacSHA1) }
-func TestAXFR_SIDN_YADIFA_SHA256(t *testing.T) { testAXFRSIDN(t, "yadifa", HmacSHA256) }
-
-func testAXFRSIDN(t *testing.T, host, alg string) {
- // This tests run against a server maintained by SIDN labs, see:
- // https://workbench.sidnlabs.nl/
- if testing.Short() {
- return
- }
- x := new(Transfer)
- x.TsigSecret = map[string]string{
- "wb_md5.": "Wu/utSasZUkoeCNku152Zw==",
- "wb_sha1_longkey.": "uhMpEhPq/RAD9Bt4mqhfmi+7ZdKmjLQb/lcrqYPXR4s/nnbsqw==",
- "wb_sha256.": "npfrIJjt/MJOjGJoBNZtsjftKMhkSpIYMv2RzRZt1f8=",
- }
- keyname := map[string]string{
- HmacMD5: "wb_md5.",
- HmacSHA1: "wb_sha1_longkey.",
- HmacSHA256: "wb_sha256.",
- }[alg]
-
- m := new(Msg)
- m.SetAxfr("types.wb.sidnlabs.nl.")
- if keyname != "" {
- m.SetTsig(keyname, alg, 300, time.Now().Unix())
- }
- c, err := x.In(m, host+".sidnlabs.nl:53")
- if err != nil {
- t.Fatal(err)
- }
- for e := range c {
- if e.Error != nil {
- t.Fatal(e.Error)
- }
- }
-}
-
-func TestAXFRFailNotAuth(t *testing.T) {
- // This tests run against a server maintained by SIDN labs, see:
- // https://workbench.sidnlabs.nl/
- if testing.Short() {
- return
- }
- x := new(Transfer)
-
- m := new(Msg)
- m.SetAxfr("sidnlabs.nl.")
- c, err := x.In(m, "yadifa.sidnlabs.nl:53")
- if err != nil {
- t.Fatal(err)
- }
- for e := range c {
- if e.Error != nil {
- if !strings.HasPrefix(e.Error.Error(), "dns: bad xfr rcode:") {
- t.Fatal(e.Error)
- }
- }
- }
-}
diff --git a/vendor/github.com/miekg/dns/zcompress.go b/vendor/github.com/miekg/dns/zcompress.go
deleted file mode 100644
index b277978b9..000000000
--- a/vendor/github.com/miekg/dns/zcompress.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// *** DO NOT MODIFY ***
-// AUTOGENERATED BY go generate from compress_generate.go
-
-package dns
-
-func compressionLenHelperType(c map[string]int, r RR) {
- switch x := r.(type) {
- case *PTR:
- compressionLenHelper(c, x.Ptr)
- case *SOA:
- compressionLenHelper(c, x.Ns)
- compressionLenHelper(c, x.Mbox)
- case *AFSDB:
- compressionLenHelper(c, x.Hostname)
- case *HIP:
- for i := range x.RendezvousServers {
- compressionLenHelper(c, x.RendezvousServers[i])
- }
- case *LP:
- compressionLenHelper(c, x.Fqdn)
- case *CNAME:
- compressionLenHelper(c, x.Target)
- case *MB:
- compressionLenHelper(c, x.Mb)
- case *RP:
- compressionLenHelper(c, x.Mbox)
- compressionLenHelper(c, x.Txt)
- case *RRSIG:
- compressionLenHelper(c, x.SignerName)
- case *MF:
- compressionLenHelper(c, x.Mf)
- case *MINFO:
- compressionLenHelper(c, x.Rmail)
- compressionLenHelper(c, x.Email)
- case *SIG:
- compressionLenHelper(c, x.SignerName)
- case *SRV:
- compressionLenHelper(c, x.Target)
- case *TSIG:
- compressionLenHelper(c, x.Algorithm)
- case *KX:
- compressionLenHelper(c, x.Exchanger)
- case *MG:
- compressionLenHelper(c, x.Mg)
- case *NSAPPTR:
- compressionLenHelper(c, x.Ptr)
- case *PX:
- compressionLenHelper(c, x.Map822)
- compressionLenHelper(c, x.Mapx400)
- case *DNAME:
- compressionLenHelper(c, x.Target)
- case *MR:
- compressionLenHelper(c, x.Mr)
- case *MX:
- compressionLenHelper(c, x.Mx)
- case *TKEY:
- compressionLenHelper(c, x.Algorithm)
- case *NSEC:
- compressionLenHelper(c, x.NextDomain)
- case *TALINK:
- compressionLenHelper(c, x.PreviousName)
- compressionLenHelper(c, x.NextName)
- case *MD:
- compressionLenHelper(c, x.Md)
- case *NAPTR:
- compressionLenHelper(c, x.Replacement)
- case *NS:
- compressionLenHelper(c, x.Ns)
- case *RT:
- compressionLenHelper(c, x.Host)
- }
-}
-
-func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
- switch x := r.(type) {
- case *MG:
- k1, ok1 := compressionLenSearch(c, x.Mg)
- return k1, ok1
- case *PTR:
- k1, ok1 := compressionLenSearch(c, x.Ptr)
- return k1, ok1
- case *AFSDB:
- k1, ok1 := compressionLenSearch(c, x.Hostname)
- return k1, ok1
- case *MB:
- k1, ok1 := compressionLenSearch(c, x.Mb)
- return k1, ok1
- case *MD:
- k1, ok1 := compressionLenSearch(c, x.Md)
- return k1, ok1
- case *MF:
- k1, ok1 := compressionLenSearch(c, x.Mf)
- return k1, ok1
- case *NS:
- k1, ok1 := compressionLenSearch(c, x.Ns)
- return k1, ok1
- case *RT:
- k1, ok1 := compressionLenSearch(c, x.Host)
- return k1, ok1
- case *SOA:
- k1, ok1 := compressionLenSearch(c, x.Ns)
- k2, ok2 := compressionLenSearch(c, x.Mbox)
- return k1 + k2, ok1 && ok2
- case *CNAME:
- k1, ok1 := compressionLenSearch(c, x.Target)
- return k1, ok1
- case *MINFO:
- k1, ok1 := compressionLenSearch(c, x.Rmail)
- k2, ok2 := compressionLenSearch(c, x.Email)
- return k1 + k2, ok1 && ok2
- case *MR:
- k1, ok1 := compressionLenSearch(c, x.Mr)
- return k1, ok1
- case *MX:
- k1, ok1 := compressionLenSearch(c, x.Mx)
- return k1, ok1
- }
- return 0, false
-}
diff --git a/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/miekg/dns/zmsg.go
deleted file mode 100644
index 418fb1fe3..000000000
--- a/vendor/github.com/miekg/dns/zmsg.go
+++ /dev/null
@@ -1,3565 +0,0 @@
-// *** DO NOT MODIFY ***
-// AUTOGENERATED BY go generate from msg_generate.go
-
-package dns
-
-// pack*() functions
-
-func (rr *A) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packDataA(rr.A, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *AAAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packDataAAAA(rr.AAAA, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *AFSDB) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Subtype, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Hostname, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *ANY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *AVC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringTxt(rr.Txt, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint8(rr.Flag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.Tag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringOctet(rr.Value, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *CDNSKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Flags, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Protocol, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(rr.PublicKey, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *CDS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.KeyTag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.DigestType, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.Digest, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *CERT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Type, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.KeyTag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(rr.Certificate, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *CNAME) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Target, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *DHCID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringBase64(rr.Digest, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *DLV) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.KeyTag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.DigestType, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.Digest, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *DNAME) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Target, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *DNSKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Flags, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Protocol, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(rr.PublicKey, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *DS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.KeyTag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.DigestType, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.Digest, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *EID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringHex(rr.Endpoint, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *EUI48) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint48(rr.Address, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *EUI64) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint64(rr.Address, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *GID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint32(rr.Gid, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *GPOS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packString(rr.Longitude, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.Latitude, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.Altitude, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *HINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packString(rr.Cpu, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.Os, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *HIP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint8(rr.HitLength, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.PublicKeyAlgorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.PublicKeyLength, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.Hit, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(rr.PublicKey, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *KEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Flags, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Protocol, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(rr.PublicKey, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *KX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Exchanger, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *L32) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packDataA(rr.Locator32, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *L64) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint64(rr.Locator64, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *LOC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint8(rr.Version, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Size, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.HorizPre, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.VertPre, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Latitude, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Longitude, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Altitude, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *LP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Fqdn, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *MB) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Mb, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *MD) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Md, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *MF) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Mf, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *MG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Mg, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *MINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Rmail, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Email, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *MR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Mr, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *MX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Mx, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NAPTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Order, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.Flags, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.Service, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.Regexp, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Replacement, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint64(rr.NodeID, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NIMLOC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringHex(rr.Locator, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringTxt(rr.ZSData, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Ns, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NSAPPTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Ptr, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NSEC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.NextDomain, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- off, err = packDataNsec(rr.TypeBitMap, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint8(rr.Hash, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Flags, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Iterations, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.SaltLength, msg, off)
- if err != nil {
- return off, err
- }
- // Only pack salt if value is not "-", i.e. empty
- if rr.Salt != "-" {
- off, err = packStringHex(rr.Salt, msg, off)
- if err != nil {
- return off, err
- }
- }
- off, err = packUint8(rr.HashLength, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringBase32(rr.NextDomain, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packDataNsec(rr.TypeBitMap, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint8(rr.Hash, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Flags, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Iterations, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.SaltLength, msg, off)
- if err != nil {
- return off, err
- }
- // Only pack salt if value is not "-", i.e. empty
- if rr.Salt != "-" {
- off, err = packStringHex(rr.Salt, msg, off)
- if err != nil {
- return off, err
- }
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *OPENPGPKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringBase64(rr.PublicKey, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *OPT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packDataOpt(rr.Option, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *PTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Ptr, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *PX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Map822, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Mapx400, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *RFC3597) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringHex(rr.Rdata, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *RKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Flags, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Protocol, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(rr.PublicKey, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *RP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Mbox, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Txt, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *RRSIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.TypeCovered, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Labels, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.OrigTtl, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Expiration, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Inception, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.KeyTag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.SignerName, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(rr.Signature, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *RT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Preference, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Host, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.TypeCovered, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Labels, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.OrigTtl, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Expiration, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Inception, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.KeyTag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.SignerName, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- off, err = packStringBase64(rr.Signature, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *SMIMEA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint8(rr.Usage, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Selector, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.MatchingType, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.Certificate, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *SOA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Ns, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Mbox, msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Serial, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Refresh, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Retry, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Expire, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Minttl, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *SPF) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringTxt(rr.Txt, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *SRV) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Priority, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Weight, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Port, msg, off)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.Target, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *SSHFP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Type, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.FingerPrint, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *TA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.KeyTag, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Algorithm, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.DigestType, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.Digest, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *TALINK) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.PreviousName, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- off, err = PackDomainName(rr.NextName, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Algorithm, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Inception, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint32(rr.Expiration, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Mode, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Error, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.KeySize, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.Key, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.OtherLen, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packString(rr.OtherData, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *TLSA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint8(rr.Usage, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.Selector, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint8(rr.MatchingType, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.Certificate, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = PackDomainName(rr.Algorithm, msg, off, compression, false)
- if err != nil {
- return off, err
- }
- off, err = packUint48(rr.TimeSigned, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Fudge, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.MACSize, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.MAC, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.OrigId, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Error, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.OtherLen, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringHex(rr.OtherData, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *TXT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packStringTxt(rr.Txt, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *UID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint32(rr.Uid, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *UINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packString(rr.Uinfo, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *URI) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packUint16(rr.Priority, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packUint16(rr.Weight, msg, off)
- if err != nil {
- return off, err
- }
- off, err = packStringOctet(rr.Target, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-func (rr *X25) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
- off, err := rr.Hdr.pack(msg, off, compression, compress)
- if err != nil {
- return off, err
- }
- headerEnd := off
- off, err = packString(rr.PSDNAddress, msg, off)
- if err != nil {
- return off, err
- }
- rr.Header().Rdlength = uint16(off - headerEnd)
- return off, nil
-}
-
-// unpack*() functions
-
-func unpackA(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(A)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.A, off, err = unpackDataA(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackAAAA(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(AAAA)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.AAAA, off, err = unpackDataAAAA(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackAFSDB(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(AFSDB)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Subtype, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Hostname, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(ANY)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- return rr, off, err
-}
-
-func unpackAVC(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(AVC)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Txt, off, err = unpackStringTxt(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(CAA)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Flag, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Tag, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Value, off, err = unpackStringOctet(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackCDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(CDNSKEY)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Flags, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Protocol, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackCDS(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(CDS)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.KeyTag, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.DigestType, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackCERT(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(CERT)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Type, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.KeyTag, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Certificate, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackCNAME(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(CNAME)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Target, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackDHCID(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(DHCID)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Digest, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackDLV(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(DLV)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.KeyTag, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.DigestType, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackDNAME(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(DNAME)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Target, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(DNSKEY)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Flags, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Protocol, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackDS(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(DS)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.KeyTag, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.DigestType, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackEID(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(EID)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Endpoint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackEUI48(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(EUI48)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Address, off, err = unpackUint48(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackEUI64(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(EUI64)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Address, off, err = unpackUint64(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackGID(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(GID)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Gid, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackGPOS(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(GPOS)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Longitude, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Latitude, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Altitude, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackHINFO(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(HINFO)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Cpu, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Os, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackHIP(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(HIP)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.HitLength, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.PublicKeyAlgorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.PublicKeyLength, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Hit, off, err = unpackStringHex(msg, off, off+int(rr.HitLength))
- if err != nil {
- return rr, off, err
- }
- rr.PublicKey, off, err = unpackStringBase64(msg, off, off+int(rr.PublicKeyLength))
- if err != nil {
- return rr, off, err
- }
- rr.RendezvousServers, off, err = unpackDataDomainNames(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(KEY)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Flags, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Protocol, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackKX(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(KX)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Exchanger, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackL32(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(L32)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Locator32, off, err = unpackDataA(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackL64(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(L64)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Locator64, off, err = unpackUint64(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackLOC(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(LOC)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Version, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Size, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.HorizPre, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.VertPre, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Latitude, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Longitude, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Altitude, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackLP(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(LP)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Fqdn, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackMB(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(MB)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Mb, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackMD(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(MD)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Md, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackMF(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(MF)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Mf, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackMG(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(MG)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Mg, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackMINFO(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(MINFO)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Rmail, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Email, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackMR(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(MR)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Mr, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackMX(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(MX)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Mx, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNAPTR(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NAPTR)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Order, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Flags, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Service, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Regexp, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Replacement, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNID(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NID)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.NodeID, off, err = unpackUint64(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNIMLOC(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NIMLOC)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Locator, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNINFO(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NINFO)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.ZSData, off, err = unpackStringTxt(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNS(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NS)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Ns, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNSAPPTR(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NSAPPTR)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Ptr, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNSEC(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NSEC)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.NextDomain, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNSEC3(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NSEC3)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Hash, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Flags, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Iterations, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.SaltLength, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength))
- if err != nil {
- return rr, off, err
- }
- rr.HashLength, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.NextDomain, off, err = unpackStringBase32(msg, off, off+int(rr.HashLength))
- if err != nil {
- return rr, off, err
- }
- rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackNSEC3PARAM(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(NSEC3PARAM)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Hash, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Flags, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Iterations, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.SaltLength, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackOPENPGPKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(OPENPGPKEY)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackOPT(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(OPT)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Option, off, err = unpackDataOpt(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackPTR(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(PTR)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Ptr, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackPX(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(PX)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Map822, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Mapx400, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackRFC3597(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(RFC3597)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Rdata, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackRKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(RKEY)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Flags, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Protocol, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackRP(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(RP)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Mbox, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Txt, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackRRSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(RRSIG)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.TypeCovered, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Labels, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.OrigTtl, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Expiration, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Inception, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.KeyTag, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.SignerName, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackRT(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(RT)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Preference, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Host, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(SIG)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.TypeCovered, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Labels, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.OrigTtl, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Expiration, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Inception, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.KeyTag, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.SignerName, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackSMIMEA(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(SMIMEA)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Usage, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Selector, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.MatchingType, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackSOA(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(SOA)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Ns, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Mbox, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Serial, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Refresh, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Retry, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Expire, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Minttl, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackSPF(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(SPF)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Txt, off, err = unpackStringTxt(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackSRV(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(SRV)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Priority, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Weight, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Port, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Target, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackSSHFP(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(SSHFP)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Type, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.FingerPrint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackTA(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(TA)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.KeyTag, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Algorithm, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.DigestType, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackTALINK(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(TALINK)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.PreviousName, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.NextName, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackTKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(TKEY)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Algorithm, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Inception, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Expiration, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Mode, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Error, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.KeySize, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Key, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.OtherLen, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.OtherData, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackTLSA(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(TLSA)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Usage, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Selector, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.MatchingType, off, err = unpackUint8(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackTSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(TSIG)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Algorithm, off, err = UnpackDomainName(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.TimeSigned, off, err = unpackUint48(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Fudge, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.MACSize, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.MAC, off, err = unpackStringHex(msg, off, off+int(rr.MACSize))
- if err != nil {
- return rr, off, err
- }
- rr.OrigId, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Error, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.OtherLen, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen))
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackTXT(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(TXT)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Txt, off, err = unpackStringTxt(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackUID(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(UID)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Uid, off, err = unpackUint32(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackUINFO(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(UINFO)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Uinfo, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackURI(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(URI)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.Priority, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Weight, off, err = unpackUint16(msg, off)
- if err != nil {
- return rr, off, err
- }
- if off == len(msg) {
- return rr, off, nil
- }
- rr.Target, off, err = unpackStringOctet(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-func unpackX25(h RR_Header, msg []byte, off int) (RR, int, error) {
- rr := new(X25)
- rr.Hdr = h
- if noRdata(h) {
- return rr, off, nil
- }
- var err error
- rdStart := off
- _ = rdStart
-
- rr.PSDNAddress, off, err = unpackString(msg, off)
- if err != nil {
- return rr, off, err
- }
- return rr, off, err
-}
-
-var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
- TypeA: unpackA,
- TypeAAAA: unpackAAAA,
- TypeAFSDB: unpackAFSDB,
- TypeANY: unpackANY,
- TypeAVC: unpackAVC,
- TypeCAA: unpackCAA,
- TypeCDNSKEY: unpackCDNSKEY,
- TypeCDS: unpackCDS,
- TypeCERT: unpackCERT,
- TypeCNAME: unpackCNAME,
- TypeDHCID: unpackDHCID,
- TypeDLV: unpackDLV,
- TypeDNAME: unpackDNAME,
- TypeDNSKEY: unpackDNSKEY,
- TypeDS: unpackDS,
- TypeEID: unpackEID,
- TypeEUI48: unpackEUI48,
- TypeEUI64: unpackEUI64,
- TypeGID: unpackGID,
- TypeGPOS: unpackGPOS,
- TypeHINFO: unpackHINFO,
- TypeHIP: unpackHIP,
- TypeKEY: unpackKEY,
- TypeKX: unpackKX,
- TypeL32: unpackL32,
- TypeL64: unpackL64,
- TypeLOC: unpackLOC,
- TypeLP: unpackLP,
- TypeMB: unpackMB,
- TypeMD: unpackMD,
- TypeMF: unpackMF,
- TypeMG: unpackMG,
- TypeMINFO: unpackMINFO,
- TypeMR: unpackMR,
- TypeMX: unpackMX,
- TypeNAPTR: unpackNAPTR,
- TypeNID: unpackNID,
- TypeNIMLOC: unpackNIMLOC,
- TypeNINFO: unpackNINFO,
- TypeNS: unpackNS,
- TypeNSAPPTR: unpackNSAPPTR,
- TypeNSEC: unpackNSEC,
- TypeNSEC3: unpackNSEC3,
- TypeNSEC3PARAM: unpackNSEC3PARAM,
- TypeOPENPGPKEY: unpackOPENPGPKEY,
- TypeOPT: unpackOPT,
- TypePTR: unpackPTR,
- TypePX: unpackPX,
- TypeRKEY: unpackRKEY,
- TypeRP: unpackRP,
- TypeRRSIG: unpackRRSIG,
- TypeRT: unpackRT,
- TypeSIG: unpackSIG,
- TypeSMIMEA: unpackSMIMEA,
- TypeSOA: unpackSOA,
- TypeSPF: unpackSPF,
- TypeSRV: unpackSRV,
- TypeSSHFP: unpackSSHFP,
- TypeTA: unpackTA,
- TypeTALINK: unpackTALINK,
- TypeTKEY: unpackTKEY,
- TypeTLSA: unpackTLSA,
- TypeTSIG: unpackTSIG,
- TypeTXT: unpackTXT,
- TypeUID: unpackUID,
- TypeUINFO: unpackUINFO,
- TypeURI: unpackURI,
- TypeX25: unpackX25,
-}
diff --git a/vendor/github.com/miekg/dns/ztypes.go b/vendor/github.com/miekg/dns/ztypes.go
deleted file mode 100644
index 3e534f12e..000000000
--- a/vendor/github.com/miekg/dns/ztypes.go
+++ /dev/null
@@ -1,857 +0,0 @@
-// *** DO NOT MODIFY ***
-// AUTOGENERATED BY go generate from type_generate.go
-
-package dns
-
-import (
- "encoding/base64"
- "net"
-)
-
-// TypeToRR is a map of constructors for each RR type.
-var TypeToRR = map[uint16]func() RR{
- TypeA: func() RR { return new(A) },
- TypeAAAA: func() RR { return new(AAAA) },
- TypeAFSDB: func() RR { return new(AFSDB) },
- TypeANY: func() RR { return new(ANY) },
- TypeAVC: func() RR { return new(AVC) },
- TypeCAA: func() RR { return new(CAA) },
- TypeCDNSKEY: func() RR { return new(CDNSKEY) },
- TypeCDS: func() RR { return new(CDS) },
- TypeCERT: func() RR { return new(CERT) },
- TypeCNAME: func() RR { return new(CNAME) },
- TypeDHCID: func() RR { return new(DHCID) },
- TypeDLV: func() RR { return new(DLV) },
- TypeDNAME: func() RR { return new(DNAME) },
- TypeDNSKEY: func() RR { return new(DNSKEY) },
- TypeDS: func() RR { return new(DS) },
- TypeEID: func() RR { return new(EID) },
- TypeEUI48: func() RR { return new(EUI48) },
- TypeEUI64: func() RR { return new(EUI64) },
- TypeGID: func() RR { return new(GID) },
- TypeGPOS: func() RR { return new(GPOS) },
- TypeHINFO: func() RR { return new(HINFO) },
- TypeHIP: func() RR { return new(HIP) },
- TypeKEY: func() RR { return new(KEY) },
- TypeKX: func() RR { return new(KX) },
- TypeL32: func() RR { return new(L32) },
- TypeL64: func() RR { return new(L64) },
- TypeLOC: func() RR { return new(LOC) },
- TypeLP: func() RR { return new(LP) },
- TypeMB: func() RR { return new(MB) },
- TypeMD: func() RR { return new(MD) },
- TypeMF: func() RR { return new(MF) },
- TypeMG: func() RR { return new(MG) },
- TypeMINFO: func() RR { return new(MINFO) },
- TypeMR: func() RR { return new(MR) },
- TypeMX: func() RR { return new(MX) },
- TypeNAPTR: func() RR { return new(NAPTR) },
- TypeNID: func() RR { return new(NID) },
- TypeNIMLOC: func() RR { return new(NIMLOC) },
- TypeNINFO: func() RR { return new(NINFO) },
- TypeNS: func() RR { return new(NS) },
- TypeNSAPPTR: func() RR { return new(NSAPPTR) },
- TypeNSEC: func() RR { return new(NSEC) },
- TypeNSEC3: func() RR { return new(NSEC3) },
- TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
- TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
- TypeOPT: func() RR { return new(OPT) },
- TypePTR: func() RR { return new(PTR) },
- TypePX: func() RR { return new(PX) },
- TypeRKEY: func() RR { return new(RKEY) },
- TypeRP: func() RR { return new(RP) },
- TypeRRSIG: func() RR { return new(RRSIG) },
- TypeRT: func() RR { return new(RT) },
- TypeSIG: func() RR { return new(SIG) },
- TypeSMIMEA: func() RR { return new(SMIMEA) },
- TypeSOA: func() RR { return new(SOA) },
- TypeSPF: func() RR { return new(SPF) },
- TypeSRV: func() RR { return new(SRV) },
- TypeSSHFP: func() RR { return new(SSHFP) },
- TypeTA: func() RR { return new(TA) },
- TypeTALINK: func() RR { return new(TALINK) },
- TypeTKEY: func() RR { return new(TKEY) },
- TypeTLSA: func() RR { return new(TLSA) },
- TypeTSIG: func() RR { return new(TSIG) },
- TypeTXT: func() RR { return new(TXT) },
- TypeUID: func() RR { return new(UID) },
- TypeUINFO: func() RR { return new(UINFO) },
- TypeURI: func() RR { return new(URI) },
- TypeX25: func() RR { return new(X25) },
-}
-
-// TypeToString is a map of strings for each RR type.
-var TypeToString = map[uint16]string{
- TypeA: "A",
- TypeAAAA: "AAAA",
- TypeAFSDB: "AFSDB",
- TypeANY: "ANY",
- TypeATMA: "ATMA",
- TypeAVC: "AVC",
- TypeAXFR: "AXFR",
- TypeCAA: "CAA",
- TypeCDNSKEY: "CDNSKEY",
- TypeCDS: "CDS",
- TypeCERT: "CERT",
- TypeCNAME: "CNAME",
- TypeDHCID: "DHCID",
- TypeDLV: "DLV",
- TypeDNAME: "DNAME",
- TypeDNSKEY: "DNSKEY",
- TypeDS: "DS",
- TypeEID: "EID",
- TypeEUI48: "EUI48",
- TypeEUI64: "EUI64",
- TypeGID: "GID",
- TypeGPOS: "GPOS",
- TypeHINFO: "HINFO",
- TypeHIP: "HIP",
- TypeISDN: "ISDN",
- TypeIXFR: "IXFR",
- TypeKEY: "KEY",
- TypeKX: "KX",
- TypeL32: "L32",
- TypeL64: "L64",
- TypeLOC: "LOC",
- TypeLP: "LP",
- TypeMAILA: "MAILA",
- TypeMAILB: "MAILB",
- TypeMB: "MB",
- TypeMD: "MD",
- TypeMF: "MF",
- TypeMG: "MG",
- TypeMINFO: "MINFO",
- TypeMR: "MR",
- TypeMX: "MX",
- TypeNAPTR: "NAPTR",
- TypeNID: "NID",
- TypeNIMLOC: "NIMLOC",
- TypeNINFO: "NINFO",
- TypeNS: "NS",
- TypeNSEC: "NSEC",
- TypeNSEC3: "NSEC3",
- TypeNSEC3PARAM: "NSEC3PARAM",
- TypeNULL: "NULL",
- TypeNXT: "NXT",
- TypeNone: "None",
- TypeOPENPGPKEY: "OPENPGPKEY",
- TypeOPT: "OPT",
- TypePTR: "PTR",
- TypePX: "PX",
- TypeRKEY: "RKEY",
- TypeRP: "RP",
- TypeRRSIG: "RRSIG",
- TypeRT: "RT",
- TypeReserved: "Reserved",
- TypeSIG: "SIG",
- TypeSMIMEA: "SMIMEA",
- TypeSOA: "SOA",
- TypeSPF: "SPF",
- TypeSRV: "SRV",
- TypeSSHFP: "SSHFP",
- TypeTA: "TA",
- TypeTALINK: "TALINK",
- TypeTKEY: "TKEY",
- TypeTLSA: "TLSA",
- TypeTSIG: "TSIG",
- TypeTXT: "TXT",
- TypeUID: "UID",
- TypeUINFO: "UINFO",
- TypeUNSPEC: "UNSPEC",
- TypeURI: "URI",
- TypeX25: "X25",
- TypeNSAPPTR: "NSAP-PTR",
-}
-
-// Header() functions
-func (rr *A) Header() *RR_Header { return &rr.Hdr }
-func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
-func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
-func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
-func (rr *AVC) Header() *RR_Header { return &rr.Hdr }
-func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
-func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr }
-func (rr *CDS) Header() *RR_Header { return &rr.Hdr }
-func (rr *CERT) Header() *RR_Header { return &rr.Hdr }
-func (rr *CNAME) Header() *RR_Header { return &rr.Hdr }
-func (rr *DHCID) Header() *RR_Header { return &rr.Hdr }
-func (rr *DLV) Header() *RR_Header { return &rr.Hdr }
-func (rr *DNAME) Header() *RR_Header { return &rr.Hdr }
-func (rr *DNSKEY) Header() *RR_Header { return &rr.Hdr }
-func (rr *DS) Header() *RR_Header { return &rr.Hdr }
-func (rr *EID) Header() *RR_Header { return &rr.Hdr }
-func (rr *EUI48) Header() *RR_Header { return &rr.Hdr }
-func (rr *EUI64) Header() *RR_Header { return &rr.Hdr }
-func (rr *GID) Header() *RR_Header { return &rr.Hdr }
-func (rr *GPOS) Header() *RR_Header { return &rr.Hdr }
-func (rr *HINFO) Header() *RR_Header { return &rr.Hdr }
-func (rr *HIP) Header() *RR_Header { return &rr.Hdr }
-func (rr *KEY) Header() *RR_Header { return &rr.Hdr }
-func (rr *KX) Header() *RR_Header { return &rr.Hdr }
-func (rr *L32) Header() *RR_Header { return &rr.Hdr }
-func (rr *L64) Header() *RR_Header { return &rr.Hdr }
-func (rr *LOC) Header() *RR_Header { return &rr.Hdr }
-func (rr *LP) Header() *RR_Header { return &rr.Hdr }
-func (rr *MB) Header() *RR_Header { return &rr.Hdr }
-func (rr *MD) Header() *RR_Header { return &rr.Hdr }
-func (rr *MF) Header() *RR_Header { return &rr.Hdr }
-func (rr *MG) Header() *RR_Header { return &rr.Hdr }
-func (rr *MINFO) Header() *RR_Header { return &rr.Hdr }
-func (rr *MR) Header() *RR_Header { return &rr.Hdr }
-func (rr *MX) Header() *RR_Header { return &rr.Hdr }
-func (rr *NAPTR) Header() *RR_Header { return &rr.Hdr }
-func (rr *NID) Header() *RR_Header { return &rr.Hdr }
-func (rr *NIMLOC) Header() *RR_Header { return &rr.Hdr }
-func (rr *NINFO) Header() *RR_Header { return &rr.Hdr }
-func (rr *NS) Header() *RR_Header { return &rr.Hdr }
-func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr }
-func (rr *NSEC) Header() *RR_Header { return &rr.Hdr }
-func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr }
-func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
-func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
-func (rr *OPT) Header() *RR_Header { return &rr.Hdr }
-func (rr *PTR) Header() *RR_Header { return &rr.Hdr }
-func (rr *PX) Header() *RR_Header { return &rr.Hdr }
-func (rr *RFC3597) Header() *RR_Header { return &rr.Hdr }
-func (rr *RKEY) Header() *RR_Header { return &rr.Hdr }
-func (rr *RP) Header() *RR_Header { return &rr.Hdr }
-func (rr *RRSIG) Header() *RR_Header { return &rr.Hdr }
-func (rr *RT) Header() *RR_Header { return &rr.Hdr }
-func (rr *SIG) Header() *RR_Header { return &rr.Hdr }
-func (rr *SMIMEA) Header() *RR_Header { return &rr.Hdr }
-func (rr *SOA) Header() *RR_Header { return &rr.Hdr }
-func (rr *SPF) Header() *RR_Header { return &rr.Hdr }
-func (rr *SRV) Header() *RR_Header { return &rr.Hdr }
-func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr }
-func (rr *TA) Header() *RR_Header { return &rr.Hdr }
-func (rr *TALINK) Header() *RR_Header { return &rr.Hdr }
-func (rr *TKEY) Header() *RR_Header { return &rr.Hdr }
-func (rr *TLSA) Header() *RR_Header { return &rr.Hdr }
-func (rr *TSIG) Header() *RR_Header { return &rr.Hdr }
-func (rr *TXT) Header() *RR_Header { return &rr.Hdr }
-func (rr *UID) Header() *RR_Header { return &rr.Hdr }
-func (rr *UINFO) Header() *RR_Header { return &rr.Hdr }
-func (rr *URI) Header() *RR_Header { return &rr.Hdr }
-func (rr *X25) Header() *RR_Header { return &rr.Hdr }
-
-// len() functions
-func (rr *A) len() int {
- l := rr.Hdr.len()
- l += net.IPv4len // A
- return l
-}
-func (rr *AAAA) len() int {
- l := rr.Hdr.len()
- l += net.IPv6len // AAAA
- return l
-}
-func (rr *AFSDB) len() int {
- l := rr.Hdr.len()
- l += 2 // Subtype
- l += len(rr.Hostname) + 1
- return l
-}
-func (rr *ANY) len() int {
- l := rr.Hdr.len()
- return l
-}
-func (rr *AVC) len() int {
- l := rr.Hdr.len()
- for _, x := range rr.Txt {
- l += len(x) + 1
- }
- return l
-}
-func (rr *CAA) len() int {
- l := rr.Hdr.len()
- l++ // Flag
- l += len(rr.Tag) + 1
- l += len(rr.Value)
- return l
-}
-func (rr *CERT) len() int {
- l := rr.Hdr.len()
- l += 2 // Type
- l += 2 // KeyTag
- l++ // Algorithm
- l += base64.StdEncoding.DecodedLen(len(rr.Certificate))
- return l
-}
-func (rr *CNAME) len() int {
- l := rr.Hdr.len()
- l += len(rr.Target) + 1
- return l
-}
-func (rr *DHCID) len() int {
- l := rr.Hdr.len()
- l += base64.StdEncoding.DecodedLen(len(rr.Digest))
- return l
-}
-func (rr *DNAME) len() int {
- l := rr.Hdr.len()
- l += len(rr.Target) + 1
- return l
-}
-func (rr *DNSKEY) len() int {
- l := rr.Hdr.len()
- l += 2 // Flags
- l++ // Protocol
- l++ // Algorithm
- l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
- return l
-}
-func (rr *DS) len() int {
- l := rr.Hdr.len()
- l += 2 // KeyTag
- l++ // Algorithm
- l++ // DigestType
- l += len(rr.Digest)/2 + 1
- return l
-}
-func (rr *EID) len() int {
- l := rr.Hdr.len()
- l += len(rr.Endpoint)/2 + 1
- return l
-}
-func (rr *EUI48) len() int {
- l := rr.Hdr.len()
- l += 6 // Address
- return l
-}
-func (rr *EUI64) len() int {
- l := rr.Hdr.len()
- l += 8 // Address
- return l
-}
-func (rr *GID) len() int {
- l := rr.Hdr.len()
- l += 4 // Gid
- return l
-}
-func (rr *GPOS) len() int {
- l := rr.Hdr.len()
- l += len(rr.Longitude) + 1
- l += len(rr.Latitude) + 1
- l += len(rr.Altitude) + 1
- return l
-}
-func (rr *HINFO) len() int {
- l := rr.Hdr.len()
- l += len(rr.Cpu) + 1
- l += len(rr.Os) + 1
- return l
-}
-func (rr *HIP) len() int {
- l := rr.Hdr.len()
- l++ // HitLength
- l++ // PublicKeyAlgorithm
- l += 2 // PublicKeyLength
- l += len(rr.Hit)/2 + 1
- l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
- for _, x := range rr.RendezvousServers {
- l += len(x) + 1
- }
- return l
-}
-func (rr *KX) len() int {
- l := rr.Hdr.len()
- l += 2 // Preference
- l += len(rr.Exchanger) + 1
- return l
-}
-func (rr *L32) len() int {
- l := rr.Hdr.len()
- l += 2 // Preference
- l += net.IPv4len // Locator32
- return l
-}
-func (rr *L64) len() int {
- l := rr.Hdr.len()
- l += 2 // Preference
- l += 8 // Locator64
- return l
-}
-func (rr *LOC) len() int {
- l := rr.Hdr.len()
- l++ // Version
- l++ // Size
- l++ // HorizPre
- l++ // VertPre
- l += 4 // Latitude
- l += 4 // Longitude
- l += 4 // Altitude
- return l
-}
-func (rr *LP) len() int {
- l := rr.Hdr.len()
- l += 2 // Preference
- l += len(rr.Fqdn) + 1
- return l
-}
-func (rr *MB) len() int {
- l := rr.Hdr.len()
- l += len(rr.Mb) + 1
- return l
-}
-func (rr *MD) len() int {
- l := rr.Hdr.len()
- l += len(rr.Md) + 1
- return l
-}
-func (rr *MF) len() int {
- l := rr.Hdr.len()
- l += len(rr.Mf) + 1
- return l
-}
-func (rr *MG) len() int {
- l := rr.Hdr.len()
- l += len(rr.Mg) + 1
- return l
-}
-func (rr *MINFO) len() int {
- l := rr.Hdr.len()
- l += len(rr.Rmail) + 1
- l += len(rr.Email) + 1
- return l
-}
-func (rr *MR) len() int {
- l := rr.Hdr.len()
- l += len(rr.Mr) + 1
- return l
-}
-func (rr *MX) len() int {
- l := rr.Hdr.len()
- l += 2 // Preference
- l += len(rr.Mx) + 1
- return l
-}
-func (rr *NAPTR) len() int {
- l := rr.Hdr.len()
- l += 2 // Order
- l += 2 // Preference
- l += len(rr.Flags) + 1
- l += len(rr.Service) + 1
- l += len(rr.Regexp) + 1
- l += len(rr.Replacement) + 1
- return l
-}
-func (rr *NID) len() int {
- l := rr.Hdr.len()
- l += 2 // Preference
- l += 8 // NodeID
- return l
-}
-func (rr *NIMLOC) len() int {
- l := rr.Hdr.len()
- l += len(rr.Locator)/2 + 1
- return l
-}
-func (rr *NINFO) len() int {
- l := rr.Hdr.len()
- for _, x := range rr.ZSData {
- l += len(x) + 1
- }
- return l
-}
-func (rr *NS) len() int {
- l := rr.Hdr.len()
- l += len(rr.Ns) + 1
- return l
-}
-func (rr *NSAPPTR) len() int {
- l := rr.Hdr.len()
- l += len(rr.Ptr) + 1
- return l
-}
-func (rr *NSEC3PARAM) len() int {
- l := rr.Hdr.len()
- l++ // Hash
- l++ // Flags
- l += 2 // Iterations
- l++ // SaltLength
- l += len(rr.Salt)/2 + 1
- return l
-}
-func (rr *OPENPGPKEY) len() int {
- l := rr.Hdr.len()
- l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
- return l
-}
-func (rr *PTR) len() int {
- l := rr.Hdr.len()
- l += len(rr.Ptr) + 1
- return l
-}
-func (rr *PX) len() int {
- l := rr.Hdr.len()
- l += 2 // Preference
- l += len(rr.Map822) + 1
- l += len(rr.Mapx400) + 1
- return l
-}
-func (rr *RFC3597) len() int {
- l := rr.Hdr.len()
- l += len(rr.Rdata)/2 + 1
- return l
-}
-func (rr *RKEY) len() int {
- l := rr.Hdr.len()
- l += 2 // Flags
- l++ // Protocol
- l++ // Algorithm
- l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
- return l
-}
-func (rr *RP) len() int {
- l := rr.Hdr.len()
- l += len(rr.Mbox) + 1
- l += len(rr.Txt) + 1
- return l
-}
-func (rr *RRSIG) len() int {
- l := rr.Hdr.len()
- l += 2 // TypeCovered
- l++ // Algorithm
- l++ // Labels
- l += 4 // OrigTtl
- l += 4 // Expiration
- l += 4 // Inception
- l += 2 // KeyTag
- l += len(rr.SignerName) + 1
- l += base64.StdEncoding.DecodedLen(len(rr.Signature))
- return l
-}
-func (rr *RT) len() int {
- l := rr.Hdr.len()
- l += 2 // Preference
- l += len(rr.Host) + 1
- return l
-}
-func (rr *SMIMEA) len() int {
- l := rr.Hdr.len()
- l++ // Usage
- l++ // Selector
- l++ // MatchingType
- l += len(rr.Certificate)/2 + 1
- return l
-}
-func (rr *SOA) len() int {
- l := rr.Hdr.len()
- l += len(rr.Ns) + 1
- l += len(rr.Mbox) + 1
- l += 4 // Serial
- l += 4 // Refresh
- l += 4 // Retry
- l += 4 // Expire
- l += 4 // Minttl
- return l
-}
-func (rr *SPF) len() int {
- l := rr.Hdr.len()
- for _, x := range rr.Txt {
- l += len(x) + 1
- }
- return l
-}
-func (rr *SRV) len() int {
- l := rr.Hdr.len()
- l += 2 // Priority
- l += 2 // Weight
- l += 2 // Port
- l += len(rr.Target) + 1
- return l
-}
-func (rr *SSHFP) len() int {
- l := rr.Hdr.len()
- l++ // Algorithm
- l++ // Type
- l += len(rr.FingerPrint)/2 + 1
- return l
-}
-func (rr *TA) len() int {
- l := rr.Hdr.len()
- l += 2 // KeyTag
- l++ // Algorithm
- l++ // DigestType
- l += len(rr.Digest)/2 + 1
- return l
-}
-func (rr *TALINK) len() int {
- l := rr.Hdr.len()
- l += len(rr.PreviousName) + 1
- l += len(rr.NextName) + 1
- return l
-}
-func (rr *TKEY) len() int {
- l := rr.Hdr.len()
- l += len(rr.Algorithm) + 1
- l += 4 // Inception
- l += 4 // Expiration
- l += 2 // Mode
- l += 2 // Error
- l += 2 // KeySize
- l += len(rr.Key) + 1
- l += 2 // OtherLen
- l += len(rr.OtherData) + 1
- return l
-}
-func (rr *TLSA) len() int {
- l := rr.Hdr.len()
- l++ // Usage
- l++ // Selector
- l++ // MatchingType
- l += len(rr.Certificate)/2 + 1
- return l
-}
-func (rr *TSIG) len() int {
- l := rr.Hdr.len()
- l += len(rr.Algorithm) + 1
- l += 6 // TimeSigned
- l += 2 // Fudge
- l += 2 // MACSize
- l += len(rr.MAC)/2 + 1
- l += 2 // OrigId
- l += 2 // Error
- l += 2 // OtherLen
- l += len(rr.OtherData)/2 + 1
- return l
-}
-func (rr *TXT) len() int {
- l := rr.Hdr.len()
- for _, x := range rr.Txt {
- l += len(x) + 1
- }
- return l
-}
-func (rr *UID) len() int {
- l := rr.Hdr.len()
- l += 4 // Uid
- return l
-}
-func (rr *UINFO) len() int {
- l := rr.Hdr.len()
- l += len(rr.Uinfo) + 1
- return l
-}
-func (rr *URI) len() int {
- l := rr.Hdr.len()
- l += 2 // Priority
- l += 2 // Weight
- l += len(rr.Target)
- return l
-}
-func (rr *X25) len() int {
- l := rr.Hdr.len()
- l += len(rr.PSDNAddress) + 1
- return l
-}
-
-// copy() functions
-func (rr *A) copy() RR {
- return &A{*rr.Hdr.copyHeader(), copyIP(rr.A)}
-}
-func (rr *AAAA) copy() RR {
- return &AAAA{*rr.Hdr.copyHeader(), copyIP(rr.AAAA)}
-}
-func (rr *AFSDB) copy() RR {
- return &AFSDB{*rr.Hdr.copyHeader(), rr.Subtype, rr.Hostname}
-}
-func (rr *ANY) copy() RR {
- return &ANY{*rr.Hdr.copyHeader()}
-}
-func (rr *AVC) copy() RR {
- Txt := make([]string, len(rr.Txt))
- copy(Txt, rr.Txt)
- return &AVC{*rr.Hdr.copyHeader(), Txt}
-}
-func (rr *CAA) copy() RR {
- return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value}
-}
-func (rr *CERT) copy() RR {
- return &CERT{*rr.Hdr.copyHeader(), rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate}
-}
-func (rr *CNAME) copy() RR {
- return &CNAME{*rr.Hdr.copyHeader(), rr.Target}
-}
-func (rr *DHCID) copy() RR {
- return &DHCID{*rr.Hdr.copyHeader(), rr.Digest}
-}
-func (rr *DNAME) copy() RR {
- return &DNAME{*rr.Hdr.copyHeader(), rr.Target}
-}
-func (rr *DNSKEY) copy() RR {
- return &DNSKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
-}
-func (rr *DS) copy() RR {
- return &DS{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
-}
-func (rr *EID) copy() RR {
- return &EID{*rr.Hdr.copyHeader(), rr.Endpoint}
-}
-func (rr *EUI48) copy() RR {
- return &EUI48{*rr.Hdr.copyHeader(), rr.Address}
-}
-func (rr *EUI64) copy() RR {
- return &EUI64{*rr.Hdr.copyHeader(), rr.Address}
-}
-func (rr *GID) copy() RR {
- return &GID{*rr.Hdr.copyHeader(), rr.Gid}
-}
-func (rr *GPOS) copy() RR {
- return &GPOS{*rr.Hdr.copyHeader(), rr.Longitude, rr.Latitude, rr.Altitude}
-}
-func (rr *HINFO) copy() RR {
- return &HINFO{*rr.Hdr.copyHeader(), rr.Cpu, rr.Os}
-}
-func (rr *HIP) copy() RR {
- RendezvousServers := make([]string, len(rr.RendezvousServers))
- copy(RendezvousServers, rr.RendezvousServers)
- return &HIP{*rr.Hdr.copyHeader(), rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
-}
-func (rr *KX) copy() RR {
- return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger}
-}
-func (rr *L32) copy() RR {
- return &L32{*rr.Hdr.copyHeader(), rr.Preference, copyIP(rr.Locator32)}
-}
-func (rr *L64) copy() RR {
- return &L64{*rr.Hdr.copyHeader(), rr.Preference, rr.Locator64}
-}
-func (rr *LOC) copy() RR {
- return &LOC{*rr.Hdr.copyHeader(), rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude}
-}
-func (rr *LP) copy() RR {
- return &LP{*rr.Hdr.copyHeader(), rr.Preference, rr.Fqdn}
-}
-func (rr *MB) copy() RR {
- return &MB{*rr.Hdr.copyHeader(), rr.Mb}
-}
-func (rr *MD) copy() RR {
- return &MD{*rr.Hdr.copyHeader(), rr.Md}
-}
-func (rr *MF) copy() RR {
- return &MF{*rr.Hdr.copyHeader(), rr.Mf}
-}
-func (rr *MG) copy() RR {
- return &MG{*rr.Hdr.copyHeader(), rr.Mg}
-}
-func (rr *MINFO) copy() RR {
- return &MINFO{*rr.Hdr.copyHeader(), rr.Rmail, rr.Email}
-}
-func (rr *MR) copy() RR {
- return &MR{*rr.Hdr.copyHeader(), rr.Mr}
-}
-func (rr *MX) copy() RR {
- return &MX{*rr.Hdr.copyHeader(), rr.Preference, rr.Mx}
-}
-func (rr *NAPTR) copy() RR {
- return &NAPTR{*rr.Hdr.copyHeader(), rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement}
-}
-func (rr *NID) copy() RR {
- return &NID{*rr.Hdr.copyHeader(), rr.Preference, rr.NodeID}
-}
-func (rr *NIMLOC) copy() RR {
- return &NIMLOC{*rr.Hdr.copyHeader(), rr.Locator}
-}
-func (rr *NINFO) copy() RR {
- ZSData := make([]string, len(rr.ZSData))
- copy(ZSData, rr.ZSData)
- return &NINFO{*rr.Hdr.copyHeader(), ZSData}
-}
-func (rr *NS) copy() RR {
- return &NS{*rr.Hdr.copyHeader(), rr.Ns}
-}
-func (rr *NSAPPTR) copy() RR {
- return &NSAPPTR{*rr.Hdr.copyHeader(), rr.Ptr}
-}
-func (rr *NSEC) copy() RR {
- TypeBitMap := make([]uint16, len(rr.TypeBitMap))
- copy(TypeBitMap, rr.TypeBitMap)
- return &NSEC{*rr.Hdr.copyHeader(), rr.NextDomain, TypeBitMap}
-}
-func (rr *NSEC3) copy() RR {
- TypeBitMap := make([]uint16, len(rr.TypeBitMap))
- copy(TypeBitMap, rr.TypeBitMap)
- return &NSEC3{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, TypeBitMap}
-}
-func (rr *NSEC3PARAM) copy() RR {
- return &NSEC3PARAM{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
-}
-func (rr *OPENPGPKEY) copy() RR {
- return &OPENPGPKEY{*rr.Hdr.copyHeader(), rr.PublicKey}
-}
-func (rr *OPT) copy() RR {
- Option := make([]EDNS0, len(rr.Option))
- copy(Option, rr.Option)
- return &OPT{*rr.Hdr.copyHeader(), Option}
-}
-func (rr *PTR) copy() RR {
- return &PTR{*rr.Hdr.copyHeader(), rr.Ptr}
-}
-func (rr *PX) copy() RR {
- return &PX{*rr.Hdr.copyHeader(), rr.Preference, rr.Map822, rr.Mapx400}
-}
-func (rr *RFC3597) copy() RR {
- return &RFC3597{*rr.Hdr.copyHeader(), rr.Rdata}
-}
-func (rr *RKEY) copy() RR {
- return &RKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
-}
-func (rr *RP) copy() RR {
- return &RP{*rr.Hdr.copyHeader(), rr.Mbox, rr.Txt}
-}
-func (rr *RRSIG) copy() RR {
- return &RRSIG{*rr.Hdr.copyHeader(), rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature}
-}
-func (rr *RT) copy() RR {
- return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host}
-}
-func (rr *SMIMEA) copy() RR {
- return &SMIMEA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
-}
-func (rr *SOA) copy() RR {
- return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
-}
-func (rr *SPF) copy() RR {
- Txt := make([]string, len(rr.Txt))
- copy(Txt, rr.Txt)
- return &SPF{*rr.Hdr.copyHeader(), Txt}
-}
-func (rr *SRV) copy() RR {
- return &SRV{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Port, rr.Target}
-}
-func (rr *SSHFP) copy() RR {
- return &SSHFP{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Type, rr.FingerPrint}
-}
-func (rr *TA) copy() RR {
- return &TA{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
-}
-func (rr *TALINK) copy() RR {
- return &TALINK{*rr.Hdr.copyHeader(), rr.PreviousName, rr.NextName}
-}
-func (rr *TKEY) copy() RR {
- return &TKEY{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData}
-}
-func (rr *TLSA) copy() RR {
- return &TLSA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
-}
-func (rr *TSIG) copy() RR {
- return &TSIG{*rr.Hdr.copyHeader(), rr.Algorithm, rr.TimeSigned, rr.Fudge, rr.MACSize, rr.MAC, rr.OrigId, rr.Error, rr.OtherLen, rr.OtherData}
-}
-func (rr *TXT) copy() RR {
- Txt := make([]string, len(rr.Txt))
- copy(Txt, rr.Txt)
- return &TXT{*rr.Hdr.copyHeader(), Txt}
-}
-func (rr *UID) copy() RR {
- return &UID{*rr.Hdr.copyHeader(), rr.Uid}
-}
-func (rr *UINFO) copy() RR {
- return &UINFO{*rr.Hdr.copyHeader(), rr.Uinfo}
-}
-func (rr *URI) copy() RR {
- return &URI{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Target}
-}
-func (rr *X25) copy() RR {
- return &X25{*rr.Hdr.copyHeader(), rr.PSDNAddress}
-}
diff --git a/vendor/golang.org/x/net/.gitattributes b/vendor/golang.org/x/net/.gitattributes
deleted file mode 100644
index d2f212e5d..000000000
--- a/vendor/golang.org/x/net/.gitattributes
+++ /dev/null
@@ -1,10 +0,0 @@
-# Treat all files in this repo as binary, with no git magic updating
-# line endings. Windows users contributing to Go will need to use a
-# modern version of git and editors capable of LF line endings.
-#
-# We'll prevent accidental CRLF line endings from entering the repo
-# via the git-review gofmt checks.
-#
-# See golang.org/issue/9281
-
-* -text
diff --git a/vendor/golang.org/x/net/.gitignore b/vendor/golang.org/x/net/.gitignore
deleted file mode 100644
index 8339fd61d..000000000
--- a/vendor/golang.org/x/net/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Add no patterns to .hgignore except for files generated by the build.
-last-change
diff --git a/vendor/golang.org/x/net/AUTHORS b/vendor/golang.org/x/net/AUTHORS
deleted file mode 100644
index 15167cd74..000000000
--- a/vendor/golang.org/x/net/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/net/CONTRIBUTING.md b/vendor/golang.org/x/net/CONTRIBUTING.md
deleted file mode 100644
index 88dff59bc..000000000
--- a/vendor/golang.org/x/net/CONTRIBUTING.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Contributing to Go
-
-Go is an open source project.
-
-It is the work of hundreds of contributors. We appreciate your help!
-
-
-## Filing issues
-
-When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
-
-1. What version of Go are you using (`go version`)?
-2. What operating system and processor architecture are you using?
-3. What did you do?
-4. What did you expect to see?
-5. What did you see instead?
-
-General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
-The gophers there will answer or ask you to file an issue if you've tripped over a bug.
-
-## Contributing code
-
-Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
-before sending patches.
-
-**We do not accept GitHub pull requests**
-(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
-
-Unless otherwise noted, the Go source files are distributed under
-the BSD-style license found in the LICENSE file.
-
diff --git a/vendor/golang.org/x/net/CONTRIBUTORS b/vendor/golang.org/x/net/CONTRIBUTORS
deleted file mode 100644
index 1c4577e96..000000000
--- a/vendor/golang.org/x/net/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/net/LICENSE b/vendor/golang.org/x/net/LICENSE
deleted file mode 100644
index 6a66aea5e..000000000
--- a/vendor/golang.org/x/net/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/net/PATENTS b/vendor/golang.org/x/net/PATENTS
deleted file mode 100644
index 733099041..000000000
--- a/vendor/golang.org/x/net/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Go project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Go, where such license applies only to those patent
-claims, both currently owned or controlled by Google and acquired in
-the future, licensable by Google that are necessarily infringed by this
-implementation of Go. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of Go or any code incorporated within this
-implementation of Go constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of Go
-shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/net/README b/vendor/golang.org/x/net/README
deleted file mode 100644
index 6b13d8e50..000000000
--- a/vendor/golang.org/x/net/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This repository holds supplementary Go networking libraries.
-
-To submit changes to this repository, see http://golang.org/doc/contribute.html.
diff --git a/vendor/golang.org/x/net/codereview.cfg b/vendor/golang.org/x/net/codereview.cfg
deleted file mode 100644
index 3f8b14b64..000000000
--- a/vendor/golang.org/x/net/codereview.cfg
+++ /dev/null
@@ -1 +0,0 @@
-issuerepo: golang/go
diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go
deleted file mode 100644
index f143ed6a1..000000000
--- a/vendor/golang.org/x/net/context/context.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package context defines the Context type, which carries deadlines,
-// cancelation signals, and other request-scoped values across API boundaries
-// and between processes.
-//
-// Incoming requests to a server should create a Context, and outgoing calls to
-// servers should accept a Context. The chain of function calls between must
-// propagate the Context, optionally replacing it with a modified copy created
-// using WithDeadline, WithTimeout, WithCancel, or WithValue.
-//
-// Programs that use Contexts should follow these rules to keep interfaces
-// consistent across packages and enable static analysis tools to check context
-// propagation:
-//
-// Do not store Contexts inside a struct type; instead, pass a Context
-// explicitly to each function that needs it. The Context should be the first
-// parameter, typically named ctx:
-//
-// func DoSomething(ctx context.Context, arg Arg) error {
-// // ... use ctx ...
-// }
-//
-// Do not pass a nil Context, even if a function permits it. Pass context.TODO
-// if you are unsure about which Context to use.
-//
-// Use context Values only for request-scoped data that transits processes and
-// APIs, not for passing optional parameters to functions.
-//
-// The same Context may be passed to functions running in different goroutines;
-// Contexts are safe for simultaneous use by multiple goroutines.
-//
-// See http://blog.golang.org/context for example code for a server that uses
-// Contexts.
-package context // import "golang.org/x/net/context"
-
-import "time"
-
-// A Context carries a deadline, a cancelation signal, and other values across
-// API boundaries.
-//
-// Context's methods may be called by multiple goroutines simultaneously.
-type Context interface {
- // Deadline returns the time when work done on behalf of this context
- // should be canceled. Deadline returns ok==false when no deadline is
- // set. Successive calls to Deadline return the same results.
- Deadline() (deadline time.Time, ok bool)
-
- // Done returns a channel that's closed when work done on behalf of this
- // context should be canceled. Done may return nil if this context can
- // never be canceled. Successive calls to Done return the same value.
- //
- // WithCancel arranges for Done to be closed when cancel is called;
- // WithDeadline arranges for Done to be closed when the deadline
- // expires; WithTimeout arranges for Done to be closed when the timeout
- // elapses.
- //
- // Done is provided for use in select statements:
- //
- // // Stream generates values with DoSomething and sends them to out
- // // until DoSomething returns an error or ctx.Done is closed.
- // func Stream(ctx context.Context, out chan<- Value) error {
- // for {
- // v, err := DoSomething(ctx)
- // if err != nil {
- // return err
- // }
- // select {
- // case <-ctx.Done():
- // return ctx.Err()
- // case out <- v:
- // }
- // }
- // }
- //
- // See http://blog.golang.org/pipelines for more examples of how to use
- // a Done channel for cancelation.
- Done() <-chan struct{}
-
- // Err returns a non-nil error value after Done is closed. Err returns
- // Canceled if the context was canceled or DeadlineExceeded if the
- // context's deadline passed. No other values for Err are defined.
- // After Done is closed, successive calls to Err return the same value.
- Err() error
-
- // Value returns the value associated with this context for key, or nil
- // if no value is associated with key. Successive calls to Value with
- // the same key returns the same result.
- //
- // Use context values only for request-scoped data that transits
- // processes and API boundaries, not for passing optional parameters to
- // functions.
- //
- // A key identifies a specific value in a Context. Functions that wish
- // to store values in Context typically allocate a key in a global
- // variable then use that key as the argument to context.WithValue and
- // Context.Value. A key can be any type that supports equality;
- // packages should define keys as an unexported type to avoid
- // collisions.
- //
- // Packages that define a Context key should provide type-safe accessors
- // for the values stores using that key:
- //
- // // Package user defines a User type that's stored in Contexts.
- // package user
- //
- // import "golang.org/x/net/context"
- //
- // // User is the type of value stored in the Contexts.
- // type User struct {...}
- //
- // // key is an unexported type for keys defined in this package.
- // // This prevents collisions with keys defined in other packages.
- // type key int
- //
- // // userKey is the key for user.User values in Contexts. It is
- // // unexported; clients use user.NewContext and user.FromContext
- // // instead of using this key directly.
- // var userKey key = 0
- //
- // // NewContext returns a new Context that carries value u.
- // func NewContext(ctx context.Context, u *User) context.Context {
- // return context.WithValue(ctx, userKey, u)
- // }
- //
- // // FromContext returns the User value stored in ctx, if any.
- // func FromContext(ctx context.Context) (*User, bool) {
- // u, ok := ctx.Value(userKey).(*User)
- // return u, ok
- // }
- Value(key interface{}) interface{}
-}
-
-// Background returns a non-nil, empty Context. It is never canceled, has no
-// values, and has no deadline. It is typically used by the main function,
-// initialization, and tests, and as the top-level Context for incoming
-// requests.
-func Background() Context {
- return background
-}
-
-// TODO returns a non-nil, empty Context. Code should use context.TODO when
-// it's unclear which Context to use or it is not yet available (because the
-// surrounding function has not yet been extended to accept a Context
-// parameter). TODO is recognized by static analysis tools that determine
-// whether Contexts are propagated correctly in a program.
-func TODO() Context {
- return todo
-}
-
-// A CancelFunc tells an operation to abandon its work.
-// A CancelFunc does not wait for the work to stop.
-// After the first call, subsequent calls to a CancelFunc do nothing.
-type CancelFunc func()
diff --git a/vendor/golang.org/x/net/context/context_test.go b/vendor/golang.org/x/net/context/context_test.go
deleted file mode 100644
index 62844131b..000000000
--- a/vendor/golang.org/x/net/context/context_test.go
+++ /dev/null
@@ -1,583 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.7
-
-package context
-
-import (
- "fmt"
- "math/rand"
- "runtime"
- "strings"
- "sync"
- "testing"
- "time"
-)
-
-// otherContext is a Context that's not one of the types defined in context.go.
-// This lets us test code paths that differ based on the underlying type of the
-// Context.
-type otherContext struct {
- Context
-}
-
-func TestBackground(t *testing.T) {
- c := Background()
- if c == nil {
- t.Fatalf("Background returned nil")
- }
- select {
- case x := <-c.Done():
- t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
- default:
- }
- if got, want := fmt.Sprint(c), "context.Background"; got != want {
- t.Errorf("Background().String() = %q want %q", got, want)
- }
-}
-
-func TestTODO(t *testing.T) {
- c := TODO()
- if c == nil {
- t.Fatalf("TODO returned nil")
- }
- select {
- case x := <-c.Done():
- t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
- default:
- }
- if got, want := fmt.Sprint(c), "context.TODO"; got != want {
- t.Errorf("TODO().String() = %q want %q", got, want)
- }
-}
-
-func TestWithCancel(t *testing.T) {
- c1, cancel := WithCancel(Background())
-
- if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want {
- t.Errorf("c1.String() = %q want %q", got, want)
- }
-
- o := otherContext{c1}
- c2, _ := WithCancel(o)
- contexts := []Context{c1, o, c2}
-
- for i, c := range contexts {
- if d := c.Done(); d == nil {
- t.Errorf("c[%d].Done() == %v want non-nil", i, d)
- }
- if e := c.Err(); e != nil {
- t.Errorf("c[%d].Err() == %v want nil", i, e)
- }
-
- select {
- case x := <-c.Done():
- t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
- default:
- }
- }
-
- cancel()
- time.Sleep(100 * time.Millisecond) // let cancelation propagate
-
- for i, c := range contexts {
- select {
- case <-c.Done():
- default:
- t.Errorf("<-c[%d].Done() blocked, but shouldn't have", i)
- }
- if e := c.Err(); e != Canceled {
- t.Errorf("c[%d].Err() == %v want %v", i, e, Canceled)
- }
- }
-}
-
-func TestParentFinishesChild(t *testing.T) {
- // Context tree:
- // parent -> cancelChild
- // parent -> valueChild -> timerChild
- parent, cancel := WithCancel(Background())
- cancelChild, stop := WithCancel(parent)
- defer stop()
- valueChild := WithValue(parent, "key", "value")
- timerChild, stop := WithTimeout(valueChild, 10000*time.Hour)
- defer stop()
-
- select {
- case x := <-parent.Done():
- t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
- case x := <-cancelChild.Done():
- t.Errorf("<-cancelChild.Done() == %v want nothing (it should block)", x)
- case x := <-timerChild.Done():
- t.Errorf("<-timerChild.Done() == %v want nothing (it should block)", x)
- case x := <-valueChild.Done():
- t.Errorf("<-valueChild.Done() == %v want nothing (it should block)", x)
- default:
- }
-
- // The parent's children should contain the two cancelable children.
- pc := parent.(*cancelCtx)
- cc := cancelChild.(*cancelCtx)
- tc := timerChild.(*timerCtx)
- pc.mu.Lock()
- if len(pc.children) != 2 || !pc.children[cc] || !pc.children[tc] {
- t.Errorf("bad linkage: pc.children = %v, want %v and %v",
- pc.children, cc, tc)
- }
- pc.mu.Unlock()
-
- if p, ok := parentCancelCtx(cc.Context); !ok || p != pc {
- t.Errorf("bad linkage: parentCancelCtx(cancelChild.Context) = %v, %v want %v, true", p, ok, pc)
- }
- if p, ok := parentCancelCtx(tc.Context); !ok || p != pc {
- t.Errorf("bad linkage: parentCancelCtx(timerChild.Context) = %v, %v want %v, true", p, ok, pc)
- }
-
- cancel()
-
- pc.mu.Lock()
- if len(pc.children) != 0 {
- t.Errorf("pc.cancel didn't clear pc.children = %v", pc.children)
- }
- pc.mu.Unlock()
-
- // parent and children should all be finished.
- check := func(ctx Context, name string) {
- select {
- case <-ctx.Done():
- default:
- t.Errorf("<-%s.Done() blocked, but shouldn't have", name)
- }
- if e := ctx.Err(); e != Canceled {
- t.Errorf("%s.Err() == %v want %v", name, e, Canceled)
- }
- }
- check(parent, "parent")
- check(cancelChild, "cancelChild")
- check(valueChild, "valueChild")
- check(timerChild, "timerChild")
-
- // WithCancel should return a canceled context on a canceled parent.
- precanceledChild := WithValue(parent, "key", "value")
- select {
- case <-precanceledChild.Done():
- default:
- t.Errorf("<-precanceledChild.Done() blocked, but shouldn't have")
- }
- if e := precanceledChild.Err(); e != Canceled {
- t.Errorf("precanceledChild.Err() == %v want %v", e, Canceled)
- }
-}
-
-func TestChildFinishesFirst(t *testing.T) {
- cancelable, stop := WithCancel(Background())
- defer stop()
- for _, parent := range []Context{Background(), cancelable} {
- child, cancel := WithCancel(parent)
-
- select {
- case x := <-parent.Done():
- t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
- case x := <-child.Done():
- t.Errorf("<-child.Done() == %v want nothing (it should block)", x)
- default:
- }
-
- cc := child.(*cancelCtx)
- pc, pcok := parent.(*cancelCtx) // pcok == false when parent == Background()
- if p, ok := parentCancelCtx(cc.Context); ok != pcok || (ok && pc != p) {
- t.Errorf("bad linkage: parentCancelCtx(cc.Context) = %v, %v want %v, %v", p, ok, pc, pcok)
- }
-
- if pcok {
- pc.mu.Lock()
- if len(pc.children) != 1 || !pc.children[cc] {
- t.Errorf("bad linkage: pc.children = %v, cc = %v", pc.children, cc)
- }
- pc.mu.Unlock()
- }
-
- cancel()
-
- if pcok {
- pc.mu.Lock()
- if len(pc.children) != 0 {
- t.Errorf("child's cancel didn't remove self from pc.children = %v", pc.children)
- }
- pc.mu.Unlock()
- }
-
- // child should be finished.
- select {
- case <-child.Done():
- default:
- t.Errorf("<-child.Done() blocked, but shouldn't have")
- }
- if e := child.Err(); e != Canceled {
- t.Errorf("child.Err() == %v want %v", e, Canceled)
- }
-
- // parent should not be finished.
- select {
- case x := <-parent.Done():
- t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
- default:
- }
- if e := parent.Err(); e != nil {
- t.Errorf("parent.Err() == %v want nil", e)
- }
- }
-}
-
-func testDeadline(c Context, wait time.Duration, t *testing.T) {
- select {
- case <-time.After(wait):
- t.Fatalf("context should have timed out")
- case <-c.Done():
- }
- if e := c.Err(); e != DeadlineExceeded {
- t.Errorf("c.Err() == %v want %v", e, DeadlineExceeded)
- }
-}
-
-func TestDeadline(t *testing.T) {
- t.Parallel()
- const timeUnit = 500 * time.Millisecond
- c, _ := WithDeadline(Background(), time.Now().Add(1*timeUnit))
- if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
- t.Errorf("c.String() = %q want prefix %q", got, prefix)
- }
- testDeadline(c, 2*timeUnit, t)
-
- c, _ = WithDeadline(Background(), time.Now().Add(1*timeUnit))
- o := otherContext{c}
- testDeadline(o, 2*timeUnit, t)
-
- c, _ = WithDeadline(Background(), time.Now().Add(1*timeUnit))
- o = otherContext{c}
- c, _ = WithDeadline(o, time.Now().Add(3*timeUnit))
- testDeadline(c, 2*timeUnit, t)
-}
-
-func TestTimeout(t *testing.T) {
- t.Parallel()
- const timeUnit = 500 * time.Millisecond
- c, _ := WithTimeout(Background(), 1*timeUnit)
- if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
- t.Errorf("c.String() = %q want prefix %q", got, prefix)
- }
- testDeadline(c, 2*timeUnit, t)
-
- c, _ = WithTimeout(Background(), 1*timeUnit)
- o := otherContext{c}
- testDeadline(o, 2*timeUnit, t)
-
- c, _ = WithTimeout(Background(), 1*timeUnit)
- o = otherContext{c}
- c, _ = WithTimeout(o, 3*timeUnit)
- testDeadline(c, 2*timeUnit, t)
-}
-
-func TestCanceledTimeout(t *testing.T) {
- t.Parallel()
- const timeUnit = 500 * time.Millisecond
- c, _ := WithTimeout(Background(), 2*timeUnit)
- o := otherContext{c}
- c, cancel := WithTimeout(o, 4*timeUnit)
- cancel()
- time.Sleep(1 * timeUnit) // let cancelation propagate
- select {
- case <-c.Done():
- default:
- t.Errorf("<-c.Done() blocked, but shouldn't have")
- }
- if e := c.Err(); e != Canceled {
- t.Errorf("c.Err() == %v want %v", e, Canceled)
- }
-}
-
-type key1 int
-type key2 int
-
-var k1 = key1(1)
-var k2 = key2(1) // same int as k1, different type
-var k3 = key2(3) // same type as k2, different int
-
-func TestValues(t *testing.T) {
- check := func(c Context, nm, v1, v2, v3 string) {
- if v, ok := c.Value(k1).(string); ok == (len(v1) == 0) || v != v1 {
- t.Errorf(`%s.Value(k1).(string) = %q, %t want %q, %t`, nm, v, ok, v1, len(v1) != 0)
- }
- if v, ok := c.Value(k2).(string); ok == (len(v2) == 0) || v != v2 {
- t.Errorf(`%s.Value(k2).(string) = %q, %t want %q, %t`, nm, v, ok, v2, len(v2) != 0)
- }
- if v, ok := c.Value(k3).(string); ok == (len(v3) == 0) || v != v3 {
- t.Errorf(`%s.Value(k3).(string) = %q, %t want %q, %t`, nm, v, ok, v3, len(v3) != 0)
- }
- }
-
- c0 := Background()
- check(c0, "c0", "", "", "")
-
- c1 := WithValue(Background(), k1, "c1k1")
- check(c1, "c1", "c1k1", "", "")
-
- if got, want := fmt.Sprint(c1), `context.Background.WithValue(1, "c1k1")`; got != want {
- t.Errorf("c.String() = %q want %q", got, want)
- }
-
- c2 := WithValue(c1, k2, "c2k2")
- check(c2, "c2", "c1k1", "c2k2", "")
-
- c3 := WithValue(c2, k3, "c3k3")
- check(c3, "c2", "c1k1", "c2k2", "c3k3")
-
- c4 := WithValue(c3, k1, nil)
- check(c4, "c4", "", "c2k2", "c3k3")
-
- o0 := otherContext{Background()}
- check(o0, "o0", "", "", "")
-
- o1 := otherContext{WithValue(Background(), k1, "c1k1")}
- check(o1, "o1", "c1k1", "", "")
-
- o2 := WithValue(o1, k2, "o2k2")
- check(o2, "o2", "c1k1", "o2k2", "")
-
- o3 := otherContext{c4}
- check(o3, "o3", "", "c2k2", "c3k3")
-
- o4 := WithValue(o3, k3, nil)
- check(o4, "o4", "", "c2k2", "")
-}
-
-func TestAllocs(t *testing.T) {
- bg := Background()
- for _, test := range []struct {
- desc string
- f func()
- limit float64
- gccgoLimit float64
- }{
- {
- desc: "Background()",
- f: func() { Background() },
- limit: 0,
- gccgoLimit: 0,
- },
- {
- desc: fmt.Sprintf("WithValue(bg, %v, nil)", k1),
- f: func() {
- c := WithValue(bg, k1, nil)
- c.Value(k1)
- },
- limit: 3,
- gccgoLimit: 3,
- },
- {
- desc: "WithTimeout(bg, 15*time.Millisecond)",
- f: func() {
- c, _ := WithTimeout(bg, 15*time.Millisecond)
- <-c.Done()
- },
- limit: 8,
- gccgoLimit: 16,
- },
- {
- desc: "WithCancel(bg)",
- f: func() {
- c, cancel := WithCancel(bg)
- cancel()
- <-c.Done()
- },
- limit: 5,
- gccgoLimit: 8,
- },
- {
- desc: "WithTimeout(bg, 100*time.Millisecond)",
- f: func() {
- c, cancel := WithTimeout(bg, 100*time.Millisecond)
- cancel()
- <-c.Done()
- },
- limit: 8,
- gccgoLimit: 25,
- },
- } {
- limit := test.limit
- if runtime.Compiler == "gccgo" {
- // gccgo does not yet do escape analysis.
- // TODO(iant): Remove this when gccgo does do escape analysis.
- limit = test.gccgoLimit
- }
- if n := testing.AllocsPerRun(100, test.f); n > limit {
- t.Errorf("%s allocs = %f want %d", test.desc, n, int(limit))
- }
- }
-}
-
-func TestSimultaneousCancels(t *testing.T) {
- root, cancel := WithCancel(Background())
- m := map[Context]CancelFunc{root: cancel}
- q := []Context{root}
- // Create a tree of contexts.
- for len(q) != 0 && len(m) < 100 {
- parent := q[0]
- q = q[1:]
- for i := 0; i < 4; i++ {
- ctx, cancel := WithCancel(parent)
- m[ctx] = cancel
- q = append(q, ctx)
- }
- }
- // Start all the cancels in a random order.
- var wg sync.WaitGroup
- wg.Add(len(m))
- for _, cancel := range m {
- go func(cancel CancelFunc) {
- cancel()
- wg.Done()
- }(cancel)
- }
- // Wait on all the contexts in a random order.
- for ctx := range m {
- select {
- case <-ctx.Done():
- case <-time.After(1 * time.Second):
- buf := make([]byte, 10<<10)
- n := runtime.Stack(buf, true)
- t.Fatalf("timed out waiting for <-ctx.Done(); stacks:\n%s", buf[:n])
- }
- }
- // Wait for all the cancel functions to return.
- done := make(chan struct{})
- go func() {
- wg.Wait()
- close(done)
- }()
- select {
- case <-done:
- case <-time.After(1 * time.Second):
- buf := make([]byte, 10<<10)
- n := runtime.Stack(buf, true)
- t.Fatalf("timed out waiting for cancel functions; stacks:\n%s", buf[:n])
- }
-}
-
-func TestInterlockedCancels(t *testing.T) {
- parent, cancelParent := WithCancel(Background())
- child, cancelChild := WithCancel(parent)
- go func() {
- parent.Done()
- cancelChild()
- }()
- cancelParent()
- select {
- case <-child.Done():
- case <-time.After(1 * time.Second):
- buf := make([]byte, 10<<10)
- n := runtime.Stack(buf, true)
- t.Fatalf("timed out waiting for child.Done(); stacks:\n%s", buf[:n])
- }
-}
-
-func TestLayersCancel(t *testing.T) {
- testLayers(t, time.Now().UnixNano(), false)
-}
-
-func TestLayersTimeout(t *testing.T) {
- testLayers(t, time.Now().UnixNano(), true)
-}
-
-func testLayers(t *testing.T, seed int64, testTimeout bool) {
- rand.Seed(seed)
- errorf := func(format string, a ...interface{}) {
- t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...)
- }
- const (
- timeout = 200 * time.Millisecond
- minLayers = 30
- )
- type value int
- var (
- vals []*value
- cancels []CancelFunc
- numTimers int
- ctx = Background()
- )
- for i := 0; i < minLayers || numTimers == 0 || len(cancels) == 0 || len(vals) == 0; i++ {
- switch rand.Intn(3) {
- case 0:
- v := new(value)
- ctx = WithValue(ctx, v, v)
- vals = append(vals, v)
- case 1:
- var cancel CancelFunc
- ctx, cancel = WithCancel(ctx)
- cancels = append(cancels, cancel)
- case 2:
- var cancel CancelFunc
- ctx, cancel = WithTimeout(ctx, timeout)
- cancels = append(cancels, cancel)
- numTimers++
- }
- }
- checkValues := func(when string) {
- for _, key := range vals {
- if val := ctx.Value(key).(*value); key != val {
- errorf("%s: ctx.Value(%p) = %p want %p", when, key, val, key)
- }
- }
- }
- select {
- case <-ctx.Done():
- errorf("ctx should not be canceled yet")
- default:
- }
- if s, prefix := fmt.Sprint(ctx), "context.Background."; !strings.HasPrefix(s, prefix) {
- t.Errorf("ctx.String() = %q want prefix %q", s, prefix)
- }
- t.Log(ctx)
- checkValues("before cancel")
- if testTimeout {
- select {
- case <-ctx.Done():
- case <-time.After(timeout + 100*time.Millisecond):
- errorf("ctx should have timed out")
- }
- checkValues("after timeout")
- } else {
- cancel := cancels[rand.Intn(len(cancels))]
- cancel()
- select {
- case <-ctx.Done():
- default:
- errorf("ctx should be canceled")
- }
- checkValues("after cancel")
- }
-}
-
-func TestCancelRemoves(t *testing.T) {
- checkChildren := func(when string, ctx Context, want int) {
- if got := len(ctx.(*cancelCtx).children); got != want {
- t.Errorf("%s: context has %d children, want %d", when, got, want)
- }
- }
-
- ctx, _ := WithCancel(Background())
- checkChildren("after creation", ctx, 0)
- _, cancel := WithCancel(ctx)
- checkChildren("with WithCancel child ", ctx, 1)
- cancel()
- checkChildren("after cancelling WithCancel child", ctx, 0)
-
- ctx, _ = WithCancel(Background())
- checkChildren("after creation", ctx, 0)
- _, cancel = WithTimeout(ctx, 60*time.Minute)
- checkChildren("with WithTimeout child ", ctx, 1)
- cancel()
- checkChildren("after cancelling WithTimeout child", ctx, 0)
-}
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
deleted file mode 100644
index 606cf1f97..000000000
--- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.7
-
-// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
-package ctxhttp // import "golang.org/x/net/context/ctxhttp"
-
-import (
- "io"
- "net/http"
- "net/url"
- "strings"
-
- "golang.org/x/net/context"
-)
-
-// Do sends an HTTP request with the provided http.Client and returns
-// an HTTP response.
-//
-// If the client is nil, http.DefaultClient is used.
-//
-// The provided ctx must be non-nil. If it is canceled or times out,
-// ctx.Err() will be returned.
-func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
- if client == nil {
- client = http.DefaultClient
- }
- resp, err := client.Do(req.WithContext(ctx))
- // If we got an error, and the context has been canceled,
- // the context's error is probably more useful.
- if err != nil {
- select {
- case <-ctx.Done():
- err = ctx.Err()
- default:
- }
- }
- return resp, err
-}
-
-// Get issues a GET request via the Do function.
-func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
- req, err := http.NewRequest("GET", url, nil)
- if err != nil {
- return nil, err
- }
- return Do(ctx, client, req)
-}
-
-// Head issues a HEAD request via the Do function.
-func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
- req, err := http.NewRequest("HEAD", url, nil)
- if err != nil {
- return nil, err
- }
- return Do(ctx, client, req)
-}
-
-// Post issues a POST request via the Do function.
-func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
- req, err := http.NewRequest("POST", url, body)
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", bodyType)
- return Do(ctx, client, req)
-}
-
-// PostForm issues a POST request via the Do function.
-func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
- return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
-}
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_17_test.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_17_test.go
deleted file mode 100644
index 72411b1b6..000000000
--- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_17_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9,go1.7
-
-package ctxhttp
-
-import (
- "io"
- "net/http"
- "net/http/httptest"
- "testing"
-
- "context"
-)
-
-func TestGo17Context(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, "ok")
- }))
- defer ts.Close()
- ctx := context.Background()
- resp, err := Get(ctx, http.DefaultClient, ts.URL)
- if resp == nil || err != nil {
- t.Fatalf("error received from client: %v %v", err, resp)
- }
- resp.Body.Close()
-}
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
deleted file mode 100644
index 926870cc2..000000000
--- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.7
-
-package ctxhttp // import "golang.org/x/net/context/ctxhttp"
-
-import (
- "io"
- "net/http"
- "net/url"
- "strings"
-
- "golang.org/x/net/context"
-)
-
-func nop() {}
-
-var (
- testHookContextDoneBeforeHeaders = nop
- testHookDoReturned = nop
- testHookDidBodyClose = nop
-)
-
-// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
-// If the client is nil, http.DefaultClient is used.
-// If the context is canceled or times out, ctx.Err() will be returned.
-func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
- if client == nil {
- client = http.DefaultClient
- }
-
- // TODO(djd): Respect any existing value of req.Cancel.
- cancel := make(chan struct{})
- req.Cancel = cancel
-
- type responseAndError struct {
- resp *http.Response
- err error
- }
- result := make(chan responseAndError, 1)
-
- // Make local copies of test hooks closed over by goroutines below.
- // Prevents data races in tests.
- testHookDoReturned := testHookDoReturned
- testHookDidBodyClose := testHookDidBodyClose
-
- go func() {
- resp, err := client.Do(req)
- testHookDoReturned()
- result <- responseAndError{resp, err}
- }()
-
- var resp *http.Response
-
- select {
- case <-ctx.Done():
- testHookContextDoneBeforeHeaders()
- close(cancel)
- // Clean up after the goroutine calling client.Do:
- go func() {
- if r := <-result; r.resp != nil {
- testHookDidBodyClose()
- r.resp.Body.Close()
- }
- }()
- return nil, ctx.Err()
- case r := <-result:
- var err error
- resp, err = r.resp, r.err
- if err != nil {
- return resp, err
- }
- }
-
- c := make(chan struct{})
- go func() {
- select {
- case <-ctx.Done():
- close(cancel)
- case <-c:
- // The response's Body is closed.
- }
- }()
- resp.Body = &notifyingReader{resp.Body, c}
-
- return resp, nil
-}
-
-// Get issues a GET request via the Do function.
-func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
- req, err := http.NewRequest("GET", url, nil)
- if err != nil {
- return nil, err
- }
- return Do(ctx, client, req)
-}
-
-// Head issues a HEAD request via the Do function.
-func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
- req, err := http.NewRequest("HEAD", url, nil)
- if err != nil {
- return nil, err
- }
- return Do(ctx, client, req)
-}
-
-// Post issues a POST request via the Do function.
-func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
- req, err := http.NewRequest("POST", url, body)
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", bodyType)
- return Do(ctx, client, req)
-}
-
-// PostForm issues a POST request via the Do function.
-func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
- return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
-}
-
-// notifyingReader is an io.ReadCloser that closes the notify channel after
-// Close is called or a Read fails on the underlying ReadCloser.
-type notifyingReader struct {
- io.ReadCloser
- notify chan<- struct{}
-}
-
-func (r *notifyingReader) Read(p []byte) (int, error) {
- n, err := r.ReadCloser.Read(p)
- if err != nil && r.notify != nil {
- close(r.notify)
- r.notify = nil
- }
- return n, err
-}
-
-func (r *notifyingReader) Close() error {
- err := r.ReadCloser.Close()
- if r.notify != nil {
- close(r.notify)
- r.notify = nil
- }
- return err
-}
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17_test.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17_test.go
deleted file mode 100644
index 9159cf022..000000000
--- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17_test.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9,!go1.7
-
-package ctxhttp
-
-import (
- "net"
- "net/http"
- "net/http/httptest"
- "sync"
- "testing"
- "time"
-
- "golang.org/x/net/context"
-)
-
-// golang.org/issue/14065
-func TestClosesResponseBodyOnCancel(t *testing.T) {
- defer func() { testHookContextDoneBeforeHeaders = nop }()
- defer func() { testHookDoReturned = nop }()
- defer func() { testHookDidBodyClose = nop }()
-
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
- defer ts.Close()
-
- ctx, cancel := context.WithCancel(context.Background())
-
- // closed when Do enters select case <-ctx.Done()
- enteredDonePath := make(chan struct{})
-
- testHookContextDoneBeforeHeaders = func() {
- close(enteredDonePath)
- }
-
- testHookDoReturned = func() {
- // We now have the result (the Flush'd headers) at least,
- // so we can cancel the request.
- cancel()
-
- // But block the client.Do goroutine from sending
- // until Do enters into the <-ctx.Done() path, since
- // otherwise if both channels are readable, select
- // picks a random one.
- <-enteredDonePath
- }
-
- sawBodyClose := make(chan struct{})
- testHookDidBodyClose = func() { close(sawBodyClose) }
-
- tr := &http.Transport{}
- defer tr.CloseIdleConnections()
- c := &http.Client{Transport: tr}
- req, _ := http.NewRequest("GET", ts.URL, nil)
- _, doErr := Do(ctx, c, req)
-
- select {
- case <-sawBodyClose:
- case <-time.After(5 * time.Second):
- t.Fatal("timeout waiting for body to close")
- }
-
- if doErr != ctx.Err() {
- t.Errorf("Do error = %v; want %v", doErr, ctx.Err())
- }
-}
-
-type noteCloseConn struct {
- net.Conn
- onceClose sync.Once
- closefn func()
-}
-
-func (c *noteCloseConn) Close() error {
- c.onceClose.Do(c.closefn)
- return c.Conn.Close()
-}
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_test.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_test.go
deleted file mode 100644
index 1e4155180..000000000
--- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9
-
-package ctxhttp
-
-import (
- "io"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "testing"
- "time"
-
- "golang.org/x/net/context"
-)
-
-const (
- requestDuration = 100 * time.Millisecond
- requestBody = "ok"
-)
-
-func okHandler(w http.ResponseWriter, r *http.Request) {
- time.Sleep(requestDuration)
- io.WriteString(w, requestBody)
-}
-
-func TestNoTimeout(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(okHandler))
- defer ts.Close()
-
- ctx := context.Background()
- res, err := Get(ctx, nil, ts.URL)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- t.Fatal(err)
- }
- if string(slurp) != requestBody {
- t.Errorf("body = %q; want %q", slurp, requestBody)
- }
-}
-
-func TestCancelBeforeHeaders(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
-
- blockServer := make(chan struct{})
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- cancel()
- <-blockServer
- io.WriteString(w, requestBody)
- }))
- defer ts.Close()
- defer close(blockServer)
-
- res, err := Get(ctx, nil, ts.URL)
- if err == nil {
- res.Body.Close()
- t.Fatal("Get returned unexpected nil error")
- }
- if err != context.Canceled {
- t.Errorf("err = %v; want %v", err, context.Canceled)
- }
-}
-
-func TestCancelAfterHangingRequest(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusOK)
- w.(http.Flusher).Flush()
- <-w.(http.CloseNotifier).CloseNotify()
- }))
- defer ts.Close()
-
- ctx, cancel := context.WithCancel(context.Background())
- resp, err := Get(ctx, nil, ts.URL)
- if err != nil {
- t.Fatalf("unexpected error in Get: %v", err)
- }
-
- // Cancel befer reading the body.
- // Reading Request.Body should fail, since the request was
- // canceled before anything was written.
- cancel()
-
- done := make(chan struct{})
-
- go func() {
- b, err := ioutil.ReadAll(resp.Body)
- if len(b) != 0 || err == nil {
- t.Errorf(`Read got (%q, %v); want ("", error)`, b, err)
- }
- close(done)
- }()
-
- select {
- case <-time.After(1 * time.Second):
- t.Errorf("Test timed out")
- case <-done:
- }
-}
diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go
deleted file mode 100644
index d20f52b7d..000000000
--- a/vendor/golang.org/x/net/context/go17.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.7
-
-package context
-
-import (
- "context" // standard library's context, as of Go 1.7
- "time"
-)
-
-var (
- todo = context.TODO()
- background = context.Background()
-)
-
-// Canceled is the error returned by Context.Err when the context is canceled.
-var Canceled = context.Canceled
-
-// DeadlineExceeded is the error returned by Context.Err when the context's
-// deadline passes.
-var DeadlineExceeded = context.DeadlineExceeded
-
-// WithCancel returns a copy of parent with a new Done channel. The returned
-// context's Done channel is closed when the returned cancel function is called
-// or when the parent context's Done channel is closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
- ctx, f := context.WithCancel(parent)
- return ctx, CancelFunc(f)
-}
-
-// WithDeadline returns a copy of the parent context with the deadline adjusted
-// to be no later than d. If the parent's deadline is already earlier than d,
-// WithDeadline(parent, d) is semantically equivalent to parent. The returned
-// context's Done channel is closed when the deadline expires, when the returned
-// cancel function is called, or when the parent context's Done channel is
-// closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
- ctx, f := context.WithDeadline(parent, deadline)
- return ctx, CancelFunc(f)
-}
-
-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete:
-//
-// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
-// defer cancel() // releases resources if slowOperation completes before timeout elapses
-// return slowOperation(ctx)
-// }
-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
- return WithDeadline(parent, time.Now().Add(timeout))
-}
-
-// WithValue returns a copy of parent in which the value associated with key is
-// val.
-//
-// Use context Values only for request-scoped data that transits processes and
-// APIs, not for passing optional parameters to functions.
-func WithValue(parent Context, key interface{}, val interface{}) Context {
- return context.WithValue(parent, key, val)
-}
diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go
deleted file mode 100644
index 0f35592df..000000000
--- a/vendor/golang.org/x/net/context/pre_go17.go
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.7
-
-package context
-
-import (
- "errors"
- "fmt"
- "sync"
- "time"
-)
-
-// An emptyCtx is never canceled, has no values, and has no deadline. It is not
-// struct{}, since vars of this type must have distinct addresses.
-type emptyCtx int
-
-func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
- return
-}
-
-func (*emptyCtx) Done() <-chan struct{} {
- return nil
-}
-
-func (*emptyCtx) Err() error {
- return nil
-}
-
-func (*emptyCtx) Value(key interface{}) interface{} {
- return nil
-}
-
-func (e *emptyCtx) String() string {
- switch e {
- case background:
- return "context.Background"
- case todo:
- return "context.TODO"
- }
- return "unknown empty Context"
-}
-
-var (
- background = new(emptyCtx)
- todo = new(emptyCtx)
-)
-
-// Canceled is the error returned by Context.Err when the context is canceled.
-var Canceled = errors.New("context canceled")
-
-// DeadlineExceeded is the error returned by Context.Err when the context's
-// deadline passes.
-var DeadlineExceeded = errors.New("context deadline exceeded")
-
-// WithCancel returns a copy of parent with a new Done channel. The returned
-// context's Done channel is closed when the returned cancel function is called
-// or when the parent context's Done channel is closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
- c := newCancelCtx(parent)
- propagateCancel(parent, c)
- return c, func() { c.cancel(true, Canceled) }
-}
-
-// newCancelCtx returns an initialized cancelCtx.
-func newCancelCtx(parent Context) *cancelCtx {
- return &cancelCtx{
- Context: parent,
- done: make(chan struct{}),
- }
-}
-
-// propagateCancel arranges for child to be canceled when parent is.
-func propagateCancel(parent Context, child canceler) {
- if parent.Done() == nil {
- return // parent is never canceled
- }
- if p, ok := parentCancelCtx(parent); ok {
- p.mu.Lock()
- if p.err != nil {
- // parent has already been canceled
- child.cancel(false, p.err)
- } else {
- if p.children == nil {
- p.children = make(map[canceler]bool)
- }
- p.children[child] = true
- }
- p.mu.Unlock()
- } else {
- go func() {
- select {
- case <-parent.Done():
- child.cancel(false, parent.Err())
- case <-child.Done():
- }
- }()
- }
-}
-
-// parentCancelCtx follows a chain of parent references until it finds a
-// *cancelCtx. This function understands how each of the concrete types in this
-// package represents its parent.
-func parentCancelCtx(parent Context) (*cancelCtx, bool) {
- for {
- switch c := parent.(type) {
- case *cancelCtx:
- return c, true
- case *timerCtx:
- return c.cancelCtx, true
- case *valueCtx:
- parent = c.Context
- default:
- return nil, false
- }
- }
-}
-
-// removeChild removes a context from its parent.
-func removeChild(parent Context, child canceler) {
- p, ok := parentCancelCtx(parent)
- if !ok {
- return
- }
- p.mu.Lock()
- if p.children != nil {
- delete(p.children, child)
- }
- p.mu.Unlock()
-}
-
-// A canceler is a context type that can be canceled directly. The
-// implementations are *cancelCtx and *timerCtx.
-type canceler interface {
- cancel(removeFromParent bool, err error)
- Done() <-chan struct{}
-}
-
-// A cancelCtx can be canceled. When canceled, it also cancels any children
-// that implement canceler.
-type cancelCtx struct {
- Context
-
- done chan struct{} // closed by the first cancel call.
-
- mu sync.Mutex
- children map[canceler]bool // set to nil by the first cancel call
- err error // set to non-nil by the first cancel call
-}
-
-func (c *cancelCtx) Done() <-chan struct{} {
- return c.done
-}
-
-func (c *cancelCtx) Err() error {
- c.mu.Lock()
- defer c.mu.Unlock()
- return c.err
-}
-
-func (c *cancelCtx) String() string {
- return fmt.Sprintf("%v.WithCancel", c.Context)
-}
-
-// cancel closes c.done, cancels each of c's children, and, if
-// removeFromParent is true, removes c from its parent's children.
-func (c *cancelCtx) cancel(removeFromParent bool, err error) {
- if err == nil {
- panic("context: internal error: missing cancel error")
- }
- c.mu.Lock()
- if c.err != nil {
- c.mu.Unlock()
- return // already canceled
- }
- c.err = err
- close(c.done)
- for child := range c.children {
- // NOTE: acquiring the child's lock while holding parent's lock.
- child.cancel(false, err)
- }
- c.children = nil
- c.mu.Unlock()
-
- if removeFromParent {
- removeChild(c.Context, c)
- }
-}
-
-// WithDeadline returns a copy of the parent context with the deadline adjusted
-// to be no later than d. If the parent's deadline is already earlier than d,
-// WithDeadline(parent, d) is semantically equivalent to parent. The returned
-// context's Done channel is closed when the deadline expires, when the returned
-// cancel function is called, or when the parent context's Done channel is
-// closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
- if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
- // The current deadline is already sooner than the new one.
- return WithCancel(parent)
- }
- c := &timerCtx{
- cancelCtx: newCancelCtx(parent),
- deadline: deadline,
- }
- propagateCancel(parent, c)
- d := deadline.Sub(time.Now())
- if d <= 0 {
- c.cancel(true, DeadlineExceeded) // deadline has already passed
- return c, func() { c.cancel(true, Canceled) }
- }
- c.mu.Lock()
- defer c.mu.Unlock()
- if c.err == nil {
- c.timer = time.AfterFunc(d, func() {
- c.cancel(true, DeadlineExceeded)
- })
- }
- return c, func() { c.cancel(true, Canceled) }
-}
-
-// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
-// implement Done and Err. It implements cancel by stopping its timer then
-// delegating to cancelCtx.cancel.
-type timerCtx struct {
- *cancelCtx
- timer *time.Timer // Under cancelCtx.mu.
-
- deadline time.Time
-}
-
-func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
- return c.deadline, true
-}
-
-func (c *timerCtx) String() string {
- return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
-}
-
-func (c *timerCtx) cancel(removeFromParent bool, err error) {
- c.cancelCtx.cancel(false, err)
- if removeFromParent {
- // Remove this timerCtx from its parent cancelCtx's children.
- removeChild(c.cancelCtx.Context, c)
- }
- c.mu.Lock()
- if c.timer != nil {
- c.timer.Stop()
- c.timer = nil
- }
- c.mu.Unlock()
-}
-
-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete:
-//
-// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
-// defer cancel() // releases resources if slowOperation completes before timeout elapses
-// return slowOperation(ctx)
-// }
-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
- return WithDeadline(parent, time.Now().Add(timeout))
-}
-
-// WithValue returns a copy of parent in which the value associated with key is
-// val.
-//
-// Use context Values only for request-scoped data that transits processes and
-// APIs, not for passing optional parameters to functions.
-func WithValue(parent Context, key interface{}, val interface{}) Context {
- return &valueCtx{parent, key, val}
-}
-
-// A valueCtx carries a key-value pair. It implements Value for that key and
-// delegates all other calls to the embedded Context.
-type valueCtx struct {
- Context
- key, val interface{}
-}
-
-func (c *valueCtx) String() string {
- return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
-}
-
-func (c *valueCtx) Value(key interface{}) interface{} {
- if c.key == key {
- return c.val
- }
- return c.Context.Value(key)
-}
diff --git a/vendor/golang.org/x/net/context/withtimeout_test.go b/vendor/golang.org/x/net/context/withtimeout_test.go
deleted file mode 100644
index a6754dc36..000000000
--- a/vendor/golang.org/x/net/context/withtimeout_test.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package context_test
-
-import (
- "fmt"
- "time"
-
- "golang.org/x/net/context"
-)
-
-func ExampleWithTimeout() {
- // Pass a context with a timeout to tell a blocking function that it
- // should abandon its work after the timeout elapses.
- ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond)
- select {
- case <-time.After(200 * time.Millisecond):
- fmt.Println("overslept")
- case <-ctx.Done():
- fmt.Println(ctx.Err()) // prints "context deadline exceeded"
- }
- // Output:
- // context deadline exceeded
-}
diff --git a/vendor/golang.org/x/net/http2/.gitignore b/vendor/golang.org/x/net/http2/.gitignore
deleted file mode 100644
index 190f12234..000000000
--- a/vendor/golang.org/x/net/http2/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*~
-h2i/h2i
diff --git a/vendor/golang.org/x/net/http2/Dockerfile b/vendor/golang.org/x/net/http2/Dockerfile
deleted file mode 100644
index 53fc52579..000000000
--- a/vendor/golang.org/x/net/http2/Dockerfile
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# This Dockerfile builds a recent curl with HTTP/2 client support, using
-# a recent nghttp2 build.
-#
-# See the Makefile for how to tag it. If Docker and that image is found, the
-# Go tests use this curl binary for integration tests.
-#
-
-FROM ubuntu:trusty
-
-RUN apt-get update && \
- apt-get upgrade -y && \
- apt-get install -y git-core build-essential wget
-
-RUN apt-get install -y --no-install-recommends \
- autotools-dev libtool pkg-config zlib1g-dev \
- libcunit1-dev libssl-dev libxml2-dev libevent-dev \
- automake autoconf
-
-# The list of packages nghttp2 recommends for h2load:
-RUN apt-get install -y --no-install-recommends make binutils \
- autoconf automake autotools-dev \
- libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev \
- libev-dev libevent-dev libjansson-dev libjemalloc-dev \
- cython python3.4-dev python-setuptools
-
-# Note: setting NGHTTP2_VER before the git clone, so an old git clone isn't cached:
-ENV NGHTTP2_VER 895da9a
-RUN cd /root && git clone https://github.com/tatsuhiro-t/nghttp2.git
-
-WORKDIR /root/nghttp2
-RUN git reset --hard $NGHTTP2_VER
-RUN autoreconf -i
-RUN automake
-RUN autoconf
-RUN ./configure
-RUN make
-RUN make install
-
-WORKDIR /root
-RUN wget http://curl.haxx.se/download/curl-7.45.0.tar.gz
-RUN tar -zxvf curl-7.45.0.tar.gz
-WORKDIR /root/curl-7.45.0
-RUN ./configure --with-ssl --with-nghttp2=/usr/local
-RUN make
-RUN make install
-RUN ldconfig
-
-CMD ["-h"]
-ENTRYPOINT ["/usr/local/bin/curl"]
-
diff --git a/vendor/golang.org/x/net/http2/Makefile b/vendor/golang.org/x/net/http2/Makefile
deleted file mode 100644
index 55fd826f7..000000000
--- a/vendor/golang.org/x/net/http2/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-curlimage:
- docker build -t gohttp2/curl .
-
diff --git a/vendor/golang.org/x/net/http2/README b/vendor/golang.org/x/net/http2/README
deleted file mode 100644
index 360d5aa37..000000000
--- a/vendor/golang.org/x/net/http2/README
+++ /dev/null
@@ -1,20 +0,0 @@
-This is a work-in-progress HTTP/2 implementation for Go.
-
-It will eventually live in the Go standard library and won't require
-any changes to your code to use. It will just be automatic.
-
-Status:
-
-* The server support is pretty good. A few things are missing
- but are being worked on.
-* The client work has just started but shares a lot of code
- is coming along much quicker.
-
-Docs are at https://godoc.org/golang.org/x/net/http2
-
-Demo test server at https://http2.golang.org/
-
-Help & bug reports welcome!
-
-Contributing: https://golang.org/doc/contribute.html
-Bugs: https://golang.org/issue/new?title=x/net/http2:+
diff --git a/vendor/golang.org/x/net/http2/ciphers.go b/vendor/golang.org/x/net/http2/ciphers.go
deleted file mode 100644
index 698860b77..000000000
--- a/vendor/golang.org/x/net/http2/ciphers.go
+++ /dev/null
@@ -1,641 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-// A list of the possible cipher suite ids. Taken from
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt
-
-const (
- cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000
- cipher_TLS_RSA_WITH_NULL_MD5 uint16 = 0x0001
- cipher_TLS_RSA_WITH_NULL_SHA uint16 = 0x0002
- cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0003
- cipher_TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
- cipher_TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
- cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x0006
- cipher_TLS_RSA_WITH_IDEA_CBC_SHA uint16 = 0x0007
- cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0008
- cipher_TLS_RSA_WITH_DES_CBC_SHA uint16 = 0x0009
- cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000A
- cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000B
- cipher_TLS_DH_DSS_WITH_DES_CBC_SHA uint16 = 0x000C
- cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x000D
- cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000E
- cipher_TLS_DH_RSA_WITH_DES_CBC_SHA uint16 = 0x000F
- cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0010
- cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011
- cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA uint16 = 0x0012
- cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x0013
- cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014
- cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA uint16 = 0x0015
- cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016
- cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0017
- cipher_TLS_DH_anon_WITH_RC4_128_MD5 uint16 = 0x0018
- cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019
- cipher_TLS_DH_anon_WITH_DES_CBC_SHA uint16 = 0x001A
- cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0x001B
- // Reserved uint16 = 0x001C-1D
- cipher_TLS_KRB5_WITH_DES_CBC_SHA uint16 = 0x001E
- cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA uint16 = 0x001F
- cipher_TLS_KRB5_WITH_RC4_128_SHA uint16 = 0x0020
- cipher_TLS_KRB5_WITH_IDEA_CBC_SHA uint16 = 0x0021
- cipher_TLS_KRB5_WITH_DES_CBC_MD5 uint16 = 0x0022
- cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5 uint16 = 0x0023
- cipher_TLS_KRB5_WITH_RC4_128_MD5 uint16 = 0x0024
- cipher_TLS_KRB5_WITH_IDEA_CBC_MD5 uint16 = 0x0025
- cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA uint16 = 0x0026
- cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA uint16 = 0x0027
- cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA uint16 = 0x0028
- cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 uint16 = 0x0029
- cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x002A
- cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5 uint16 = 0x002B
- cipher_TLS_PSK_WITH_NULL_SHA uint16 = 0x002C
- cipher_TLS_DHE_PSK_WITH_NULL_SHA uint16 = 0x002D
- cipher_TLS_RSA_PSK_WITH_NULL_SHA uint16 = 0x002E
- cipher_TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002F
- cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0030
- cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0031
- cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0032
- cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033
- cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA uint16 = 0x0034
- cipher_TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
- cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0036
- cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0037
- cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0038
- cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039
- cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA uint16 = 0x003A
- cipher_TLS_RSA_WITH_NULL_SHA256 uint16 = 0x003B
- cipher_TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003C
- cipher_TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003D
- cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x003E
- cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003F
- cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x0040
- cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0041
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0042
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0043
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046
- // Reserved uint16 = 0x0047-4F
- // Reserved uint16 = 0x0050-58
- // Reserved uint16 = 0x0059-5C
- // Unassigned uint16 = 0x005D-5F
- // Reserved uint16 = 0x0060-66
- cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067
- cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x0068
- cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x0069
- cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A
- cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B
- cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C
- cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D
- // Unassigned uint16 = 0x006E-83
- cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0084
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0085
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0086
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0087
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0088
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0089
- cipher_TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008A
- cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008B
- cipher_TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008C
- cipher_TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008D
- cipher_TLS_DHE_PSK_WITH_RC4_128_SHA uint16 = 0x008E
- cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008F
- cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0090
- cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0091
- cipher_TLS_RSA_PSK_WITH_RC4_128_SHA uint16 = 0x0092
- cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x0093
- cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0094
- cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0095
- cipher_TLS_RSA_WITH_SEED_CBC_SHA uint16 = 0x0096
- cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA uint16 = 0x0097
- cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA uint16 = 0x0098
- cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA uint16 = 0x0099
- cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA uint16 = 0x009A
- cipher_TLS_DH_anon_WITH_SEED_CBC_SHA uint16 = 0x009B
- cipher_TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009C
- cipher_TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009D
- cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009E
- cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009F
- cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x00A0
- cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x00A1
- cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A2
- cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A3
- cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A4
- cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A5
- cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256 uint16 = 0x00A6
- cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384 uint16 = 0x00A7
- cipher_TLS_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00A8
- cipher_TLS_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00A9
- cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AA
- cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AB
- cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AC
- cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AD
- cipher_TLS_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00AE
- cipher_TLS_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00AF
- cipher_TLS_PSK_WITH_NULL_SHA256 uint16 = 0x00B0
- cipher_TLS_PSK_WITH_NULL_SHA384 uint16 = 0x00B1
- cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B2
- cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B3
- cipher_TLS_DHE_PSK_WITH_NULL_SHA256 uint16 = 0x00B4
- cipher_TLS_DHE_PSK_WITH_NULL_SHA384 uint16 = 0x00B5
- cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B6
- cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B7
- cipher_TLS_RSA_PSK_WITH_NULL_SHA256 uint16 = 0x00B8
- cipher_TLS_RSA_PSK_WITH_NULL_SHA384 uint16 = 0x00B9
- cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BA
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BB
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BC
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF
- cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C0
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C1
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C2
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5
- // Unassigned uint16 = 0x00C6-FE
- cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF
- // Unassigned uint16 = 0x01-55,*
- cipher_TLS_FALLBACK_SCSV uint16 = 0x5600
- // Unassigned uint16 = 0x5601 - 0xC000
- cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA uint16 = 0xC001
- cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA uint16 = 0xC002
- cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC003
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC004
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC005
- cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA uint16 = 0xC006
- cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xC007
- cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC008
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC009
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC00A
- cipher_TLS_ECDH_RSA_WITH_NULL_SHA uint16 = 0xC00B
- cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA uint16 = 0xC00C
- cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC00D
- cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC00E
- cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC00F
- cipher_TLS_ECDHE_RSA_WITH_NULL_SHA uint16 = 0xC010
- cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xC011
- cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC012
- cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC013
- cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC014
- cipher_TLS_ECDH_anon_WITH_NULL_SHA uint16 = 0xC015
- cipher_TLS_ECDH_anon_WITH_RC4_128_SHA uint16 = 0xC016
- cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0xC017
- cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA uint16 = 0xC018
- cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA uint16 = 0xC019
- cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01A
- cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01B
- cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01C
- cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA uint16 = 0xC01D
- cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC01E
- cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA uint16 = 0xC01F
- cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA uint16 = 0xC020
- cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC021
- cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA uint16 = 0xC022
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC023
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC024
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC025
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC026
- cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC027
- cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC028
- cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC029
- cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC02A
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02B
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02C
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02D
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02E
- cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02F
- cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC030
- cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC031
- cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC032
- cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA uint16 = 0xC033
- cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0xC034
- cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xC035
- cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xC036
- cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0xC037
- cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0xC038
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA uint16 = 0xC039
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256 uint16 = 0xC03A
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384 uint16 = 0xC03B
- cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03C
- cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03D
- cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03E
- cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03F
- cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC040
- cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC041
- cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC042
- cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC043
- cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC044
- cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC045
- cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC046
- cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC047
- cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC048
- cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC049
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04A
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04B
- cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04C
- cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04D
- cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04E
- cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04F
- cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC050
- cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC051
- cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC052
- cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC053
- cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC054
- cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC055
- cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC056
- cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC057
- cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC058
- cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC059
- cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05A
- cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05B
- cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05C
- cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05D
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05E
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05F
- cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC060
- cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC061
- cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC062
- cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC063
- cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC064
- cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC065
- cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC066
- cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC067
- cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC068
- cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC069
- cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06A
- cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06B
- cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06C
- cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06D
- cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06E
- cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06F
- cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC070
- cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC071
- cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072
- cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC074
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC075
- cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC076
- cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC077
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC078
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC079
- cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07A
- cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07B
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07C
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07D
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07E
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07F
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC080
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC081
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC082
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC083
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC084
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC085
- cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086
- cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC088
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC089
- cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08A
- cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08B
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08C
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08D
- cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08E
- cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08F
- cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC090
- cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC091
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC092
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC093
- cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC094
- cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC095
- cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC096
- cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC097
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC098
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC099
- cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC09A
- cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC09B
- cipher_TLS_RSA_WITH_AES_128_CCM uint16 = 0xC09C
- cipher_TLS_RSA_WITH_AES_256_CCM uint16 = 0xC09D
- cipher_TLS_DHE_RSA_WITH_AES_128_CCM uint16 = 0xC09E
- cipher_TLS_DHE_RSA_WITH_AES_256_CCM uint16 = 0xC09F
- cipher_TLS_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A0
- cipher_TLS_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A1
- cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A2
- cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A3
- cipher_TLS_PSK_WITH_AES_128_CCM uint16 = 0xC0A4
- cipher_TLS_PSK_WITH_AES_256_CCM uint16 = 0xC0A5
- cipher_TLS_DHE_PSK_WITH_AES_128_CCM uint16 = 0xC0A6
- cipher_TLS_DHE_PSK_WITH_AES_256_CCM uint16 = 0xC0A7
- cipher_TLS_PSK_WITH_AES_128_CCM_8 uint16 = 0xC0A8
- cipher_TLS_PSK_WITH_AES_256_CCM_8 uint16 = 0xC0A9
- cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8 uint16 = 0xC0AA
- cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8 uint16 = 0xC0AB
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM uint16 = 0xC0AC
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM uint16 = 0xC0AD
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 uint16 = 0xC0AE
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 uint16 = 0xC0AF
- // Unassigned uint16 = 0xC0B0-FF
- // Unassigned uint16 = 0xC1-CB,*
- // Unassigned uint16 = 0xCC00-A7
- cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA8
- cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9
- cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAA
- cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAB
- cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAC
- cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAD
- cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAE
-)
-
-// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
-// References:
-// https://tools.ietf.org/html/rfc7540#appendix-A
-// Reject cipher suites from Appendix A.
-// "This list includes those cipher suites that do not
-// offer an ephemeral key exchange and those that are
-// based on the TLS null, stream or block cipher type"
-func isBadCipher(cipher uint16) bool {
- switch cipher {
- case cipher_TLS_NULL_WITH_NULL_NULL,
- cipher_TLS_RSA_WITH_NULL_MD5,
- cipher_TLS_RSA_WITH_NULL_SHA,
- cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5,
- cipher_TLS_RSA_WITH_RC4_128_MD5,
- cipher_TLS_RSA_WITH_RC4_128_SHA,
- cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- cipher_TLS_RSA_WITH_IDEA_CBC_SHA,
- cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_RSA_WITH_DES_CBC_SHA,
- cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_DES_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_DES_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,
- cipher_TLS_DH_anon_WITH_RC4_128_MD5,
- cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DH_anon_WITH_DES_CBC_SHA,
- cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_KRB5_WITH_DES_CBC_SHA,
- cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_KRB5_WITH_RC4_128_SHA,
- cipher_TLS_KRB5_WITH_IDEA_CBC_SHA,
- cipher_TLS_KRB5_WITH_DES_CBC_MD5,
- cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5,
- cipher_TLS_KRB5_WITH_RC4_128_MD5,
- cipher_TLS_KRB5_WITH_IDEA_CBC_MD5,
- cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,
- cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA,
- cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA,
- cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5,
- cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5,
- cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5,
- cipher_TLS_PSK_WITH_NULL_SHA,
- cipher_TLS_DHE_PSK_WITH_NULL_SHA,
- cipher_TLS_RSA_PSK_WITH_NULL_SHA,
- cipher_TLS_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA,
- cipher_TLS_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA,
- cipher_TLS_RSA_WITH_NULL_SHA256,
- cipher_TLS_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_RSA_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
- cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256,
- cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_PSK_WITH_RC4_128_SHA,
- cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_PSK_WITH_AES_128_CBC_SHA,
- cipher_TLS_PSK_WITH_AES_256_CBC_SHA,
- cipher_TLS_DHE_PSK_WITH_RC4_128_SHA,
- cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
- cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
- cipher_TLS_RSA_PSK_WITH_RC4_128_SHA,
- cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
- cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
- cipher_TLS_RSA_WITH_SEED_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA,
- cipher_TLS_DH_anon_WITH_SEED_CBC_SHA,
- cipher_TLS_RSA_WITH_AES_128_GCM_SHA256,
- cipher_TLS_RSA_WITH_AES_256_GCM_SHA384,
- cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
- cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
- cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256,
- cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
- cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256,
- cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_AES_128_GCM_SHA256,
- cipher_TLS_PSK_WITH_AES_256_GCM_SHA384,
- cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
- cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_AES_128_CBC_SHA256,
- cipher_TLS_PSK_WITH_AES_256_CBC_SHA384,
- cipher_TLS_PSK_WITH_NULL_SHA256,
- cipher_TLS_PSK_WITH_NULL_SHA384,
- cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
- cipher_TLS_DHE_PSK_WITH_NULL_SHA256,
- cipher_TLS_DHE_PSK_WITH_NULL_SHA384,
- cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
- cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
- cipher_TLS_RSA_PSK_WITH_NULL_SHA256,
- cipher_TLS_RSA_PSK_WITH_NULL_SHA384,
- cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
- cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA,
- cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDH_RSA_WITH_NULL_SHA,
- cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA,
- cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDHE_RSA_WITH_NULL_SHA,
- cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDH_anon_WITH_NULL_SHA,
- cipher_TLS_ECDH_anon_WITH_RC4_128_SHA,
- cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
- cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
- cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
- cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
- cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
- cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
- cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
- cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
- cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA,
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256,
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384,
- cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_RSA_WITH_AES_128_CCM,
- cipher_TLS_RSA_WITH_AES_256_CCM,
- cipher_TLS_RSA_WITH_AES_128_CCM_8,
- cipher_TLS_RSA_WITH_AES_256_CCM_8,
- cipher_TLS_PSK_WITH_AES_128_CCM,
- cipher_TLS_PSK_WITH_AES_256_CCM,
- cipher_TLS_PSK_WITH_AES_128_CCM_8,
- cipher_TLS_PSK_WITH_AES_256_CCM_8:
- return true
- default:
- return false
- }
-}
diff --git a/vendor/golang.org/x/net/http2/ciphers_test.go b/vendor/golang.org/x/net/http2/ciphers_test.go
deleted file mode 100644
index 25aead013..000000000
--- a/vendor/golang.org/x/net/http2/ciphers_test.go
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import "testing"
-
-func TestIsBadCipherBad(t *testing.T) {
- for _, c := range badCiphers {
- if !isBadCipher(c) {
- t.Errorf("Wrong result for isBadCipher(%d), want true")
- }
- }
-}
-
-// verify we don't give false positives on ciphers not on blacklist
-func TestIsBadCipherGood(t *testing.T) {
- goodCiphers := map[uint16]string{
- cipher_TLS_DHE_RSA_WITH_AES_256_CCM: "cipher_TLS_DHE_RSA_WITH_AES_256_CCM",
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM: "cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM",
- cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: "cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
- }
- for c, name := range goodCiphers {
- if isBadCipher(c) {
- t.Errorf("Wrong result for isBadCipher(%d) %s, want false", c, name)
- }
- }
-}
-
-// copied from https://http2.github.io/http2-spec/#BadCipherSuites,
-var badCiphers = []uint16{
- cipher_TLS_NULL_WITH_NULL_NULL,
- cipher_TLS_RSA_WITH_NULL_MD5,
- cipher_TLS_RSA_WITH_NULL_SHA,
- cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5,
- cipher_TLS_RSA_WITH_RC4_128_MD5,
- cipher_TLS_RSA_WITH_RC4_128_SHA,
- cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- cipher_TLS_RSA_WITH_IDEA_CBC_SHA,
- cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_RSA_WITH_DES_CBC_SHA,
- cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_DES_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_DES_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,
- cipher_TLS_DH_anon_WITH_RC4_128_MD5,
- cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
- cipher_TLS_DH_anon_WITH_DES_CBC_SHA,
- cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_KRB5_WITH_DES_CBC_SHA,
- cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_KRB5_WITH_RC4_128_SHA,
- cipher_TLS_KRB5_WITH_IDEA_CBC_SHA,
- cipher_TLS_KRB5_WITH_DES_CBC_MD5,
- cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5,
- cipher_TLS_KRB5_WITH_RC4_128_MD5,
- cipher_TLS_KRB5_WITH_IDEA_CBC_MD5,
- cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,
- cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA,
- cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA,
- cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5,
- cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5,
- cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5,
- cipher_TLS_PSK_WITH_NULL_SHA,
- cipher_TLS_DHE_PSK_WITH_NULL_SHA,
- cipher_TLS_RSA_PSK_WITH_NULL_SHA,
- cipher_TLS_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA,
- cipher_TLS_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA,
- cipher_TLS_RSA_WITH_NULL_SHA256,
- cipher_TLS_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_RSA_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
- cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256,
- cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA,
- cipher_TLS_PSK_WITH_RC4_128_SHA,
- cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_PSK_WITH_AES_128_CBC_SHA,
- cipher_TLS_PSK_WITH_AES_256_CBC_SHA,
- cipher_TLS_DHE_PSK_WITH_RC4_128_SHA,
- cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
- cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
- cipher_TLS_RSA_PSK_WITH_RC4_128_SHA,
- cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
- cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
- cipher_TLS_RSA_WITH_SEED_CBC_SHA,
- cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA,
- cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA,
- cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA,
- cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA,
- cipher_TLS_DH_anon_WITH_SEED_CBC_SHA,
- cipher_TLS_RSA_WITH_AES_128_GCM_SHA256,
- cipher_TLS_RSA_WITH_AES_256_GCM_SHA384,
- cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
- cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
- cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256,
- cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
- cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256,
- cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_AES_128_GCM_SHA256,
- cipher_TLS_PSK_WITH_AES_256_GCM_SHA384,
- cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
- cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_AES_128_CBC_SHA256,
- cipher_TLS_PSK_WITH_AES_256_CBC_SHA384,
- cipher_TLS_PSK_WITH_NULL_SHA256,
- cipher_TLS_PSK_WITH_NULL_SHA384,
- cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
- cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
- cipher_TLS_DHE_PSK_WITH_NULL_SHA256,
- cipher_TLS_DHE_PSK_WITH_NULL_SHA384,
- cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
- cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
- cipher_TLS_RSA_PSK_WITH_NULL_SHA256,
- cipher_TLS_RSA_PSK_WITH_NULL_SHA384,
- cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
- cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
- cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA,
- cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDH_RSA_WITH_NULL_SHA,
- cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA,
- cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDHE_RSA_WITH_NULL_SHA,
- cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDH_anon_WITH_NULL_SHA,
- cipher_TLS_ECDH_anon_WITH_RC4_128_SHA,
- cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
- cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
- cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
- cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
- cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
- cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
- cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
- cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
- cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
- cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
- cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
- cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
- cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
- cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA,
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256,
- cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384,
- cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
- cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
- cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- cipher_TLS_RSA_WITH_AES_128_CCM,
- cipher_TLS_RSA_WITH_AES_256_CCM,
- cipher_TLS_RSA_WITH_AES_128_CCM_8,
- cipher_TLS_RSA_WITH_AES_256_CCM_8,
- cipher_TLS_PSK_WITH_AES_128_CCM,
- cipher_TLS_PSK_WITH_AES_256_CCM,
- cipher_TLS_PSK_WITH_AES_128_CCM_8,
- cipher_TLS_PSK_WITH_AES_256_CCM_8,
-}
diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go
deleted file mode 100644
index bdf5652b0..000000000
--- a/vendor/golang.org/x/net/http2/client_conn_pool.go
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Transport code's client connection pooling.
-
-package http2
-
-import (
- "crypto/tls"
- "net/http"
- "sync"
-)
-
-// ClientConnPool manages a pool of HTTP/2 client connections.
-type ClientConnPool interface {
- GetClientConn(req *http.Request, addr string) (*ClientConn, error)
- MarkDead(*ClientConn)
-}
-
-// clientConnPoolIdleCloser is the interface implemented by ClientConnPool
-// implementations which can close their idle connections.
-type clientConnPoolIdleCloser interface {
- ClientConnPool
- closeIdleConnections()
-}
-
-var (
- _ clientConnPoolIdleCloser = (*clientConnPool)(nil)
- _ clientConnPoolIdleCloser = noDialClientConnPool{}
-)
-
-// TODO: use singleflight for dialing and addConnCalls?
-type clientConnPool struct {
- t *Transport
-
- mu sync.Mutex // TODO: maybe switch to RWMutex
- // TODO: add support for sharing conns based on cert names
- // (e.g. share conn for googleapis.com and appspot.com)
- conns map[string][]*ClientConn // key is host:port
- dialing map[string]*dialCall // currently in-flight dials
- keys map[*ClientConn][]string
- addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls
-}
-
-func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
- return p.getClientConn(req, addr, dialOnMiss)
-}
-
-const (
- dialOnMiss = true
- noDialOnMiss = false
-)
-
-func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
- if isConnectionCloseRequest(req) && dialOnMiss {
- // It gets its own connection.
- const singleUse = true
- cc, err := p.t.dialClientConn(addr, singleUse)
- if err != nil {
- return nil, err
- }
- return cc, nil
- }
- p.mu.Lock()
- for _, cc := range p.conns[addr] {
- if cc.CanTakeNewRequest() {
- p.mu.Unlock()
- return cc, nil
- }
- }
- if !dialOnMiss {
- p.mu.Unlock()
- return nil, ErrNoCachedConn
- }
- call := p.getStartDialLocked(addr)
- p.mu.Unlock()
- <-call.done
- return call.res, call.err
-}
-
-// dialCall is an in-flight Transport dial call to a host.
-type dialCall struct {
- p *clientConnPool
- done chan struct{} // closed when done
- res *ClientConn // valid after done is closed
- err error // valid after done is closed
-}
-
-// requires p.mu is held.
-func (p *clientConnPool) getStartDialLocked(addr string) *dialCall {
- if call, ok := p.dialing[addr]; ok {
- // A dial is already in-flight. Don't start another.
- return call
- }
- call := &dialCall{p: p, done: make(chan struct{})}
- if p.dialing == nil {
- p.dialing = make(map[string]*dialCall)
- }
- p.dialing[addr] = call
- go call.dial(addr)
- return call
-}
-
-// run in its own goroutine.
-func (c *dialCall) dial(addr string) {
- const singleUse = false // shared conn
- c.res, c.err = c.p.t.dialClientConn(addr, singleUse)
- close(c.done)
-
- c.p.mu.Lock()
- delete(c.p.dialing, addr)
- if c.err == nil {
- c.p.addConnLocked(addr, c.res)
- }
- c.p.mu.Unlock()
-}
-
-// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
-// already exist. It coalesces concurrent calls with the same key.
-// This is used by the http1 Transport code when it creates a new connection. Because
-// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know
-// the protocol), it can get into a situation where it has multiple TLS connections.
-// This code decides which ones live or die.
-// The return value used is whether c was used.
-// c is never closed.
-func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c *tls.Conn) (used bool, err error) {
- p.mu.Lock()
- for _, cc := range p.conns[key] {
- if cc.CanTakeNewRequest() {
- p.mu.Unlock()
- return false, nil
- }
- }
- call, dup := p.addConnCalls[key]
- if !dup {
- if p.addConnCalls == nil {
- p.addConnCalls = make(map[string]*addConnCall)
- }
- call = &addConnCall{
- p: p,
- done: make(chan struct{}),
- }
- p.addConnCalls[key] = call
- go call.run(t, key, c)
- }
- p.mu.Unlock()
-
- <-call.done
- if call.err != nil {
- return false, call.err
- }
- return !dup, nil
-}
-
-type addConnCall struct {
- p *clientConnPool
- done chan struct{} // closed when done
- err error
-}
-
-func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
- cc, err := t.NewClientConn(tc)
-
- p := c.p
- p.mu.Lock()
- if err != nil {
- c.err = err
- } else {
- p.addConnLocked(key, cc)
- }
- delete(p.addConnCalls, key)
- p.mu.Unlock()
- close(c.done)
-}
-
-func (p *clientConnPool) addConn(key string, cc *ClientConn) {
- p.mu.Lock()
- p.addConnLocked(key, cc)
- p.mu.Unlock()
-}
-
-// p.mu must be held
-func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {
- for _, v := range p.conns[key] {
- if v == cc {
- return
- }
- }
- if p.conns == nil {
- p.conns = make(map[string][]*ClientConn)
- }
- if p.keys == nil {
- p.keys = make(map[*ClientConn][]string)
- }
- p.conns[key] = append(p.conns[key], cc)
- p.keys[cc] = append(p.keys[cc], key)
-}
-
-func (p *clientConnPool) MarkDead(cc *ClientConn) {
- p.mu.Lock()
- defer p.mu.Unlock()
- for _, key := range p.keys[cc] {
- vv, ok := p.conns[key]
- if !ok {
- continue
- }
- newList := filterOutClientConn(vv, cc)
- if len(newList) > 0 {
- p.conns[key] = newList
- } else {
- delete(p.conns, key)
- }
- }
- delete(p.keys, cc)
-}
-
-func (p *clientConnPool) closeIdleConnections() {
- p.mu.Lock()
- defer p.mu.Unlock()
- // TODO: don't close a cc if it was just added to the pool
- // milliseconds ago and has never been used. There's currently
- // a small race window with the HTTP/1 Transport's integration
- // where it can add an idle conn just before using it, and
- // somebody else can concurrently call CloseIdleConns and
- // break some caller's RoundTrip.
- for _, vv := range p.conns {
- for _, cc := range vv {
- cc.closeIfIdle()
- }
- }
-}
-
-func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn {
- out := in[:0]
- for _, v := range in {
- if v != exclude {
- out = append(out, v)
- }
- }
- // If we filtered it out, zero out the last item to prevent
- // the GC from seeing it.
- if len(in) != len(out) {
- in[len(in)-1] = nil
- }
- return out
-}
-
-// noDialClientConnPool is an implementation of http2.ClientConnPool
-// which never dials. We let the HTTP/1.1 client dial and use its TLS
-// connection instead.
-type noDialClientConnPool struct{ *clientConnPool }
-
-func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
- return p.getClientConn(req, addr, noDialOnMiss)
-}
diff --git a/vendor/golang.org/x/net/http2/configure_transport.go b/vendor/golang.org/x/net/http2/configure_transport.go
deleted file mode 100644
index b65fc6d42..000000000
--- a/vendor/golang.org/x/net/http2/configure_transport.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.6
-
-package http2
-
-import (
- "crypto/tls"
- "fmt"
- "net/http"
-)
-
-func configureTransport(t1 *http.Transport) (*Transport, error) {
- connPool := new(clientConnPool)
- t2 := &Transport{
- ConnPool: noDialClientConnPool{connPool},
- t1: t1,
- }
- connPool.t = t2
- if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
- return nil, err
- }
- if t1.TLSClientConfig == nil {
- t1.TLSClientConfig = new(tls.Config)
- }
- if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
- t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
- }
- if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
- t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
- }
- upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper {
- addr := authorityAddr("https", authority)
- if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
- go c.Close()
- return erringRoundTripper{err}
- } else if !used {
- // Turns out we don't need this c.
- // For example, two goroutines made requests to the same host
- // at the same time, both kicking off TCP dials. (since protocol
- // was unknown)
- go c.Close()
- }
- return t2
- }
- if m := t1.TLSNextProto; len(m) == 0 {
- t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{
- "h2": upgradeFn,
- }
- } else {
- m["h2"] = upgradeFn
- }
- return t2, nil
-}
-
-// registerHTTPSProtocol calls Transport.RegisterProtocol but
-// converting panics into errors.
-func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
- defer func() {
- if e := recover(); e != nil {
- err = fmt.Errorf("%v", e)
- }
- }()
- t.RegisterProtocol("https", rt)
- return nil
-}
-
-// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
-// if there's already has a cached connection to the host.
-type noDialH2RoundTripper struct{ t *Transport }
-
-func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
- res, err := rt.t.RoundTrip(req)
- if err == ErrNoCachedConn {
- return nil, http.ErrSkipAltProtocol
- }
- return res, err
-}
diff --git a/vendor/golang.org/x/net/http2/databuffer.go b/vendor/golang.org/x/net/http2/databuffer.go
deleted file mode 100644
index a3067f8de..000000000
--- a/vendor/golang.org/x/net/http2/databuffer.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "errors"
- "fmt"
- "sync"
-)
-
-// Buffer chunks are allocated from a pool to reduce pressure on GC.
-// The maximum wasted space per dataBuffer is 2x the largest size class,
-// which happens when the dataBuffer has multiple chunks and there is
-// one unread byte in both the first and last chunks. We use a few size
-// classes to minimize overheads for servers that typically receive very
-// small request bodies.
-//
-// TODO: Benchmark to determine if the pools are necessary. The GC may have
-// improved enough that we can instead allocate chunks like this:
-// make([]byte, max(16<<10, expectedBytesRemaining))
-var (
- dataChunkSizeClasses = []int{
- 1 << 10,
- 2 << 10,
- 4 << 10,
- 8 << 10,
- 16 << 10,
- }
- dataChunkPools = [...]sync.Pool{
- {New: func() interface{} { return make([]byte, 1<<10) }},
- {New: func() interface{} { return make([]byte, 2<<10) }},
- {New: func() interface{} { return make([]byte, 4<<10) }},
- {New: func() interface{} { return make([]byte, 8<<10) }},
- {New: func() interface{} { return make([]byte, 16<<10) }},
- }
-)
-
-func getDataBufferChunk(size int64) []byte {
- i := 0
- for ; i < len(dataChunkSizeClasses)-1; i++ {
- if size <= int64(dataChunkSizeClasses[i]) {
- break
- }
- }
- return dataChunkPools[i].Get().([]byte)
-}
-
-func putDataBufferChunk(p []byte) {
- for i, n := range dataChunkSizeClasses {
- if len(p) == n {
- dataChunkPools[i].Put(p)
- return
- }
- }
- panic(fmt.Sprintf("unexpected buffer len=%v", len(p)))
-}
-
-// dataBuffer is an io.ReadWriter backed by a list of data chunks.
-// Each dataBuffer is used to read DATA frames on a single stream.
-// The buffer is divided into chunks so the server can limit the
-// total memory used by a single connection without limiting the
-// request body size on any single stream.
-type dataBuffer struct {
- chunks [][]byte
- r int // next byte to read is chunks[0][r]
- w int // next byte to write is chunks[len(chunks)-1][w]
- size int // total buffered bytes
- expected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0)
-}
-
-var errReadEmpty = errors.New("read from empty dataBuffer")
-
-// Read copies bytes from the buffer into p.
-// It is an error to read when no data is available.
-func (b *dataBuffer) Read(p []byte) (int, error) {
- if b.size == 0 {
- return 0, errReadEmpty
- }
- var ntotal int
- for len(p) > 0 && b.size > 0 {
- readFrom := b.bytesFromFirstChunk()
- n := copy(p, readFrom)
- p = p[n:]
- ntotal += n
- b.r += n
- b.size -= n
- // If the first chunk has been consumed, advance to the next chunk.
- if b.r == len(b.chunks[0]) {
- putDataBufferChunk(b.chunks[0])
- end := len(b.chunks) - 1
- copy(b.chunks[:end], b.chunks[1:])
- b.chunks[end] = nil
- b.chunks = b.chunks[:end]
- b.r = 0
- }
- }
- return ntotal, nil
-}
-
-func (b *dataBuffer) bytesFromFirstChunk() []byte {
- if len(b.chunks) == 1 {
- return b.chunks[0][b.r:b.w]
- }
- return b.chunks[0][b.r:]
-}
-
-// Len returns the number of bytes of the unread portion of the buffer.
-func (b *dataBuffer) Len() int {
- return b.size
-}
-
-// Write appends p to the buffer.
-func (b *dataBuffer) Write(p []byte) (int, error) {
- ntotal := len(p)
- for len(p) > 0 {
- // If the last chunk is empty, allocate a new chunk. Try to allocate
- // enough to fully copy p plus any additional bytes we expect to
- // receive. However, this may allocate less than len(p).
- want := int64(len(p))
- if b.expected > want {
- want = b.expected
- }
- chunk := b.lastChunkOrAlloc(want)
- n := copy(chunk[b.w:], p)
- p = p[n:]
- b.w += n
- b.size += n
- b.expected -= int64(n)
- }
- return ntotal, nil
-}
-
-func (b *dataBuffer) lastChunkOrAlloc(want int64) []byte {
- if len(b.chunks) != 0 {
- last := b.chunks[len(b.chunks)-1]
- if b.w < len(last) {
- return last
- }
- }
- chunk := getDataBufferChunk(want)
- b.chunks = append(b.chunks, chunk)
- b.w = 0
- return chunk
-}
diff --git a/vendor/golang.org/x/net/http2/databuffer_test.go b/vendor/golang.org/x/net/http2/databuffer_test.go
deleted file mode 100644
index 028e12e52..000000000
--- a/vendor/golang.org/x/net/http2/databuffer_test.go
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.7
-
-package http2
-
-import (
- "bytes"
- "fmt"
- "reflect"
- "testing"
-)
-
-func fmtDataChunk(chunk []byte) string {
- out := ""
- var last byte
- var count int
- for _, c := range chunk {
- if c != last {
- if count > 0 {
- out += fmt.Sprintf(" x %d ", count)
- count = 0
- }
- out += string([]byte{c})
- last = c
- }
- count++
- }
- if count > 0 {
- out += fmt.Sprintf(" x %d", count)
- }
- return out
-}
-
-func fmtDataChunks(chunks [][]byte) string {
- var out string
- for _, chunk := range chunks {
- out += fmt.Sprintf("{%q}", fmtDataChunk(chunk))
- }
- return out
-}
-
-func testDataBuffer(t *testing.T, wantBytes []byte, setup func(t *testing.T) *dataBuffer) {
- // Run setup, then read the remaining bytes from the dataBuffer and check
- // that they match wantBytes. We use different read sizes to check corner
- // cases in Read.
- for _, readSize := range []int{1, 2, 1 * 1024, 32 * 1024} {
- t.Run(fmt.Sprintf("ReadSize=%d", readSize), func(t *testing.T) {
- b := setup(t)
- buf := make([]byte, readSize)
- var gotRead bytes.Buffer
- for {
- n, err := b.Read(buf)
- gotRead.Write(buf[:n])
- if err == errReadEmpty {
- break
- }
- if err != nil {
- t.Fatalf("error after %v bytes: %v", gotRead.Len(), err)
- }
- }
- if got, want := gotRead.Bytes(), wantBytes; !bytes.Equal(got, want) {
- t.Errorf("FinalRead=%q, want %q", fmtDataChunk(got), fmtDataChunk(want))
- }
- })
- }
-}
-
-func TestDataBufferAllocation(t *testing.T) {
- writes := [][]byte{
- bytes.Repeat([]byte("a"), 1*1024-1),
- []byte("a"),
- bytes.Repeat([]byte("b"), 4*1024-1),
- []byte("b"),
- bytes.Repeat([]byte("c"), 8*1024-1),
- []byte("c"),
- bytes.Repeat([]byte("d"), 16*1024-1),
- []byte("d"),
- bytes.Repeat([]byte("e"), 32*1024),
- }
- var wantRead bytes.Buffer
- for _, p := range writes {
- wantRead.Write(p)
- }
-
- testDataBuffer(t, wantRead.Bytes(), func(t *testing.T) *dataBuffer {
- b := &dataBuffer{}
- for _, p := range writes {
- if n, err := b.Write(p); n != len(p) || err != nil {
- t.Fatalf("Write(%q x %d)=%v,%v want %v,nil", p[:1], len(p), n, err, len(p))
- }
- }
- want := [][]byte{
- bytes.Repeat([]byte("a"), 1*1024),
- bytes.Repeat([]byte("b"), 4*1024),
- bytes.Repeat([]byte("c"), 8*1024),
- bytes.Repeat([]byte("d"), 16*1024),
- bytes.Repeat([]byte("e"), 16*1024),
- bytes.Repeat([]byte("e"), 16*1024),
- }
- if !reflect.DeepEqual(b.chunks, want) {
- t.Errorf("dataBuffer.chunks\ngot: %s\nwant: %s", fmtDataChunks(b.chunks), fmtDataChunks(want))
- }
- return b
- })
-}
-
-func TestDataBufferAllocationWithExpected(t *testing.T) {
- writes := [][]byte{
- bytes.Repeat([]byte("a"), 1*1024), // allocates 16KB
- bytes.Repeat([]byte("b"), 14*1024),
- bytes.Repeat([]byte("c"), 15*1024), // allocates 16KB more
- bytes.Repeat([]byte("d"), 2*1024),
- bytes.Repeat([]byte("e"), 1*1024), // overflows 32KB expectation, allocates just 1KB
- }
- var wantRead bytes.Buffer
- for _, p := range writes {
- wantRead.Write(p)
- }
-
- testDataBuffer(t, wantRead.Bytes(), func(t *testing.T) *dataBuffer {
- b := &dataBuffer{expected: 32 * 1024}
- for _, p := range writes {
- if n, err := b.Write(p); n != len(p) || err != nil {
- t.Fatalf("Write(%q x %d)=%v,%v want %v,nil", p[:1], len(p), n, err, len(p))
- }
- }
- want := [][]byte{
- append(bytes.Repeat([]byte("a"), 1*1024), append(bytes.Repeat([]byte("b"), 14*1024), bytes.Repeat([]byte("c"), 1*1024)...)...),
- append(bytes.Repeat([]byte("c"), 14*1024), bytes.Repeat([]byte("d"), 2*1024)...),
- bytes.Repeat([]byte("e"), 1*1024),
- }
- if !reflect.DeepEqual(b.chunks, want) {
- t.Errorf("dataBuffer.chunks\ngot: %s\nwant: %s", fmtDataChunks(b.chunks), fmtDataChunks(want))
- }
- return b
- })
-}
-
-func TestDataBufferWriteAfterPartialRead(t *testing.T) {
- testDataBuffer(t, []byte("cdxyz"), func(t *testing.T) *dataBuffer {
- b := &dataBuffer{}
- if n, err := b.Write([]byte("abcd")); n != 4 || err != nil {
- t.Fatalf("Write(\"abcd\")=%v,%v want 4,nil", n, err)
- }
- p := make([]byte, 2)
- if n, err := b.Read(p); n != 2 || err != nil || !bytes.Equal(p, []byte("ab")) {
- t.Fatalf("Read()=%q,%v,%v want \"ab\",2,nil", p, n, err)
- }
- if n, err := b.Write([]byte("xyz")); n != 3 || err != nil {
- t.Fatalf("Write(\"xyz\")=%v,%v want 3,nil", n, err)
- }
- return b
- })
-}
diff --git a/vendor/golang.org/x/net/http2/errors.go b/vendor/golang.org/x/net/http2/errors.go
deleted file mode 100644
index 20fd7626a..000000000
--- a/vendor/golang.org/x/net/http2/errors.go
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "errors"
- "fmt"
-)
-
-// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
-type ErrCode uint32
-
-const (
- ErrCodeNo ErrCode = 0x0
- ErrCodeProtocol ErrCode = 0x1
- ErrCodeInternal ErrCode = 0x2
- ErrCodeFlowControl ErrCode = 0x3
- ErrCodeSettingsTimeout ErrCode = 0x4
- ErrCodeStreamClosed ErrCode = 0x5
- ErrCodeFrameSize ErrCode = 0x6
- ErrCodeRefusedStream ErrCode = 0x7
- ErrCodeCancel ErrCode = 0x8
- ErrCodeCompression ErrCode = 0x9
- ErrCodeConnect ErrCode = 0xa
- ErrCodeEnhanceYourCalm ErrCode = 0xb
- ErrCodeInadequateSecurity ErrCode = 0xc
- ErrCodeHTTP11Required ErrCode = 0xd
-)
-
-var errCodeName = map[ErrCode]string{
- ErrCodeNo: "NO_ERROR",
- ErrCodeProtocol: "PROTOCOL_ERROR",
- ErrCodeInternal: "INTERNAL_ERROR",
- ErrCodeFlowControl: "FLOW_CONTROL_ERROR",
- ErrCodeSettingsTimeout: "SETTINGS_TIMEOUT",
- ErrCodeStreamClosed: "STREAM_CLOSED",
- ErrCodeFrameSize: "FRAME_SIZE_ERROR",
- ErrCodeRefusedStream: "REFUSED_STREAM",
- ErrCodeCancel: "CANCEL",
- ErrCodeCompression: "COMPRESSION_ERROR",
- ErrCodeConnect: "CONNECT_ERROR",
- ErrCodeEnhanceYourCalm: "ENHANCE_YOUR_CALM",
- ErrCodeInadequateSecurity: "INADEQUATE_SECURITY",
- ErrCodeHTTP11Required: "HTTP_1_1_REQUIRED",
-}
-
-func (e ErrCode) String() string {
- if s, ok := errCodeName[e]; ok {
- return s
- }
- return fmt.Sprintf("unknown error code 0x%x", uint32(e))
-}
-
-// ConnectionError is an error that results in the termination of the
-// entire connection.
-type ConnectionError ErrCode
-
-func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: %s", ErrCode(e)) }
-
-// StreamError is an error that only affects one stream within an
-// HTTP/2 connection.
-type StreamError struct {
- StreamID uint32
- Code ErrCode
- Cause error // optional additional detail
-}
-
-func streamError(id uint32, code ErrCode) StreamError {
- return StreamError{StreamID: id, Code: code}
-}
-
-func (e StreamError) Error() string {
- if e.Cause != nil {
- return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause)
- }
- return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
-}
-
-// 6.9.1 The Flow Control Window
-// "If a sender receives a WINDOW_UPDATE that causes a flow control
-// window to exceed this maximum it MUST terminate either the stream
-// or the connection, as appropriate. For streams, [...]; for the
-// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code."
-type goAwayFlowError struct{}
-
-func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
-
-// connErrorReason wraps a ConnectionError with an informative error about why it occurs.
-
-// Errors of this type are only returned by the frame parser functions
-// and converted into ConnectionError(ErrCodeProtocol).
-type connError struct {
- Code ErrCode
- Reason string
-}
-
-func (e connError) Error() string {
- return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
-}
-
-type pseudoHeaderError string
-
-func (e pseudoHeaderError) Error() string {
- return fmt.Sprintf("invalid pseudo-header %q", string(e))
-}
-
-type duplicatePseudoHeaderError string
-
-func (e duplicatePseudoHeaderError) Error() string {
- return fmt.Sprintf("duplicate pseudo-header %q", string(e))
-}
-
-type headerFieldNameError string
-
-func (e headerFieldNameError) Error() string {
- return fmt.Sprintf("invalid header field name %q", string(e))
-}
-
-type headerFieldValueError string
-
-func (e headerFieldValueError) Error() string {
- return fmt.Sprintf("invalid header field value %q", string(e))
-}
-
-var (
- errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
- errPseudoAfterRegular = errors.New("pseudo header field after regular")
-)
diff --git a/vendor/golang.org/x/net/http2/errors_test.go b/vendor/golang.org/x/net/http2/errors_test.go
deleted file mode 100644
index da5c58c31..000000000
--- a/vendor/golang.org/x/net/http2/errors_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import "testing"
-
-func TestErrCodeString(t *testing.T) {
- tests := []struct {
- err ErrCode
- want string
- }{
- {ErrCodeProtocol, "PROTOCOL_ERROR"},
- {0xd, "HTTP_1_1_REQUIRED"},
- {0xf, "unknown error code 0xf"},
- }
- for i, tt := range tests {
- got := tt.err.String()
- if got != tt.want {
- t.Errorf("%d. Error = %q; want %q", i, got, tt.want)
- }
- }
-}
diff --git a/vendor/golang.org/x/net/http2/flow.go b/vendor/golang.org/x/net/http2/flow.go
deleted file mode 100644
index 957de2542..000000000
--- a/vendor/golang.org/x/net/http2/flow.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Flow control
-
-package http2
-
-// flow is the flow control window's size.
-type flow struct {
- // n is the number of DATA bytes we're allowed to send.
- // A flow is kept both on a conn and a per-stream.
- n int32
-
- // conn points to the shared connection-level flow that is
- // shared by all streams on that conn. It is nil for the flow
- // that's on the conn directly.
- conn *flow
-}
-
-func (f *flow) setConnFlow(cf *flow) { f.conn = cf }
-
-func (f *flow) available() int32 {
- n := f.n
- if f.conn != nil && f.conn.n < n {
- n = f.conn.n
- }
- return n
-}
-
-func (f *flow) take(n int32) {
- if n > f.available() {
- panic("internal error: took too much")
- }
- f.n -= n
- if f.conn != nil {
- f.conn.n -= n
- }
-}
-
-// add adds n bytes (positive or negative) to the flow control window.
-// It returns false if the sum would exceed 2^31-1.
-func (f *flow) add(n int32) bool {
- remain := (1<<31 - 1) - f.n
- if n > remain {
- return false
- }
- f.n += n
- return true
-}
diff --git a/vendor/golang.org/x/net/http2/flow_test.go b/vendor/golang.org/x/net/http2/flow_test.go
deleted file mode 100644
index 859adf5d1..000000000
--- a/vendor/golang.org/x/net/http2/flow_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import "testing"
-
-func TestFlow(t *testing.T) {
- var st flow
- var conn flow
- st.add(3)
- conn.add(2)
-
- if got, want := st.available(), int32(3); got != want {
- t.Errorf("available = %d; want %d", got, want)
- }
- st.setConnFlow(&conn)
- if got, want := st.available(), int32(2); got != want {
- t.Errorf("after parent setup, available = %d; want %d", got, want)
- }
-
- st.take(2)
- if got, want := conn.available(), int32(0); got != want {
- t.Errorf("after taking 2, conn = %d; want %d", got, want)
- }
- if got, want := st.available(), int32(0); got != want {
- t.Errorf("after taking 2, stream = %d; want %d", got, want)
- }
-}
-
-func TestFlowAdd(t *testing.T) {
- var f flow
- if !f.add(1) {
- t.Fatal("failed to add 1")
- }
- if !f.add(-1) {
- t.Fatal("failed to add -1")
- }
- if got, want := f.available(), int32(0); got != want {
- t.Fatalf("size = %d; want %d", got, want)
- }
- if !f.add(1<<31 - 1) {
- t.Fatal("failed to add 2^31-1")
- }
- if got, want := f.available(), int32(1<<31-1); got != want {
- t.Fatalf("size = %d; want %d", got, want)
- }
- if f.add(1) {
- t.Fatal("adding 1 to max shouldn't be allowed")
- }
-
-}
diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go
deleted file mode 100644
index 3b1489072..000000000
--- a/vendor/golang.org/x/net/http2/frame.go
+++ /dev/null
@@ -1,1579 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bytes"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "log"
- "strings"
- "sync"
-
- "golang.org/x/net/http2/hpack"
- "golang.org/x/net/lex/httplex"
-)
-
-const frameHeaderLen = 9
-
-var padZeros = make([]byte, 255) // zeros for padding
-
-// A FrameType is a registered frame type as defined in
-// http://http2.github.io/http2-spec/#rfc.section.11.2
-type FrameType uint8
-
-const (
- FrameData FrameType = 0x0
- FrameHeaders FrameType = 0x1
- FramePriority FrameType = 0x2
- FrameRSTStream FrameType = 0x3
- FrameSettings FrameType = 0x4
- FramePushPromise FrameType = 0x5
- FramePing FrameType = 0x6
- FrameGoAway FrameType = 0x7
- FrameWindowUpdate FrameType = 0x8
- FrameContinuation FrameType = 0x9
-)
-
-var frameName = map[FrameType]string{
- FrameData: "DATA",
- FrameHeaders: "HEADERS",
- FramePriority: "PRIORITY",
- FrameRSTStream: "RST_STREAM",
- FrameSettings: "SETTINGS",
- FramePushPromise: "PUSH_PROMISE",
- FramePing: "PING",
- FrameGoAway: "GOAWAY",
- FrameWindowUpdate: "WINDOW_UPDATE",
- FrameContinuation: "CONTINUATION",
-}
-
-func (t FrameType) String() string {
- if s, ok := frameName[t]; ok {
- return s
- }
- return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
-}
-
-// Flags is a bitmask of HTTP/2 flags.
-// The meaning of flags varies depending on the frame type.
-type Flags uint8
-
-// Has reports whether f contains all (0 or more) flags in v.
-func (f Flags) Has(v Flags) bool {
- return (f & v) == v
-}
-
-// Frame-specific FrameHeader flag bits.
-const (
- // Data Frame
- FlagDataEndStream Flags = 0x1
- FlagDataPadded Flags = 0x8
-
- // Headers Frame
- FlagHeadersEndStream Flags = 0x1
- FlagHeadersEndHeaders Flags = 0x4
- FlagHeadersPadded Flags = 0x8
- FlagHeadersPriority Flags = 0x20
-
- // Settings Frame
- FlagSettingsAck Flags = 0x1
-
- // Ping Frame
- FlagPingAck Flags = 0x1
-
- // Continuation Frame
- FlagContinuationEndHeaders Flags = 0x4
-
- FlagPushPromiseEndHeaders Flags = 0x4
- FlagPushPromisePadded Flags = 0x8
-)
-
-var flagName = map[FrameType]map[Flags]string{
- FrameData: {
- FlagDataEndStream: "END_STREAM",
- FlagDataPadded: "PADDED",
- },
- FrameHeaders: {
- FlagHeadersEndStream: "END_STREAM",
- FlagHeadersEndHeaders: "END_HEADERS",
- FlagHeadersPadded: "PADDED",
- FlagHeadersPriority: "PRIORITY",
- },
- FrameSettings: {
- FlagSettingsAck: "ACK",
- },
- FramePing: {
- FlagPingAck: "ACK",
- },
- FrameContinuation: {
- FlagContinuationEndHeaders: "END_HEADERS",
- },
- FramePushPromise: {
- FlagPushPromiseEndHeaders: "END_HEADERS",
- FlagPushPromisePadded: "PADDED",
- },
-}
-
-// a frameParser parses a frame given its FrameHeader and payload
-// bytes. The length of payload will always equal fh.Length (which
-// might be 0).
-type frameParser func(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error)
-
-var frameParsers = map[FrameType]frameParser{
- FrameData: parseDataFrame,
- FrameHeaders: parseHeadersFrame,
- FramePriority: parsePriorityFrame,
- FrameRSTStream: parseRSTStreamFrame,
- FrameSettings: parseSettingsFrame,
- FramePushPromise: parsePushPromise,
- FramePing: parsePingFrame,
- FrameGoAway: parseGoAwayFrame,
- FrameWindowUpdate: parseWindowUpdateFrame,
- FrameContinuation: parseContinuationFrame,
-}
-
-func typeFrameParser(t FrameType) frameParser {
- if f := frameParsers[t]; f != nil {
- return f
- }
- return parseUnknownFrame
-}
-
-// A FrameHeader is the 9 byte header of all HTTP/2 frames.
-//
-// See http://http2.github.io/http2-spec/#FrameHeader
-type FrameHeader struct {
- valid bool // caller can access []byte fields in the Frame
-
- // Type is the 1 byte frame type. There are ten standard frame
- // types, but extension frame types may be written by WriteRawFrame
- // and will be returned by ReadFrame (as UnknownFrame).
- Type FrameType
-
- // Flags are the 1 byte of 8 potential bit flags per frame.
- // They are specific to the frame type.
- Flags Flags
-
- // Length is the length of the frame, not including the 9 byte header.
- // The maximum size is one byte less than 16MB (uint24), but only
- // frames up to 16KB are allowed without peer agreement.
- Length uint32
-
- // StreamID is which stream this frame is for. Certain frames
- // are not stream-specific, in which case this field is 0.
- StreamID uint32
-}
-
-// Header returns h. It exists so FrameHeaders can be embedded in other
-// specific frame types and implement the Frame interface.
-func (h FrameHeader) Header() FrameHeader { return h }
-
-func (h FrameHeader) String() string {
- var buf bytes.Buffer
- buf.WriteString("[FrameHeader ")
- h.writeDebug(&buf)
- buf.WriteByte(']')
- return buf.String()
-}
-
-func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
- buf.WriteString(h.Type.String())
- if h.Flags != 0 {
- buf.WriteString(" flags=")
- set := 0
- for i := uint8(0); i < 8; i++ {
- if h.Flags&(1<<i) == 0 {
- continue
- }
- set++
- if set > 1 {
- buf.WriteByte('|')
- }
- name := flagName[h.Type][Flags(1<<i)]
- if name != "" {
- buf.WriteString(name)
- } else {
- fmt.Fprintf(buf, "0x%x", 1<<i)
- }
- }
- }
- if h.StreamID != 0 {
- fmt.Fprintf(buf, " stream=%d", h.StreamID)
- }
- fmt.Fprintf(buf, " len=%d", h.Length)
-}
-
-func (h *FrameHeader) checkValid() {
- if !h.valid {
- panic("Frame accessor called on non-owned Frame")
- }
-}
-
-func (h *FrameHeader) invalidate() { h.valid = false }
-
-// frame header bytes.
-// Used only by ReadFrameHeader.
-var fhBytes = sync.Pool{
- New: func() interface{} {
- buf := make([]byte, frameHeaderLen)
- return &buf
- },
-}
-
-// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
-// Most users should use Framer.ReadFrame instead.
-func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
- bufp := fhBytes.Get().(*[]byte)
- defer fhBytes.Put(bufp)
- return readFrameHeader(*bufp, r)
-}
-
-func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {
- _, err := io.ReadFull(r, buf[:frameHeaderLen])
- if err != nil {
- return FrameHeader{}, err
- }
- return FrameHeader{
- Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
- Type: FrameType(buf[3]),
- Flags: Flags(buf[4]),
- StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
- valid: true,
- }, nil
-}
-
-// A Frame is the base interface implemented by all frame types.
-// Callers will generally type-assert the specific frame type:
-// *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
-//
-// Frames are only valid until the next call to Framer.ReadFrame.
-type Frame interface {
- Header() FrameHeader
-
- // invalidate is called by Framer.ReadFrame to make this
- // frame's buffers as being invalid, since the subsequent
- // frame will reuse them.
- invalidate()
-}
-
-// A Framer reads and writes Frames.
-type Framer struct {
- r io.Reader
- lastFrame Frame
- errDetail error
-
- // lastHeaderStream is non-zero if the last frame was an
- // unfinished HEADERS/CONTINUATION.
- lastHeaderStream uint32
-
- maxReadSize uint32
- headerBuf [frameHeaderLen]byte
-
- // TODO: let getReadBuf be configurable, and use a less memory-pinning
- // allocator in server.go to minimize memory pinned for many idle conns.
- // Will probably also need to make frame invalidation have a hook too.
- getReadBuf func(size uint32) []byte
- readBuf []byte // cache for default getReadBuf
-
- maxWriteSize uint32 // zero means unlimited; TODO: implement
-
- w io.Writer
- wbuf []byte
-
- // AllowIllegalWrites permits the Framer's Write methods to
- // write frames that do not conform to the HTTP/2 spec. This
- // permits using the Framer to test other HTTP/2
- // implementations' conformance to the spec.
- // If false, the Write methods will prefer to return an error
- // rather than comply.
- AllowIllegalWrites bool
-
- // AllowIllegalReads permits the Framer's ReadFrame method
- // to return non-compliant frames or frame orders.
- // This is for testing and permits using the Framer to test
- // other HTTP/2 implementations' conformance to the spec.
- // It is not compatible with ReadMetaHeaders.
- AllowIllegalReads bool
-
- // ReadMetaHeaders if non-nil causes ReadFrame to merge
- // HEADERS and CONTINUATION frames together and return
- // MetaHeadersFrame instead.
- ReadMetaHeaders *hpack.Decoder
-
- // MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
- // It's used only if ReadMetaHeaders is set; 0 means a sane default
- // (currently 16MB)
- // If the limit is hit, MetaHeadersFrame.Truncated is set true.
- MaxHeaderListSize uint32
-
- // TODO: track which type of frame & with which flags was sent
- // last. Then return an error (unless AllowIllegalWrites) if
- // we're in the middle of a header block and a
- // non-Continuation or Continuation on a different stream is
- // attempted to be written.
-
- logReads, logWrites bool
-
- debugFramer *Framer // only use for logging written writes
- debugFramerBuf *bytes.Buffer
- debugReadLoggerf func(string, ...interface{})
- debugWriteLoggerf func(string, ...interface{})
-
- frameCache *frameCache // nil if frames aren't reused (default)
-}
-
-func (fr *Framer) maxHeaderListSize() uint32 {
- if fr.MaxHeaderListSize == 0 {
- return 16 << 20 // sane default, per docs
- }
- return fr.MaxHeaderListSize
-}
-
-func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
- // Write the FrameHeader.
- f.wbuf = append(f.wbuf[:0],
- 0, // 3 bytes of length, filled in in endWrite
- 0,
- 0,
- byte(ftype),
- byte(flags),
- byte(streamID>>24),
- byte(streamID>>16),
- byte(streamID>>8),
- byte(streamID))
-}
-
-func (f *Framer) endWrite() error {
- // Now that we know the final size, fill in the FrameHeader in
- // the space previously reserved for it. Abuse append.
- length := len(f.wbuf) - frameHeaderLen
- if length >= (1 << 24) {
- return ErrFrameTooLarge
- }
- _ = append(f.wbuf[:0],
- byte(length>>16),
- byte(length>>8),
- byte(length))
- if f.logWrites {
- f.logWrite()
- }
-
- n, err := f.w.Write(f.wbuf)
- if err == nil && n != len(f.wbuf) {
- err = io.ErrShortWrite
- }
- return err
-}
-
-func (f *Framer) logWrite() {
- if f.debugFramer == nil {
- f.debugFramerBuf = new(bytes.Buffer)
- f.debugFramer = NewFramer(nil, f.debugFramerBuf)
- f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
- // Let us read anything, even if we accidentally wrote it
- // in the wrong order:
- f.debugFramer.AllowIllegalReads = true
- }
- f.debugFramerBuf.Write(f.wbuf)
- fr, err := f.debugFramer.ReadFrame()
- if err != nil {
- f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f)
- return
- }
- f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
-}
-
-func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) }
-func (f *Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) }
-func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
-func (f *Framer) writeUint32(v uint32) {
- f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
-}
-
-const (
- minMaxFrameSize = 1 << 14
- maxFrameSize = 1<<24 - 1
-)
-
-// SetReuseFrames allows the Framer to reuse Frames.
-// If called on a Framer, Frames returned by calls to ReadFrame are only
-// valid until the next call to ReadFrame.
-func (fr *Framer) SetReuseFrames() {
- if fr.frameCache != nil {
- return
- }
- fr.frameCache = &frameCache{}
-}
-
-type frameCache struct {
- dataFrame DataFrame
-}
-
-func (fc *frameCache) getDataFrame() *DataFrame {
- if fc == nil {
- return &DataFrame{}
- }
- return &fc.dataFrame
-}
-
-// NewFramer returns a Framer that writes frames to w and reads them from r.
-func NewFramer(w io.Writer, r io.Reader) *Framer {
- fr := &Framer{
- w: w,
- r: r,
- logReads: logFrameReads,
- logWrites: logFrameWrites,
- debugReadLoggerf: log.Printf,
- debugWriteLoggerf: log.Printf,
- }
- fr.getReadBuf = func(size uint32) []byte {
- if cap(fr.readBuf) >= int(size) {
- return fr.readBuf[:size]
- }
- fr.readBuf = make([]byte, size)
- return fr.readBuf
- }
- fr.SetMaxReadFrameSize(maxFrameSize)
- return fr
-}
-
-// SetMaxReadFrameSize sets the maximum size of a frame
-// that will be read by a subsequent call to ReadFrame.
-// It is the caller's responsibility to advertise this
-// limit with a SETTINGS frame.
-func (fr *Framer) SetMaxReadFrameSize(v uint32) {
- if v > maxFrameSize {
- v = maxFrameSize
- }
- fr.maxReadSize = v
-}
-
-// ErrorDetail returns a more detailed error of the last error
-// returned by Framer.ReadFrame. For instance, if ReadFrame
-// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
-// will say exactly what was invalid. ErrorDetail is not guaranteed
-// to return a non-nil value and like the rest of the http2 package,
-// its return value is not protected by an API compatibility promise.
-// ErrorDetail is reset after the next call to ReadFrame.
-func (fr *Framer) ErrorDetail() error {
- return fr.errDetail
-}
-
-// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
-// sends a frame that is larger than declared with SetMaxReadFrameSize.
-var ErrFrameTooLarge = errors.New("http2: frame too large")
-
-// terminalReadFrameError reports whether err is an unrecoverable
-// error from ReadFrame and no other frames should be read.
-func terminalReadFrameError(err error) bool {
- if _, ok := err.(StreamError); ok {
- return false
- }
- return err != nil
-}
-
-// ReadFrame reads a single frame. The returned Frame is only valid
-// until the next call to ReadFrame.
-//
-// If the frame is larger than previously set with SetMaxReadFrameSize, the
-// returned error is ErrFrameTooLarge. Other errors may be of type
-// ConnectionError, StreamError, or anything else from the underlying
-// reader.
-func (fr *Framer) ReadFrame() (Frame, error) {
- fr.errDetail = nil
- if fr.lastFrame != nil {
- fr.lastFrame.invalidate()
- }
- fh, err := readFrameHeader(fr.headerBuf[:], fr.r)
- if err != nil {
- return nil, err
- }
- if fh.Length > fr.maxReadSize {
- return nil, ErrFrameTooLarge
- }
- payload := fr.getReadBuf(fh.Length)
- if _, err := io.ReadFull(fr.r, payload); err != nil {
- return nil, err
- }
- f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, payload)
- if err != nil {
- if ce, ok := err.(connError); ok {
- return nil, fr.connError(ce.Code, ce.Reason)
- }
- return nil, err
- }
- if err := fr.checkFrameOrder(f); err != nil {
- return nil, err
- }
- if fr.logReads {
- fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f))
- }
- if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {
- return fr.readMetaFrame(f.(*HeadersFrame))
- }
- return f, nil
-}
-
-// connError returns ConnectionError(code) but first
-// stashes away a public reason to the caller can optionally relay it
-// to the peer before hanging up on them. This might help others debug
-// their implementations.
-func (fr *Framer) connError(code ErrCode, reason string) error {
- fr.errDetail = errors.New(reason)
- return ConnectionError(code)
-}
-
-// checkFrameOrder reports an error if f is an invalid frame to return
-// next from ReadFrame. Mostly it checks whether HEADERS and
-// CONTINUATION frames are contiguous.
-func (fr *Framer) checkFrameOrder(f Frame) error {
- last := fr.lastFrame
- fr.lastFrame = f
- if fr.AllowIllegalReads {
- return nil
- }
-
- fh := f.Header()
- if fr.lastHeaderStream != 0 {
- if fh.Type != FrameContinuation {
- return fr.connError(ErrCodeProtocol,
- fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
- fh.Type, fh.StreamID,
- last.Header().Type, fr.lastHeaderStream))
- }
- if fh.StreamID != fr.lastHeaderStream {
- return fr.connError(ErrCodeProtocol,
- fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
- fh.StreamID, fr.lastHeaderStream))
- }
- } else if fh.Type == FrameContinuation {
- return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
- }
-
- switch fh.Type {
- case FrameHeaders, FrameContinuation:
- if fh.Flags.Has(FlagHeadersEndHeaders) {
- fr.lastHeaderStream = 0
- } else {
- fr.lastHeaderStream = fh.StreamID
- }
- }
-
- return nil
-}
-
-// A DataFrame conveys arbitrary, variable-length sequences of octets
-// associated with a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.1
-type DataFrame struct {
- FrameHeader
- data []byte
-}
-
-func (f *DataFrame) StreamEnded() bool {
- return f.FrameHeader.Flags.Has(FlagDataEndStream)
-}
-
-// Data returns the frame's data octets, not including any padding
-// size byte or padding suffix bytes.
-// The caller must not retain the returned memory past the next
-// call to ReadFrame.
-func (f *DataFrame) Data() []byte {
- f.checkValid()
- return f.data
-}
-
-func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
- if fh.StreamID == 0 {
- // DATA frames MUST be associated with a stream. If a
- // DATA frame is received whose stream identifier
- // field is 0x0, the recipient MUST respond with a
- // connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR.
- return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
- }
- f := fc.getDataFrame()
- f.FrameHeader = fh
-
- var padSize byte
- if fh.Flags.Has(FlagDataPadded) {
- var err error
- payload, padSize, err = readByte(payload)
- if err != nil {
- return nil, err
- }
- }
- if int(padSize) > len(payload) {
- // If the length of the padding is greater than the
- // length of the frame payload, the recipient MUST
- // treat this as a connection error.
- // Filed: https://github.com/http2/http2-spec/issues/610
- return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
- }
- f.data = payload[:len(payload)-int(padSize)]
- return f, nil
-}
-
-var (
- errStreamID = errors.New("invalid stream ID")
- errDepStreamID = errors.New("invalid dependent stream ID")
- errPadLength = errors.New("pad length too large")
- errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled")
-)
-
-func validStreamIDOrZero(streamID uint32) bool {
- return streamID&(1<<31) == 0
-}
-
-func validStreamID(streamID uint32) bool {
- return streamID != 0 && streamID&(1<<31) == 0
-}
-
-// WriteData writes a DATA frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility not to violate the maximum frame size
-// and to not call other Write methods concurrently.
-func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
- return f.WriteDataPadded(streamID, endStream, data, nil)
-}
-
-// WriteData writes a DATA frame with optional padding.
-//
-// If pad is nil, the padding bit is not sent.
-// The length of pad must not exceed 255 bytes.
-// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility not to violate the maximum frame size
-// and to not call other Write methods concurrently.
-func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
- if !validStreamID(streamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- if len(pad) > 0 {
- if len(pad) > 255 {
- return errPadLength
- }
- if !f.AllowIllegalWrites {
- for _, b := range pad {
- if b != 0 {
- // "Padding octets MUST be set to zero when sending."
- return errPadBytes
- }
- }
- }
- }
- var flags Flags
- if endStream {
- flags |= FlagDataEndStream
- }
- if pad != nil {
- flags |= FlagDataPadded
- }
- f.startWrite(FrameData, flags, streamID)
- if pad != nil {
- f.wbuf = append(f.wbuf, byte(len(pad)))
- }
- f.wbuf = append(f.wbuf, data...)
- f.wbuf = append(f.wbuf, pad...)
- return f.endWrite()
-}
-
-// A SettingsFrame conveys configuration parameters that affect how
-// endpoints communicate, such as preferences and constraints on peer
-// behavior.
-//
-// See http://http2.github.io/http2-spec/#SETTINGS
-type SettingsFrame struct {
- FrameHeader
- p []byte
-}
-
-func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
- if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
- // When this (ACK 0x1) bit is set, the payload of the
- // SETTINGS frame MUST be empty. Receipt of a
- // SETTINGS frame with the ACK flag set and a length
- // field value other than 0 MUST be treated as a
- // connection error (Section 5.4.1) of type
- // FRAME_SIZE_ERROR.
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- if fh.StreamID != 0 {
- // SETTINGS frames always apply to a connection,
- // never a single stream. The stream identifier for a
- // SETTINGS frame MUST be zero (0x0). If an endpoint
- // receives a SETTINGS frame whose stream identifier
- // field is anything other than 0x0, the endpoint MUST
- // respond with a connection error (Section 5.4.1) of
- // type PROTOCOL_ERROR.
- return nil, ConnectionError(ErrCodeProtocol)
- }
- if len(p)%6 != 0 {
- // Expecting even number of 6 byte settings.
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- f := &SettingsFrame{FrameHeader: fh, p: p}
- if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
- // Values above the maximum flow control window size of 2^31 - 1 MUST
- // be treated as a connection error (Section 5.4.1) of type
- // FLOW_CONTROL_ERROR.
- return nil, ConnectionError(ErrCodeFlowControl)
- }
- return f, nil
-}
-
-func (f *SettingsFrame) IsAck() bool {
- return f.FrameHeader.Flags.Has(FlagSettingsAck)
-}
-
-func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) {
- f.checkValid()
- buf := f.p
- for len(buf) > 0 {
- settingID := SettingID(binary.BigEndian.Uint16(buf[:2]))
- if settingID == s {
- return binary.BigEndian.Uint32(buf[2:6]), true
- }
- buf = buf[6:]
- }
- return 0, false
-}
-
-// ForeachSetting runs fn for each setting.
-// It stops and returns the first error.
-func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
- f.checkValid()
- buf := f.p
- for len(buf) > 0 {
- if err := fn(Setting{
- SettingID(binary.BigEndian.Uint16(buf[:2])),
- binary.BigEndian.Uint32(buf[2:6]),
- }); err != nil {
- return err
- }
- buf = buf[6:]
- }
- return nil
-}
-
-// WriteSettings writes a SETTINGS frame with zero or more settings
-// specified and the ACK bit not set.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteSettings(settings ...Setting) error {
- f.startWrite(FrameSettings, 0, 0)
- for _, s := range settings {
- f.writeUint16(uint16(s.ID))
- f.writeUint32(s.Val)
- }
- return f.endWrite()
-}
-
-// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteSettingsAck() error {
- f.startWrite(FrameSettings, FlagSettingsAck, 0)
- return f.endWrite()
-}
-
-// A PingFrame is a mechanism for measuring a minimal round trip time
-// from the sender, as well as determining whether an idle connection
-// is still functional.
-// See http://http2.github.io/http2-spec/#rfc.section.6.7
-type PingFrame struct {
- FrameHeader
- Data [8]byte
-}
-
-func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
-
-func parsePingFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
- if len(payload) != 8 {
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- if fh.StreamID != 0 {
- return nil, ConnectionError(ErrCodeProtocol)
- }
- f := &PingFrame{FrameHeader: fh}
- copy(f.Data[:], payload)
- return f, nil
-}
-
-func (f *Framer) WritePing(ack bool, data [8]byte) error {
- var flags Flags
- if ack {
- flags = FlagPingAck
- }
- f.startWrite(FramePing, flags, 0)
- f.writeBytes(data[:])
- return f.endWrite()
-}
-
-// A GoAwayFrame informs the remote peer to stop creating streams on this connection.
-// See http://http2.github.io/http2-spec/#rfc.section.6.8
-type GoAwayFrame struct {
- FrameHeader
- LastStreamID uint32
- ErrCode ErrCode
- debugData []byte
-}
-
-// DebugData returns any debug data in the GOAWAY frame. Its contents
-// are not defined.
-// The caller must not retain the returned memory past the next
-// call to ReadFrame.
-func (f *GoAwayFrame) DebugData() []byte {
- f.checkValid()
- return f.debugData
-}
-
-func parseGoAwayFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
- if fh.StreamID != 0 {
- return nil, ConnectionError(ErrCodeProtocol)
- }
- if len(p) < 8 {
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- return &GoAwayFrame{
- FrameHeader: fh,
- LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
- ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])),
- debugData: p[8:],
- }, nil
-}
-
-func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {
- f.startWrite(FrameGoAway, 0, 0)
- f.writeUint32(maxStreamID & (1<<31 - 1))
- f.writeUint32(uint32(code))
- f.writeBytes(debugData)
- return f.endWrite()
-}
-
-// An UnknownFrame is the frame type returned when the frame type is unknown
-// or no specific frame type parser exists.
-type UnknownFrame struct {
- FrameHeader
- p []byte
-}
-
-// Payload returns the frame's payload (after the header). It is not
-// valid to call this method after a subsequent call to
-// Framer.ReadFrame, nor is it valid to retain the returned slice.
-// The memory is owned by the Framer and is invalidated when the next
-// frame is read.
-func (f *UnknownFrame) Payload() []byte {
- f.checkValid()
- return f.p
-}
-
-func parseUnknownFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
- return &UnknownFrame{fh, p}, nil
-}
-
-// A WindowUpdateFrame is used to implement flow control.
-// See http://http2.github.io/http2-spec/#rfc.section.6.9
-type WindowUpdateFrame struct {
- FrameHeader
- Increment uint32 // never read with high bit set
-}
-
-func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
- if len(p) != 4 {
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
- if inc == 0 {
- // A receiver MUST treat the receipt of a
- // WINDOW_UPDATE frame with an flow control window
- // increment of 0 as a stream error (Section 5.4.2) of
- // type PROTOCOL_ERROR; errors on the connection flow
- // control window MUST be treated as a connection
- // error (Section 5.4.1).
- if fh.StreamID == 0 {
- return nil, ConnectionError(ErrCodeProtocol)
- }
- return nil, streamError(fh.StreamID, ErrCodeProtocol)
- }
- return &WindowUpdateFrame{
- FrameHeader: fh,
- Increment: inc,
- }, nil
-}
-
-// WriteWindowUpdate writes a WINDOW_UPDATE frame.
-// The increment value must be between 1 and 2,147,483,647, inclusive.
-// If the Stream ID is zero, the window update applies to the
-// connection as a whole.
-func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {
- // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
- if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
- return errors.New("illegal window increment value")
- }
- f.startWrite(FrameWindowUpdate, 0, streamID)
- f.writeUint32(incr)
- return f.endWrite()
-}
-
-// A HeadersFrame is used to open a stream and additionally carries a
-// header block fragment.
-type HeadersFrame struct {
- FrameHeader
-
- // Priority is set if FlagHeadersPriority is set in the FrameHeader.
- Priority PriorityParam
-
- headerFragBuf []byte // not owned
-}
-
-func (f *HeadersFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *HeadersFrame) HeadersEnded() bool {
- return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)
-}
-
-func (f *HeadersFrame) StreamEnded() bool {
- return f.FrameHeader.Flags.Has(FlagHeadersEndStream)
-}
-
-func (f *HeadersFrame) HasPriority() bool {
- return f.FrameHeader.Flags.Has(FlagHeadersPriority)
-}
-
-func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) {
- hf := &HeadersFrame{
- FrameHeader: fh,
- }
- if fh.StreamID == 0 {
- // HEADERS frames MUST be associated with a stream. If a HEADERS frame
- // is received whose stream identifier field is 0x0, the recipient MUST
- // respond with a connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR.
- return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
- }
- var padLength uint8
- if fh.Flags.Has(FlagHeadersPadded) {
- if p, padLength, err = readByte(p); err != nil {
- return
- }
- }
- if fh.Flags.Has(FlagHeadersPriority) {
- var v uint32
- p, v, err = readUint32(p)
- if err != nil {
- return nil, err
- }
- hf.Priority.StreamDep = v & 0x7fffffff
- hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
- p, hf.Priority.Weight, err = readByte(p)
- if err != nil {
- return nil, err
- }
- }
- if len(p)-int(padLength) <= 0 {
- return nil, streamError(fh.StreamID, ErrCodeProtocol)
- }
- hf.headerFragBuf = p[:len(p)-int(padLength)]
- return hf, nil
-}
-
-// HeadersFrameParam are the parameters for writing a HEADERS frame.
-type HeadersFrameParam struct {
- // StreamID is the required Stream ID to initiate.
- StreamID uint32
- // BlockFragment is part (or all) of a Header Block.
- BlockFragment []byte
-
- // EndStream indicates that the header block is the last that
- // the endpoint will send for the identified stream. Setting
- // this flag causes the stream to enter one of "half closed"
- // states.
- EndStream bool
-
- // EndHeaders indicates that this frame contains an entire
- // header block and is not followed by any
- // CONTINUATION frames.
- EndHeaders bool
-
- // PadLength is the optional number of bytes of zeros to add
- // to this frame.
- PadLength uint8
-
- // Priority, if non-zero, includes stream priority information
- // in the HEADER frame.
- Priority PriorityParam
-}
-
-// WriteHeaders writes a single HEADERS frame.
-//
-// This is a low-level header writing method. Encoding headers and
-// splitting them into any necessary CONTINUATION frames is handled
-// elsewhere.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
- if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- var flags Flags
- if p.PadLength != 0 {
- flags |= FlagHeadersPadded
- }
- if p.EndStream {
- flags |= FlagHeadersEndStream
- }
- if p.EndHeaders {
- flags |= FlagHeadersEndHeaders
- }
- if !p.Priority.IsZero() {
- flags |= FlagHeadersPriority
- }
- f.startWrite(FrameHeaders, flags, p.StreamID)
- if p.PadLength != 0 {
- f.writeByte(p.PadLength)
- }
- if !p.Priority.IsZero() {
- v := p.Priority.StreamDep
- if !validStreamIDOrZero(v) && !f.AllowIllegalWrites {
- return errDepStreamID
- }
- if p.Priority.Exclusive {
- v |= 1 << 31
- }
- f.writeUint32(v)
- f.writeByte(p.Priority.Weight)
- }
- f.wbuf = append(f.wbuf, p.BlockFragment...)
- f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
- return f.endWrite()
-}
-
-// A PriorityFrame specifies the sender-advised priority of a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.3
-type PriorityFrame struct {
- FrameHeader
- PriorityParam
-}
-
-// PriorityParam are the stream prioritzation parameters.
-type PriorityParam struct {
- // StreamDep is a 31-bit stream identifier for the
- // stream that this stream depends on. Zero means no
- // dependency.
- StreamDep uint32
-
- // Exclusive is whether the dependency is exclusive.
- Exclusive bool
-
- // Weight is the stream's zero-indexed weight. It should be
- // set together with StreamDep, or neither should be set. Per
- // the spec, "Add one to the value to obtain a weight between
- // 1 and 256."
- Weight uint8
-}
-
-func (p PriorityParam) IsZero() bool {
- return p == PriorityParam{}
-}
-
-func parsePriorityFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
- if fh.StreamID == 0 {
- return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
- }
- if len(payload) != 5 {
- return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
- }
- v := binary.BigEndian.Uint32(payload[:4])
- streamID := v & 0x7fffffff // mask off high bit
- return &PriorityFrame{
- FrameHeader: fh,
- PriorityParam: PriorityParam{
- Weight: payload[4],
- StreamDep: streamID,
- Exclusive: streamID != v, // was high bit set?
- },
- }, nil
-}
-
-// WritePriority writes a PRIORITY frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
- if !validStreamID(streamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- if !validStreamIDOrZero(p.StreamDep) {
- return errDepStreamID
- }
- f.startWrite(FramePriority, 0, streamID)
- v := p.StreamDep
- if p.Exclusive {
- v |= 1 << 31
- }
- f.writeUint32(v)
- f.writeByte(p.Weight)
- return f.endWrite()
-}
-
-// A RSTStreamFrame allows for abnormal termination of a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.4
-type RSTStreamFrame struct {
- FrameHeader
- ErrCode ErrCode
-}
-
-func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
- if len(p) != 4 {
- return nil, ConnectionError(ErrCodeFrameSize)
- }
- if fh.StreamID == 0 {
- return nil, ConnectionError(ErrCodeProtocol)
- }
- return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
-}
-
-// WriteRSTStream writes a RST_STREAM frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
- if !validStreamID(streamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- f.startWrite(FrameRSTStream, 0, streamID)
- f.writeUint32(uint32(code))
- return f.endWrite()
-}
-
-// A ContinuationFrame is used to continue a sequence of header block fragments.
-// See http://http2.github.io/http2-spec/#rfc.section.6.10
-type ContinuationFrame struct {
- FrameHeader
- headerFragBuf []byte
-}
-
-func parseContinuationFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
- if fh.StreamID == 0 {
- return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
- }
- return &ContinuationFrame{fh, p}, nil
-}
-
-func (f *ContinuationFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *ContinuationFrame) HeadersEnded() bool {
- return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)
-}
-
-// WriteContinuation writes a CONTINUATION frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
- if !validStreamID(streamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- var flags Flags
- if endHeaders {
- flags |= FlagContinuationEndHeaders
- }
- f.startWrite(FrameContinuation, flags, streamID)
- f.wbuf = append(f.wbuf, headerBlockFragment...)
- return f.endWrite()
-}
-
-// A PushPromiseFrame is used to initiate a server stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.6
-type PushPromiseFrame struct {
- FrameHeader
- PromiseID uint32
- headerFragBuf []byte // not owned
-}
-
-func (f *PushPromiseFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *PushPromiseFrame) HeadersEnded() bool {
- return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
-}
-
-func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) {
- pp := &PushPromiseFrame{
- FrameHeader: fh,
- }
- if pp.StreamID == 0 {
- // PUSH_PROMISE frames MUST be associated with an existing,
- // peer-initiated stream. The stream identifier of a
- // PUSH_PROMISE frame indicates the stream it is associated
- // with. If the stream identifier field specifies the value
- // 0x0, a recipient MUST respond with a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- return nil, ConnectionError(ErrCodeProtocol)
- }
- // The PUSH_PROMISE frame includes optional padding.
- // Padding fields and flags are identical to those defined for DATA frames
- var padLength uint8
- if fh.Flags.Has(FlagPushPromisePadded) {
- if p, padLength, err = readByte(p); err != nil {
- return
- }
- }
-
- p, pp.PromiseID, err = readUint32(p)
- if err != nil {
- return
- }
- pp.PromiseID = pp.PromiseID & (1<<31 - 1)
-
- if int(padLength) > len(p) {
- // like the DATA frame, error out if padding is longer than the body.
- return nil, ConnectionError(ErrCodeProtocol)
- }
- pp.headerFragBuf = p[:len(p)-int(padLength)]
- return pp, nil
-}
-
-// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
-type PushPromiseParam struct {
- // StreamID is the required Stream ID to initiate.
- StreamID uint32
-
- // PromiseID is the required Stream ID which this
- // Push Promises
- PromiseID uint32
-
- // BlockFragment is part (or all) of a Header Block.
- BlockFragment []byte
-
- // EndHeaders indicates that this frame contains an entire
- // header block and is not followed by any
- // CONTINUATION frames.
- EndHeaders bool
-
- // PadLength is the optional number of bytes of zeros to add
- // to this frame.
- PadLength uint8
-}
-
-// WritePushPromise writes a single PushPromise Frame.
-//
-// As with Header Frames, This is the low level call for writing
-// individual frames. Continuation frames are handled elsewhere.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *Framer) WritePushPromise(p PushPromiseParam) error {
- if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- var flags Flags
- if p.PadLength != 0 {
- flags |= FlagPushPromisePadded
- }
- if p.EndHeaders {
- flags |= FlagPushPromiseEndHeaders
- }
- f.startWrite(FramePushPromise, flags, p.StreamID)
- if p.PadLength != 0 {
- f.writeByte(p.PadLength)
- }
- if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
- return errStreamID
- }
- f.writeUint32(p.PromiseID)
- f.wbuf = append(f.wbuf, p.BlockFragment...)
- f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
- return f.endWrite()
-}
-
-// WriteRawFrame writes a raw frame. This can be used to write
-// extension frames unknown to this package.
-func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {
- f.startWrite(t, flags, streamID)
- f.writeBytes(payload)
- return f.endWrite()
-}
-
-func readByte(p []byte) (remain []byte, b byte, err error) {
- if len(p) == 0 {
- return nil, 0, io.ErrUnexpectedEOF
- }
- return p[1:], p[0], nil
-}
-
-func readUint32(p []byte) (remain []byte, v uint32, err error) {
- if len(p) < 4 {
- return nil, 0, io.ErrUnexpectedEOF
- }
- return p[4:], binary.BigEndian.Uint32(p[:4]), nil
-}
-
-type streamEnder interface {
- StreamEnded() bool
-}
-
-type headersEnder interface {
- HeadersEnded() bool
-}
-
-type headersOrContinuation interface {
- headersEnder
- HeaderBlockFragment() []byte
-}
-
-// A MetaHeadersFrame is the representation of one HEADERS frame and
-// zero or more contiguous CONTINUATION frames and the decoding of
-// their HPACK-encoded contents.
-//
-// This type of frame does not appear on the wire and is only returned
-// by the Framer when Framer.ReadMetaHeaders is set.
-type MetaHeadersFrame struct {
- *HeadersFrame
-
- // Fields are the fields contained in the HEADERS and
- // CONTINUATION frames. The underlying slice is owned by the
- // Framer and must not be retained after the next call to
- // ReadFrame.
- //
- // Fields are guaranteed to be in the correct http2 order and
- // not have unknown pseudo header fields or invalid header
- // field names or values. Required pseudo header fields may be
- // missing, however. Use the MetaHeadersFrame.Pseudo accessor
- // method access pseudo headers.
- Fields []hpack.HeaderField
-
- // Truncated is whether the max header list size limit was hit
- // and Fields is incomplete. The hpack decoder state is still
- // valid, however.
- Truncated bool
-}
-
-// PseudoValue returns the given pseudo header field's value.
-// The provided pseudo field should not contain the leading colon.
-func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string {
- for _, hf := range mh.Fields {
- if !hf.IsPseudo() {
- return ""
- }
- if hf.Name[1:] == pseudo {
- return hf.Value
- }
- }
- return ""
-}
-
-// RegularFields returns the regular (non-pseudo) header fields of mh.
-// The caller does not own the returned slice.
-func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField {
- for i, hf := range mh.Fields {
- if !hf.IsPseudo() {
- return mh.Fields[i:]
- }
- }
- return nil
-}
-
-// PseudoFields returns the pseudo header fields of mh.
-// The caller does not own the returned slice.
-func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
- for i, hf := range mh.Fields {
- if !hf.IsPseudo() {
- return mh.Fields[:i]
- }
- }
- return mh.Fields
-}
-
-func (mh *MetaHeadersFrame) checkPseudos() error {
- var isRequest, isResponse bool
- pf := mh.PseudoFields()
- for i, hf := range pf {
- switch hf.Name {
- case ":method", ":path", ":scheme", ":authority":
- isRequest = true
- case ":status":
- isResponse = true
- default:
- return pseudoHeaderError(hf.Name)
- }
- // Check for duplicates.
- // This would be a bad algorithm, but N is 4.
- // And this doesn't allocate.
- for _, hf2 := range pf[:i] {
- if hf.Name == hf2.Name {
- return duplicatePseudoHeaderError(hf.Name)
- }
- }
- }
- if isRequest && isResponse {
- return errMixPseudoHeaderTypes
- }
- return nil
-}
-
-func (fr *Framer) maxHeaderStringLen() int {
- v := fr.maxHeaderListSize()
- if uint32(int(v)) == v {
- return int(v)
- }
- // They had a crazy big number for MaxHeaderBytes anyway,
- // so give them unlimited header lengths:
- return 0
-}
-
-// readMetaFrame returns 0 or more CONTINUATION frames from fr and
-// merge them into into the provided hf and returns a MetaHeadersFrame
-// with the decoded hpack values.
-func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
- if fr.AllowIllegalReads {
- return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
- }
- mh := &MetaHeadersFrame{
- HeadersFrame: hf,
- }
- var remainSize = fr.maxHeaderListSize()
- var sawRegular bool
-
- var invalid error // pseudo header field errors
- hdec := fr.ReadMetaHeaders
- hdec.SetEmitEnabled(true)
- hdec.SetMaxStringLength(fr.maxHeaderStringLen())
- hdec.SetEmitFunc(func(hf hpack.HeaderField) {
- if VerboseLogs && fr.logReads {
- fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
- }
- if !httplex.ValidHeaderFieldValue(hf.Value) {
- invalid = headerFieldValueError(hf.Value)
- }
- isPseudo := strings.HasPrefix(hf.Name, ":")
- if isPseudo {
- if sawRegular {
- invalid = errPseudoAfterRegular
- }
- } else {
- sawRegular = true
- if !validWireHeaderFieldName(hf.Name) {
- invalid = headerFieldNameError(hf.Name)
- }
- }
-
- if invalid != nil {
- hdec.SetEmitEnabled(false)
- return
- }
-
- size := hf.Size()
- if size > remainSize {
- hdec.SetEmitEnabled(false)
- mh.Truncated = true
- return
- }
- remainSize -= size
-
- mh.Fields = append(mh.Fields, hf)
- })
- // Lose reference to MetaHeadersFrame:
- defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})
-
- var hc headersOrContinuation = hf
- for {
- frag := hc.HeaderBlockFragment()
- if _, err := hdec.Write(frag); err != nil {
- return nil, ConnectionError(ErrCodeCompression)
- }
-
- if hc.HeadersEnded() {
- break
- }
- if f, err := fr.ReadFrame(); err != nil {
- return nil, err
- } else {
- hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder
- }
- }
-
- mh.HeadersFrame.headerFragBuf = nil
- mh.HeadersFrame.invalidate()
-
- if err := hdec.Close(); err != nil {
- return nil, ConnectionError(ErrCodeCompression)
- }
- if invalid != nil {
- fr.errDetail = invalid
- if VerboseLogs {
- log.Printf("http2: invalid header: %v", invalid)
- }
- return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid}
- }
- if err := mh.checkPseudos(); err != nil {
- fr.errDetail = err
- if VerboseLogs {
- log.Printf("http2: invalid pseudo headers: %v", err)
- }
- return nil, StreamError{mh.StreamID, ErrCodeProtocol, err}
- }
- return mh, nil
-}
-
-func summarizeFrame(f Frame) string {
- var buf bytes.Buffer
- f.Header().writeDebug(&buf)
- switch f := f.(type) {
- case *SettingsFrame:
- n := 0
- f.ForeachSetting(func(s Setting) error {
- n++
- if n == 1 {
- buf.WriteString(", settings:")
- }
- fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
- return nil
- })
- if n > 0 {
- buf.Truncate(buf.Len() - 1) // remove trailing comma
- }
- case *DataFrame:
- data := f.Data()
- const max = 256
- if len(data) > max {
- data = data[:max]
- }
- fmt.Fprintf(&buf, " data=%q", data)
- if len(f.Data()) > max {
- fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
- }
- case *WindowUpdateFrame:
- if f.StreamID == 0 {
- buf.WriteString(" (conn)")
- }
- fmt.Fprintf(&buf, " incr=%v", f.Increment)
- case *PingFrame:
- fmt.Fprintf(&buf, " ping=%q", f.Data[:])
- case *GoAwayFrame:
- fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
- f.LastStreamID, f.ErrCode, f.debugData)
- case *RSTStreamFrame:
- fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
- }
- return buf.String()
-}
diff --git a/vendor/golang.org/x/net/http2/frame_test.go b/vendor/golang.org/x/net/http2/frame_test.go
deleted file mode 100644
index 37266bc58..000000000
--- a/vendor/golang.org/x/net/http2/frame_test.go
+++ /dev/null
@@ -1,1191 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bytes"
- "fmt"
- "io"
- "reflect"
- "strings"
- "testing"
- "unsafe"
-
- "golang.org/x/net/http2/hpack"
-)
-
-func testFramer() (*Framer, *bytes.Buffer) {
- buf := new(bytes.Buffer)
- return NewFramer(buf, buf), buf
-}
-
-func TestFrameSizes(t *testing.T) {
- // Catch people rearranging the FrameHeader fields.
- if got, want := int(unsafe.Sizeof(FrameHeader{})), 12; got != want {
- t.Errorf("FrameHeader size = %d; want %d", got, want)
- }
-}
-
-func TestFrameTypeString(t *testing.T) {
- tests := []struct {
- ft FrameType
- want string
- }{
- {FrameData, "DATA"},
- {FramePing, "PING"},
- {FrameGoAway, "GOAWAY"},
- {0xf, "UNKNOWN_FRAME_TYPE_15"},
- }
-
- for i, tt := range tests {
- got := tt.ft.String()
- if got != tt.want {
- t.Errorf("%d. String(FrameType %d) = %q; want %q", i, int(tt.ft), got, tt.want)
- }
- }
-}
-
-func TestWriteRST(t *testing.T) {
- fr, buf := testFramer()
- var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
- var errCode uint32 = 7<<24 + 6<<16 + 5<<8 + 4
- fr.WriteRSTStream(streamID, ErrCode(errCode))
- const wantEnc = "\x00\x00\x04\x03\x00\x01\x02\x03\x04\x07\x06\x05\x04"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- want := &RSTStreamFrame{
- FrameHeader: FrameHeader{
- valid: true,
- Type: 0x3,
- Flags: 0x0,
- Length: 0x4,
- StreamID: 0x1020304,
- },
- ErrCode: 0x7060504,
- }
- if !reflect.DeepEqual(f, want) {
- t.Errorf("parsed back %#v; want %#v", f, want)
- }
-}
-
-func TestWriteData(t *testing.T) {
- fr, buf := testFramer()
- var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
- data := []byte("ABC")
- fr.WriteData(streamID, true, data)
- const wantEnc = "\x00\x00\x03\x00\x01\x01\x02\x03\x04ABC"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- df, ok := f.(*DataFrame)
- if !ok {
- t.Fatalf("got %T; want *DataFrame", f)
- }
- if !bytes.Equal(df.Data(), data) {
- t.Errorf("got %q; want %q", df.Data(), data)
- }
- if f.Header().Flags&1 == 0 {
- t.Errorf("didn't see END_STREAM flag")
- }
-}
-
-func TestWriteDataPadded(t *testing.T) {
- tests := [...]struct {
- streamID uint32
- endStream bool
- data []byte
- pad []byte
- wantHeader FrameHeader
- }{
- // Unpadded:
- 0: {
- streamID: 1,
- endStream: true,
- data: []byte("foo"),
- pad: nil,
- wantHeader: FrameHeader{
- Type: FrameData,
- Flags: FlagDataEndStream,
- Length: 3,
- StreamID: 1,
- },
- },
-
- // Padded bit set, but no padding:
- 1: {
- streamID: 1,
- endStream: true,
- data: []byte("foo"),
- pad: []byte{},
- wantHeader: FrameHeader{
- Type: FrameData,
- Flags: FlagDataEndStream | FlagDataPadded,
- Length: 4,
- StreamID: 1,
- },
- },
-
- // Padded bit set, with padding:
- 2: {
- streamID: 1,
- endStream: false,
- data: []byte("foo"),
- pad: []byte{0, 0, 0},
- wantHeader: FrameHeader{
- Type: FrameData,
- Flags: FlagDataPadded,
- Length: 7,
- StreamID: 1,
- },
- },
- }
- for i, tt := range tests {
- fr, _ := testFramer()
- fr.WriteDataPadded(tt.streamID, tt.endStream, tt.data, tt.pad)
- f, err := fr.ReadFrame()
- if err != nil {
- t.Errorf("%d. ReadFrame: %v", i, err)
- continue
- }
- got := f.Header()
- tt.wantHeader.valid = true
- if got != tt.wantHeader {
- t.Errorf("%d. read %+v; want %+v", i, got, tt.wantHeader)
- continue
- }
- df := f.(*DataFrame)
- if !bytes.Equal(df.Data(), tt.data) {
- t.Errorf("%d. got %q; want %q", i, df.Data(), tt.data)
- }
- }
-}
-
-func TestWriteHeaders(t *testing.T) {
- tests := []struct {
- name string
- p HeadersFrameParam
- wantEnc string
- wantFrame *HeadersFrame
- }{
- {
- "basic",
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- Priority: PriorityParam{},
- },
- "\x00\x00\x03\x01\x00\x00\x00\x00*abc",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Length: uint32(len("abc")),
- },
- Priority: PriorityParam{},
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "basic + end flags",
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- EndStream: true,
- EndHeaders: true,
- Priority: PriorityParam{},
- },
- "\x00\x00\x03\x01\x05\x00\x00\x00*abc",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Flags: FlagHeadersEndStream | FlagHeadersEndHeaders,
- Length: uint32(len("abc")),
- },
- Priority: PriorityParam{},
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "with padding",
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- EndStream: true,
- EndHeaders: true,
- PadLength: 5,
- Priority: PriorityParam{},
- },
- "\x00\x00\t\x01\r\x00\x00\x00*\x05abc\x00\x00\x00\x00\x00",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded,
- Length: uint32(1 + len("abc") + 5), // pad length + contents + padding
- },
- Priority: PriorityParam{},
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "with priority",
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- EndStream: true,
- EndHeaders: true,
- PadLength: 2,
- Priority: PriorityParam{
- StreamDep: 15,
- Exclusive: true,
- Weight: 127,
- },
- },
- "\x00\x00\v\x01-\x00\x00\x00*\x02\x80\x00\x00\x0f\u007fabc\x00\x00",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded | FlagHeadersPriority,
- Length: uint32(1 + 5 + len("abc") + 2), // pad length + priority + contents + padding
- },
- Priority: PriorityParam{
- StreamDep: 15,
- Exclusive: true,
- Weight: 127,
- },
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "with priority stream dep zero", // golang.org/issue/15444
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- EndStream: true,
- EndHeaders: true,
- PadLength: 2,
- Priority: PriorityParam{
- StreamDep: 0,
- Exclusive: true,
- Weight: 127,
- },
- },
- "\x00\x00\v\x01-\x00\x00\x00*\x02\x80\x00\x00\x00\u007fabc\x00\x00",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded | FlagHeadersPriority,
- Length: uint32(1 + 5 + len("abc") + 2), // pad length + priority + contents + padding
- },
- Priority: PriorityParam{
- StreamDep: 0,
- Exclusive: true,
- Weight: 127,
- },
- headerFragBuf: []byte("abc"),
- },
- },
- }
- for _, tt := range tests {
- fr, buf := testFramer()
- if err := fr.WriteHeaders(tt.p); err != nil {
- t.Errorf("test %q: %v", tt.name, err)
- continue
- }
- if buf.String() != tt.wantEnc {
- t.Errorf("test %q: encoded %q; want %q", tt.name, buf.Bytes(), tt.wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
- continue
- }
- if !reflect.DeepEqual(f, tt.wantFrame) {
- t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
- }
- }
-}
-
-func TestWriteInvalidStreamDep(t *testing.T) {
- fr, _ := testFramer()
- err := fr.WriteHeaders(HeadersFrameParam{
- StreamID: 42,
- Priority: PriorityParam{
- StreamDep: 1 << 31,
- },
- })
- if err != errDepStreamID {
- t.Errorf("header error = %v; want %q", err, errDepStreamID)
- }
-
- err = fr.WritePriority(2, PriorityParam{StreamDep: 1 << 31})
- if err != errDepStreamID {
- t.Errorf("priority error = %v; want %q", err, errDepStreamID)
- }
-}
-
-func TestWriteContinuation(t *testing.T) {
- const streamID = 42
- tests := []struct {
- name string
- end bool
- frag []byte
-
- wantFrame *ContinuationFrame
- }{
- {
- "not end",
- false,
- []byte("abc"),
- &ContinuationFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: streamID,
- Type: FrameContinuation,
- Length: uint32(len("abc")),
- },
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "end",
- true,
- []byte("def"),
- &ContinuationFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: streamID,
- Type: FrameContinuation,
- Flags: FlagContinuationEndHeaders,
- Length: uint32(len("def")),
- },
- headerFragBuf: []byte("def"),
- },
- },
- }
- for _, tt := range tests {
- fr, _ := testFramer()
- if err := fr.WriteContinuation(streamID, tt.end, tt.frag); err != nil {
- t.Errorf("test %q: %v", tt.name, err)
- continue
- }
- fr.AllowIllegalReads = true
- f, err := fr.ReadFrame()
- if err != nil {
- t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
- continue
- }
- if !reflect.DeepEqual(f, tt.wantFrame) {
- t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
- }
- }
-}
-
-func TestWritePriority(t *testing.T) {
- const streamID = 42
- tests := []struct {
- name string
- priority PriorityParam
- wantFrame *PriorityFrame
- }{
- {
- "not exclusive",
- PriorityParam{
- StreamDep: 2,
- Exclusive: false,
- Weight: 127,
- },
- &PriorityFrame{
- FrameHeader{
- valid: true,
- StreamID: streamID,
- Type: FramePriority,
- Length: 5,
- },
- PriorityParam{
- StreamDep: 2,
- Exclusive: false,
- Weight: 127,
- },
- },
- },
-
- {
- "exclusive",
- PriorityParam{
- StreamDep: 3,
- Exclusive: true,
- Weight: 77,
- },
- &PriorityFrame{
- FrameHeader{
- valid: true,
- StreamID: streamID,
- Type: FramePriority,
- Length: 5,
- },
- PriorityParam{
- StreamDep: 3,
- Exclusive: true,
- Weight: 77,
- },
- },
- },
- }
- for _, tt := range tests {
- fr, _ := testFramer()
- if err := fr.WritePriority(streamID, tt.priority); err != nil {
- t.Errorf("test %q: %v", tt.name, err)
- continue
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
- continue
- }
- if !reflect.DeepEqual(f, tt.wantFrame) {
- t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
- }
- }
-}
-
-func TestWriteSettings(t *testing.T) {
- fr, buf := testFramer()
- settings := []Setting{{1, 2}, {3, 4}}
- fr.WriteSettings(settings...)
- const wantEnc = "\x00\x00\f\x04\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00\x00\x04"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- sf, ok := f.(*SettingsFrame)
- if !ok {
- t.Fatalf("Got a %T; want a SettingsFrame", f)
- }
- var got []Setting
- sf.ForeachSetting(func(s Setting) error {
- got = append(got, s)
- valBack, ok := sf.Value(s.ID)
- if !ok || valBack != s.Val {
- t.Errorf("Value(%d) = %v, %v; want %v, true", s.ID, valBack, ok, s.Val)
- }
- return nil
- })
- if !reflect.DeepEqual(settings, got) {
- t.Errorf("Read settings %+v != written settings %+v", got, settings)
- }
-}
-
-func TestWriteSettingsAck(t *testing.T) {
- fr, buf := testFramer()
- fr.WriteSettingsAck()
- const wantEnc = "\x00\x00\x00\x04\x01\x00\x00\x00\x00"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
-}
-
-func TestWriteWindowUpdate(t *testing.T) {
- fr, buf := testFramer()
- const streamID = 1<<24 + 2<<16 + 3<<8 + 4
- const incr = 7<<24 + 6<<16 + 5<<8 + 4
- if err := fr.WriteWindowUpdate(streamID, incr); err != nil {
- t.Fatal(err)
- }
- const wantEnc = "\x00\x00\x04\x08\x00\x01\x02\x03\x04\x07\x06\x05\x04"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- want := &WindowUpdateFrame{
- FrameHeader: FrameHeader{
- valid: true,
- Type: 0x8,
- Flags: 0x0,
- Length: 0x4,
- StreamID: 0x1020304,
- },
- Increment: 0x7060504,
- }
- if !reflect.DeepEqual(f, want) {
- t.Errorf("parsed back %#v; want %#v", f, want)
- }
-}
-
-func TestWritePing(t *testing.T) { testWritePing(t, false) }
-func TestWritePingAck(t *testing.T) { testWritePing(t, true) }
-
-func testWritePing(t *testing.T, ack bool) {
- fr, buf := testFramer()
- if err := fr.WritePing(ack, [8]byte{1, 2, 3, 4, 5, 6, 7, 8}); err != nil {
- t.Fatal(err)
- }
- var wantFlags Flags
- if ack {
- wantFlags = FlagPingAck
- }
- var wantEnc = "\x00\x00\x08\x06" + string(wantFlags) + "\x00\x00\x00\x00" + "\x01\x02\x03\x04\x05\x06\x07\x08"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
-
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- want := &PingFrame{
- FrameHeader: FrameHeader{
- valid: true,
- Type: 0x6,
- Flags: wantFlags,
- Length: 0x8,
- StreamID: 0,
- },
- Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
- }
- if !reflect.DeepEqual(f, want) {
- t.Errorf("parsed back %#v; want %#v", f, want)
- }
-}
-
-func TestReadFrameHeader(t *testing.T) {
- tests := []struct {
- in string
- want FrameHeader
- }{
- {in: "\x00\x00\x00" + "\x00" + "\x00" + "\x00\x00\x00\x00", want: FrameHeader{}},
- {in: "\x01\x02\x03" + "\x04" + "\x05" + "\x06\x07\x08\x09", want: FrameHeader{
- Length: 66051, Type: 4, Flags: 5, StreamID: 101124105,
- }},
- // Ignore high bit:
- {in: "\xff\xff\xff" + "\xff" + "\xff" + "\xff\xff\xff\xff", want: FrameHeader{
- Length: 16777215, Type: 255, Flags: 255, StreamID: 2147483647}},
- {in: "\xff\xff\xff" + "\xff" + "\xff" + "\x7f\xff\xff\xff", want: FrameHeader{
- Length: 16777215, Type: 255, Flags: 255, StreamID: 2147483647}},
- }
- for i, tt := range tests {
- got, err := readFrameHeader(make([]byte, 9), strings.NewReader(tt.in))
- if err != nil {
- t.Errorf("%d. readFrameHeader(%q) = %v", i, tt.in, err)
- continue
- }
- tt.want.valid = true
- if got != tt.want {
- t.Errorf("%d. readFrameHeader(%q) = %+v; want %+v", i, tt.in, got, tt.want)
- }
- }
-}
-
-func TestReadWriteFrameHeader(t *testing.T) {
- tests := []struct {
- len uint32
- typ FrameType
- flags Flags
- streamID uint32
- }{
- {len: 0, typ: 255, flags: 1, streamID: 0},
- {len: 0, typ: 255, flags: 1, streamID: 1},
- {len: 0, typ: 255, flags: 1, streamID: 255},
- {len: 0, typ: 255, flags: 1, streamID: 256},
- {len: 0, typ: 255, flags: 1, streamID: 65535},
- {len: 0, typ: 255, flags: 1, streamID: 65536},
-
- {len: 0, typ: 1, flags: 255, streamID: 1},
- {len: 255, typ: 1, flags: 255, streamID: 1},
- {len: 256, typ: 1, flags: 255, streamID: 1},
- {len: 65535, typ: 1, flags: 255, streamID: 1},
- {len: 65536, typ: 1, flags: 255, streamID: 1},
- {len: 16777215, typ: 1, flags: 255, streamID: 1},
- }
- for _, tt := range tests {
- fr, buf := testFramer()
- fr.startWrite(tt.typ, tt.flags, tt.streamID)
- fr.writeBytes(make([]byte, tt.len))
- fr.endWrite()
- fh, err := ReadFrameHeader(buf)
- if err != nil {
- t.Errorf("ReadFrameHeader(%+v) = %v", tt, err)
- continue
- }
- if fh.Type != tt.typ || fh.Flags != tt.flags || fh.Length != tt.len || fh.StreamID != tt.streamID {
- t.Errorf("ReadFrameHeader(%+v) = %+v; mismatch", tt, fh)
- }
- }
-
-}
-
-func TestWriteTooLargeFrame(t *testing.T) {
- fr, _ := testFramer()
- fr.startWrite(0, 1, 1)
- fr.writeBytes(make([]byte, 1<<24))
- err := fr.endWrite()
- if err != ErrFrameTooLarge {
- t.Errorf("endWrite = %v; want errFrameTooLarge", err)
- }
-}
-
-func TestWriteGoAway(t *testing.T) {
- const debug = "foo"
- fr, buf := testFramer()
- if err := fr.WriteGoAway(0x01020304, 0x05060708, []byte(debug)); err != nil {
- t.Fatal(err)
- }
- const wantEnc = "\x00\x00\v\a\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08" + debug
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- want := &GoAwayFrame{
- FrameHeader: FrameHeader{
- valid: true,
- Type: 0x7,
- Flags: 0,
- Length: uint32(4 + 4 + len(debug)),
- StreamID: 0,
- },
- LastStreamID: 0x01020304,
- ErrCode: 0x05060708,
- debugData: []byte(debug),
- }
- if !reflect.DeepEqual(f, want) {
- t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
- }
- if got := string(f.(*GoAwayFrame).DebugData()); got != debug {
- t.Errorf("debug data = %q; want %q", got, debug)
- }
-}
-
-func TestWritePushPromise(t *testing.T) {
- pp := PushPromiseParam{
- StreamID: 42,
- PromiseID: 42,
- BlockFragment: []byte("abc"),
- }
- fr, buf := testFramer()
- if err := fr.WritePushPromise(pp); err != nil {
- t.Fatal(err)
- }
- const wantEnc = "\x00\x00\x07\x05\x00\x00\x00\x00*\x00\x00\x00*abc"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- _, ok := f.(*PushPromiseFrame)
- if !ok {
- t.Fatalf("got %T; want *PushPromiseFrame", f)
- }
- want := &PushPromiseFrame{
- FrameHeader: FrameHeader{
- valid: true,
- Type: 0x5,
- Flags: 0x0,
- Length: 0x7,
- StreamID: 42,
- },
- PromiseID: 42,
- headerFragBuf: []byte("abc"),
- }
- if !reflect.DeepEqual(f, want) {
- t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
- }
-}
-
-// test checkFrameOrder and that HEADERS and CONTINUATION frames can't be intermingled.
-func TestReadFrameOrder(t *testing.T) {
- head := func(f *Framer, id uint32, end bool) {
- f.WriteHeaders(HeadersFrameParam{
- StreamID: id,
- BlockFragment: []byte("foo"), // unused, but non-empty
- EndHeaders: end,
- })
- }
- cont := func(f *Framer, id uint32, end bool) {
- f.WriteContinuation(id, end, []byte("foo"))
- }
-
- tests := [...]struct {
- name string
- w func(*Framer)
- atLeast int
- wantErr string
- }{
- 0: {
- w: func(f *Framer) {
- head(f, 1, true)
- },
- },
- 1: {
- w: func(f *Framer) {
- head(f, 1, true)
- head(f, 2, true)
- },
- },
- 2: {
- wantErr: "got HEADERS for stream 2; expected CONTINUATION following HEADERS for stream 1",
- w: func(f *Framer) {
- head(f, 1, false)
- head(f, 2, true)
- },
- },
- 3: {
- wantErr: "got DATA for stream 1; expected CONTINUATION following HEADERS for stream 1",
- w: func(f *Framer) {
- head(f, 1, false)
- },
- },
- 4: {
- w: func(f *Framer) {
- head(f, 1, false)
- cont(f, 1, true)
- head(f, 2, true)
- },
- },
- 5: {
- wantErr: "got CONTINUATION for stream 2; expected stream 1",
- w: func(f *Framer) {
- head(f, 1, false)
- cont(f, 2, true)
- head(f, 2, true)
- },
- },
- 6: {
- wantErr: "unexpected CONTINUATION for stream 1",
- w: func(f *Framer) {
- cont(f, 1, true)
- },
- },
- 7: {
- wantErr: "unexpected CONTINUATION for stream 1",
- w: func(f *Framer) {
- cont(f, 1, false)
- },
- },
- 8: {
- wantErr: "HEADERS frame with stream ID 0",
- w: func(f *Framer) {
- head(f, 0, true)
- },
- },
- 9: {
- wantErr: "CONTINUATION frame with stream ID 0",
- w: func(f *Framer) {
- cont(f, 0, true)
- },
- },
- 10: {
- wantErr: "unexpected CONTINUATION for stream 1",
- atLeast: 5,
- w: func(f *Framer) {
- head(f, 1, false)
- cont(f, 1, false)
- cont(f, 1, false)
- cont(f, 1, false)
- cont(f, 1, true)
- cont(f, 1, false)
- },
- },
- }
- for i, tt := range tests {
- buf := new(bytes.Buffer)
- f := NewFramer(buf, buf)
- f.AllowIllegalWrites = true
- tt.w(f)
- f.WriteData(1, true, nil) // to test transition away from last step
-
- var err error
- n := 0
- var log bytes.Buffer
- for {
- var got Frame
- got, err = f.ReadFrame()
- fmt.Fprintf(&log, " read %v, %v\n", got, err)
- if err != nil {
- break
- }
- n++
- }
- if err == io.EOF {
- err = nil
- }
- ok := tt.wantErr == ""
- if ok && err != nil {
- t.Errorf("%d. after %d good frames, ReadFrame = %v; want success\n%s", i, n, err, log.Bytes())
- continue
- }
- if !ok && err != ConnectionError(ErrCodeProtocol) {
- t.Errorf("%d. after %d good frames, ReadFrame = %v; want ConnectionError(ErrCodeProtocol)\n%s", i, n, err, log.Bytes())
- continue
- }
- if !((f.errDetail == nil && tt.wantErr == "") || (fmt.Sprint(f.errDetail) == tt.wantErr)) {
- t.Errorf("%d. framer eror = %q; want %q\n%s", i, f.errDetail, tt.wantErr, log.Bytes())
- }
- if n < tt.atLeast {
- t.Errorf("%d. framer only read %d frames; want at least %d\n%s", i, n, tt.atLeast, log.Bytes())
- }
- }
-}
-
-func TestMetaFrameHeader(t *testing.T) {
- write := func(f *Framer, frags ...[]byte) {
- for i, frag := range frags {
- end := (i == len(frags)-1)
- if i == 0 {
- f.WriteHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: frag,
- EndHeaders: end,
- })
- } else {
- f.WriteContinuation(1, end, frag)
- }
- }
- }
-
- want := func(flags Flags, length uint32, pairs ...string) *MetaHeadersFrame {
- mh := &MetaHeadersFrame{
- HeadersFrame: &HeadersFrame{
- FrameHeader: FrameHeader{
- Type: FrameHeaders,
- Flags: flags,
- Length: length,
- StreamID: 1,
- },
- },
- Fields: []hpack.HeaderField(nil),
- }
- for len(pairs) > 0 {
- mh.Fields = append(mh.Fields, hpack.HeaderField{
- Name: pairs[0],
- Value: pairs[1],
- })
- pairs = pairs[2:]
- }
- return mh
- }
- truncated := func(mh *MetaHeadersFrame) *MetaHeadersFrame {
- mh.Truncated = true
- return mh
- }
-
- const noFlags Flags = 0
-
- oneKBString := strings.Repeat("a", 1<<10)
-
- tests := [...]struct {
- name string
- w func(*Framer)
- want interface{} // *MetaHeaderFrame or error
- wantErrReason string
- maxHeaderListSize uint32
- }{
- 0: {
- name: "single_headers",
- w: func(f *Framer) {
- var he hpackEncoder
- all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/")
- write(f, all)
- },
- want: want(FlagHeadersEndHeaders, 2, ":method", "GET", ":path", "/"),
- },
- 1: {
- name: "with_continuation",
- w: func(f *Framer) {
- var he hpackEncoder
- all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", "bar")
- write(f, all[:1], all[1:])
- },
- want: want(noFlags, 1, ":method", "GET", ":path", "/", "foo", "bar"),
- },
- 2: {
- name: "with_two_continuation",
- w: func(f *Framer) {
- var he hpackEncoder
- all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", "bar")
- write(f, all[:2], all[2:4], all[4:])
- },
- want: want(noFlags, 2, ":method", "GET", ":path", "/", "foo", "bar"),
- },
- 3: {
- name: "big_string_okay",
- w: func(f *Framer) {
- var he hpackEncoder
- all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", oneKBString)
- write(f, all[:2], all[2:])
- },
- want: want(noFlags, 2, ":method", "GET", ":path", "/", "foo", oneKBString),
- },
- 4: {
- name: "big_string_error",
- w: func(f *Framer) {
- var he hpackEncoder
- all := he.encodeHeaderRaw(t, ":method", "GET", ":path", "/", "foo", oneKBString)
- write(f, all[:2], all[2:])
- },
- maxHeaderListSize: (1 << 10) / 2,
- want: ConnectionError(ErrCodeCompression),
- },
- 5: {
- name: "max_header_list_truncated",
- w: func(f *Framer) {
- var he hpackEncoder
- var pairs = []string{":method", "GET", ":path", "/"}
- for i := 0; i < 100; i++ {
- pairs = append(pairs, "foo", "bar")
- }
- all := he.encodeHeaderRaw(t, pairs...)
- write(f, all[:2], all[2:])
- },
- maxHeaderListSize: (1 << 10) / 2,
- want: truncated(want(noFlags, 2,
- ":method", "GET",
- ":path", "/",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar",
- "foo", "bar", // 11
- )),
- },
- 6: {
- name: "pseudo_order",
- w: func(f *Framer) {
- write(f, encodeHeaderRaw(t,
- ":method", "GET",
- "foo", "bar",
- ":path", "/", // bogus
- ))
- },
- want: streamError(1, ErrCodeProtocol),
- wantErrReason: "pseudo header field after regular",
- },
- 7: {
- name: "pseudo_unknown",
- w: func(f *Framer) {
- write(f, encodeHeaderRaw(t,
- ":unknown", "foo", // bogus
- "foo", "bar",
- ))
- },
- want: streamError(1, ErrCodeProtocol),
- wantErrReason: "invalid pseudo-header \":unknown\"",
- },
- 8: {
- name: "pseudo_mix_request_response",
- w: func(f *Framer) {
- write(f, encodeHeaderRaw(t,
- ":method", "GET",
- ":status", "100",
- ))
- },
- want: streamError(1, ErrCodeProtocol),
- wantErrReason: "mix of request and response pseudo headers",
- },
- 9: {
- name: "pseudo_dup",
- w: func(f *Framer) {
- write(f, encodeHeaderRaw(t,
- ":method", "GET",
- ":method", "POST",
- ))
- },
- want: streamError(1, ErrCodeProtocol),
- wantErrReason: "duplicate pseudo-header \":method\"",
- },
- 10: {
- name: "trailer_okay_no_pseudo",
- w: func(f *Framer) { write(f, encodeHeaderRaw(t, "foo", "bar")) },
- want: want(FlagHeadersEndHeaders, 8, "foo", "bar"),
- },
- 11: {
- name: "invalid_field_name",
- w: func(f *Framer) { write(f, encodeHeaderRaw(t, "CapitalBad", "x")) },
- want: streamError(1, ErrCodeProtocol),
- wantErrReason: "invalid header field name \"CapitalBad\"",
- },
- 12: {
- name: "invalid_field_value",
- w: func(f *Framer) { write(f, encodeHeaderRaw(t, "key", "bad_null\x00")) },
- want: streamError(1, ErrCodeProtocol),
- wantErrReason: "invalid header field value \"bad_null\\x00\"",
- },
- }
- for i, tt := range tests {
- buf := new(bytes.Buffer)
- f := NewFramer(buf, buf)
- f.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
- f.MaxHeaderListSize = tt.maxHeaderListSize
- tt.w(f)
-
- name := tt.name
- if name == "" {
- name = fmt.Sprintf("test index %d", i)
- }
-
- var got interface{}
- var err error
- got, err = f.ReadFrame()
- if err != nil {
- got = err
-
- // Ignore the StreamError.Cause field, if it matches the wantErrReason.
- // The test table above predates the Cause field.
- if se, ok := err.(StreamError); ok && se.Cause != nil && se.Cause.Error() == tt.wantErrReason {
- se.Cause = nil
- got = se
- }
- }
- if !reflect.DeepEqual(got, tt.want) {
- if mhg, ok := got.(*MetaHeadersFrame); ok {
- if mhw, ok := tt.want.(*MetaHeadersFrame); ok {
- hg := mhg.HeadersFrame
- hw := mhw.HeadersFrame
- if hg != nil && hw != nil && !reflect.DeepEqual(*hg, *hw) {
- t.Errorf("%s: headers differ:\n got: %+v\nwant: %+v\n", name, *hg, *hw)
- }
- }
- }
- str := func(v interface{}) string {
- if _, ok := v.(error); ok {
- return fmt.Sprintf("error %v", v)
- } else {
- return fmt.Sprintf("value %#v", v)
- }
- }
- t.Errorf("%s:\n got: %v\nwant: %s", name, str(got), str(tt.want))
- }
- if tt.wantErrReason != "" && tt.wantErrReason != fmt.Sprint(f.errDetail) {
- t.Errorf("%s: got error reason %q; want %q", name, f.errDetail, tt.wantErrReason)
- }
- }
-}
-
-func TestSetReuseFrames(t *testing.T) {
- fr, buf := testFramer()
- fr.SetReuseFrames()
-
- // Check that DataFrames are reused. Note that
- // SetReuseFrames only currently implements reuse of DataFrames.
- firstDf := readAndVerifyDataFrame("ABC", 3, fr, buf, t)
-
- for i := 0; i < 10; i++ {
- df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
- if df != firstDf {
- t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
- }
- }
-
- for i := 0; i < 10; i++ {
- df := readAndVerifyDataFrame("", 0, fr, buf, t)
- if df != firstDf {
- t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
- }
- }
-
- for i := 0; i < 10; i++ {
- df := readAndVerifyDataFrame("HHH", 3, fr, buf, t)
- if df != firstDf {
- t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
- }
- }
-}
-
-func TestSetReuseFramesMoreThanOnce(t *testing.T) {
- fr, buf := testFramer()
- fr.SetReuseFrames()
-
- firstDf := readAndVerifyDataFrame("ABC", 3, fr, buf, t)
- fr.SetReuseFrames()
-
- for i := 0; i < 10; i++ {
- df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
- // SetReuseFrames should be idempotent
- fr.SetReuseFrames()
- if df != firstDf {
- t.Errorf("Expected Framer to return references to the same DataFrame. Have %v and %v", &df, &firstDf)
- }
- }
-}
-
-func TestNoSetReuseFrames(t *testing.T) {
- fr, buf := testFramer()
- const numNewDataFrames = 10
- dfSoFar := make([]interface{}, numNewDataFrames)
-
- // Check that DataFrames are not reused if SetReuseFrames wasn't called.
- // SetReuseFrames only currently implements reuse of DataFrames.
- for i := 0; i < numNewDataFrames; i++ {
- df := readAndVerifyDataFrame("XYZ", 3, fr, buf, t)
- for _, item := range dfSoFar {
- if df == item {
- t.Errorf("Expected Framer to return new DataFrames since SetNoReuseFrames not set.")
- }
- }
- dfSoFar[i] = df
- }
-}
-
-func readAndVerifyDataFrame(data string, length byte, fr *Framer, buf *bytes.Buffer, t *testing.T) *DataFrame {
- var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
- fr.WriteData(streamID, true, []byte(data))
- wantEnc := "\x00\x00" + string(length) + "\x00\x01\x01\x02\x03\x04" + data
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- df, ok := f.(*DataFrame)
- if !ok {
- t.Fatalf("got %T; want *DataFrame", f)
- }
- if !bytes.Equal(df.Data(), []byte(data)) {
- t.Errorf("got %q; want %q", df.Data(), []byte(data))
- }
- if f.Header().Flags&1 == 0 {
- t.Errorf("didn't see END_STREAM flag")
- }
- return df
-}
-
-func encodeHeaderRaw(t *testing.T, pairs ...string) []byte {
- var he hpackEncoder
- return he.encodeHeaderRaw(t, pairs...)
-}
diff --git a/vendor/golang.org/x/net/http2/go16.go b/vendor/golang.org/x/net/http2/go16.go
deleted file mode 100644
index 00b2e9e3c..000000000
--- a/vendor/golang.org/x/net/http2/go16.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.6
-
-package http2
-
-import (
- "net/http"
- "time"
-)
-
-func transportExpectContinueTimeout(t1 *http.Transport) time.Duration {
- return t1.ExpectContinueTimeout
-}
diff --git a/vendor/golang.org/x/net/http2/go17.go b/vendor/golang.org/x/net/http2/go17.go
deleted file mode 100644
index 47b7fae08..000000000
--- a/vendor/golang.org/x/net/http2/go17.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.7
-
-package http2
-
-import (
- "context"
- "net"
- "net/http"
- "net/http/httptrace"
- "time"
-)
-
-type contextContext interface {
- context.Context
-}
-
-func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) {
- ctx, cancel = context.WithCancel(context.Background())
- ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())
- if hs := opts.baseConfig(); hs != nil {
- ctx = context.WithValue(ctx, http.ServerContextKey, hs)
- }
- return
-}
-
-func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) {
- return context.WithCancel(ctx)
-}
-
-func requestWithContext(req *http.Request, ctx contextContext) *http.Request {
- return req.WithContext(ctx)
-}
-
-type clientTrace httptrace.ClientTrace
-
-func reqContext(r *http.Request) context.Context { return r.Context() }
-
-func (t *Transport) idleConnTimeout() time.Duration {
- if t.t1 != nil {
- return t.t1.IdleConnTimeout
- }
- return 0
-}
-
-func setResponseUncompressed(res *http.Response) { res.Uncompressed = true }
-
-func traceGotConn(req *http.Request, cc *ClientConn) {
- trace := httptrace.ContextClientTrace(req.Context())
- if trace == nil || trace.GotConn == nil {
- return
- }
- ci := httptrace.GotConnInfo{Conn: cc.tconn}
- cc.mu.Lock()
- ci.Reused = cc.nextStreamID > 1
- ci.WasIdle = len(cc.streams) == 0 && ci.Reused
- if ci.WasIdle && !cc.lastActive.IsZero() {
- ci.IdleTime = time.Now().Sub(cc.lastActive)
- }
- cc.mu.Unlock()
-
- trace.GotConn(ci)
-}
-
-func traceWroteHeaders(trace *clientTrace) {
- if trace != nil && trace.WroteHeaders != nil {
- trace.WroteHeaders()
- }
-}
-
-func traceGot100Continue(trace *clientTrace) {
- if trace != nil && trace.Got100Continue != nil {
- trace.Got100Continue()
- }
-}
-
-func traceWait100Continue(trace *clientTrace) {
- if trace != nil && trace.Wait100Continue != nil {
- trace.Wait100Continue()
- }
-}
-
-func traceWroteRequest(trace *clientTrace, err error) {
- if trace != nil && trace.WroteRequest != nil {
- trace.WroteRequest(httptrace.WroteRequestInfo{Err: err})
- }
-}
-
-func traceFirstResponseByte(trace *clientTrace) {
- if trace != nil && trace.GotFirstResponseByte != nil {
- trace.GotFirstResponseByte()
- }
-}
-
-func requestTrace(req *http.Request) *clientTrace {
- trace := httptrace.ContextClientTrace(req.Context())
- return (*clientTrace)(trace)
-}
-
-// Ping sends a PING frame to the server and waits for the ack.
-func (cc *ClientConn) Ping(ctx context.Context) error {
- return cc.ping(ctx)
-}
diff --git a/vendor/golang.org/x/net/http2/go17_not18.go b/vendor/golang.org/x/net/http2/go17_not18.go
deleted file mode 100644
index b4c52ecec..000000000
--- a/vendor/golang.org/x/net/http2/go17_not18.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.7,!go1.8
-
-package http2
-
-import "crypto/tls"
-
-// temporary copy of Go 1.7's private tls.Config.clone:
-func cloneTLSConfig(c *tls.Config) *tls.Config {
- return &tls.Config{
- Rand: c.Rand,
- Time: c.Time,
- Certificates: c.Certificates,
- NameToCertificate: c.NameToCertificate,
- GetCertificate: c.GetCertificate,
- RootCAs: c.RootCAs,
- NextProtos: c.NextProtos,
- ServerName: c.ServerName,
- ClientAuth: c.ClientAuth,
- ClientCAs: c.ClientCAs,
- InsecureSkipVerify: c.InsecureSkipVerify,
- CipherSuites: c.CipherSuites,
- PreferServerCipherSuites: c.PreferServerCipherSuites,
- SessionTicketsDisabled: c.SessionTicketsDisabled,
- SessionTicketKey: c.SessionTicketKey,
- ClientSessionCache: c.ClientSessionCache,
- MinVersion: c.MinVersion,
- MaxVersion: c.MaxVersion,
- CurvePreferences: c.CurvePreferences,
- DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
- Renegotiation: c.Renegotiation,
- }
-}
diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go
deleted file mode 100644
index 73cc2381f..000000000
--- a/vendor/golang.org/x/net/http2/go18.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.8
-
-package http2
-
-import (
- "crypto/tls"
- "io"
- "net/http"
-)
-
-func cloneTLSConfig(c *tls.Config) *tls.Config {
- c2 := c.Clone()
- c2.GetClientCertificate = c.GetClientCertificate // golang.org/issue/19264
- return c2
-}
-
-var _ http.Pusher = (*responseWriter)(nil)
-
-// Push implements http.Pusher.
-func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
- internalOpts := pushOptions{}
- if opts != nil {
- internalOpts.Method = opts.Method
- internalOpts.Header = opts.Header
- }
- return w.push(target, internalOpts)
-}
-
-func configureServer18(h1 *http.Server, h2 *Server) error {
- if h2.IdleTimeout == 0 {
- if h1.IdleTimeout != 0 {
- h2.IdleTimeout = h1.IdleTimeout
- } else {
- h2.IdleTimeout = h1.ReadTimeout
- }
- }
- return nil
-}
-
-func shouldLogPanic(panicValue interface{}) bool {
- return panicValue != nil && panicValue != http.ErrAbortHandler
-}
-
-func reqGetBody(req *http.Request) func() (io.ReadCloser, error) {
- return req.GetBody
-}
-
-func reqBodyIsNoBody(body io.ReadCloser) bool {
- return body == http.NoBody
-}
diff --git a/vendor/golang.org/x/net/http2/go18_test.go b/vendor/golang.org/x/net/http2/go18_test.go
deleted file mode 100644
index 30e3b038b..000000000
--- a/vendor/golang.org/x/net/http2/go18_test.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.8
-
-package http2
-
-import (
- "crypto/tls"
- "net/http"
- "testing"
- "time"
-)
-
-// Tests that http2.Server.IdleTimeout is initialized from
-// http.Server.{Idle,Read}Timeout. http.Server.IdleTimeout was
-// added in Go 1.8.
-func TestConfigureServerIdleTimeout_Go18(t *testing.T) {
- const timeout = 5 * time.Second
- const notThisOne = 1 * time.Second
-
- // With a zero http2.Server, verify that it copies IdleTimeout:
- {
- s1 := &http.Server{
- IdleTimeout: timeout,
- ReadTimeout: notThisOne,
- }
- s2 := &Server{}
- if err := ConfigureServer(s1, s2); err != nil {
- t.Fatal(err)
- }
- if s2.IdleTimeout != timeout {
- t.Errorf("s2.IdleTimeout = %v; want %v", s2.IdleTimeout, timeout)
- }
- }
-
- // And that it falls back to ReadTimeout:
- {
- s1 := &http.Server{
- ReadTimeout: timeout,
- }
- s2 := &Server{}
- if err := ConfigureServer(s1, s2); err != nil {
- t.Fatal(err)
- }
- if s2.IdleTimeout != timeout {
- t.Errorf("s2.IdleTimeout = %v; want %v", s2.IdleTimeout, timeout)
- }
- }
-
- // Verify that s1's IdleTimeout doesn't overwrite an existing setting:
- {
- s1 := &http.Server{
- IdleTimeout: notThisOne,
- }
- s2 := &Server{
- IdleTimeout: timeout,
- }
- if err := ConfigureServer(s1, s2); err != nil {
- t.Fatal(err)
- }
- if s2.IdleTimeout != timeout {
- t.Errorf("s2.IdleTimeout = %v; want %v", s2.IdleTimeout, timeout)
- }
- }
-}
-
-func TestCertClone(t *testing.T) {
- c := &tls.Config{
- GetClientCertificate: func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
- panic("shouldn't be called")
- },
- }
- c2 := cloneTLSConfig(c)
- if c2.GetClientCertificate == nil {
- t.Error("GetClientCertificate is nil")
- }
-}
diff --git a/vendor/golang.org/x/net/http2/go19.go b/vendor/golang.org/x/net/http2/go19.go
deleted file mode 100644
index 38124ba56..000000000
--- a/vendor/golang.org/x/net/http2/go19.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.9
-
-package http2
-
-import (
- "net/http"
-)
-
-func configureServer19(s *http.Server, conf *Server) error {
- s.RegisterOnShutdown(conf.state.startGracefulShutdown)
- return nil
-}
diff --git a/vendor/golang.org/x/net/http2/go19_test.go b/vendor/golang.org/x/net/http2/go19_test.go
deleted file mode 100644
index 1675d248f..000000000
--- a/vendor/golang.org/x/net/http2/go19_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.9
-
-package http2
-
-import (
- "context"
- "net/http"
- "reflect"
- "testing"
- "time"
-)
-
-func TestServerGracefulShutdown(t *testing.T) {
- var st *serverTester
- handlerDone := make(chan struct{})
- st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- defer close(handlerDone)
- go st.ts.Config.Shutdown(context.Background())
-
- ga := st.wantGoAway()
- if ga.ErrCode != ErrCodeNo {
- t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
- }
- if ga.LastStreamID != 1 {
- t.Errorf("GOAWAY LastStreamID = %v; want 1", ga.LastStreamID)
- }
-
- w.Header().Set("x-foo", "bar")
- })
- defer st.Close()
-
- st.greet()
- st.bodylessReq1()
-
- select {
- case <-handlerDone:
- case <-time.After(5 * time.Second):
- t.Fatalf("server did not shutdown?")
- }
- hf := st.wantHeaders()
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"x-foo", "bar"},
- {"content-type", "text/plain; charset=utf-8"},
- {"content-length", "0"},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
-
- n, err := st.cc.Read([]byte{0})
- if n != 0 || err == nil {
- t.Errorf("Read = %v, %v; want 0, non-nil", n, err)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/gotrack.go b/vendor/golang.org/x/net/http2/gotrack.go
deleted file mode 100644
index 9933c9f8c..000000000
--- a/vendor/golang.org/x/net/http2/gotrack.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Defensive debug-only utility to track that functions run on the
-// goroutine that they're supposed to.
-
-package http2
-
-import (
- "bytes"
- "errors"
- "fmt"
- "os"
- "runtime"
- "strconv"
- "sync"
-)
-
-var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
-
-type goroutineLock uint64
-
-func newGoroutineLock() goroutineLock {
- if !DebugGoroutines {
- return 0
- }
- return goroutineLock(curGoroutineID())
-}
-
-func (g goroutineLock) check() {
- if !DebugGoroutines {
- return
- }
- if curGoroutineID() != uint64(g) {
- panic("running on the wrong goroutine")
- }
-}
-
-func (g goroutineLock) checkNotOn() {
- if !DebugGoroutines {
- return
- }
- if curGoroutineID() == uint64(g) {
- panic("running on the wrong goroutine")
- }
-}
-
-var goroutineSpace = []byte("goroutine ")
-
-func curGoroutineID() uint64 {
- bp := littleBuf.Get().(*[]byte)
- defer littleBuf.Put(bp)
- b := *bp
- b = b[:runtime.Stack(b, false)]
- // Parse the 4707 out of "goroutine 4707 ["
- b = bytes.TrimPrefix(b, goroutineSpace)
- i := bytes.IndexByte(b, ' ')
- if i < 0 {
- panic(fmt.Sprintf("No space found in %q", b))
- }
- b = b[:i]
- n, err := parseUintBytes(b, 10, 64)
- if err != nil {
- panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err))
- }
- return n
-}
-
-var littleBuf = sync.Pool{
- New: func() interface{} {
- buf := make([]byte, 64)
- return &buf
- },
-}
-
-// parseUintBytes is like strconv.ParseUint, but using a []byte.
-func parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {
- var cutoff, maxVal uint64
-
- if bitSize == 0 {
- bitSize = int(strconv.IntSize)
- }
-
- s0 := s
- switch {
- case len(s) < 1:
- err = strconv.ErrSyntax
- goto Error
-
- case 2 <= base && base <= 36:
- // valid base; nothing to do
-
- case base == 0:
- // Look for octal, hex prefix.
- switch {
- case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
- base = 16
- s = s[2:]
- if len(s) < 1 {
- err = strconv.ErrSyntax
- goto Error
- }
- case s[0] == '0':
- base = 8
- default:
- base = 10
- }
-
- default:
- err = errors.New("invalid base " + strconv.Itoa(base))
- goto Error
- }
-
- n = 0
- cutoff = cutoff64(base)
- maxVal = 1<<uint(bitSize) - 1
-
- for i := 0; i < len(s); i++ {
- var v byte
- d := s[i]
- switch {
- case '0' <= d && d <= '9':
- v = d - '0'
- case 'a' <= d && d <= 'z':
- v = d - 'a' + 10
- case 'A' <= d && d <= 'Z':
- v = d - 'A' + 10
- default:
- n = 0
- err = strconv.ErrSyntax
- goto Error
- }
- if int(v) >= base {
- n = 0
- err = strconv.ErrSyntax
- goto Error
- }
-
- if n >= cutoff {
- // n*base overflows
- n = 1<<64 - 1
- err = strconv.ErrRange
- goto Error
- }
- n *= uint64(base)
-
- n1 := n + uint64(v)
- if n1 < n || n1 > maxVal {
- // n+v overflows
- n = 1<<64 - 1
- err = strconv.ErrRange
- goto Error
- }
- n = n1
- }
-
- return n, nil
-
-Error:
- return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
-}
-
-// Return the first number n such that n*base >= 1<<64.
-func cutoff64(base int) uint64 {
- if base < 2 {
- return 0
- }
- return (1<<64-1)/uint64(base) + 1
-}
diff --git a/vendor/golang.org/x/net/http2/gotrack_test.go b/vendor/golang.org/x/net/http2/gotrack_test.go
deleted file mode 100644
index 06db61231..000000000
--- a/vendor/golang.org/x/net/http2/gotrack_test.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "fmt"
- "strings"
- "testing"
-)
-
-func TestGoroutineLock(t *testing.T) {
- oldDebug := DebugGoroutines
- DebugGoroutines = true
- defer func() { DebugGoroutines = oldDebug }()
-
- g := newGoroutineLock()
- g.check()
-
- sawPanic := make(chan interface{})
- go func() {
- defer func() { sawPanic <- recover() }()
- g.check() // should panic
- }()
- e := <-sawPanic
- if e == nil {
- t.Fatal("did not see panic from check in other goroutine")
- }
- if !strings.Contains(fmt.Sprint(e), "wrong goroutine") {
- t.Errorf("expected on see panic about running on the wrong goroutine; got %v", e)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/headermap.go b/vendor/golang.org/x/net/http2/headermap.go
deleted file mode 100644
index c2805f6ac..000000000
--- a/vendor/golang.org/x/net/http2/headermap.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "net/http"
- "strings"
-)
-
-var (
- commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case
- commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case
-)
-
-func init() {
- for _, v := range []string{
- "accept",
- "accept-charset",
- "accept-encoding",
- "accept-language",
- "accept-ranges",
- "age",
- "access-control-allow-origin",
- "allow",
- "authorization",
- "cache-control",
- "content-disposition",
- "content-encoding",
- "content-language",
- "content-length",
- "content-location",
- "content-range",
- "content-type",
- "cookie",
- "date",
- "etag",
- "expect",
- "expires",
- "from",
- "host",
- "if-match",
- "if-modified-since",
- "if-none-match",
- "if-unmodified-since",
- "last-modified",
- "link",
- "location",
- "max-forwards",
- "proxy-authenticate",
- "proxy-authorization",
- "range",
- "referer",
- "refresh",
- "retry-after",
- "server",
- "set-cookie",
- "strict-transport-security",
- "trailer",
- "transfer-encoding",
- "user-agent",
- "vary",
- "via",
- "www-authenticate",
- } {
- chk := http.CanonicalHeaderKey(v)
- commonLowerHeader[chk] = v
- commonCanonHeader[v] = chk
- }
-}
-
-func lowerHeader(v string) string {
- if s, ok := commonLowerHeader[v]; ok {
- return s
- }
- return strings.ToLower(v)
-}
diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go
deleted file mode 100644
index 54726c2a3..000000000
--- a/vendor/golang.org/x/net/http2/hpack/encode.go
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package hpack
-
-import (
- "io"
-)
-
-const (
- uint32Max = ^uint32(0)
- initialHeaderTableSize = 4096
-)
-
-type Encoder struct {
- dynTab dynamicTable
- // minSize is the minimum table size set by
- // SetMaxDynamicTableSize after the previous Header Table Size
- // Update.
- minSize uint32
- // maxSizeLimit is the maximum table size this encoder
- // supports. This will protect the encoder from too large
- // size.
- maxSizeLimit uint32
- // tableSizeUpdate indicates whether "Header Table Size
- // Update" is required.
- tableSizeUpdate bool
- w io.Writer
- buf []byte
-}
-
-// NewEncoder returns a new Encoder which performs HPACK encoding. An
-// encoded data is written to w.
-func NewEncoder(w io.Writer) *Encoder {
- e := &Encoder{
- minSize: uint32Max,
- maxSizeLimit: initialHeaderTableSize,
- tableSizeUpdate: false,
- w: w,
- }
- e.dynTab.table.init()
- e.dynTab.setMaxSize(initialHeaderTableSize)
- return e
-}
-
-// WriteField encodes f into a single Write to e's underlying Writer.
-// This function may also produce bytes for "Header Table Size Update"
-// if necessary. If produced, it is done before encoding f.
-func (e *Encoder) WriteField(f HeaderField) error {
- e.buf = e.buf[:0]
-
- if e.tableSizeUpdate {
- e.tableSizeUpdate = false
- if e.minSize < e.dynTab.maxSize {
- e.buf = appendTableSize(e.buf, e.minSize)
- }
- e.minSize = uint32Max
- e.buf = appendTableSize(e.buf, e.dynTab.maxSize)
- }
-
- idx, nameValueMatch := e.searchTable(f)
- if nameValueMatch {
- e.buf = appendIndexed(e.buf, idx)
- } else {
- indexing := e.shouldIndex(f)
- if indexing {
- e.dynTab.add(f)
- }
-
- if idx == 0 {
- e.buf = appendNewName(e.buf, f, indexing)
- } else {
- e.buf = appendIndexedName(e.buf, f, idx, indexing)
- }
- }
- n, err := e.w.Write(e.buf)
- if err == nil && n != len(e.buf) {
- err = io.ErrShortWrite
- }
- return err
-}
-
-// searchTable searches f in both stable and dynamic header tables.
-// The static header table is searched first. Only when there is no
-// exact match for both name and value, the dynamic header table is
-// then searched. If there is no match, i is 0. If both name and value
-// match, i is the matched index and nameValueMatch becomes true. If
-// only name matches, i points to that index and nameValueMatch
-// becomes false.
-func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) {
- i, nameValueMatch = staticTable.search(f)
- if nameValueMatch {
- return i, true
- }
-
- j, nameValueMatch := e.dynTab.table.search(f)
- if nameValueMatch || (i == 0 && j != 0) {
- return j + uint64(staticTable.len()), nameValueMatch
- }
-
- return i, false
-}
-
-// SetMaxDynamicTableSize changes the dynamic header table size to v.
-// The actual size is bounded by the value passed to
-// SetMaxDynamicTableSizeLimit.
-func (e *Encoder) SetMaxDynamicTableSize(v uint32) {
- if v > e.maxSizeLimit {
- v = e.maxSizeLimit
- }
- if v < e.minSize {
- e.minSize = v
- }
- e.tableSizeUpdate = true
- e.dynTab.setMaxSize(v)
-}
-
-// SetMaxDynamicTableSizeLimit changes the maximum value that can be
-// specified in SetMaxDynamicTableSize to v. By default, it is set to
-// 4096, which is the same size of the default dynamic header table
-// size described in HPACK specification. If the current maximum
-// dynamic header table size is strictly greater than v, "Header Table
-// Size Update" will be done in the next WriteField call and the
-// maximum dynamic header table size is truncated to v.
-func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {
- e.maxSizeLimit = v
- if e.dynTab.maxSize > v {
- e.tableSizeUpdate = true
- e.dynTab.setMaxSize(v)
- }
-}
-
-// shouldIndex reports whether f should be indexed.
-func (e *Encoder) shouldIndex(f HeaderField) bool {
- return !f.Sensitive && f.Size() <= e.dynTab.maxSize
-}
-
-// appendIndexed appends index i, as encoded in "Indexed Header Field"
-// representation, to dst and returns the extended buffer.
-func appendIndexed(dst []byte, i uint64) []byte {
- first := len(dst)
- dst = appendVarInt(dst, 7, i)
- dst[first] |= 0x80
- return dst
-}
-
-// appendNewName appends f, as encoded in one of "Literal Header field
-// - New Name" representation variants, to dst and returns the
-// extended buffer.
-//
-// If f.Sensitive is true, "Never Indexed" representation is used. If
-// f.Sensitive is false and indexing is true, "Inremental Indexing"
-// representation is used.
-func appendNewName(dst []byte, f HeaderField, indexing bool) []byte {
- dst = append(dst, encodeTypeByte(indexing, f.Sensitive))
- dst = appendHpackString(dst, f.Name)
- return appendHpackString(dst, f.Value)
-}
-
-// appendIndexedName appends f and index i referring indexed name
-// entry, as encoded in one of "Literal Header field - Indexed Name"
-// representation variants, to dst and returns the extended buffer.
-//
-// If f.Sensitive is true, "Never Indexed" representation is used. If
-// f.Sensitive is false and indexing is true, "Incremental Indexing"
-// representation is used.
-func appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte {
- first := len(dst)
- var n byte
- if indexing {
- n = 6
- } else {
- n = 4
- }
- dst = appendVarInt(dst, n, i)
- dst[first] |= encodeTypeByte(indexing, f.Sensitive)
- return appendHpackString(dst, f.Value)
-}
-
-// appendTableSize appends v, as encoded in "Header Table Size Update"
-// representation, to dst and returns the extended buffer.
-func appendTableSize(dst []byte, v uint32) []byte {
- first := len(dst)
- dst = appendVarInt(dst, 5, uint64(v))
- dst[first] |= 0x20
- return dst
-}
-
-// appendVarInt appends i, as encoded in variable integer form using n
-// bit prefix, to dst and returns the extended buffer.
-//
-// See
-// http://http2.github.io/http2-spec/compression.html#integer.representation
-func appendVarInt(dst []byte, n byte, i uint64) []byte {
- k := uint64((1 << n) - 1)
- if i < k {
- return append(dst, byte(i))
- }
- dst = append(dst, byte(k))
- i -= k
- for ; i >= 128; i >>= 7 {
- dst = append(dst, byte(0x80|(i&0x7f)))
- }
- return append(dst, byte(i))
-}
-
-// appendHpackString appends s, as encoded in "String Literal"
-// representation, to dst and returns the the extended buffer.
-//
-// s will be encoded in Huffman codes only when it produces strictly
-// shorter byte string.
-func appendHpackString(dst []byte, s string) []byte {
- huffmanLength := HuffmanEncodeLength(s)
- if huffmanLength < uint64(len(s)) {
- first := len(dst)
- dst = appendVarInt(dst, 7, huffmanLength)
- dst = AppendHuffmanString(dst, s)
- dst[first] |= 0x80
- } else {
- dst = appendVarInt(dst, 7, uint64(len(s)))
- dst = append(dst, s...)
- }
- return dst
-}
-
-// encodeTypeByte returns type byte. If sensitive is true, type byte
-// for "Never Indexed" representation is returned. If sensitive is
-// false and indexing is true, type byte for "Incremental Indexing"
-// representation is returned. Otherwise, type byte for "Without
-// Indexing" is returned.
-func encodeTypeByte(indexing, sensitive bool) byte {
- if sensitive {
- return 0x10
- }
- if indexing {
- return 0x40
- }
- return 0
-}
diff --git a/vendor/golang.org/x/net/http2/hpack/encode_test.go b/vendor/golang.org/x/net/http2/hpack/encode_test.go
deleted file mode 100644
index 05f12db9c..000000000
--- a/vendor/golang.org/x/net/http2/hpack/encode_test.go
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package hpack
-
-import (
- "bytes"
- "encoding/hex"
- "fmt"
- "math/rand"
- "reflect"
- "strings"
- "testing"
-)
-
-func TestEncoderTableSizeUpdate(t *testing.T) {
- tests := []struct {
- size1, size2 uint32
- wantHex string
- }{
- // Should emit 2 table size updates (2048 and 4096)
- {2048, 4096, "3fe10f 3fe11f 82"},
-
- // Should emit 1 table size update (2048)
- {16384, 2048, "3fe10f 82"},
- }
- for _, tt := range tests {
- var buf bytes.Buffer
- e := NewEncoder(&buf)
- e.SetMaxDynamicTableSize(tt.size1)
- e.SetMaxDynamicTableSize(tt.size2)
- if err := e.WriteField(pair(":method", "GET")); err != nil {
- t.Fatal(err)
- }
- want := removeSpace(tt.wantHex)
- if got := hex.EncodeToString(buf.Bytes()); got != want {
- t.Errorf("e.SetDynamicTableSize %v, %v = %q; want %q", tt.size1, tt.size2, got, want)
- }
- }
-}
-
-func TestEncoderWriteField(t *testing.T) {
- var buf bytes.Buffer
- e := NewEncoder(&buf)
- var got []HeaderField
- d := NewDecoder(4<<10, func(f HeaderField) {
- got = append(got, f)
- })
-
- tests := []struct {
- hdrs []HeaderField
- }{
- {[]HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "http"),
- pair(":path", "/"),
- pair(":authority", "www.example.com"),
- }},
- {[]HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "http"),
- pair(":path", "/"),
- pair(":authority", "www.example.com"),
- pair("cache-control", "no-cache"),
- }},
- {[]HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "https"),
- pair(":path", "/index.html"),
- pair(":authority", "www.example.com"),
- pair("custom-key", "custom-value"),
- }},
- }
- for i, tt := range tests {
- buf.Reset()
- got = got[:0]
- for _, hf := range tt.hdrs {
- if err := e.WriteField(hf); err != nil {
- t.Fatal(err)
- }
- }
- _, err := d.Write(buf.Bytes())
- if err != nil {
- t.Errorf("%d. Decoder Write = %v", i, err)
- }
- if !reflect.DeepEqual(got, tt.hdrs) {
- t.Errorf("%d. Decoded %+v; want %+v", i, got, tt.hdrs)
- }
- }
-}
-
-func TestEncoderSearchTable(t *testing.T) {
- e := NewEncoder(nil)
-
- e.dynTab.add(pair("foo", "bar"))
- e.dynTab.add(pair("blake", "miz"))
- e.dynTab.add(pair(":method", "GET"))
-
- tests := []struct {
- hf HeaderField
- wantI uint64
- wantMatch bool
- }{
- // Name and Value match
- {pair("foo", "bar"), uint64(staticTable.len()) + 3, true},
- {pair("blake", "miz"), uint64(staticTable.len()) + 2, true},
- {pair(":method", "GET"), 2, true},
-
- // Only name match because Sensitive == true. This is allowed to match
- // any ":method" entry. The current implementation uses the last entry
- // added in newStaticTable.
- {HeaderField{":method", "GET", true}, 3, false},
-
- // Only Name matches
- {pair("foo", "..."), uint64(staticTable.len()) + 3, false},
- {pair("blake", "..."), uint64(staticTable.len()) + 2, false},
- // As before, this is allowed to match any ":method" entry.
- {pair(":method", "..."), 3, false},
-
- // None match
- {pair("foo-", "bar"), 0, false},
- }
- for _, tt := range tests {
- if gotI, gotMatch := e.searchTable(tt.hf); gotI != tt.wantI || gotMatch != tt.wantMatch {
- t.Errorf("d.search(%+v) = %v, %v; want %v, %v", tt.hf, gotI, gotMatch, tt.wantI, tt.wantMatch)
- }
- }
-}
-
-func TestAppendVarInt(t *testing.T) {
- tests := []struct {
- n byte
- i uint64
- want []byte
- }{
- // Fits in a byte:
- {1, 0, []byte{0}},
- {2, 2, []byte{2}},
- {3, 6, []byte{6}},
- {4, 14, []byte{14}},
- {5, 30, []byte{30}},
- {6, 62, []byte{62}},
- {7, 126, []byte{126}},
- {8, 254, []byte{254}},
-
- // Multiple bytes:
- {5, 1337, []byte{31, 154, 10}},
- }
- for _, tt := range tests {
- got := appendVarInt(nil, tt.n, tt.i)
- if !bytes.Equal(got, tt.want) {
- t.Errorf("appendVarInt(nil, %v, %v) = %v; want %v", tt.n, tt.i, got, tt.want)
- }
- }
-}
-
-func TestAppendHpackString(t *testing.T) {
- tests := []struct {
- s, wantHex string
- }{
- // Huffman encoded
- {"www.example.com", "8c f1e3 c2e5 f23a 6ba0 ab90 f4ff"},
-
- // Not Huffman encoded
- {"a", "01 61"},
-
- // zero length
- {"", "00"},
- }
- for _, tt := range tests {
- want := removeSpace(tt.wantHex)
- buf := appendHpackString(nil, tt.s)
- if got := hex.EncodeToString(buf); want != got {
- t.Errorf("appendHpackString(nil, %q) = %q; want %q", tt.s, got, want)
- }
- }
-}
-
-func TestAppendIndexed(t *testing.T) {
- tests := []struct {
- i uint64
- wantHex string
- }{
- // 1 byte
- {1, "81"},
- {126, "fe"},
-
- // 2 bytes
- {127, "ff00"},
- {128, "ff01"},
- }
- for _, tt := range tests {
- want := removeSpace(tt.wantHex)
- buf := appendIndexed(nil, tt.i)
- if got := hex.EncodeToString(buf); want != got {
- t.Errorf("appendIndex(nil, %v) = %q; want %q", tt.i, got, want)
- }
- }
-}
-
-func TestAppendNewName(t *testing.T) {
- tests := []struct {
- f HeaderField
- indexing bool
- wantHex string
- }{
- // Incremental indexing
- {HeaderField{"custom-key", "custom-value", false}, true, "40 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"},
-
- // Without indexing
- {HeaderField{"custom-key", "custom-value", false}, false, "00 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"},
-
- // Never indexed
- {HeaderField{"custom-key", "custom-value", true}, true, "10 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"},
- {HeaderField{"custom-key", "custom-value", true}, false, "10 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"},
- }
- for _, tt := range tests {
- want := removeSpace(tt.wantHex)
- buf := appendNewName(nil, tt.f, tt.indexing)
- if got := hex.EncodeToString(buf); want != got {
- t.Errorf("appendNewName(nil, %+v, %v) = %q; want %q", tt.f, tt.indexing, got, want)
- }
- }
-}
-
-func TestAppendIndexedName(t *testing.T) {
- tests := []struct {
- f HeaderField
- i uint64
- indexing bool
- wantHex string
- }{
- // Incremental indexing
- {HeaderField{":status", "302", false}, 8, true, "48 82 6402"},
-
- // Without indexing
- {HeaderField{":status", "302", false}, 8, false, "08 82 6402"},
-
- // Never indexed
- {HeaderField{":status", "302", true}, 8, true, "18 82 6402"},
- {HeaderField{":status", "302", true}, 8, false, "18 82 6402"},
- }
- for _, tt := range tests {
- want := removeSpace(tt.wantHex)
- buf := appendIndexedName(nil, tt.f, tt.i, tt.indexing)
- if got := hex.EncodeToString(buf); want != got {
- t.Errorf("appendIndexedName(nil, %+v, %v) = %q; want %q", tt.f, tt.indexing, got, want)
- }
- }
-}
-
-func TestAppendTableSize(t *testing.T) {
- tests := []struct {
- i uint32
- wantHex string
- }{
- // Fits into 1 byte
- {30, "3e"},
-
- // Extra byte
- {31, "3f00"},
- {32, "3f01"},
- }
- for _, tt := range tests {
- want := removeSpace(tt.wantHex)
- buf := appendTableSize(nil, tt.i)
- if got := hex.EncodeToString(buf); want != got {
- t.Errorf("appendTableSize(nil, %v) = %q; want %q", tt.i, got, want)
- }
- }
-}
-
-func TestEncoderSetMaxDynamicTableSize(t *testing.T) {
- var buf bytes.Buffer
- e := NewEncoder(&buf)
- tests := []struct {
- v uint32
- wantUpdate bool
- wantMinSize uint32
- wantMaxSize uint32
- }{
- // Set new table size to 2048
- {2048, true, 2048, 2048},
-
- // Set new table size to 16384, but still limited to
- // 4096
- {16384, true, 2048, 4096},
- }
- for _, tt := range tests {
- e.SetMaxDynamicTableSize(tt.v)
- if got := e.tableSizeUpdate; tt.wantUpdate != got {
- t.Errorf("e.tableSizeUpdate = %v; want %v", got, tt.wantUpdate)
- }
- if got := e.minSize; tt.wantMinSize != got {
- t.Errorf("e.minSize = %v; want %v", got, tt.wantMinSize)
- }
- if got := e.dynTab.maxSize; tt.wantMaxSize != got {
- t.Errorf("e.maxSize = %v; want %v", got, tt.wantMaxSize)
- }
- }
-}
-
-func TestEncoderSetMaxDynamicTableSizeLimit(t *testing.T) {
- e := NewEncoder(nil)
- // 4095 < initialHeaderTableSize means maxSize is truncated to
- // 4095.
- e.SetMaxDynamicTableSizeLimit(4095)
- if got, want := e.dynTab.maxSize, uint32(4095); got != want {
- t.Errorf("e.dynTab.maxSize = %v; want %v", got, want)
- }
- if got, want := e.maxSizeLimit, uint32(4095); got != want {
- t.Errorf("e.maxSizeLimit = %v; want %v", got, want)
- }
- if got, want := e.tableSizeUpdate, true; got != want {
- t.Errorf("e.tableSizeUpdate = %v; want %v", got, want)
- }
- // maxSize will be truncated to maxSizeLimit
- e.SetMaxDynamicTableSize(16384)
- if got, want := e.dynTab.maxSize, uint32(4095); got != want {
- t.Errorf("e.dynTab.maxSize = %v; want %v", got, want)
- }
- // 8192 > current maxSizeLimit, so maxSize does not change.
- e.SetMaxDynamicTableSizeLimit(8192)
- if got, want := e.dynTab.maxSize, uint32(4095); got != want {
- t.Errorf("e.dynTab.maxSize = %v; want %v", got, want)
- }
- if got, want := e.maxSizeLimit, uint32(8192); got != want {
- t.Errorf("e.maxSizeLimit = %v; want %v", got, want)
- }
-}
-
-func removeSpace(s string) string {
- return strings.Replace(s, " ", "", -1)
-}
-
-func BenchmarkEncoderSearchTable(b *testing.B) {
- e := NewEncoder(nil)
-
- // A sample of possible header fields.
- // This is not based on any actual data from HTTP/2 traces.
- var possible []HeaderField
- for _, f := range staticTable.ents {
- if f.Value == "" {
- possible = append(possible, f)
- continue
- }
- // Generate 5 random values, except for cookie and set-cookie,
- // which we know can have many values in practice.
- num := 5
- if f.Name == "cookie" || f.Name == "set-cookie" {
- num = 25
- }
- for i := 0; i < num; i++ {
- f.Value = fmt.Sprintf("%s-%d", f.Name, i)
- possible = append(possible, f)
- }
- }
- for k := 0; k < 10; k++ {
- f := HeaderField{
- Name: fmt.Sprintf("x-header-%d", k),
- Sensitive: rand.Int()%2 == 0,
- }
- for i := 0; i < 5; i++ {
- f.Value = fmt.Sprintf("%s-%d", f.Name, i)
- possible = append(possible, f)
- }
- }
-
- // Add a random sample to the dynamic table. This very loosely simulates
- // a history of 100 requests with 20 header fields per request.
- for r := 0; r < 100*20; r++ {
- f := possible[rand.Int31n(int32(len(possible)))]
- // Skip if this is in the staticTable verbatim.
- if _, has := staticTable.search(f); !has {
- e.dynTab.add(f)
- }
- }
-
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- for _, f := range possible {
- e.searchTable(f)
- }
- }
-}
diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go
deleted file mode 100644
index 176644acd..000000000
--- a/vendor/golang.org/x/net/http2/hpack/hpack.go
+++ /dev/null
@@ -1,490 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package hpack implements HPACK, a compression format for
-// efficiently representing HTTP header fields in the context of HTTP/2.
-//
-// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
-package hpack
-
-import (
- "bytes"
- "errors"
- "fmt"
-)
-
-// A DecodingError is something the spec defines as a decoding error.
-type DecodingError struct {
- Err error
-}
-
-func (de DecodingError) Error() string {
- return fmt.Sprintf("decoding error: %v", de.Err)
-}
-
-// An InvalidIndexError is returned when an encoder references a table
-// entry before the static table or after the end of the dynamic table.
-type InvalidIndexError int
-
-func (e InvalidIndexError) Error() string {
- return fmt.Sprintf("invalid indexed representation index %d", int(e))
-}
-
-// A HeaderField is a name-value pair. Both the name and value are
-// treated as opaque sequences of octets.
-type HeaderField struct {
- Name, Value string
-
- // Sensitive means that this header field should never be
- // indexed.
- Sensitive bool
-}
-
-// IsPseudo reports whether the header field is an http2 pseudo header.
-// That is, it reports whether it starts with a colon.
-// It is not otherwise guaranteed to be a valid pseudo header field,
-// though.
-func (hf HeaderField) IsPseudo() bool {
- return len(hf.Name) != 0 && hf.Name[0] == ':'
-}
-
-func (hf HeaderField) String() string {
- var suffix string
- if hf.Sensitive {
- suffix = " (sensitive)"
- }
- return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
-}
-
-// Size returns the size of an entry per RFC 7541 section 4.1.
-func (hf HeaderField) Size() uint32 {
- // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
- // "The size of the dynamic table is the sum of the size of
- // its entries. The size of an entry is the sum of its name's
- // length in octets (as defined in Section 5.2), its value's
- // length in octets (see Section 5.2), plus 32. The size of
- // an entry is calculated using the length of the name and
- // value without any Huffman encoding applied."
-
- // This can overflow if somebody makes a large HeaderField
- // Name and/or Value by hand, but we don't care, because that
- // won't happen on the wire because the encoding doesn't allow
- // it.
- return uint32(len(hf.Name) + len(hf.Value) + 32)
-}
-
-// A Decoder is the decoding context for incremental processing of
-// header blocks.
-type Decoder struct {
- dynTab dynamicTable
- emit func(f HeaderField)
-
- emitEnabled bool // whether calls to emit are enabled
- maxStrLen int // 0 means unlimited
-
- // buf is the unparsed buffer. It's only written to
- // saveBuf if it was truncated in the middle of a header
- // block. Because it's usually not owned, we can only
- // process it under Write.
- buf []byte // not owned; only valid during Write
-
- // saveBuf is previous data passed to Write which we weren't able
- // to fully parse before. Unlike buf, we own this data.
- saveBuf bytes.Buffer
-}
-
-// NewDecoder returns a new decoder with the provided maximum dynamic
-// table size. The emitFunc will be called for each valid field
-// parsed, in the same goroutine as calls to Write, before Write returns.
-func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
- d := &Decoder{
- emit: emitFunc,
- emitEnabled: true,
- }
- d.dynTab.table.init()
- d.dynTab.allowedMaxSize = maxDynamicTableSize
- d.dynTab.setMaxSize(maxDynamicTableSize)
- return d
-}
-
-// ErrStringLength is returned by Decoder.Write when the max string length
-// (as configured by Decoder.SetMaxStringLength) would be violated.
-var ErrStringLength = errors.New("hpack: string too long")
-
-// SetMaxStringLength sets the maximum size of a HeaderField name or
-// value string. If a string exceeds this length (even after any
-// decompression), Write will return ErrStringLength.
-// A value of 0 means unlimited and is the default from NewDecoder.
-func (d *Decoder) SetMaxStringLength(n int) {
- d.maxStrLen = n
-}
-
-// SetEmitFunc changes the callback used when new header fields
-// are decoded.
-// It must be non-nil. It does not affect EmitEnabled.
-func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
- d.emit = emitFunc
-}
-
-// SetEmitEnabled controls whether the emitFunc provided to NewDecoder
-// should be called. The default is true.
-//
-// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
-// while still decoding and keeping in-sync with decoder state, but
-// without doing unnecessary decompression or generating unnecessary
-// garbage for header fields past the limit.
-func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
-
-// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
-// are currently enabled. The default is true.
-func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
-
-// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
-// underlying buffers for garbage reasons.
-
-func (d *Decoder) SetMaxDynamicTableSize(v uint32) {
- d.dynTab.setMaxSize(v)
-}
-
-// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded
-// stream (via dynamic table size updates) may set the maximum size
-// to.
-func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
- d.dynTab.allowedMaxSize = v
-}
-
-type dynamicTable struct {
- // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2
- table headerFieldTable
- size uint32 // in bytes
- maxSize uint32 // current maxSize
- allowedMaxSize uint32 // maxSize may go up to this, inclusive
-}
-
-func (dt *dynamicTable) setMaxSize(v uint32) {
- dt.maxSize = v
- dt.evict()
-}
-
-func (dt *dynamicTable) add(f HeaderField) {
- dt.table.addEntry(f)
- dt.size += f.Size()
- dt.evict()
-}
-
-// If we're too big, evict old stuff.
-func (dt *dynamicTable) evict() {
- var n int
- for dt.size > dt.maxSize && n < dt.table.len() {
- dt.size -= dt.table.ents[n].Size()
- n++
- }
- dt.table.evictOldest(n)
-}
-
-func (d *Decoder) maxTableIndex() int {
- // This should never overflow. RFC 7540 Section 6.5.2 limits the size of
- // the dynamic table to 2^32 bytes, where each entry will occupy more than
- // one byte. Further, the staticTable has a fixed, small length.
- return d.dynTab.table.len() + staticTable.len()
-}
-
-func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {
- // See Section 2.3.3.
- if i == 0 {
- return
- }
- if i <= uint64(staticTable.len()) {
- return staticTable.ents[i-1], true
- }
- if i > uint64(d.maxTableIndex()) {
- return
- }
- // In the dynamic table, newer entries have lower indices.
- // However, dt.ents[0] is the oldest entry. Hence, dt.ents is
- // the reversed dynamic table.
- dt := d.dynTab.table
- return dt.ents[dt.len()-(int(i)-staticTable.len())], true
-}
-
-// Decode decodes an entire block.
-//
-// TODO: remove this method and make it incremental later? This is
-// easier for debugging now.
-func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
- var hf []HeaderField
- saveFunc := d.emit
- defer func() { d.emit = saveFunc }()
- d.emit = func(f HeaderField) { hf = append(hf, f) }
- if _, err := d.Write(p); err != nil {
- return nil, err
- }
- if err := d.Close(); err != nil {
- return nil, err
- }
- return hf, nil
-}
-
-func (d *Decoder) Close() error {
- if d.saveBuf.Len() > 0 {
- d.saveBuf.Reset()
- return DecodingError{errors.New("truncated headers")}
- }
- return nil
-}
-
-func (d *Decoder) Write(p []byte) (n int, err error) {
- if len(p) == 0 {
- // Prevent state machine CPU attacks (making us redo
- // work up to the point of finding out we don't have
- // enough data)
- return
- }
- // Only copy the data if we have to. Optimistically assume
- // that p will contain a complete header block.
- if d.saveBuf.Len() == 0 {
- d.buf = p
- } else {
- d.saveBuf.Write(p)
- d.buf = d.saveBuf.Bytes()
- d.saveBuf.Reset()
- }
-
- for len(d.buf) > 0 {
- err = d.parseHeaderFieldRepr()
- if err == errNeedMore {
- // Extra paranoia, making sure saveBuf won't
- // get too large. All the varint and string
- // reading code earlier should already catch
- // overlong things and return ErrStringLength,
- // but keep this as a last resort.
- const varIntOverhead = 8 // conservative
- if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
- return 0, ErrStringLength
- }
- d.saveBuf.Write(d.buf)
- return len(p), nil
- }
- if err != nil {
- break
- }
- }
- return len(p), err
-}
-
-// errNeedMore is an internal sentinel error value that means the
-// buffer is truncated and we need to read more data before we can
-// continue parsing.
-var errNeedMore = errors.New("need more data")
-
-type indexType int
-
-const (
- indexedTrue indexType = iota
- indexedFalse
- indexedNever
-)
-
-func (v indexType) indexed() bool { return v == indexedTrue }
-func (v indexType) sensitive() bool { return v == indexedNever }
-
-// returns errNeedMore if there isn't enough data available.
-// any other error is fatal.
-// consumes d.buf iff it returns nil.
-// precondition: must be called with len(d.buf) > 0
-func (d *Decoder) parseHeaderFieldRepr() error {
- b := d.buf[0]
- switch {
- case b&128 != 0:
- // Indexed representation.
- // High bit set?
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
- return d.parseFieldIndexed()
- case b&192 == 64:
- // 6.2.1 Literal Header Field with Incremental Indexing
- // 0b10xxxxxx: top two bits are 10
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1
- return d.parseFieldLiteral(6, indexedTrue)
- case b&240 == 0:
- // 6.2.2 Literal Header Field without Indexing
- // 0b0000xxxx: top four bits are 0000
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2
- return d.parseFieldLiteral(4, indexedFalse)
- case b&240 == 16:
- // 6.2.3 Literal Header Field never Indexed
- // 0b0001xxxx: top four bits are 0001
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3
- return d.parseFieldLiteral(4, indexedNever)
- case b&224 == 32:
- // 6.3 Dynamic Table Size Update
- // Top three bits are '001'.
- // http://http2.github.io/http2-spec/compression.html#rfc.section.6.3
- return d.parseDynamicTableSizeUpdate()
- }
-
- return DecodingError{errors.New("invalid encoding")}
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseFieldIndexed() error {
- buf := d.buf
- idx, buf, err := readVarInt(7, buf)
- if err != nil {
- return err
- }
- hf, ok := d.at(idx)
- if !ok {
- return DecodingError{InvalidIndexError(idx)}
- }
- d.buf = buf
- return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
- buf := d.buf
- nameIdx, buf, err := readVarInt(n, buf)
- if err != nil {
- return err
- }
-
- var hf HeaderField
- wantStr := d.emitEnabled || it.indexed()
- if nameIdx > 0 {
- ihf, ok := d.at(nameIdx)
- if !ok {
- return DecodingError{InvalidIndexError(nameIdx)}
- }
- hf.Name = ihf.Name
- } else {
- hf.Name, buf, err = d.readString(buf, wantStr)
- if err != nil {
- return err
- }
- }
- hf.Value, buf, err = d.readString(buf, wantStr)
- if err != nil {
- return err
- }
- d.buf = buf
- if it.indexed() {
- d.dynTab.add(hf)
- }
- hf.Sensitive = it.sensitive()
- return d.callEmit(hf)
-}
-
-func (d *Decoder) callEmit(hf HeaderField) error {
- if d.maxStrLen != 0 {
- if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
- return ErrStringLength
- }
- }
- if d.emitEnabled {
- d.emit(hf)
- }
- return nil
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseDynamicTableSizeUpdate() error {
- buf := d.buf
- size, buf, err := readVarInt(5, buf)
- if err != nil {
- return err
- }
- if size > uint64(d.dynTab.allowedMaxSize) {
- return DecodingError{errors.New("dynamic table size update too large")}
- }
- d.dynTab.setMaxSize(uint32(size))
- d.buf = buf
- return nil
-}
-
-var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
-
-// readVarInt reads an unsigned variable length integer off the
-// beginning of p. n is the parameter as described in
-// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1.
-//
-// n must always be between 1 and 8.
-//
-// The returned remain buffer is either a smaller suffix of p, or err != nil.
-// The error is errNeedMore if p doesn't contain a complete integer.
-func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
- if n < 1 || n > 8 {
- panic("bad n")
- }
- if len(p) == 0 {
- return 0, p, errNeedMore
- }
- i = uint64(p[0])
- if n < 8 {
- i &= (1 << uint64(n)) - 1
- }
- if i < (1<<uint64(n))-1 {
- return i, p[1:], nil
- }
-
- origP := p
- p = p[1:]
- var m uint64
- for len(p) > 0 {
- b := p[0]
- p = p[1:]
- i += uint64(b&127) << m
- if b&128 == 0 {
- return i, p, nil
- }
- m += 7
- if m >= 63 { // TODO: proper overflow check. making this up.
- return 0, origP, errVarintOverflow
- }
- }
- return 0, origP, errNeedMore
-}
-
-// readString decodes an hpack string from p.
-//
-// wantStr is whether s will be used. If false, decompression and
-// []byte->string garbage are skipped if s will be ignored
-// anyway. This does mean that huffman decoding errors for non-indexed
-// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
-// is returning an error anyway, and because they're not indexed, the error
-// won't affect the decoding state.
-func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) {
- if len(p) == 0 {
- return "", p, errNeedMore
- }
- isHuff := p[0]&128 != 0
- strLen, p, err := readVarInt(7, p)
- if err != nil {
- return "", p, err
- }
- if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
- return "", nil, ErrStringLength
- }
- if uint64(len(p)) < strLen {
- return "", p, errNeedMore
- }
- if !isHuff {
- if wantStr {
- s = string(p[:strLen])
- }
- return s, p[strLen:], nil
- }
-
- if wantStr {
- buf := bufPool.Get().(*bytes.Buffer)
- buf.Reset() // don't trust others
- defer bufPool.Put(buf)
- if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil {
- buf.Reset()
- return "", nil, err
- }
- s = buf.String()
- buf.Reset() // be nice to GC
- }
- return s, p[strLen:], nil
-}
diff --git a/vendor/golang.org/x/net/http2/hpack/hpack_test.go b/vendor/golang.org/x/net/http2/hpack/hpack_test.go
deleted file mode 100644
index bc7f47678..000000000
--- a/vendor/golang.org/x/net/http2/hpack/hpack_test.go
+++ /dev/null
@@ -1,722 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package hpack
-
-import (
- "bytes"
- "encoding/hex"
- "fmt"
- "math/rand"
- "reflect"
- "strings"
- "testing"
- "time"
-)
-
-func (d *Decoder) mustAt(idx int) HeaderField {
- if hf, ok := d.at(uint64(idx)); !ok {
- panic(fmt.Sprintf("bogus index %d", idx))
- } else {
- return hf
- }
-}
-
-func TestDynamicTableAt(t *testing.T) {
- d := NewDecoder(4096, nil)
- at := d.mustAt
- if got, want := at(2), (pair(":method", "GET")); got != want {
- t.Errorf("at(2) = %v; want %v", got, want)
- }
- d.dynTab.add(pair("foo", "bar"))
- d.dynTab.add(pair("blake", "miz"))
- if got, want := at(staticTable.len()+1), (pair("blake", "miz")); got != want {
- t.Errorf("at(dyn 1) = %v; want %v", got, want)
- }
- if got, want := at(staticTable.len()+2), (pair("foo", "bar")); got != want {
- t.Errorf("at(dyn 2) = %v; want %v", got, want)
- }
- if got, want := at(3), (pair(":method", "POST")); got != want {
- t.Errorf("at(3) = %v; want %v", got, want)
- }
-}
-
-func TestDynamicTableSizeEvict(t *testing.T) {
- d := NewDecoder(4096, nil)
- if want := uint32(0); d.dynTab.size != want {
- t.Fatalf("size = %d; want %d", d.dynTab.size, want)
- }
- add := d.dynTab.add
- add(pair("blake", "eats pizza"))
- if want := uint32(15 + 32); d.dynTab.size != want {
- t.Fatalf("after pizza, size = %d; want %d", d.dynTab.size, want)
- }
- add(pair("foo", "bar"))
- if want := uint32(15 + 32 + 6 + 32); d.dynTab.size != want {
- t.Fatalf("after foo bar, size = %d; want %d", d.dynTab.size, want)
- }
- d.dynTab.setMaxSize(15 + 32 + 1 /* slop */)
- if want := uint32(6 + 32); d.dynTab.size != want {
- t.Fatalf("after setMaxSize, size = %d; want %d", d.dynTab.size, want)
- }
- if got, want := d.mustAt(staticTable.len()+1), (pair("foo", "bar")); got != want {
- t.Errorf("at(dyn 1) = %v; want %v", got, want)
- }
- add(pair("long", strings.Repeat("x", 500)))
- if want := uint32(0); d.dynTab.size != want {
- t.Fatalf("after big one, size = %d; want %d", d.dynTab.size, want)
- }
-}
-
-func TestDecoderDecode(t *testing.T) {
- tests := []struct {
- name string
- in []byte
- want []HeaderField
- wantDynTab []HeaderField // newest entry first
- }{
- // C.2.1 Literal Header Field with Indexing
- // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.1
- {"C.2.1", dehex("400a 6375 7374 6f6d 2d6b 6579 0d63 7573 746f 6d2d 6865 6164 6572"),
- []HeaderField{pair("custom-key", "custom-header")},
- []HeaderField{pair("custom-key", "custom-header")},
- },
-
- // C.2.2 Literal Header Field without Indexing
- // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.2
- {"C.2.2", dehex("040c 2f73 616d 706c 652f 7061 7468"),
- []HeaderField{pair(":path", "/sample/path")},
- []HeaderField{}},
-
- // C.2.3 Literal Header Field never Indexed
- // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.3
- {"C.2.3", dehex("1008 7061 7373 776f 7264 0673 6563 7265 74"),
- []HeaderField{{"password", "secret", true}},
- []HeaderField{}},
-
- // C.2.4 Indexed Header Field
- // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.4
- {"C.2.4", []byte("\x82"),
- []HeaderField{pair(":method", "GET")},
- []HeaderField{}},
- }
- for _, tt := range tests {
- d := NewDecoder(4096, nil)
- hf, err := d.DecodeFull(tt.in)
- if err != nil {
- t.Errorf("%s: %v", tt.name, err)
- continue
- }
- if !reflect.DeepEqual(hf, tt.want) {
- t.Errorf("%s: Got %v; want %v", tt.name, hf, tt.want)
- }
- gotDynTab := d.dynTab.reverseCopy()
- if !reflect.DeepEqual(gotDynTab, tt.wantDynTab) {
- t.Errorf("%s: dynamic table after = %v; want %v", tt.name, gotDynTab, tt.wantDynTab)
- }
- }
-}
-
-func (dt *dynamicTable) reverseCopy() (hf []HeaderField) {
- hf = make([]HeaderField, len(dt.table.ents))
- for i := range hf {
- hf[i] = dt.table.ents[len(dt.table.ents)-1-i]
- }
- return
-}
-
-type encAndWant struct {
- enc []byte
- want []HeaderField
- wantDynTab []HeaderField
- wantDynSize uint32
-}
-
-// C.3 Request Examples without Huffman Coding
-// http://http2.github.io/http2-spec/compression.html#rfc.section.C.3
-func TestDecodeC3_NoHuffman(t *testing.T) {
- testDecodeSeries(t, 4096, []encAndWant{
- {dehex("8286 8441 0f77 7777 2e65 7861 6d70 6c65 2e63 6f6d"),
- []HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "http"),
- pair(":path", "/"),
- pair(":authority", "www.example.com"),
- },
- []HeaderField{
- pair(":authority", "www.example.com"),
- },
- 57,
- },
- {dehex("8286 84be 5808 6e6f 2d63 6163 6865"),
- []HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "http"),
- pair(":path", "/"),
- pair(":authority", "www.example.com"),
- pair("cache-control", "no-cache"),
- },
- []HeaderField{
- pair("cache-control", "no-cache"),
- pair(":authority", "www.example.com"),
- },
- 110,
- },
- {dehex("8287 85bf 400a 6375 7374 6f6d 2d6b 6579 0c63 7573 746f 6d2d 7661 6c75 65"),
- []HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "https"),
- pair(":path", "/index.html"),
- pair(":authority", "www.example.com"),
- pair("custom-key", "custom-value"),
- },
- []HeaderField{
- pair("custom-key", "custom-value"),
- pair("cache-control", "no-cache"),
- pair(":authority", "www.example.com"),
- },
- 164,
- },
- })
-}
-
-// C.4 Request Examples with Huffman Coding
-// http://http2.github.io/http2-spec/compression.html#rfc.section.C.4
-func TestDecodeC4_Huffman(t *testing.T) {
- testDecodeSeries(t, 4096, []encAndWant{
- {dehex("8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4 ff"),
- []HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "http"),
- pair(":path", "/"),
- pair(":authority", "www.example.com"),
- },
- []HeaderField{
- pair(":authority", "www.example.com"),
- },
- 57,
- },
- {dehex("8286 84be 5886 a8eb 1064 9cbf"),
- []HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "http"),
- pair(":path", "/"),
- pair(":authority", "www.example.com"),
- pair("cache-control", "no-cache"),
- },
- []HeaderField{
- pair("cache-control", "no-cache"),
- pair(":authority", "www.example.com"),
- },
- 110,
- },
- {dehex("8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925 a849 e95b b8e8 b4bf"),
- []HeaderField{
- pair(":method", "GET"),
- pair(":scheme", "https"),
- pair(":path", "/index.html"),
- pair(":authority", "www.example.com"),
- pair("custom-key", "custom-value"),
- },
- []HeaderField{
- pair("custom-key", "custom-value"),
- pair("cache-control", "no-cache"),
- pair(":authority", "www.example.com"),
- },
- 164,
- },
- })
-}
-
-// http://http2.github.io/http2-spec/compression.html#rfc.section.C.5
-// "This section shows several consecutive header lists, corresponding
-// to HTTP responses, on the same connection. The HTTP/2 setting
-// parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256
-// octets, causing some evictions to occur."
-func TestDecodeC5_ResponsesNoHuff(t *testing.T) {
- testDecodeSeries(t, 256, []encAndWant{
- {dehex(`
-4803 3330 3258 0770 7269 7661 7465 611d
-4d6f 6e2c 2032 3120 4f63 7420 3230 3133
-2032 303a 3133 3a32 3120 474d 546e 1768
-7474 7073 3a2f 2f77 7777 2e65 7861 6d70
-6c65 2e63 6f6d
-`),
- []HeaderField{
- pair(":status", "302"),
- pair("cache-control", "private"),
- pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
- pair("location", "https://www.example.com"),
- },
- []HeaderField{
- pair("location", "https://www.example.com"),
- pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
- pair("cache-control", "private"),
- pair(":status", "302"),
- },
- 222,
- },
- {dehex("4803 3330 37c1 c0bf"),
- []HeaderField{
- pair(":status", "307"),
- pair("cache-control", "private"),
- pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
- pair("location", "https://www.example.com"),
- },
- []HeaderField{
- pair(":status", "307"),
- pair("location", "https://www.example.com"),
- pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
- pair("cache-control", "private"),
- },
- 222,
- },
- {dehex(`
-88c1 611d 4d6f 6e2c 2032 3120 4f63 7420
-3230 3133 2032 303a 3133 3a32 3220 474d
-54c0 5a04 677a 6970 7738 666f 6f3d 4153
-444a 4b48 514b 425a 584f 5157 454f 5049
-5541 5851 5745 4f49 553b 206d 6178 2d61
-6765 3d33 3630 303b 2076 6572 7369 6f6e
-3d31
-`),
- []HeaderField{
- pair(":status", "200"),
- pair("cache-control", "private"),
- pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
- pair("location", "https://www.example.com"),
- pair("content-encoding", "gzip"),
- pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
- },
- []HeaderField{
- pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
- pair("content-encoding", "gzip"),
- pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
- },
- 215,
- },
- })
-}
-
-// http://http2.github.io/http2-spec/compression.html#rfc.section.C.6
-// "This section shows the same examples as the previous section, but
-// using Huffman encoding for the literal values. The HTTP/2 setting
-// parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256
-// octets, causing some evictions to occur. The eviction mechanism
-// uses the length of the decoded literal values, so the same
-// evictions occurs as in the previous section."
-func TestDecodeC6_ResponsesHuffman(t *testing.T) {
- testDecodeSeries(t, 256, []encAndWant{
- {dehex(`
-4882 6402 5885 aec3 771a 4b61 96d0 7abe
-9410 54d4 44a8 2005 9504 0b81 66e0 82a6
-2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8
-e9ae 82ae 43d3
-`),
- []HeaderField{
- pair(":status", "302"),
- pair("cache-control", "private"),
- pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
- pair("location", "https://www.example.com"),
- },
- []HeaderField{
- pair("location", "https://www.example.com"),
- pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
- pair("cache-control", "private"),
- pair(":status", "302"),
- },
- 222,
- },
- {dehex("4883 640e ffc1 c0bf"),
- []HeaderField{
- pair(":status", "307"),
- pair("cache-control", "private"),
- pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
- pair("location", "https://www.example.com"),
- },
- []HeaderField{
- pair(":status", "307"),
- pair("location", "https://www.example.com"),
- pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
- pair("cache-control", "private"),
- },
- 222,
- },
- {dehex(`
-88c1 6196 d07a be94 1054 d444 a820 0595
-040b 8166 e084 a62d 1bff c05a 839b d9ab
-77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b
-3960 d5af 2708 7f36 72c1 ab27 0fb5 291f
-9587 3160 65c0 03ed 4ee5 b106 3d50 07
-`),
- []HeaderField{
- pair(":status", "200"),
- pair("cache-control", "private"),
- pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
- pair("location", "https://www.example.com"),
- pair("content-encoding", "gzip"),
- pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
- },
- []HeaderField{
- pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
- pair("content-encoding", "gzip"),
- pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
- },
- 215,
- },
- })
-}
-
-func testDecodeSeries(t *testing.T, size uint32, steps []encAndWant) {
- d := NewDecoder(size, nil)
- for i, step := range steps {
- hf, err := d.DecodeFull(step.enc)
- if err != nil {
- t.Fatalf("Error at step index %d: %v", i, err)
- }
- if !reflect.DeepEqual(hf, step.want) {
- t.Fatalf("At step index %d: Got headers %v; want %v", i, hf, step.want)
- }
- gotDynTab := d.dynTab.reverseCopy()
- if !reflect.DeepEqual(gotDynTab, step.wantDynTab) {
- t.Errorf("After step index %d, dynamic table = %v; want %v", i, gotDynTab, step.wantDynTab)
- }
- if d.dynTab.size != step.wantDynSize {
- t.Errorf("After step index %d, dynamic table size = %v; want %v", i, d.dynTab.size, step.wantDynSize)
- }
- }
-}
-
-func TestHuffmanDecodeExcessPadding(t *testing.T) {
- tests := [][]byte{
- {0xff}, // Padding Exceeds 7 bits
- {0x1f, 0xff}, // {"a", 1 byte excess padding}
- {0x1f, 0xff, 0xff}, // {"a", 2 byte excess padding}
- {0x1f, 0xff, 0xff, 0xff}, // {"a", 3 byte excess padding}
- {0xff, 0x9f, 0xff, 0xff, 0xff}, // {"a", 29 bit excess padding}
- {'R', 0xbc, '0', 0xff, 0xff, 0xff, 0xff}, // Padding ends on partial symbol.
- }
- for i, in := range tests {
- var buf bytes.Buffer
- if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
- t.Errorf("test-%d: decode(%q) = %v; want ErrInvalidHuffman", i, in, err)
- }
- }
-}
-
-func TestHuffmanDecodeEOS(t *testing.T) {
- in := []byte{0xff, 0xff, 0xff, 0xff, 0xfc} // {EOS, "?"}
- var buf bytes.Buffer
- if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
- t.Errorf("error = %v; want ErrInvalidHuffman", err)
- }
-}
-
-func TestHuffmanDecodeMaxLengthOnTrailingByte(t *testing.T) {
- in := []byte{0x00, 0x01} // {"0", "0", "0"}
- var buf bytes.Buffer
- if err := huffmanDecode(&buf, 2, in); err != ErrStringLength {
- t.Errorf("error = %v; want ErrStringLength", err)
- }
-}
-
-func TestHuffmanDecodeCorruptPadding(t *testing.T) {
- in := []byte{0x00}
- var buf bytes.Buffer
- if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
- t.Errorf("error = %v; want ErrInvalidHuffman", err)
- }
-}
-
-func TestHuffmanDecode(t *testing.T) {
- tests := []struct {
- inHex, want string
- }{
- {"f1e3 c2e5 f23a 6ba0 ab90 f4ff", "www.example.com"},
- {"a8eb 1064 9cbf", "no-cache"},
- {"25a8 49e9 5ba9 7d7f", "custom-key"},
- {"25a8 49e9 5bb8 e8b4 bf", "custom-value"},
- {"6402", "302"},
- {"aec3 771a 4b", "private"},
- {"d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff", "Mon, 21 Oct 2013 20:13:21 GMT"},
- {"9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3", "https://www.example.com"},
- {"9bd9 ab", "gzip"},
- {"94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07",
- "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
- }
- for i, tt := range tests {
- var buf bytes.Buffer
- in, err := hex.DecodeString(strings.Replace(tt.inHex, " ", "", -1))
- if err != nil {
- t.Errorf("%d. hex input error: %v", i, err)
- continue
- }
- if _, err := HuffmanDecode(&buf, in); err != nil {
- t.Errorf("%d. decode error: %v", i, err)
- continue
- }
- if got := buf.String(); tt.want != got {
- t.Errorf("%d. decode = %q; want %q", i, got, tt.want)
- }
- }
-}
-
-func TestAppendHuffmanString(t *testing.T) {
- tests := []struct {
- in, want string
- }{
- {"www.example.com", "f1e3 c2e5 f23a 6ba0 ab90 f4ff"},
- {"no-cache", "a8eb 1064 9cbf"},
- {"custom-key", "25a8 49e9 5ba9 7d7f"},
- {"custom-value", "25a8 49e9 5bb8 e8b4 bf"},
- {"302", "6402"},
- {"private", "aec3 771a 4b"},
- {"Mon, 21 Oct 2013 20:13:21 GMT", "d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff"},
- {"https://www.example.com", "9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3"},
- {"gzip", "9bd9 ab"},
- {"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
- "94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07"},
- }
- for i, tt := range tests {
- buf := []byte{}
- want := strings.Replace(tt.want, " ", "", -1)
- buf = AppendHuffmanString(buf, tt.in)
- if got := hex.EncodeToString(buf); want != got {
- t.Errorf("%d. encode = %q; want %q", i, got, want)
- }
- }
-}
-
-func TestHuffmanMaxStrLen(t *testing.T) {
- const msg = "Some string"
- huff := AppendHuffmanString(nil, msg)
-
- testGood := func(max int) {
- var out bytes.Buffer
- if err := huffmanDecode(&out, max, huff); err != nil {
- t.Errorf("For maxLen=%d, unexpected error: %v", max, err)
- }
- if out.String() != msg {
- t.Errorf("For maxLen=%d, out = %q; want %q", max, out.String(), msg)
- }
- }
- testGood(0)
- testGood(len(msg))
- testGood(len(msg) + 1)
-
- var out bytes.Buffer
- if err := huffmanDecode(&out, len(msg)-1, huff); err != ErrStringLength {
- t.Errorf("err = %v; want ErrStringLength", err)
- }
-}
-
-func TestHuffmanRoundtripStress(t *testing.T) {
- const Len = 50 // of uncompressed string
- input := make([]byte, Len)
- var output bytes.Buffer
- var huff []byte
-
- n := 5000
- if testing.Short() {
- n = 100
- }
- seed := time.Now().UnixNano()
- t.Logf("Seed = %v", seed)
- src := rand.New(rand.NewSource(seed))
- var encSize int64
- for i := 0; i < n; i++ {
- for l := range input {
- input[l] = byte(src.Intn(256))
- }
- huff = AppendHuffmanString(huff[:0], string(input))
- encSize += int64(len(huff))
- output.Reset()
- if err := huffmanDecode(&output, 0, huff); err != nil {
- t.Errorf("Failed to decode %q -> %q -> error %v", input, huff, err)
- continue
- }
- if !bytes.Equal(output.Bytes(), input) {
- t.Errorf("Roundtrip failure on %q -> %q -> %q", input, huff, output.Bytes())
- }
- }
- t.Logf("Compressed size of original: %0.02f%% (%v -> %v)", 100*(float64(encSize)/(Len*float64(n))), Len*n, encSize)
-}
-
-func TestHuffmanDecodeFuzz(t *testing.T) {
- const Len = 50 // of compressed
- var buf, zbuf bytes.Buffer
-
- n := 5000
- if testing.Short() {
- n = 100
- }
- seed := time.Now().UnixNano()
- t.Logf("Seed = %v", seed)
- src := rand.New(rand.NewSource(seed))
- numFail := 0
- for i := 0; i < n; i++ {
- zbuf.Reset()
- if i == 0 {
- // Start with at least one invalid one.
- zbuf.WriteString("00\x91\xff\xff\xff\xff\xc8")
- } else {
- for l := 0; l < Len; l++ {
- zbuf.WriteByte(byte(src.Intn(256)))
- }
- }
-
- buf.Reset()
- if err := huffmanDecode(&buf, 0, zbuf.Bytes()); err != nil {
- if err == ErrInvalidHuffman {
- numFail++
- continue
- }
- t.Errorf("Failed to decode %q: %v", zbuf.Bytes(), err)
- continue
- }
- }
- t.Logf("%0.02f%% are invalid (%d / %d)", 100*float64(numFail)/float64(n), numFail, n)
- if numFail < 1 {
- t.Error("expected at least one invalid huffman encoding (test starts with one)")
- }
-}
-
-func TestReadVarInt(t *testing.T) {
- type res struct {
- i uint64
- consumed int
- err error
- }
- tests := []struct {
- n byte
- p []byte
- want res
- }{
- // Fits in a byte:
- {1, []byte{0}, res{0, 1, nil}},
- {2, []byte{2}, res{2, 1, nil}},
- {3, []byte{6}, res{6, 1, nil}},
- {4, []byte{14}, res{14, 1, nil}},
- {5, []byte{30}, res{30, 1, nil}},
- {6, []byte{62}, res{62, 1, nil}},
- {7, []byte{126}, res{126, 1, nil}},
- {8, []byte{254}, res{254, 1, nil}},
-
- // Doesn't fit in a byte:
- {1, []byte{1}, res{0, 0, errNeedMore}},
- {2, []byte{3}, res{0, 0, errNeedMore}},
- {3, []byte{7}, res{0, 0, errNeedMore}},
- {4, []byte{15}, res{0, 0, errNeedMore}},
- {5, []byte{31}, res{0, 0, errNeedMore}},
- {6, []byte{63}, res{0, 0, errNeedMore}},
- {7, []byte{127}, res{0, 0, errNeedMore}},
- {8, []byte{255}, res{0, 0, errNeedMore}},
-
- // Ignoring top bits:
- {5, []byte{255, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 111
- {5, []byte{159, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 100
- {5, []byte{191, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 101
-
- // Extra byte:
- {5, []byte{191, 154, 10, 2}, res{1337, 3, nil}}, // extra byte
-
- // Short a byte:
- {5, []byte{191, 154}, res{0, 0, errNeedMore}},
-
- // integer overflow:
- {1, []byte{255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, res{0, 0, errVarintOverflow}},
- }
- for _, tt := range tests {
- i, remain, err := readVarInt(tt.n, tt.p)
- consumed := len(tt.p) - len(remain)
- got := res{i, consumed, err}
- if got != tt.want {
- t.Errorf("readVarInt(%d, %v ~ %x) = %+v; want %+v", tt.n, tt.p, tt.p, got, tt.want)
- }
- }
-}
-
-// Fuzz crash, originally reported at https://github.com/bradfitz/http2/issues/56
-func TestHuffmanFuzzCrash(t *testing.T) {
- got, err := HuffmanDecodeToString([]byte("00\x91\xff\xff\xff\xff\xc8"))
- if got != "" {
- t.Errorf("Got %q; want empty string", got)
- }
- if err != ErrInvalidHuffman {
- t.Errorf("Err = %v; want ErrInvalidHuffman", err)
- }
-}
-
-func pair(name, value string) HeaderField {
- return HeaderField{Name: name, Value: value}
-}
-
-func dehex(s string) []byte {
- s = strings.Replace(s, " ", "", -1)
- s = strings.Replace(s, "\n", "", -1)
- b, err := hex.DecodeString(s)
- if err != nil {
- panic(err)
- }
- return b
-}
-
-func TestEmitEnabled(t *testing.T) {
- var buf bytes.Buffer
- enc := NewEncoder(&buf)
- enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
- enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
-
- numCallback := 0
- var dec *Decoder
- dec = NewDecoder(8<<20, func(HeaderField) {
- numCallback++
- dec.SetEmitEnabled(false)
- })
- if !dec.EmitEnabled() {
- t.Errorf("initial emit enabled = false; want true")
- }
- if _, err := dec.Write(buf.Bytes()); err != nil {
- t.Error(err)
- }
- if numCallback != 1 {
- t.Errorf("num callbacks = %d; want 1", numCallback)
- }
- if dec.EmitEnabled() {
- t.Errorf("emit enabled = true; want false")
- }
-}
-
-func TestSaveBufLimit(t *testing.T) {
- const maxStr = 1 << 10
- var got []HeaderField
- dec := NewDecoder(initialHeaderTableSize, func(hf HeaderField) {
- got = append(got, hf)
- })
- dec.SetMaxStringLength(maxStr)
- var frag []byte
- frag = append(frag[:0], encodeTypeByte(false, false))
- frag = appendVarInt(frag, 7, 3)
- frag = append(frag, "foo"...)
- frag = appendVarInt(frag, 7, 3)
- frag = append(frag, "bar"...)
-
- if _, err := dec.Write(frag); err != nil {
- t.Fatal(err)
- }
-
- want := []HeaderField{{Name: "foo", Value: "bar"}}
- if !reflect.DeepEqual(got, want) {
- t.Errorf("After small writes, got %v; want %v", got, want)
- }
-
- frag = append(frag[:0], encodeTypeByte(false, false))
- frag = appendVarInt(frag, 7, maxStr*3)
- frag = append(frag, make([]byte, maxStr*3)...)
-
- _, err := dec.Write(frag)
- if err != ErrStringLength {
- t.Fatalf("Write error = %v; want ErrStringLength", err)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/hpack/huffman.go b/vendor/golang.org/x/net/http2/hpack/huffman.go
deleted file mode 100644
index 8850e3946..000000000
--- a/vendor/golang.org/x/net/http2/hpack/huffman.go
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package hpack
-
-import (
- "bytes"
- "errors"
- "io"
- "sync"
-)
-
-var bufPool = sync.Pool{
- New: func() interface{} { return new(bytes.Buffer) },
-}
-
-// HuffmanDecode decodes the string in v and writes the expanded
-// result to w, returning the number of bytes written to w and the
-// Write call's return value. At most one Write call is made.
-func HuffmanDecode(w io.Writer, v []byte) (int, error) {
- buf := bufPool.Get().(*bytes.Buffer)
- buf.Reset()
- defer bufPool.Put(buf)
- if err := huffmanDecode(buf, 0, v); err != nil {
- return 0, err
- }
- return w.Write(buf.Bytes())
-}
-
-// HuffmanDecodeToString decodes the string in v.
-func HuffmanDecodeToString(v []byte) (string, error) {
- buf := bufPool.Get().(*bytes.Buffer)
- buf.Reset()
- defer bufPool.Put(buf)
- if err := huffmanDecode(buf, 0, v); err != nil {
- return "", err
- }
- return buf.String(), nil
-}
-
-// ErrInvalidHuffman is returned for errors found decoding
-// Huffman-encoded strings.
-var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
-
-// huffmanDecode decodes v to buf.
-// If maxLen is greater than 0, attempts to write more to buf than
-// maxLen bytes will return ErrStringLength.
-func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
- n := rootHuffmanNode
- // cur is the bit buffer that has not been fed into n.
- // cbits is the number of low order bits in cur that are valid.
- // sbits is the number of bits of the symbol prefix being decoded.
- cur, cbits, sbits := uint(0), uint8(0), uint8(0)
- for _, b := range v {
- cur = cur<<8 | uint(b)
- cbits += 8
- sbits += 8
- for cbits >= 8 {
- idx := byte(cur >> (cbits - 8))
- n = n.children[idx]
- if n == nil {
- return ErrInvalidHuffman
- }
- if n.children == nil {
- if maxLen != 0 && buf.Len() == maxLen {
- return ErrStringLength
- }
- buf.WriteByte(n.sym)
- cbits -= n.codeLen
- n = rootHuffmanNode
- sbits = cbits
- } else {
- cbits -= 8
- }
- }
- }
- for cbits > 0 {
- n = n.children[byte(cur<<(8-cbits))]
- if n == nil {
- return ErrInvalidHuffman
- }
- if n.children != nil || n.codeLen > cbits {
- break
- }
- if maxLen != 0 && buf.Len() == maxLen {
- return ErrStringLength
- }
- buf.WriteByte(n.sym)
- cbits -= n.codeLen
- n = rootHuffmanNode
- sbits = cbits
- }
- if sbits > 7 {
- // Either there was an incomplete symbol, or overlong padding.
- // Both are decoding errors per RFC 7541 section 5.2.
- return ErrInvalidHuffman
- }
- if mask := uint(1<<cbits - 1); cur&mask != mask {
- // Trailing bits must be a prefix of EOS per RFC 7541 section 5.2.
- return ErrInvalidHuffman
- }
-
- return nil
-}
-
-type node struct {
- // children is non-nil for internal nodes
- children []*node
-
- // The following are only valid if children is nil:
- codeLen uint8 // number of bits that led to the output of sym
- sym byte // output symbol
-}
-
-func newInternalNode() *node {
- return &node{children: make([]*node, 256)}
-}
-
-var rootHuffmanNode = newInternalNode()
-
-func init() {
- if len(huffmanCodes) != 256 {
- panic("unexpected size")
- }
- for i, code := range huffmanCodes {
- addDecoderNode(byte(i), code, huffmanCodeLen[i])
- }
-}
-
-func addDecoderNode(sym byte, code uint32, codeLen uint8) {
- cur := rootHuffmanNode
- for codeLen > 8 {
- codeLen -= 8
- i := uint8(code >> codeLen)
- if cur.children[i] == nil {
- cur.children[i] = newInternalNode()
- }
- cur = cur.children[i]
- }
- shift := 8 - codeLen
- start, end := int(uint8(code<<shift)), int(1<<shift)
- for i := start; i < start+end; i++ {
- cur.children[i] = &node{sym: sym, codeLen: codeLen}
- }
-}
-
-// AppendHuffmanString appends s, as encoded in Huffman codes, to dst
-// and returns the extended buffer.
-func AppendHuffmanString(dst []byte, s string) []byte {
- rembits := uint8(8)
-
- for i := 0; i < len(s); i++ {
- if rembits == 8 {
- dst = append(dst, 0)
- }
- dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i])
- }
-
- if rembits < 8 {
- // special EOS symbol
- code := uint32(0x3fffffff)
- nbits := uint8(30)
-
- t := uint8(code >> (nbits - rembits))
- dst[len(dst)-1] |= t
- }
-
- return dst
-}
-
-// HuffmanEncodeLength returns the number of bytes required to encode
-// s in Huffman codes. The result is round up to byte boundary.
-func HuffmanEncodeLength(s string) uint64 {
- n := uint64(0)
- for i := 0; i < len(s); i++ {
- n += uint64(huffmanCodeLen[s[i]])
- }
- return (n + 7) / 8
-}
-
-// appendByteToHuffmanCode appends Huffman code for c to dst and
-// returns the extended buffer and the remaining bits in the last
-// element. The appending is not byte aligned and the remaining bits
-// in the last element of dst is given in rembits.
-func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) {
- code := huffmanCodes[c]
- nbits := huffmanCodeLen[c]
-
- for {
- if rembits > nbits {
- t := uint8(code << (rembits - nbits))
- dst[len(dst)-1] |= t
- rembits -= nbits
- break
- }
-
- t := uint8(code >> (nbits - rembits))
- dst[len(dst)-1] |= t
-
- nbits -= rembits
- rembits = 8
-
- if nbits == 0 {
- break
- }
-
- dst = append(dst, 0)
- }
-
- return dst, rembits
-}
diff --git a/vendor/golang.org/x/net/http2/hpack/tables.go b/vendor/golang.org/x/net/http2/hpack/tables.go
deleted file mode 100644
index a66cfbea6..000000000
--- a/vendor/golang.org/x/net/http2/hpack/tables.go
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package hpack
-
-import (
- "fmt"
-)
-
-// headerFieldTable implements a list of HeaderFields.
-// This is used to implement the static and dynamic tables.
-type headerFieldTable struct {
- // For static tables, entries are never evicted.
- //
- // For dynamic tables, entries are evicted from ents[0] and added to the end.
- // Each entry has a unique id that starts at one and increments for each
- // entry that is added. This unique id is stable across evictions, meaning
- // it can be used as a pointer to a specific entry. As in hpack, unique ids
- // are 1-based. The unique id for ents[k] is k + evictCount + 1.
- //
- // Zero is not a valid unique id.
- //
- // evictCount should not overflow in any remotely practical situation. In
- // practice, we will have one dynamic table per HTTP/2 connection. If we
- // assume a very powerful server that handles 1M QPS per connection and each
- // request adds (then evicts) 100 entries from the table, it would still take
- // 2M years for evictCount to overflow.
- ents []HeaderField
- evictCount uint64
-
- // byName maps a HeaderField name to the unique id of the newest entry with
- // the same name. See above for a definition of "unique id".
- byName map[string]uint64
-
- // byNameValue maps a HeaderField name/value pair to the unique id of the newest
- // entry with the same name and value. See above for a definition of "unique id".
- byNameValue map[pairNameValue]uint64
-}
-
-type pairNameValue struct {
- name, value string
-}
-
-func (t *headerFieldTable) init() {
- t.byName = make(map[string]uint64)
- t.byNameValue = make(map[pairNameValue]uint64)
-}
-
-// len reports the number of entries in the table.
-func (t *headerFieldTable) len() int {
- return len(t.ents)
-}
-
-// addEntry adds a new entry.
-func (t *headerFieldTable) addEntry(f HeaderField) {
- id := uint64(t.len()) + t.evictCount + 1
- t.byName[f.Name] = id
- t.byNameValue[pairNameValue{f.Name, f.Value}] = id
- t.ents = append(t.ents, f)
-}
-
-// evictOldest evicts the n oldest entries in the table.
-func (t *headerFieldTable) evictOldest(n int) {
- if n > t.len() {
- panic(fmt.Sprintf("evictOldest(%v) on table with %v entries", n, t.len()))
- }
- for k := 0; k < n; k++ {
- f := t.ents[k]
- id := t.evictCount + uint64(k) + 1
- if t.byName[f.Name] == id {
- delete(t.byName, f.Name)
- }
- if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id {
- delete(t.byNameValue, p)
- }
- }
- copy(t.ents, t.ents[n:])
- for k := t.len() - n; k < t.len(); k++ {
- t.ents[k] = HeaderField{} // so strings can be garbage collected
- }
- t.ents = t.ents[:t.len()-n]
- if t.evictCount+uint64(n) < t.evictCount {
- panic("evictCount overflow")
- }
- t.evictCount += uint64(n)
-}
-
-// search finds f in the table. If there is no match, i is 0.
-// If both name and value match, i is the matched index and nameValueMatch
-// becomes true. If only name matches, i points to that index and
-// nameValueMatch becomes false.
-//
-// The returned index is a 1-based HPACK index. For dynamic tables, HPACK says
-// that index 1 should be the newest entry, but t.ents[0] is the oldest entry,
-// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic
-// table, the return value i actually refers to the entry t.ents[t.len()-i].
-//
-// All tables are assumed to be a dynamic tables except for the global
-// staticTable pointer.
-//
-// See Section 2.3.3.
-func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
- if !f.Sensitive {
- if id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 {
- return t.idToIndex(id), true
- }
- }
- if id := t.byName[f.Name]; id != 0 {
- return t.idToIndex(id), false
- }
- return 0, false
-}
-
-// idToIndex converts a unique id to an HPACK index.
-// See Section 2.3.3.
-func (t *headerFieldTable) idToIndex(id uint64) uint64 {
- if id <= t.evictCount {
- panic(fmt.Sprintf("id (%v) <= evictCount (%v)", id, t.evictCount))
- }
- k := id - t.evictCount - 1 // convert id to an index t.ents[k]
- if t != staticTable {
- return uint64(t.len()) - k // dynamic table
- }
- return k + 1
-}
-
-// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
-var staticTable = newStaticTable()
-var staticTableEntries = [...]HeaderField{
- {Name: ":authority"},
- {Name: ":method", Value: "GET"},
- {Name: ":method", Value: "POST"},
- {Name: ":path", Value: "/"},
- {Name: ":path", Value: "/index.html"},
- {Name: ":scheme", Value: "http"},
- {Name: ":scheme", Value: "https"},
- {Name: ":status", Value: "200"},
- {Name: ":status", Value: "204"},
- {Name: ":status", Value: "206"},
- {Name: ":status", Value: "304"},
- {Name: ":status", Value: "400"},
- {Name: ":status", Value: "404"},
- {Name: ":status", Value: "500"},
- {Name: "accept-charset"},
- {Name: "accept-encoding", Value: "gzip, deflate"},
- {Name: "accept-language"},
- {Name: "accept-ranges"},
- {Name: "accept"},
- {Name: "access-control-allow-origin"},
- {Name: "age"},
- {Name: "allow"},
- {Name: "authorization"},
- {Name: "cache-control"},
- {Name: "content-disposition"},
- {Name: "content-encoding"},
- {Name: "content-language"},
- {Name: "content-length"},
- {Name: "content-location"},
- {Name: "content-range"},
- {Name: "content-type"},
- {Name: "cookie"},
- {Name: "date"},
- {Name: "etag"},
- {Name: "expect"},
- {Name: "expires"},
- {Name: "from"},
- {Name: "host"},
- {Name: "if-match"},
- {Name: "if-modified-since"},
- {Name: "if-none-match"},
- {Name: "if-range"},
- {Name: "if-unmodified-since"},
- {Name: "last-modified"},
- {Name: "link"},
- {Name: "location"},
- {Name: "max-forwards"},
- {Name: "proxy-authenticate"},
- {Name: "proxy-authorization"},
- {Name: "range"},
- {Name: "referer"},
- {Name: "refresh"},
- {Name: "retry-after"},
- {Name: "server"},
- {Name: "set-cookie"},
- {Name: "strict-transport-security"},
- {Name: "transfer-encoding"},
- {Name: "user-agent"},
- {Name: "vary"},
- {Name: "via"},
- {Name: "www-authenticate"},
-}
-
-func newStaticTable() *headerFieldTable {
- t := &headerFieldTable{}
- t.init()
- for _, e := range staticTableEntries[:] {
- t.addEntry(e)
- }
- return t
-}
-
-var huffmanCodes = [256]uint32{
- 0x1ff8,
- 0x7fffd8,
- 0xfffffe2,
- 0xfffffe3,
- 0xfffffe4,
- 0xfffffe5,
- 0xfffffe6,
- 0xfffffe7,
- 0xfffffe8,
- 0xffffea,
- 0x3ffffffc,
- 0xfffffe9,
- 0xfffffea,
- 0x3ffffffd,
- 0xfffffeb,
- 0xfffffec,
- 0xfffffed,
- 0xfffffee,
- 0xfffffef,
- 0xffffff0,
- 0xffffff1,
- 0xffffff2,
- 0x3ffffffe,
- 0xffffff3,
- 0xffffff4,
- 0xffffff5,
- 0xffffff6,
- 0xffffff7,
- 0xffffff8,
- 0xffffff9,
- 0xffffffa,
- 0xffffffb,
- 0x14,
- 0x3f8,
- 0x3f9,
- 0xffa,
- 0x1ff9,
- 0x15,
- 0xf8,
- 0x7fa,
- 0x3fa,
- 0x3fb,
- 0xf9,
- 0x7fb,
- 0xfa,
- 0x16,
- 0x17,
- 0x18,
- 0x0,
- 0x1,
- 0x2,
- 0x19,
- 0x1a,
- 0x1b,
- 0x1c,
- 0x1d,
- 0x1e,
- 0x1f,
- 0x5c,
- 0xfb,
- 0x7ffc,
- 0x20,
- 0xffb,
- 0x3fc,
- 0x1ffa,
- 0x21,
- 0x5d,
- 0x5e,
- 0x5f,
- 0x60,
- 0x61,
- 0x62,
- 0x63,
- 0x64,
- 0x65,
- 0x66,
- 0x67,
- 0x68,
- 0x69,
- 0x6a,
- 0x6b,
- 0x6c,
- 0x6d,
- 0x6e,
- 0x6f,
- 0x70,
- 0x71,
- 0x72,
- 0xfc,
- 0x73,
- 0xfd,
- 0x1ffb,
- 0x7fff0,
- 0x1ffc,
- 0x3ffc,
- 0x22,
- 0x7ffd,
- 0x3,
- 0x23,
- 0x4,
- 0x24,
- 0x5,
- 0x25,
- 0x26,
- 0x27,
- 0x6,
- 0x74,
- 0x75,
- 0x28,
- 0x29,
- 0x2a,
- 0x7,
- 0x2b,
- 0x76,
- 0x2c,
- 0x8,
- 0x9,
- 0x2d,
- 0x77,
- 0x78,
- 0x79,
- 0x7a,
- 0x7b,
- 0x7ffe,
- 0x7fc,
- 0x3ffd,
- 0x1ffd,
- 0xffffffc,
- 0xfffe6,
- 0x3fffd2,
- 0xfffe7,
- 0xfffe8,
- 0x3fffd3,
- 0x3fffd4,
- 0x3fffd5,
- 0x7fffd9,
- 0x3fffd6,
- 0x7fffda,
- 0x7fffdb,
- 0x7fffdc,
- 0x7fffdd,
- 0x7fffde,
- 0xffffeb,
- 0x7fffdf,
- 0xffffec,
- 0xffffed,
- 0x3fffd7,
- 0x7fffe0,
- 0xffffee,
- 0x7fffe1,
- 0x7fffe2,
- 0x7fffe3,
- 0x7fffe4,
- 0x1fffdc,
- 0x3fffd8,
- 0x7fffe5,
- 0x3fffd9,
- 0x7fffe6,
- 0x7fffe7,
- 0xffffef,
- 0x3fffda,
- 0x1fffdd,
- 0xfffe9,
- 0x3fffdb,
- 0x3fffdc,
- 0x7fffe8,
- 0x7fffe9,
- 0x1fffde,
- 0x7fffea,
- 0x3fffdd,
- 0x3fffde,
- 0xfffff0,
- 0x1fffdf,
- 0x3fffdf,
- 0x7fffeb,
- 0x7fffec,
- 0x1fffe0,
- 0x1fffe1,
- 0x3fffe0,
- 0x1fffe2,
- 0x7fffed,
- 0x3fffe1,
- 0x7fffee,
- 0x7fffef,
- 0xfffea,
- 0x3fffe2,
- 0x3fffe3,
- 0x3fffe4,
- 0x7ffff0,
- 0x3fffe5,
- 0x3fffe6,
- 0x7ffff1,
- 0x3ffffe0,
- 0x3ffffe1,
- 0xfffeb,
- 0x7fff1,
- 0x3fffe7,
- 0x7ffff2,
- 0x3fffe8,
- 0x1ffffec,
- 0x3ffffe2,
- 0x3ffffe3,
- 0x3ffffe4,
- 0x7ffffde,
- 0x7ffffdf,
- 0x3ffffe5,
- 0xfffff1,
- 0x1ffffed,
- 0x7fff2,
- 0x1fffe3,
- 0x3ffffe6,
- 0x7ffffe0,
- 0x7ffffe1,
- 0x3ffffe7,
- 0x7ffffe2,
- 0xfffff2,
- 0x1fffe4,
- 0x1fffe5,
- 0x3ffffe8,
- 0x3ffffe9,
- 0xffffffd,
- 0x7ffffe3,
- 0x7ffffe4,
- 0x7ffffe5,
- 0xfffec,
- 0xfffff3,
- 0xfffed,
- 0x1fffe6,
- 0x3fffe9,
- 0x1fffe7,
- 0x1fffe8,
- 0x7ffff3,
- 0x3fffea,
- 0x3fffeb,
- 0x1ffffee,
- 0x1ffffef,
- 0xfffff4,
- 0xfffff5,
- 0x3ffffea,
- 0x7ffff4,
- 0x3ffffeb,
- 0x7ffffe6,
- 0x3ffffec,
- 0x3ffffed,
- 0x7ffffe7,
- 0x7ffffe8,
- 0x7ffffe9,
- 0x7ffffea,
- 0x7ffffeb,
- 0xffffffe,
- 0x7ffffec,
- 0x7ffffed,
- 0x7ffffee,
- 0x7ffffef,
- 0x7fffff0,
- 0x3ffffee,
-}
-
-var huffmanCodeLen = [256]uint8{
- 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
- 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
- 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
- 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,
- 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,
- 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,
- 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,
- 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,
- 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,
- 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,
- 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,
- 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,
- 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,
- 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,
- 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
-}
diff --git a/vendor/golang.org/x/net/http2/hpack/tables_test.go b/vendor/golang.org/x/net/http2/hpack/tables_test.go
deleted file mode 100644
index d963f3635..000000000
--- a/vendor/golang.org/x/net/http2/hpack/tables_test.go
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package hpack
-
-import (
- "bufio"
- "regexp"
- "strconv"
- "strings"
- "testing"
-)
-
-func TestHeaderFieldTable(t *testing.T) {
- table := &headerFieldTable{}
- table.init()
- table.addEntry(pair("key1", "value1-1"))
- table.addEntry(pair("key2", "value2-1"))
- table.addEntry(pair("key1", "value1-2"))
- table.addEntry(pair("key3", "value3-1"))
- table.addEntry(pair("key4", "value4-1"))
- table.addEntry(pair("key2", "value2-2"))
-
- // Tests will be run twice: once before evicting anything, and
- // again after evicting the three oldest entries.
- tests := []struct {
- f HeaderField
- beforeWantStaticI uint64
- beforeWantMatch bool
- afterWantStaticI uint64
- afterWantMatch bool
- }{
- {HeaderField{"key1", "value1-1", false}, 1, true, 0, false},
- {HeaderField{"key1", "value1-2", false}, 3, true, 0, false},
- {HeaderField{"key1", "value1-3", false}, 3, false, 0, false},
- {HeaderField{"key2", "value2-1", false}, 2, true, 3, false},
- {HeaderField{"key2", "value2-2", false}, 6, true, 3, true},
- {HeaderField{"key2", "value2-3", false}, 6, false, 3, false},
- {HeaderField{"key4", "value4-1", false}, 5, true, 2, true},
- // Name match only, because sensitive.
- {HeaderField{"key4", "value4-1", true}, 5, false, 2, false},
- // Key not found.
- {HeaderField{"key5", "value5-x", false}, 0, false, 0, false},
- }
-
- staticToDynamic := func(i uint64) uint64 {
- if i == 0 {
- return 0
- }
- return uint64(table.len()) - i + 1 // dynamic is the reversed table
- }
-
- searchStatic := func(f HeaderField) (uint64, bool) {
- old := staticTable
- staticTable = table
- defer func() { staticTable = old }()
- return staticTable.search(f)
- }
-
- searchDynamic := func(f HeaderField) (uint64, bool) {
- return table.search(f)
- }
-
- for _, test := range tests {
- gotI, gotMatch := searchStatic(test.f)
- if wantI, wantMatch := test.beforeWantStaticI, test.beforeWantMatch; gotI != wantI || gotMatch != wantMatch {
- t.Errorf("before evictions: searchStatic(%+v)=%v,%v want %v,%v", test.f, gotI, gotMatch, wantI, wantMatch)
- }
- gotI, gotMatch = searchDynamic(test.f)
- wantDynamicI := staticToDynamic(test.beforeWantStaticI)
- if wantI, wantMatch := wantDynamicI, test.beforeWantMatch; gotI != wantI || gotMatch != wantMatch {
- t.Errorf("before evictions: searchDynamic(%+v)=%v,%v want %v,%v", test.f, gotI, gotMatch, wantI, wantMatch)
- }
- }
-
- table.evictOldest(3)
-
- for _, test := range tests {
- gotI, gotMatch := searchStatic(test.f)
- if wantI, wantMatch := test.afterWantStaticI, test.afterWantMatch; gotI != wantI || gotMatch != wantMatch {
- t.Errorf("after evictions: searchStatic(%+v)=%v,%v want %v,%v", test.f, gotI, gotMatch, wantI, wantMatch)
- }
- gotI, gotMatch = searchDynamic(test.f)
- wantDynamicI := staticToDynamic(test.afterWantStaticI)
- if wantI, wantMatch := wantDynamicI, test.afterWantMatch; gotI != wantI || gotMatch != wantMatch {
- t.Errorf("after evictions: searchDynamic(%+v)=%v,%v want %v,%v", test.f, gotI, gotMatch, wantI, wantMatch)
- }
- }
-}
-
-func TestHeaderFieldTable_LookupMapEviction(t *testing.T) {
- table := &headerFieldTable{}
- table.init()
- table.addEntry(pair("key1", "value1-1"))
- table.addEntry(pair("key2", "value2-1"))
- table.addEntry(pair("key1", "value1-2"))
- table.addEntry(pair("key3", "value3-1"))
- table.addEntry(pair("key4", "value4-1"))
- table.addEntry(pair("key2", "value2-2"))
-
- // evict all pairs
- table.evictOldest(table.len())
-
- if l := table.len(); l > 0 {
- t.Errorf("table.len() = %d, want 0", l)
- }
-
- if l := len(table.byName); l > 0 {
- t.Errorf("len(table.byName) = %d, want 0", l)
- }
-
- if l := len(table.byNameValue); l > 0 {
- t.Errorf("len(table.byNameValue) = %d, want 0", l)
- }
-}
-
-func TestStaticTable(t *testing.T) {
- fromSpec := `
- +-------+-----------------------------+---------------+
- | 1 | :authority | |
- | 2 | :method | GET |
- | 3 | :method | POST |
- | 4 | :path | / |
- | 5 | :path | /index.html |
- | 6 | :scheme | http |
- | 7 | :scheme | https |
- | 8 | :status | 200 |
- | 9 | :status | 204 |
- | 10 | :status | 206 |
- | 11 | :status | 304 |
- | 12 | :status | 400 |
- | 13 | :status | 404 |
- | 14 | :status | 500 |
- | 15 | accept-charset | |
- | 16 | accept-encoding | gzip, deflate |
- | 17 | accept-language | |
- | 18 | accept-ranges | |
- | 19 | accept | |
- | 20 | access-control-allow-origin | |
- | 21 | age | |
- | 22 | allow | |
- | 23 | authorization | |
- | 24 | cache-control | |
- | 25 | content-disposition | |
- | 26 | content-encoding | |
- | 27 | content-language | |
- | 28 | content-length | |
- | 29 | content-location | |
- | 30 | content-range | |
- | 31 | content-type | |
- | 32 | cookie | |
- | 33 | date | |
- | 34 | etag | |
- | 35 | expect | |
- | 36 | expires | |
- | 37 | from | |
- | 38 | host | |
- | 39 | if-match | |
- | 40 | if-modified-since | |
- | 41 | if-none-match | |
- | 42 | if-range | |
- | 43 | if-unmodified-since | |
- | 44 | last-modified | |
- | 45 | link | |
- | 46 | location | |
- | 47 | max-forwards | |
- | 48 | proxy-authenticate | |
- | 49 | proxy-authorization | |
- | 50 | range | |
- | 51 | referer | |
- | 52 | refresh | |
- | 53 | retry-after | |
- | 54 | server | |
- | 55 | set-cookie | |
- | 56 | strict-transport-security | |
- | 57 | transfer-encoding | |
- | 58 | user-agent | |
- | 59 | vary | |
- | 60 | via | |
- | 61 | www-authenticate | |
- +-------+-----------------------------+---------------+
-`
- bs := bufio.NewScanner(strings.NewReader(fromSpec))
- re := regexp.MustCompile(`\| (\d+)\s+\| (\S+)\s*\| (\S(.*\S)?)?\s+\|`)
- for bs.Scan() {
- l := bs.Text()
- if !strings.Contains(l, "|") {
- continue
- }
- m := re.FindStringSubmatch(l)
- if m == nil {
- continue
- }
- i, err := strconv.Atoi(m[1])
- if err != nil {
- t.Errorf("Bogus integer on line %q", l)
- continue
- }
- if i < 1 || i > staticTable.len() {
- t.Errorf("Bogus index %d on line %q", i, l)
- continue
- }
- if got, want := staticTable.ents[i-1].Name, m[2]; got != want {
- t.Errorf("header index %d name = %q; want %q", i, got, want)
- }
- if got, want := staticTable.ents[i-1].Value, m[3]; got != want {
- t.Errorf("header index %d value = %q; want %q", i, got, want)
- }
- }
- if err := bs.Err(); err != nil {
- t.Error(err)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go
deleted file mode 100644
index b6b0f9ad1..000000000
--- a/vendor/golang.org/x/net/http2/http2.go
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package http2 implements the HTTP/2 protocol.
-//
-// This package is low-level and intended to be used directly by very
-// few people. Most users will use it indirectly through the automatic
-// use by the net/http package (from Go 1.6 and later).
-// For use in earlier Go versions see ConfigureServer. (Transport support
-// requires Go 1.6 or later)
-//
-// See https://http2.github.io/ for more information on HTTP/2.
-//
-// See https://http2.golang.org/ for a test server running this code.
-//
-package http2 // import "golang.org/x/net/http2"
-
-import (
- "bufio"
- "crypto/tls"
- "errors"
- "fmt"
- "io"
- "net/http"
- "os"
- "sort"
- "strconv"
- "strings"
- "sync"
-
- "golang.org/x/net/lex/httplex"
-)
-
-var (
- VerboseLogs bool
- logFrameWrites bool
- logFrameReads bool
- inTests bool
-)
-
-func init() {
- e := os.Getenv("GODEBUG")
- if strings.Contains(e, "http2debug=1") {
- VerboseLogs = true
- }
- if strings.Contains(e, "http2debug=2") {
- VerboseLogs = true
- logFrameWrites = true
- logFrameReads = true
- }
-}
-
-const (
- // ClientPreface is the string that must be sent by new
- // connections from clients.
- ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
-
- // SETTINGS_MAX_FRAME_SIZE default
- // http://http2.github.io/http2-spec/#rfc.section.6.5.2
- initialMaxFrameSize = 16384
-
- // NextProtoTLS is the NPN/ALPN protocol negotiated during
- // HTTP/2's TLS setup.
- NextProtoTLS = "h2"
-
- // http://http2.github.io/http2-spec/#SettingValues
- initialHeaderTableSize = 4096
-
- initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
-
- defaultMaxReadFrameSize = 1 << 20
-)
-
-var (
- clientPreface = []byte(ClientPreface)
-)
-
-type streamState int
-
-// HTTP/2 stream states.
-//
-// See http://tools.ietf.org/html/rfc7540#section-5.1.
-//
-// For simplicity, the server code merges "reserved (local)" into
-// "half-closed (remote)". This is one less state transition to track.
-// The only downside is that we send PUSH_PROMISEs slightly less
-// liberally than allowable. More discussion here:
-// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html
-//
-// "reserved (remote)" is omitted since the client code does not
-// support server push.
-const (
- stateIdle streamState = iota
- stateOpen
- stateHalfClosedLocal
- stateHalfClosedRemote
- stateClosed
-)
-
-var stateName = [...]string{
- stateIdle: "Idle",
- stateOpen: "Open",
- stateHalfClosedLocal: "HalfClosedLocal",
- stateHalfClosedRemote: "HalfClosedRemote",
- stateClosed: "Closed",
-}
-
-func (st streamState) String() string {
- return stateName[st]
-}
-
-// Setting is a setting parameter: which setting it is, and its value.
-type Setting struct {
- // ID is which setting is being set.
- // See http://http2.github.io/http2-spec/#SettingValues
- ID SettingID
-
- // Val is the value.
- Val uint32
-}
-
-func (s Setting) String() string {
- return fmt.Sprintf("[%v = %d]", s.ID, s.Val)
-}
-
-// Valid reports whether the setting is valid.
-func (s Setting) Valid() error {
- // Limits and error codes from 6.5.2 Defined SETTINGS Parameters
- switch s.ID {
- case SettingEnablePush:
- if s.Val != 1 && s.Val != 0 {
- return ConnectionError(ErrCodeProtocol)
- }
- case SettingInitialWindowSize:
- if s.Val > 1<<31-1 {
- return ConnectionError(ErrCodeFlowControl)
- }
- case SettingMaxFrameSize:
- if s.Val < 16384 || s.Val > 1<<24-1 {
- return ConnectionError(ErrCodeProtocol)
- }
- }
- return nil
-}
-
-// A SettingID is an HTTP/2 setting as defined in
-// http://http2.github.io/http2-spec/#iana-settings
-type SettingID uint16
-
-const (
- SettingHeaderTableSize SettingID = 0x1
- SettingEnablePush SettingID = 0x2
- SettingMaxConcurrentStreams SettingID = 0x3
- SettingInitialWindowSize SettingID = 0x4
- SettingMaxFrameSize SettingID = 0x5
- SettingMaxHeaderListSize SettingID = 0x6
-)
-
-var settingName = map[SettingID]string{
- SettingHeaderTableSize: "HEADER_TABLE_SIZE",
- SettingEnablePush: "ENABLE_PUSH",
- SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
- SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
- SettingMaxFrameSize: "MAX_FRAME_SIZE",
- SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
-}
-
-func (s SettingID) String() string {
- if v, ok := settingName[s]; ok {
- return v
- }
- return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
-}
-
-var (
- errInvalidHeaderFieldName = errors.New("http2: invalid header field name")
- errInvalidHeaderFieldValue = errors.New("http2: invalid header field value")
-)
-
-// validWireHeaderFieldName reports whether v is a valid header field
-// name (key). See httplex.ValidHeaderName for the base rules.
-//
-// Further, http2 says:
-// "Just as in HTTP/1.x, header field names are strings of ASCII
-// characters that are compared in a case-insensitive
-// fashion. However, header field names MUST be converted to
-// lowercase prior to their encoding in HTTP/2. "
-func validWireHeaderFieldName(v string) bool {
- if len(v) == 0 {
- return false
- }
- for _, r := range v {
- if !httplex.IsTokenRune(r) {
- return false
- }
- if 'A' <= r && r <= 'Z' {
- return false
- }
- }
- return true
-}
-
-var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n)
-
-func init() {
- for i := 100; i <= 999; i++ {
- if v := http.StatusText(i); v != "" {
- httpCodeStringCommon[i] = strconv.Itoa(i)
- }
- }
-}
-
-func httpCodeString(code int) string {
- if s, ok := httpCodeStringCommon[code]; ok {
- return s
- }
- return strconv.Itoa(code)
-}
-
-// from pkg io
-type stringWriter interface {
- WriteString(s string) (n int, err error)
-}
-
-// A gate lets two goroutines coordinate their activities.
-type gate chan struct{}
-
-func (g gate) Done() { g <- struct{}{} }
-func (g gate) Wait() { <-g }
-
-// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
-type closeWaiter chan struct{}
-
-// Init makes a closeWaiter usable.
-// It exists because so a closeWaiter value can be placed inside a
-// larger struct and have the Mutex and Cond's memory in the same
-// allocation.
-func (cw *closeWaiter) Init() {
- *cw = make(chan struct{})
-}
-
-// Close marks the closeWaiter as closed and unblocks any waiters.
-func (cw closeWaiter) Close() {
- close(cw)
-}
-
-// Wait waits for the closeWaiter to become closed.
-func (cw closeWaiter) Wait() {
- <-cw
-}
-
-// bufferedWriter is a buffered writer that writes to w.
-// Its buffered writer is lazily allocated as needed, to minimize
-// idle memory usage with many connections.
-type bufferedWriter struct {
- w io.Writer // immutable
- bw *bufio.Writer // non-nil when data is buffered
-}
-
-func newBufferedWriter(w io.Writer) *bufferedWriter {
- return &bufferedWriter{w: w}
-}
-
-// bufWriterPoolBufferSize is the size of bufio.Writer's
-// buffers created using bufWriterPool.
-//
-// TODO: pick a less arbitrary value? this is a bit under
-// (3 x typical 1500 byte MTU) at least. Other than that,
-// not much thought went into it.
-const bufWriterPoolBufferSize = 4 << 10
-
-var bufWriterPool = sync.Pool{
- New: func() interface{} {
- return bufio.NewWriterSize(nil, bufWriterPoolBufferSize)
- },
-}
-
-func (w *bufferedWriter) Available() int {
- if w.bw == nil {
- return bufWriterPoolBufferSize
- }
- return w.bw.Available()
-}
-
-func (w *bufferedWriter) Write(p []byte) (n int, err error) {
- if w.bw == nil {
- bw := bufWriterPool.Get().(*bufio.Writer)
- bw.Reset(w.w)
- w.bw = bw
- }
- return w.bw.Write(p)
-}
-
-func (w *bufferedWriter) Flush() error {
- bw := w.bw
- if bw == nil {
- return nil
- }
- err := bw.Flush()
- bw.Reset(nil)
- bufWriterPool.Put(bw)
- w.bw = nil
- return err
-}
-
-func mustUint31(v int32) uint32 {
- if v < 0 || v > 2147483647 {
- panic("out of range")
- }
- return uint32(v)
-}
-
-// bodyAllowedForStatus reports whether a given response status code
-// permits a body. See RFC 2616, section 4.4.
-func bodyAllowedForStatus(status int) bool {
- switch {
- case status >= 100 && status <= 199:
- return false
- case status == 204:
- return false
- case status == 304:
- return false
- }
- return true
-}
-
-type httpError struct {
- msg string
- timeout bool
-}
-
-func (e *httpError) Error() string { return e.msg }
-func (e *httpError) Timeout() bool { return e.timeout }
-func (e *httpError) Temporary() bool { return true }
-
-var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true}
-
-type connectionStater interface {
- ConnectionState() tls.ConnectionState
-}
-
-var sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}
-
-type sorter struct {
- v []string // owned by sorter
-}
-
-func (s *sorter) Len() int { return len(s.v) }
-func (s *sorter) Swap(i, j int) { s.v[i], s.v[j] = s.v[j], s.v[i] }
-func (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }
-
-// Keys returns the sorted keys of h.
-//
-// The returned slice is only valid until s used again or returned to
-// its pool.
-func (s *sorter) Keys(h http.Header) []string {
- keys := s.v[:0]
- for k := range h {
- keys = append(keys, k)
- }
- s.v = keys
- sort.Sort(s)
- return keys
-}
-
-func (s *sorter) SortStrings(ss []string) {
- // Our sorter works on s.v, which sorter owns, so
- // stash it away while we sort the user's buffer.
- save := s.v
- s.v = ss
- sort.Sort(s)
- s.v = save
-}
-
-// validPseudoPath reports whether v is a valid :path pseudo-header
-// value. It must be either:
-//
-// *) a non-empty string starting with '/', but not with with "//",
-// *) the string '*', for OPTIONS requests.
-//
-// For now this is only used a quick check for deciding when to clean
-// up Opaque URLs before sending requests from the Transport.
-// See golang.org/issue/16847
-func validPseudoPath(v string) bool {
- return (len(v) > 0 && v[0] == '/' && (len(v) == 1 || v[1] != '/')) || v == "*"
-}
diff --git a/vendor/golang.org/x/net/http2/http2_test.go b/vendor/golang.org/x/net/http2/http2_test.go
deleted file mode 100644
index 524877647..000000000
--- a/vendor/golang.org/x/net/http2/http2_test.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bytes"
- "errors"
- "flag"
- "fmt"
- "net/http"
- "os/exec"
- "strconv"
- "strings"
- "testing"
-
- "golang.org/x/net/http2/hpack"
-)
-
-var knownFailing = flag.Bool("known_failing", false, "Run known-failing tests.")
-
-func condSkipFailingTest(t *testing.T) {
- if !*knownFailing {
- t.Skip("Skipping known-failing test without --known_failing")
- }
-}
-
-func init() {
- inTests = true
- DebugGoroutines = true
- flag.BoolVar(&VerboseLogs, "verboseh2", VerboseLogs, "Verbose HTTP/2 debug logging")
-}
-
-func TestSettingString(t *testing.T) {
- tests := []struct {
- s Setting
- want string
- }{
- {Setting{SettingMaxFrameSize, 123}, "[MAX_FRAME_SIZE = 123]"},
- {Setting{1<<16 - 1, 123}, "[UNKNOWN_SETTING_65535 = 123]"},
- }
- for i, tt := range tests {
- got := fmt.Sprint(tt.s)
- if got != tt.want {
- t.Errorf("%d. for %#v, string = %q; want %q", i, tt.s, got, tt.want)
- }
- }
-}
-
-type twriter struct {
- t testing.TB
- st *serverTester // optional
-}
-
-func (w twriter) Write(p []byte) (n int, err error) {
- if w.st != nil {
- ps := string(p)
- for _, phrase := range w.st.logFilter {
- if strings.Contains(ps, phrase) {
- return len(p), nil // no logging
- }
- }
- }
- w.t.Logf("%s", p)
- return len(p), nil
-}
-
-// like encodeHeader, but don't add implicit pseudo headers.
-func encodeHeaderNoImplicit(t *testing.T, headers ...string) []byte {
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- for len(headers) > 0 {
- k, v := headers[0], headers[1]
- headers = headers[2:]
- if err := enc.WriteField(hpack.HeaderField{Name: k, Value: v}); err != nil {
- t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
- }
- }
- return buf.Bytes()
-}
-
-// Verify that curl has http2.
-func requireCurl(t *testing.T) {
- out, err := dockerLogs(curl(t, "--version"))
- if err != nil {
- t.Skipf("failed to determine curl features; skipping test")
- }
- if !strings.Contains(string(out), "HTTP2") {
- t.Skip("curl doesn't support HTTP2; skipping test")
- }
-}
-
-func curl(t *testing.T, args ...string) (container string) {
- out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "gohttp2/curl"}, args...)...).Output()
- if err != nil {
- t.Skipf("Failed to run curl in docker: %v, %s", err, out)
- }
- return strings.TrimSpace(string(out))
-}
-
-// Verify that h2load exists.
-func requireH2load(t *testing.T) {
- out, err := dockerLogs(h2load(t, "--version"))
- if err != nil {
- t.Skipf("failed to probe h2load; skipping test: %s", out)
- }
- if !strings.Contains(string(out), "h2load nghttp2/") {
- t.Skipf("h2load not present; skipping test. (Output=%q)", out)
- }
-}
-
-func h2load(t *testing.T, args ...string) (container string) {
- out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl"}, args...)...).Output()
- if err != nil {
- t.Skipf("Failed to run h2load in docker: %v, %s", err, out)
- }
- return strings.TrimSpace(string(out))
-}
-
-type puppetCommand struct {
- fn func(w http.ResponseWriter, r *http.Request)
- done chan<- bool
-}
-
-type handlerPuppet struct {
- ch chan puppetCommand
-}
-
-func newHandlerPuppet() *handlerPuppet {
- return &handlerPuppet{
- ch: make(chan puppetCommand),
- }
-}
-
-func (p *handlerPuppet) act(w http.ResponseWriter, r *http.Request) {
- for cmd := range p.ch {
- cmd.fn(w, r)
- cmd.done <- true
- }
-}
-
-func (p *handlerPuppet) done() { close(p.ch) }
-func (p *handlerPuppet) do(fn func(http.ResponseWriter, *http.Request)) {
- done := make(chan bool)
- p.ch <- puppetCommand{fn, done}
- <-done
-}
-func dockerLogs(container string) ([]byte, error) {
- out, err := exec.Command("docker", "wait", container).CombinedOutput()
- if err != nil {
- return out, err
- }
- exitStatus, err := strconv.Atoi(strings.TrimSpace(string(out)))
- if err != nil {
- return out, errors.New("unexpected exit status from docker wait")
- }
- out, err = exec.Command("docker", "logs", container).CombinedOutput()
- exec.Command("docker", "rm", container).Run()
- if err == nil && exitStatus != 0 {
- err = fmt.Errorf("exit status %d: %s", exitStatus, out)
- }
- return out, err
-}
-
-func kill(container string) {
- exec.Command("docker", "kill", container).Run()
- exec.Command("docker", "rm", container).Run()
-}
-
-func cleanDate(res *http.Response) {
- if d := res.Header["Date"]; len(d) == 1 {
- d[0] = "XXX"
- }
-}
-
-func TestSorterPoolAllocs(t *testing.T) {
- ss := []string{"a", "b", "c"}
- h := http.Header{
- "a": nil,
- "b": nil,
- "c": nil,
- }
- sorter := new(sorter)
-
- if allocs := testing.AllocsPerRun(100, func() {
- sorter.SortStrings(ss)
- }); allocs >= 1 {
- t.Logf("SortStrings allocs = %v; want <1", allocs)
- }
-
- if allocs := testing.AllocsPerRun(5, func() {
- if len(sorter.Keys(h)) != 3 {
- t.Fatal("wrong result")
- }
- }); allocs > 0 {
- t.Logf("Keys allocs = %v; want <1", allocs)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/not_go16.go b/vendor/golang.org/x/net/http2/not_go16.go
deleted file mode 100644
index 508cebcc4..000000000
--- a/vendor/golang.org/x/net/http2/not_go16.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.6
-
-package http2
-
-import (
- "net/http"
- "time"
-)
-
-func configureTransport(t1 *http.Transport) (*Transport, error) {
- return nil, errTransportVersion
-}
-
-func transportExpectContinueTimeout(t1 *http.Transport) time.Duration {
- return 0
-
-}
diff --git a/vendor/golang.org/x/net/http2/not_go17.go b/vendor/golang.org/x/net/http2/not_go17.go
deleted file mode 100644
index 140434a79..000000000
--- a/vendor/golang.org/x/net/http2/not_go17.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.7
-
-package http2
-
-import (
- "crypto/tls"
- "net"
- "net/http"
- "time"
-)
-
-type contextContext interface {
- Done() <-chan struct{}
- Err() error
-}
-
-type fakeContext struct{}
-
-func (fakeContext) Done() <-chan struct{} { return nil }
-func (fakeContext) Err() error { panic("should not be called") }
-
-func reqContext(r *http.Request) fakeContext {
- return fakeContext{}
-}
-
-func setResponseUncompressed(res *http.Response) {
- // Nothing.
-}
-
-type clientTrace struct{}
-
-func requestTrace(*http.Request) *clientTrace { return nil }
-func traceGotConn(*http.Request, *ClientConn) {}
-func traceFirstResponseByte(*clientTrace) {}
-func traceWroteHeaders(*clientTrace) {}
-func traceWroteRequest(*clientTrace, error) {}
-func traceGot100Continue(trace *clientTrace) {}
-func traceWait100Continue(trace *clientTrace) {}
-
-func nop() {}
-
-func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) {
- return nil, nop
-}
-
-func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) {
- return ctx, nop
-}
-
-func requestWithContext(req *http.Request, ctx contextContext) *http.Request {
- return req
-}
-
-// temporary copy of Go 1.6's private tls.Config.clone:
-func cloneTLSConfig(c *tls.Config) *tls.Config {
- return &tls.Config{
- Rand: c.Rand,
- Time: c.Time,
- Certificates: c.Certificates,
- NameToCertificate: c.NameToCertificate,
- GetCertificate: c.GetCertificate,
- RootCAs: c.RootCAs,
- NextProtos: c.NextProtos,
- ServerName: c.ServerName,
- ClientAuth: c.ClientAuth,
- ClientCAs: c.ClientCAs,
- InsecureSkipVerify: c.InsecureSkipVerify,
- CipherSuites: c.CipherSuites,
- PreferServerCipherSuites: c.PreferServerCipherSuites,
- SessionTicketsDisabled: c.SessionTicketsDisabled,
- SessionTicketKey: c.SessionTicketKey,
- ClientSessionCache: c.ClientSessionCache,
- MinVersion: c.MinVersion,
- MaxVersion: c.MaxVersion,
- CurvePreferences: c.CurvePreferences,
- }
-}
-
-func (cc *ClientConn) Ping(ctx contextContext) error {
- return cc.ping(ctx)
-}
-
-func (t *Transport) idleConnTimeout() time.Duration { return 0 }
diff --git a/vendor/golang.org/x/net/http2/not_go18.go b/vendor/golang.org/x/net/http2/not_go18.go
deleted file mode 100644
index efbf83c32..000000000
--- a/vendor/golang.org/x/net/http2/not_go18.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.8
-
-package http2
-
-import (
- "io"
- "net/http"
-)
-
-func configureServer18(h1 *http.Server, h2 *Server) error {
- // No IdleTimeout to sync prior to Go 1.8.
- return nil
-}
-
-func shouldLogPanic(panicValue interface{}) bool {
- return panicValue != nil
-}
-
-func reqGetBody(req *http.Request) func() (io.ReadCloser, error) {
- return nil
-}
-
-func reqBodyIsNoBody(io.ReadCloser) bool { return false }
diff --git a/vendor/golang.org/x/net/http2/not_go19.go b/vendor/golang.org/x/net/http2/not_go19.go
deleted file mode 100644
index 5ae07726b..000000000
--- a/vendor/golang.org/x/net/http2/not_go19.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.9
-
-package http2
-
-import (
- "net/http"
-)
-
-func configureServer19(s *http.Server, conf *Server) error {
- // not supported prior to go1.9
- return nil
-}
diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go
deleted file mode 100644
index a6140099c..000000000
--- a/vendor/golang.org/x/net/http2/pipe.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "errors"
- "io"
- "sync"
-)
-
-// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like
-// io.Pipe except there are no PipeReader/PipeWriter halves, and the
-// underlying buffer is an interface. (io.Pipe is always unbuffered)
-type pipe struct {
- mu sync.Mutex
- c sync.Cond // c.L lazily initialized to &p.mu
- b pipeBuffer // nil when done reading
- err error // read error once empty. non-nil means closed.
- breakErr error // immediate read error (caller doesn't see rest of b)
- donec chan struct{} // closed on error
- readFn func() // optional code to run in Read before error
-}
-
-type pipeBuffer interface {
- Len() int
- io.Writer
- io.Reader
-}
-
-func (p *pipe) Len() int {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.b == nil {
- return 0
- }
- return p.b.Len()
-}
-
-// Read waits until data is available and copies bytes
-// from the buffer into p.
-func (p *pipe) Read(d []byte) (n int, err error) {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- for {
- if p.breakErr != nil {
- return 0, p.breakErr
- }
- if p.b != nil && p.b.Len() > 0 {
- return p.b.Read(d)
- }
- if p.err != nil {
- if p.readFn != nil {
- p.readFn() // e.g. copy trailers
- p.readFn = nil // not sticky like p.err
- }
- p.b = nil
- return 0, p.err
- }
- p.c.Wait()
- }
-}
-
-var errClosedPipeWrite = errors.New("write on closed buffer")
-
-// Write copies bytes from p into the buffer and wakes a reader.
-// It is an error to write more data than the buffer can hold.
-func (p *pipe) Write(d []byte) (n int, err error) {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- defer p.c.Signal()
- if p.err != nil {
- return 0, errClosedPipeWrite
- }
- if p.breakErr != nil {
- return len(d), nil // discard when there is no reader
- }
- return p.b.Write(d)
-}
-
-// CloseWithError causes the next Read (waking up a current blocked
-// Read if needed) to return the provided err after all data has been
-// read.
-//
-// The error must be non-nil.
-func (p *pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }
-
-// BreakWithError causes the next Read (waking up a current blocked
-// Read if needed) to return the provided err immediately, without
-// waiting for unread data.
-func (p *pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }
-
-// closeWithErrorAndCode is like CloseWithError but also sets some code to run
-// in the caller's goroutine before returning the error.
-func (p *pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) }
-
-func (p *pipe) closeWithError(dst *error, err error, fn func()) {
- if err == nil {
- panic("err must be non-nil")
- }
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- defer p.c.Signal()
- if *dst != nil {
- // Already been done.
- return
- }
- p.readFn = fn
- if dst == &p.breakErr {
- p.b = nil
- }
- *dst = err
- p.closeDoneLocked()
-}
-
-// requires p.mu be held.
-func (p *pipe) closeDoneLocked() {
- if p.donec == nil {
- return
- }
- // Close if unclosed. This isn't racy since we always
- // hold p.mu while closing.
- select {
- case <-p.donec:
- default:
- close(p.donec)
- }
-}
-
-// Err returns the error (if any) first set by BreakWithError or CloseWithError.
-func (p *pipe) Err() error {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.breakErr != nil {
- return p.breakErr
- }
- return p.err
-}
-
-// Done returns a channel which is closed if and when this pipe is closed
-// with CloseWithError.
-func (p *pipe) Done() <-chan struct{} {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.donec == nil {
- p.donec = make(chan struct{})
- if p.err != nil || p.breakErr != nil {
- // Already hit an error.
- p.closeDoneLocked()
- }
- }
- return p.donec
-}
diff --git a/vendor/golang.org/x/net/http2/pipe_test.go b/vendor/golang.org/x/net/http2/pipe_test.go
deleted file mode 100644
index 1bf351ff6..000000000
--- a/vendor/golang.org/x/net/http2/pipe_test.go
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bytes"
- "errors"
- "io"
- "io/ioutil"
- "testing"
-)
-
-func TestPipeClose(t *testing.T) {
- var p pipe
- p.b = new(bytes.Buffer)
- a := errors.New("a")
- b := errors.New("b")
- p.CloseWithError(a)
- p.CloseWithError(b)
- _, err := p.Read(make([]byte, 1))
- if err != a {
- t.Errorf("err = %v want %v", err, a)
- }
-}
-
-func TestPipeDoneChan(t *testing.T) {
- var p pipe
- done := p.Done()
- select {
- case <-done:
- t.Fatal("done too soon")
- default:
- }
- p.CloseWithError(io.EOF)
- select {
- case <-done:
- default:
- t.Fatal("should be done")
- }
-}
-
-func TestPipeDoneChan_ErrFirst(t *testing.T) {
- var p pipe
- p.CloseWithError(io.EOF)
- done := p.Done()
- select {
- case <-done:
- default:
- t.Fatal("should be done")
- }
-}
-
-func TestPipeDoneChan_Break(t *testing.T) {
- var p pipe
- done := p.Done()
- select {
- case <-done:
- t.Fatal("done too soon")
- default:
- }
- p.BreakWithError(io.EOF)
- select {
- case <-done:
- default:
- t.Fatal("should be done")
- }
-}
-
-func TestPipeDoneChan_Break_ErrFirst(t *testing.T) {
- var p pipe
- p.BreakWithError(io.EOF)
- done := p.Done()
- select {
- case <-done:
- default:
- t.Fatal("should be done")
- }
-}
-
-func TestPipeCloseWithError(t *testing.T) {
- p := &pipe{b: new(bytes.Buffer)}
- const body = "foo"
- io.WriteString(p, body)
- a := errors.New("test error")
- p.CloseWithError(a)
- all, err := ioutil.ReadAll(p)
- if string(all) != body {
- t.Errorf("read bytes = %q; want %q", all, body)
- }
- if err != a {
- t.Logf("read error = %v, %v", err, a)
- }
- // Read and Write should fail.
- if n, err := p.Write([]byte("abc")); err != errClosedPipeWrite || n != 0 {
- t.Errorf("Write(abc) after close\ngot %v, %v\nwant 0, %v", n, err, errClosedPipeWrite)
- }
- if n, err := p.Read(make([]byte, 1)); err == nil || n != 0 {
- t.Errorf("Read() after close\ngot %v, nil\nwant 0, %v", n, errClosedPipeWrite)
- }
-}
-
-func TestPipeBreakWithError(t *testing.T) {
- p := &pipe{b: new(bytes.Buffer)}
- io.WriteString(p, "foo")
- a := errors.New("test err")
- p.BreakWithError(a)
- all, err := ioutil.ReadAll(p)
- if string(all) != "" {
- t.Errorf("read bytes = %q; want empty string", all)
- }
- if err != a {
- t.Logf("read error = %v, %v", err, a)
- }
- if p.b != nil {
- t.Errorf("buffer should be nil after BreakWithError")
- }
- // Write should succeed silently.
- if n, err := p.Write([]byte("abc")); err != nil || n != 3 {
- t.Errorf("Write(abc) after break\ngot %v, %v\nwant 0, nil", n, err)
- }
- if p.b != nil {
- t.Errorf("buffer should be nil after Write")
- }
- // Read should fail.
- if n, err := p.Read(make([]byte, 1)); err == nil || n != 0 {
- t.Errorf("Read() after close\ngot %v, nil\nwant 0, not nil", n)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
deleted file mode 100644
index 7367b31c5..000000000
--- a/vendor/golang.org/x/net/http2/server.go
+++ /dev/null
@@ -1,2842 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO: turn off the serve goroutine when idle, so
-// an idle conn only has the readFrames goroutine active. (which could
-// also be optimized probably to pin less memory in crypto/tls). This
-// would involve tracking when the serve goroutine is active (atomic
-// int32 read/CAS probably?) and starting it up when frames arrive,
-// and shutting it down when all handlers exit. the occasional PING
-// packets could use time.AfterFunc to call sc.wakeStartServeLoop()
-// (which is a no-op if already running) and then queue the PING write
-// as normal. The serve loop would then exit in most cases (if no
-// Handlers running) and not be woken up again until the PING packet
-// returns.
-
-// TODO (maybe): add a mechanism for Handlers to going into
-// half-closed-local mode (rw.(io.Closer) test?) but not exit their
-// handler, and continue to be able to read from the
-// Request.Body. This would be a somewhat semantic change from HTTP/1
-// (or at least what we expose in net/http), so I'd probably want to
-// add it there too. For now, this package says that returning from
-// the Handler ServeHTTP function means you're both done reading and
-// done writing, without a way to stop just one or the other.
-
-package http2
-
-import (
- "bufio"
- "bytes"
- "crypto/tls"
- "errors"
- "fmt"
- "io"
- "log"
- "math"
- "net"
- "net/http"
- "net/textproto"
- "net/url"
- "os"
- "reflect"
- "runtime"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/http2/hpack"
-)
-
-const (
- prefaceTimeout = 10 * time.Second
- firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
- handlerChunkWriteSize = 4 << 10
- defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
-)
-
-var (
- errClientDisconnected = errors.New("client disconnected")
- errClosedBody = errors.New("body closed by handler")
- errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
- errStreamClosed = errors.New("http2: stream closed")
-)
-
-var responseWriterStatePool = sync.Pool{
- New: func() interface{} {
- rws := &responseWriterState{}
- rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)
- return rws
- },
-}
-
-// Test hooks.
-var (
- testHookOnConn func()
- testHookGetServerConn func(*serverConn)
- testHookOnPanicMu *sync.Mutex // nil except in tests
- testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
-)
-
-// Server is an HTTP/2 server.
-type Server struct {
- // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
- // which may run at a time over all connections.
- // Negative or zero no limit.
- // TODO: implement
- MaxHandlers int
-
- // MaxConcurrentStreams optionally specifies the number of
- // concurrent streams that each client may have open at a
- // time. This is unrelated to the number of http.Handler goroutines
- // which may be active globally, which is MaxHandlers.
- // If zero, MaxConcurrentStreams defaults to at least 100, per
- // the HTTP/2 spec's recommendations.
- MaxConcurrentStreams uint32
-
- // MaxReadFrameSize optionally specifies the largest frame
- // this server is willing to read. A valid value is between
- // 16k and 16M, inclusive. If zero or otherwise invalid, a
- // default value is used.
- MaxReadFrameSize uint32
-
- // PermitProhibitedCipherSuites, if true, permits the use of
- // cipher suites prohibited by the HTTP/2 spec.
- PermitProhibitedCipherSuites bool
-
- // IdleTimeout specifies how long until idle clients should be
- // closed with a GOAWAY frame. PING frames are not considered
- // activity for the purposes of IdleTimeout.
- IdleTimeout time.Duration
-
- // MaxUploadBufferPerConnection is the size of the initial flow
- // control window for each connections. The HTTP/2 spec does not
- // allow this to be smaller than 65535 or larger than 2^32-1.
- // If the value is outside this range, a default value will be
- // used instead.
- MaxUploadBufferPerConnection int32
-
- // MaxUploadBufferPerStream is the size of the initial flow control
- // window for each stream. The HTTP/2 spec does not allow this to
- // be larger than 2^32-1. If the value is zero or larger than the
- // maximum, a default value will be used instead.
- MaxUploadBufferPerStream int32
-
- // NewWriteScheduler constructs a write scheduler for a connection.
- // If nil, a default scheduler is chosen.
- NewWriteScheduler func() WriteScheduler
-
- // Internal state. This is a pointer (rather than embedded directly)
- // so that we don't embed a Mutex in this struct, which will make the
- // struct non-copyable, which might break some callers.
- state *serverInternalState
-}
-
-func (s *Server) initialConnRecvWindowSize() int32 {
- if s.MaxUploadBufferPerConnection > initialWindowSize {
- return s.MaxUploadBufferPerConnection
- }
- return 1 << 20
-}
-
-func (s *Server) initialStreamRecvWindowSize() int32 {
- if s.MaxUploadBufferPerStream > 0 {
- return s.MaxUploadBufferPerStream
- }
- return 1 << 20
-}
-
-func (s *Server) maxReadFrameSize() uint32 {
- if v := s.MaxReadFrameSize; v >= minMaxFrameSize && v <= maxFrameSize {
- return v
- }
- return defaultMaxReadFrameSize
-}
-
-func (s *Server) maxConcurrentStreams() uint32 {
- if v := s.MaxConcurrentStreams; v > 0 {
- return v
- }
- return defaultMaxStreams
-}
-
-type serverInternalState struct {
- mu sync.Mutex
- activeConns map[*serverConn]struct{}
-}
-
-func (s *serverInternalState) registerConn(sc *serverConn) {
- if s == nil {
- return // if the Server was used without calling ConfigureServer
- }
- s.mu.Lock()
- s.activeConns[sc] = struct{}{}
- s.mu.Unlock()
-}
-
-func (s *serverInternalState) unregisterConn(sc *serverConn) {
- if s == nil {
- return // if the Server was used without calling ConfigureServer
- }
- s.mu.Lock()
- delete(s.activeConns, sc)
- s.mu.Unlock()
-}
-
-func (s *serverInternalState) startGracefulShutdown() {
- if s == nil {
- return // if the Server was used without calling ConfigureServer
- }
- s.mu.Lock()
- for sc := range s.activeConns {
- sc.startGracefulShutdown()
- }
- s.mu.Unlock()
-}
-
-// ConfigureServer adds HTTP/2 support to a net/http Server.
-//
-// The configuration conf may be nil.
-//
-// ConfigureServer must be called before s begins serving.
-func ConfigureServer(s *http.Server, conf *Server) error {
- if s == nil {
- panic("nil *http.Server")
- }
- if conf == nil {
- conf = new(Server)
- }
- conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
- if err := configureServer18(s, conf); err != nil {
- return err
- }
- if err := configureServer19(s, conf); err != nil {
- return err
- }
-
- if s.TLSConfig == nil {
- s.TLSConfig = new(tls.Config)
- } else if s.TLSConfig.CipherSuites != nil {
- // If they already provided a CipherSuite list, return
- // an error if it has a bad order or is missing
- // ECDHE_RSA_WITH_AES_128_GCM_SHA256.
- const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- haveRequired := false
- sawBad := false
- for i, cs := range s.TLSConfig.CipherSuites {
- if cs == requiredCipher {
- haveRequired = true
- }
- if isBadCipher(cs) {
- sawBad = true
- } else if sawBad {
- return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs)
- }
- }
- if !haveRequired {
- return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
- }
- }
-
- // Note: not setting MinVersion to tls.VersionTLS12,
- // as we don't want to interfere with HTTP/1.1 traffic
- // on the user's server. We enforce TLS 1.2 later once
- // we accept a connection. Ideally this should be done
- // during next-proto selection, but using TLS <1.2 with
- // HTTP/2 is still the client's bug.
-
- s.TLSConfig.PreferServerCipherSuites = true
-
- haveNPN := false
- for _, p := range s.TLSConfig.NextProtos {
- if p == NextProtoTLS {
- haveNPN = true
- break
- }
- }
- if !haveNPN {
- s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
- }
-
- if s.TLSNextProto == nil {
- s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
- }
- protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {
- if testHookOnConn != nil {
- testHookOnConn()
- }
- conf.ServeConn(c, &ServeConnOpts{
- Handler: h,
- BaseConfig: hs,
- })
- }
- s.TLSNextProto[NextProtoTLS] = protoHandler
- return nil
-}
-
-// ServeConnOpts are options for the Server.ServeConn method.
-type ServeConnOpts struct {
- // BaseConfig optionally sets the base configuration
- // for values. If nil, defaults are used.
- BaseConfig *http.Server
-
- // Handler specifies which handler to use for processing
- // requests. If nil, BaseConfig.Handler is used. If BaseConfig
- // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
- Handler http.Handler
-}
-
-func (o *ServeConnOpts) baseConfig() *http.Server {
- if o != nil && o.BaseConfig != nil {
- return o.BaseConfig
- }
- return new(http.Server)
-}
-
-func (o *ServeConnOpts) handler() http.Handler {
- if o != nil {
- if o.Handler != nil {
- return o.Handler
- }
- if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
- return o.BaseConfig.Handler
- }
- }
- return http.DefaultServeMux
-}
-
-// ServeConn serves HTTP/2 requests on the provided connection and
-// blocks until the connection is no longer readable.
-//
-// ServeConn starts speaking HTTP/2 assuming that c has not had any
-// reads or writes. It writes its initial settings frame and expects
-// to be able to read the preface and settings frame from the
-// client. If c has a ConnectionState method like a *tls.Conn, the
-// ConnectionState is used to verify the TLS ciphersuite and to set
-// the Request.TLS field in Handlers.
-//
-// ServeConn does not support h2c by itself. Any h2c support must be
-// implemented in terms of providing a suitably-behaving net.Conn.
-//
-// The opts parameter is optional. If nil, default values are used.
-func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
- baseCtx, cancel := serverConnBaseContext(c, opts)
- defer cancel()
-
- sc := &serverConn{
- srv: s,
- hs: opts.baseConfig(),
- conn: c,
- baseCtx: baseCtx,
- remoteAddrStr: c.RemoteAddr().String(),
- bw: newBufferedWriter(c),
- handler: opts.handler(),
- streams: make(map[uint32]*stream),
- readFrameCh: make(chan readFrameResult),
- wantWriteFrameCh: make(chan FrameWriteRequest, 8),
- serveMsgCh: make(chan interface{}, 8),
- wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
- bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way
- doneServing: make(chan struct{}),
- clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
- advMaxStreams: s.maxConcurrentStreams(),
- initialStreamSendWindowSize: initialWindowSize,
- maxFrameSize: initialMaxFrameSize,
- headerTableSize: initialHeaderTableSize,
- serveG: newGoroutineLock(),
- pushEnabled: true,
- }
-
- s.state.registerConn(sc)
- defer s.state.unregisterConn(sc)
-
- // The net/http package sets the write deadline from the
- // http.Server.WriteTimeout during the TLS handshake, but then
- // passes the connection off to us with the deadline already set.
- // Write deadlines are set per stream in serverConn.newStream.
- // Disarm the net.Conn write deadline here.
- if sc.hs.WriteTimeout != 0 {
- sc.conn.SetWriteDeadline(time.Time{})
- }
-
- if s.NewWriteScheduler != nil {
- sc.writeSched = s.NewWriteScheduler()
- } else {
- sc.writeSched = NewRandomWriteScheduler()
- }
-
- // These start at the RFC-specified defaults. If there is a higher
- // configured value for inflow, that will be updated when we send a
- // WINDOW_UPDATE shortly after sending SETTINGS.
- sc.flow.add(initialWindowSize)
- sc.inflow.add(initialWindowSize)
- sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
-
- fr := NewFramer(sc.bw, c)
- fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
- fr.MaxHeaderListSize = sc.maxHeaderListSize()
- fr.SetMaxReadFrameSize(s.maxReadFrameSize())
- sc.framer = fr
-
- if tc, ok := c.(connectionStater); ok {
- sc.tlsState = new(tls.ConnectionState)
- *sc.tlsState = tc.ConnectionState()
- // 9.2 Use of TLS Features
- // An implementation of HTTP/2 over TLS MUST use TLS
- // 1.2 or higher with the restrictions on feature set
- // and cipher suite described in this section. Due to
- // implementation limitations, it might not be
- // possible to fail TLS negotiation. An endpoint MUST
- // immediately terminate an HTTP/2 connection that
- // does not meet the TLS requirements described in
- // this section with a connection error (Section
- // 5.4.1) of type INADEQUATE_SECURITY.
- if sc.tlsState.Version < tls.VersionTLS12 {
- sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low")
- return
- }
-
- if sc.tlsState.ServerName == "" {
- // Client must use SNI, but we don't enforce that anymore,
- // since it was causing problems when connecting to bare IP
- // addresses during development.
- //
- // TODO: optionally enforce? Or enforce at the time we receive
- // a new request, and verify the the ServerName matches the :authority?
- // But that precludes proxy situations, perhaps.
- //
- // So for now, do nothing here again.
- }
-
- if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {
- // "Endpoints MAY choose to generate a connection error
- // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
- // the prohibited cipher suites are negotiated."
- //
- // We choose that. In my opinion, the spec is weak
- // here. It also says both parties must support at least
- // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
- // excuses here. If we really must, we could allow an
- // "AllowInsecureWeakCiphers" option on the server later.
- // Let's see how it plays out first.
- sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
- return
- }
- }
-
- if hook := testHookGetServerConn; hook != nil {
- hook(sc)
- }
- sc.serve()
-}
-
-func (sc *serverConn) rejectConn(err ErrCode, debug string) {
- sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
- // ignoring errors. hanging up anyway.
- sc.framer.WriteGoAway(0, err, []byte(debug))
- sc.bw.Flush()
- sc.conn.Close()
-}
-
-type serverConn struct {
- // Immutable:
- srv *Server
- hs *http.Server
- conn net.Conn
- bw *bufferedWriter // writing to conn
- handler http.Handler
- baseCtx contextContext
- framer *Framer
- doneServing chan struct{} // closed when serverConn.serve ends
- readFrameCh chan readFrameResult // written by serverConn.readFrames
- wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve
- wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
- bodyReadCh chan bodyReadMsg // from handlers -> serve
- serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop
- flow flow // conn-wide (not stream-specific) outbound flow control
- inflow flow // conn-wide inbound flow control
- tlsState *tls.ConnectionState // shared by all handlers, like net/http
- remoteAddrStr string
- writeSched WriteScheduler
-
- // Everything following is owned by the serve loop; use serveG.check():
- serveG goroutineLock // used to verify funcs are on serve()
- pushEnabled bool
- sawFirstSettings bool // got the initial SETTINGS frame after the preface
- needToSendSettingsAck bool
- unackedSettings int // how many SETTINGS have we sent without ACKs?
- clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
- advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
- curClientStreams uint32 // number of open streams initiated by the client
- curPushedStreams uint32 // number of open streams initiated by server push
- maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests
- maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes
- streams map[uint32]*stream
- initialStreamSendWindowSize int32
- maxFrameSize int32
- headerTableSize uint32
- peerMaxHeaderListSize uint32 // zero means unknown (default)
- canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
- writingFrame bool // started writing a frame (on serve goroutine or separate)
- writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
- needsFrameFlush bool // last frame write wasn't a flush
- inGoAway bool // we've started to or sent GOAWAY
- inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop
- needToSendGoAway bool // we need to schedule a GOAWAY frame write
- goAwayCode ErrCode
- shutdownTimer *time.Timer // nil until used
- idleTimer *time.Timer // nil if unused
-
- // Owned by the writeFrameAsync goroutine:
- headerWriteBuf bytes.Buffer
- hpackEncoder *hpack.Encoder
-
- // Used by startGracefulShutdown.
- shutdownOnce sync.Once
-}
-
-func (sc *serverConn) maxHeaderListSize() uint32 {
- n := sc.hs.MaxHeaderBytes
- if n <= 0 {
- n = http.DefaultMaxHeaderBytes
- }
- // http2's count is in a slightly different unit and includes 32 bytes per pair.
- // So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
- const perFieldOverhead = 32 // per http2 spec
- const typicalHeaders = 10 // conservative
- return uint32(n + typicalHeaders*perFieldOverhead)
-}
-
-func (sc *serverConn) curOpenStreams() uint32 {
- sc.serveG.check()
- return sc.curClientStreams + sc.curPushedStreams
-}
-
-// stream represents a stream. This is the minimal metadata needed by
-// the serve goroutine. Most of the actual stream state is owned by
-// the http.Handler's goroutine in the responseWriter. Because the
-// responseWriter's responseWriterState is recycled at the end of a
-// handler, this struct intentionally has no pointer to the
-// *responseWriter{,State} itself, as the Handler ending nils out the
-// responseWriter's state field.
-type stream struct {
- // immutable:
- sc *serverConn
- id uint32
- body *pipe // non-nil if expecting DATA frames
- cw closeWaiter // closed wait stream transitions to closed state
- ctx contextContext
- cancelCtx func()
-
- // owned by serverConn's serve loop:
- bodyBytes int64 // body bytes seen so far
- declBodyBytes int64 // or -1 if undeclared
- flow flow // limits writing from Handler to client
- inflow flow // what the client is allowed to POST/etc to us
- parent *stream // or nil
- numTrailerValues int64
- weight uint8
- state streamState
- resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
- gotTrailerHeader bool // HEADER frame for trailers was seen
- wroteHeaders bool // whether we wrote headers (not status 100)
- writeDeadline *time.Timer // nil if unused
-
- trailer http.Header // accumulated trailers
- reqTrailer http.Header // handler's Request.Trailer
-}
-
-func (sc *serverConn) Framer() *Framer { return sc.framer }
-func (sc *serverConn) CloseConn() error { return sc.conn.Close() }
-func (sc *serverConn) Flush() error { return sc.bw.Flush() }
-func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
- return sc.hpackEncoder, &sc.headerWriteBuf
-}
-
-func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
- sc.serveG.check()
- // http://tools.ietf.org/html/rfc7540#section-5.1
- if st, ok := sc.streams[streamID]; ok {
- return st.state, st
- }
- // "The first use of a new stream identifier implicitly closes all
- // streams in the "idle" state that might have been initiated by
- // that peer with a lower-valued stream identifier. For example, if
- // a client sends a HEADERS frame on stream 7 without ever sending a
- // frame on stream 5, then stream 5 transitions to the "closed"
- // state when the first frame for stream 7 is sent or received."
- if streamID%2 == 1 {
- if streamID <= sc.maxClientStreamID {
- return stateClosed, nil
- }
- } else {
- if streamID <= sc.maxPushPromiseID {
- return stateClosed, nil
- }
- }
- return stateIdle, nil
-}
-
-// setConnState calls the net/http ConnState hook for this connection, if configured.
-// Note that the net/http package does StateNew and StateClosed for us.
-// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
-func (sc *serverConn) setConnState(state http.ConnState) {
- if sc.hs.ConnState != nil {
- sc.hs.ConnState(sc.conn, state)
- }
-}
-
-func (sc *serverConn) vlogf(format string, args ...interface{}) {
- if VerboseLogs {
- sc.logf(format, args...)
- }
-}
-
-func (sc *serverConn) logf(format string, args ...interface{}) {
- if lg := sc.hs.ErrorLog; lg != nil {
- lg.Printf(format, args...)
- } else {
- log.Printf(format, args...)
- }
-}
-
-// errno returns v's underlying uintptr, else 0.
-//
-// TODO: remove this helper function once http2 can use build
-// tags. See comment in isClosedConnError.
-func errno(v error) uintptr {
- if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
- return uintptr(rv.Uint())
- }
- return 0
-}
-
-// isClosedConnError reports whether err is an error from use of a closed
-// network connection.
-func isClosedConnError(err error) bool {
- if err == nil {
- return false
- }
-
- // TODO: remove this string search and be more like the Windows
- // case below. That might involve modifying the standard library
- // to return better error types.
- str := err.Error()
- if strings.Contains(str, "use of closed network connection") {
- return true
- }
-
- // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
- // build tags, so I can't make an http2_windows.go file with
- // Windows-specific stuff. Fix that and move this, once we
- // have a way to bundle this into std's net/http somehow.
- if runtime.GOOS == "windows" {
- if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
- if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
- const WSAECONNABORTED = 10053
- const WSAECONNRESET = 10054
- if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
- return true
- }
- }
- }
- }
- return false
-}
-
-func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
- if err == nil {
- return
- }
- if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) {
- // Boring, expected errors.
- sc.vlogf(format, args...)
- } else {
- sc.logf(format, args...)
- }
-}
-
-func (sc *serverConn) canonicalHeader(v string) string {
- sc.serveG.check()
- cv, ok := commonCanonHeader[v]
- if ok {
- return cv
- }
- cv, ok = sc.canonHeader[v]
- if ok {
- return cv
- }
- if sc.canonHeader == nil {
- sc.canonHeader = make(map[string]string)
- }
- cv = http.CanonicalHeaderKey(v)
- sc.canonHeader[v] = cv
- return cv
-}
-
-type readFrameResult struct {
- f Frame // valid until readMore is called
- err error
-
- // readMore should be called once the consumer no longer needs or
- // retains f. After readMore, f is invalid and more frames can be
- // read.
- readMore func()
-}
-
-// readFrames is the loop that reads incoming frames.
-// It takes care to only read one frame at a time, blocking until the
-// consumer is done with the frame.
-// It's run on its own goroutine.
-func (sc *serverConn) readFrames() {
- gate := make(gate)
- gateDone := gate.Done
- for {
- f, err := sc.framer.ReadFrame()
- select {
- case sc.readFrameCh <- readFrameResult{f, err, gateDone}:
- case <-sc.doneServing:
- return
- }
- select {
- case <-gate:
- case <-sc.doneServing:
- return
- }
- if terminalReadFrameError(err) {
- return
- }
- }
-}
-
-// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
-type frameWriteResult struct {
- wr FrameWriteRequest // what was written (or attempted)
- err error // result of the writeFrame call
-}
-
-// writeFrameAsync runs in its own goroutine and writes a single frame
-// and then reports when it's done.
-// At most one goroutine can be running writeFrameAsync at a time per
-// serverConn.
-func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest) {
- err := wr.write.writeFrame(sc)
- sc.wroteFrameCh <- frameWriteResult{wr, err}
-}
-
-func (sc *serverConn) closeAllStreamsOnConnClose() {
- sc.serveG.check()
- for _, st := range sc.streams {
- sc.closeStream(st, errClientDisconnected)
- }
-}
-
-func (sc *serverConn) stopShutdownTimer() {
- sc.serveG.check()
- if t := sc.shutdownTimer; t != nil {
- t.Stop()
- }
-}
-
-func (sc *serverConn) notePanic() {
- // Note: this is for serverConn.serve panicking, not http.Handler code.
- if testHookOnPanicMu != nil {
- testHookOnPanicMu.Lock()
- defer testHookOnPanicMu.Unlock()
- }
- if testHookOnPanic != nil {
- if e := recover(); e != nil {
- if testHookOnPanic(sc, e) {
- panic(e)
- }
- }
- }
-}
-
-func (sc *serverConn) serve() {
- sc.serveG.check()
- defer sc.notePanic()
- defer sc.conn.Close()
- defer sc.closeAllStreamsOnConnClose()
- defer sc.stopShutdownTimer()
- defer close(sc.doneServing) // unblocks handlers trying to send
-
- if VerboseLogs {
- sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
- }
-
- sc.writeFrame(FrameWriteRequest{
- write: writeSettings{
- {SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
- {SettingMaxConcurrentStreams, sc.advMaxStreams},
- {SettingMaxHeaderListSize, sc.maxHeaderListSize()},
- {SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
- },
- })
- sc.unackedSettings++
-
- // Each connection starts with intialWindowSize inflow tokens.
- // If a higher value is configured, we add more tokens.
- if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 {
- sc.sendWindowUpdate(nil, int(diff))
- }
-
- if err := sc.readPreface(); err != nil {
- sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
- return
- }
- // Now that we've got the preface, get us out of the
- // "StateNew" state. We can't go directly to idle, though.
- // Active means we read some data and anticipate a request. We'll
- // do another Active when we get a HEADERS frame.
- sc.setConnState(http.StateActive)
- sc.setConnState(http.StateIdle)
-
- if sc.srv.IdleTimeout != 0 {
- sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
- defer sc.idleTimer.Stop()
- }
-
- go sc.readFrames() // closed by defer sc.conn.Close above
-
- settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer)
- defer settingsTimer.Stop()
-
- loopNum := 0
- for {
- loopNum++
- select {
- case wr := <-sc.wantWriteFrameCh:
- if se, ok := wr.write.(StreamError); ok {
- sc.resetStream(se)
- break
- }
- sc.writeFrame(wr)
- case res := <-sc.wroteFrameCh:
- sc.wroteFrame(res)
- case res := <-sc.readFrameCh:
- if !sc.processFrameFromReader(res) {
- return
- }
- res.readMore()
- if settingsTimer != nil {
- settingsTimer.Stop()
- settingsTimer = nil
- }
- case m := <-sc.bodyReadCh:
- sc.noteBodyRead(m.st, m.n)
- case msg := <-sc.serveMsgCh:
- switch v := msg.(type) {
- case func(int):
- v(loopNum) // for testing
- case *serverMessage:
- switch v {
- case settingsTimerMsg:
- sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
- return
- case idleTimerMsg:
- sc.vlogf("connection is idle")
- sc.goAway(ErrCodeNo)
- case shutdownTimerMsg:
- sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
- return
- case gracefulShutdownMsg:
- sc.startGracefulShutdownInternal()
- default:
- panic("unknown timer")
- }
- case *startPushRequest:
- sc.startPush(v)
- default:
- panic(fmt.Sprintf("unexpected type %T", v))
- }
- }
-
- if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame {
- return
- }
- }
-}
-
-func (sc *serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) {
- select {
- case <-sc.doneServing:
- case <-sharedCh:
- close(privateCh)
- }
-}
-
-type serverMessage int
-
-// Message values sent to serveMsgCh.
-var (
- settingsTimerMsg = new(serverMessage)
- idleTimerMsg = new(serverMessage)
- shutdownTimerMsg = new(serverMessage)
- gracefulShutdownMsg = new(serverMessage)
-)
-
-func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) }
-func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) }
-func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) }
-
-func (sc *serverConn) sendServeMsg(msg interface{}) {
- sc.serveG.checkNotOn() // NOT
- select {
- case sc.serveMsgCh <- msg:
- case <-sc.doneServing:
- }
-}
-
-// readPreface reads the ClientPreface greeting from the peer
-// or returns an error on timeout or an invalid greeting.
-func (sc *serverConn) readPreface() error {
- errc := make(chan error, 1)
- go func() {
- // Read the client preface
- buf := make([]byte, len(ClientPreface))
- if _, err := io.ReadFull(sc.conn, buf); err != nil {
- errc <- err
- } else if !bytes.Equal(buf, clientPreface) {
- errc <- fmt.Errorf("bogus greeting %q", buf)
- } else {
- errc <- nil
- }
- }()
- timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
- defer timer.Stop()
- select {
- case <-timer.C:
- return errors.New("timeout waiting for client preface")
- case err := <-errc:
- if err == nil {
- if VerboseLogs {
- sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
- }
- }
- return err
- }
-}
-
-var errChanPool = sync.Pool{
- New: func() interface{} { return make(chan error, 1) },
-}
-
-var writeDataPool = sync.Pool{
- New: func() interface{} { return new(writeData) },
-}
-
-// writeDataFromHandler writes DATA response frames from a handler on
-// the given stream.
-func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
- ch := errChanPool.Get().(chan error)
- writeArg := writeDataPool.Get().(*writeData)
- *writeArg = writeData{stream.id, data, endStream}
- err := sc.writeFrameFromHandler(FrameWriteRequest{
- write: writeArg,
- stream: stream,
- done: ch,
- })
- if err != nil {
- return err
- }
- var frameWriteDone bool // the frame write is done (successfully or not)
- select {
- case err = <-ch:
- frameWriteDone = true
- case <-sc.doneServing:
- return errClientDisconnected
- case <-stream.cw:
- // If both ch and stream.cw were ready (as might
- // happen on the final Write after an http.Handler
- // ends), prefer the write result. Otherwise this
- // might just be us successfully closing the stream.
- // The writeFrameAsync and serve goroutines guarantee
- // that the ch send will happen before the stream.cw
- // close.
- select {
- case err = <-ch:
- frameWriteDone = true
- default:
- return errStreamClosed
- }
- }
- errChanPool.Put(ch)
- if frameWriteDone {
- writeDataPool.Put(writeArg)
- }
- return err
-}
-
-// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
-// if the connection has gone away.
-//
-// This must not be run from the serve goroutine itself, else it might
-// deadlock writing to sc.wantWriteFrameCh (which is only mildly
-// buffered and is read by serve itself). If you're on the serve
-// goroutine, call writeFrame instead.
-func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error {
- sc.serveG.checkNotOn() // NOT
- select {
- case sc.wantWriteFrameCh <- wr:
- return nil
- case <-sc.doneServing:
- // Serve loop is gone.
- // Client has closed their connection to the server.
- return errClientDisconnected
- }
-}
-
-// writeFrame schedules a frame to write and sends it if there's nothing
-// already being written.
-//
-// There is no pushback here (the serve goroutine never blocks). It's
-// the http.Handlers that block, waiting for their previous frames to
-// make it onto the wire
-//
-// If you're not on the serve goroutine, use writeFrameFromHandler instead.
-func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
- sc.serveG.check()
-
- // If true, wr will not be written and wr.done will not be signaled.
- var ignoreWrite bool
-
- // We are not allowed to write frames on closed streams. RFC 7540 Section
- // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
- // a closed stream." Our server never sends PRIORITY, so that exception
- // does not apply.
- //
- // The serverConn might close an open stream while the stream's handler
- // is still running. For example, the server might close a stream when it
- // receives bad data from the client. If this happens, the handler might
- // attempt to write a frame after the stream has been closed (since the
- // handler hasn't yet been notified of the close). In this case, we simply
- // ignore the frame. The handler will notice that the stream is closed when
- // it waits for the frame to be written.
- //
- // As an exception to this rule, we allow sending RST_STREAM after close.
- // This allows us to immediately reject new streams without tracking any
- // state for those streams (except for the queued RST_STREAM frame). This
- // may result in duplicate RST_STREAMs in some cases, but the client should
- // ignore those.
- if wr.StreamID() != 0 {
- _, isReset := wr.write.(StreamError)
- if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset {
- ignoreWrite = true
- }
- }
-
- // Don't send a 100-continue response if we've already sent headers.
- // See golang.org/issue/14030.
- switch wr.write.(type) {
- case *writeResHeaders:
- wr.stream.wroteHeaders = true
- case write100ContinueHeadersFrame:
- if wr.stream.wroteHeaders {
- // We do not need to notify wr.done because this frame is
- // never written with wr.done != nil.
- if wr.done != nil {
- panic("wr.done != nil for write100ContinueHeadersFrame")
- }
- ignoreWrite = true
- }
- }
-
- if !ignoreWrite {
- sc.writeSched.Push(wr)
- }
- sc.scheduleFrameWrite()
-}
-
-// startFrameWrite starts a goroutine to write wr (in a separate
-// goroutine since that might block on the network), and updates the
-// serve goroutine's state about the world, updated from info in wr.
-func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
- sc.serveG.check()
- if sc.writingFrame {
- panic("internal error: can only be writing one frame at a time")
- }
-
- st := wr.stream
- if st != nil {
- switch st.state {
- case stateHalfClosedLocal:
- switch wr.write.(type) {
- case StreamError, handlerPanicRST, writeWindowUpdate:
- // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
- // in this state. (We never send PRIORITY from the server, so that is not checked.)
- default:
- panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
- }
- case stateClosed:
- panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
- }
- }
- if wpp, ok := wr.write.(*writePushPromise); ok {
- var err error
- wpp.promisedID, err = wpp.allocatePromisedID()
- if err != nil {
- sc.writingFrameAsync = false
- wr.replyToWriter(err)
- return
- }
- }
-
- sc.writingFrame = true
- sc.needsFrameFlush = true
- if wr.write.staysWithinBuffer(sc.bw.Available()) {
- sc.writingFrameAsync = false
- err := wr.write.writeFrame(sc)
- sc.wroteFrame(frameWriteResult{wr, err})
- } else {
- sc.writingFrameAsync = true
- go sc.writeFrameAsync(wr)
- }
-}
-
-// errHandlerPanicked is the error given to any callers blocked in a read from
-// Request.Body when the main goroutine panics. Since most handlers read in the
-// the main ServeHTTP goroutine, this will show up rarely.
-var errHandlerPanicked = errors.New("http2: handler panicked")
-
-// wroteFrame is called on the serve goroutine with the result of
-// whatever happened on writeFrameAsync.
-func (sc *serverConn) wroteFrame(res frameWriteResult) {
- sc.serveG.check()
- if !sc.writingFrame {
- panic("internal error: expected to be already writing a frame")
- }
- sc.writingFrame = false
- sc.writingFrameAsync = false
-
- wr := res.wr
-
- if writeEndsStream(wr.write) {
- st := wr.stream
- if st == nil {
- panic("internal error: expecting non-nil stream")
- }
- switch st.state {
- case stateOpen:
- // Here we would go to stateHalfClosedLocal in
- // theory, but since our handler is done and
- // the net/http package provides no mechanism
- // for closing a ResponseWriter while still
- // reading data (see possible TODO at top of
- // this file), we go into closed state here
- // anyway, after telling the peer we're
- // hanging up on them. We'll transition to
- // stateClosed after the RST_STREAM frame is
- // written.
- st.state = stateHalfClosedLocal
- // Section 8.1: a server MAY request that the client abort
- // transmission of a request without error by sending a
- // RST_STREAM with an error code of NO_ERROR after sending
- // a complete response.
- sc.resetStream(streamError(st.id, ErrCodeNo))
- case stateHalfClosedRemote:
- sc.closeStream(st, errHandlerComplete)
- }
- } else {
- switch v := wr.write.(type) {
- case StreamError:
- // st may be unknown if the RST_STREAM was generated to reject bad input.
- if st, ok := sc.streams[v.StreamID]; ok {
- sc.closeStream(st, v)
- }
- case handlerPanicRST:
- sc.closeStream(wr.stream, errHandlerPanicked)
- }
- }
-
- // Reply (if requested) to unblock the ServeHTTP goroutine.
- wr.replyToWriter(res.err)
-
- sc.scheduleFrameWrite()
-}
-
-// scheduleFrameWrite tickles the frame writing scheduler.
-//
-// If a frame is already being written, nothing happens. This will be called again
-// when the frame is done being written.
-//
-// If a frame isn't being written we need to send one, the best frame
-// to send is selected, preferring first things that aren't
-// stream-specific (e.g. ACKing settings), and then finding the
-// highest priority stream.
-//
-// If a frame isn't being written and there's nothing else to send, we
-// flush the write buffer.
-func (sc *serverConn) scheduleFrameWrite() {
- sc.serveG.check()
- if sc.writingFrame || sc.inFrameScheduleLoop {
- return
- }
- sc.inFrameScheduleLoop = true
- for !sc.writingFrameAsync {
- if sc.needToSendGoAway {
- sc.needToSendGoAway = false
- sc.startFrameWrite(FrameWriteRequest{
- write: &writeGoAway{
- maxStreamID: sc.maxClientStreamID,
- code: sc.goAwayCode,
- },
- })
- continue
- }
- if sc.needToSendSettingsAck {
- sc.needToSendSettingsAck = false
- sc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}})
- continue
- }
- if !sc.inGoAway || sc.goAwayCode == ErrCodeNo {
- if wr, ok := sc.writeSched.Pop(); ok {
- sc.startFrameWrite(wr)
- continue
- }
- }
- if sc.needsFrameFlush {
- sc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}})
- sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
- continue
- }
- break
- }
- sc.inFrameScheduleLoop = false
-}
-
-// startGracefulShutdown gracefully shuts down a connection. This
-// sends GOAWAY with ErrCodeNo to tell the client we're gracefully
-// shutting down. The connection isn't closed until all current
-// streams are done.
-//
-// startGracefulShutdown returns immediately; it does not wait until
-// the connection has shut down.
-func (sc *serverConn) startGracefulShutdown() {
- sc.serveG.checkNotOn() // NOT
- sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
-}
-
-func (sc *serverConn) startGracefulShutdownInternal() {
- sc.goAwayIn(ErrCodeNo, 0)
-}
-
-func (sc *serverConn) goAway(code ErrCode) {
- sc.serveG.check()
- var forceCloseIn time.Duration
- if code != ErrCodeNo {
- forceCloseIn = 250 * time.Millisecond
- } else {
- // TODO: configurable
- forceCloseIn = 1 * time.Second
- }
- sc.goAwayIn(code, forceCloseIn)
-}
-
-func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) {
- sc.serveG.check()
- if sc.inGoAway {
- return
- }
- if forceCloseIn != 0 {
- sc.shutDownIn(forceCloseIn)
- }
- sc.inGoAway = true
- sc.needToSendGoAway = true
- sc.goAwayCode = code
- sc.scheduleFrameWrite()
-}
-
-func (sc *serverConn) shutDownIn(d time.Duration) {
- sc.serveG.check()
- sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
-}
-
-func (sc *serverConn) resetStream(se StreamError) {
- sc.serveG.check()
- sc.writeFrame(FrameWriteRequest{write: se})
- if st, ok := sc.streams[se.StreamID]; ok {
- st.resetQueued = true
- }
-}
-
-// processFrameFromReader processes the serve loop's read from readFrameCh from the
-// frame-reading goroutine.
-// processFrameFromReader returns whether the connection should be kept open.
-func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
- sc.serveG.check()
- err := res.err
- if err != nil {
- if err == ErrFrameTooLarge {
- sc.goAway(ErrCodeFrameSize)
- return true // goAway will close the loop
- }
- clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)
- if clientGone {
- // TODO: could we also get into this state if
- // the peer does a half close
- // (e.g. CloseWrite) because they're done
- // sending frames but they're still wanting
- // our open replies? Investigate.
- // TODO: add CloseWrite to crypto/tls.Conn first
- // so we have a way to test this? I suppose
- // just for testing we could have a non-TLS mode.
- return false
- }
- } else {
- f := res.f
- if VerboseLogs {
- sc.vlogf("http2: server read frame %v", summarizeFrame(f))
- }
- err = sc.processFrame(f)
- if err == nil {
- return true
- }
- }
-
- switch ev := err.(type) {
- case StreamError:
- sc.resetStream(ev)
- return true
- case goAwayFlowError:
- sc.goAway(ErrCodeFlowControl)
- return true
- case ConnectionError:
- sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
- sc.goAway(ErrCode(ev))
- return true // goAway will handle shutdown
- default:
- if res.err != nil {
- sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
- } else {
- sc.logf("http2: server closing client connection: %v", err)
- }
- return false
- }
-}
-
-func (sc *serverConn) processFrame(f Frame) error {
- sc.serveG.check()
-
- // First frame received must be SETTINGS.
- if !sc.sawFirstSettings {
- if _, ok := f.(*SettingsFrame); !ok {
- return ConnectionError(ErrCodeProtocol)
- }
- sc.sawFirstSettings = true
- }
-
- switch f := f.(type) {
- case *SettingsFrame:
- return sc.processSettings(f)
- case *MetaHeadersFrame:
- return sc.processHeaders(f)
- case *WindowUpdateFrame:
- return sc.processWindowUpdate(f)
- case *PingFrame:
- return sc.processPing(f)
- case *DataFrame:
- return sc.processData(f)
- case *RSTStreamFrame:
- return sc.processResetStream(f)
- case *PriorityFrame:
- return sc.processPriority(f)
- case *GoAwayFrame:
- return sc.processGoAway(f)
- case *PushPromiseFrame:
- // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
- // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
- return ConnectionError(ErrCodeProtocol)
- default:
- sc.vlogf("http2: server ignoring frame: %v", f.Header())
- return nil
- }
-}
-
-func (sc *serverConn) processPing(f *PingFrame) error {
- sc.serveG.check()
- if f.IsAck() {
- // 6.7 PING: " An endpoint MUST NOT respond to PING frames
- // containing this flag."
- return nil
- }
- if f.StreamID != 0 {
- // "PING frames are not associated with any individual
- // stream. If a PING frame is received with a stream
- // identifier field value other than 0x0, the recipient MUST
- // respond with a connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR."
- return ConnectionError(ErrCodeProtocol)
- }
- if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
- return nil
- }
- sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
- return nil
-}
-
-func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
- sc.serveG.check()
- switch {
- case f.StreamID != 0: // stream-level flow control
- state, st := sc.state(f.StreamID)
- if state == stateIdle {
- // Section 5.1: "Receiving any frame other than HEADERS
- // or PRIORITY on a stream in this state MUST be
- // treated as a connection error (Section 5.4.1) of
- // type PROTOCOL_ERROR."
- return ConnectionError(ErrCodeProtocol)
- }
- if st == nil {
- // "WINDOW_UPDATE can be sent by a peer that has sent a
- // frame bearing the END_STREAM flag. This means that a
- // receiver could receive a WINDOW_UPDATE frame on a "half
- // closed (remote)" or "closed" stream. A receiver MUST
- // NOT treat this as an error, see Section 5.1."
- return nil
- }
- if !st.flow.add(int32(f.Increment)) {
- return streamError(f.StreamID, ErrCodeFlowControl)
- }
- default: // connection-level flow control
- if !sc.flow.add(int32(f.Increment)) {
- return goAwayFlowError{}
- }
- }
- sc.scheduleFrameWrite()
- return nil
-}
-
-func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
- sc.serveG.check()
-
- state, st := sc.state(f.StreamID)
- if state == stateIdle {
- // 6.4 "RST_STREAM frames MUST NOT be sent for a
- // stream in the "idle" state. If a RST_STREAM frame
- // identifying an idle stream is received, the
- // recipient MUST treat this as a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- return ConnectionError(ErrCodeProtocol)
- }
- if st != nil {
- st.cancelCtx()
- sc.closeStream(st, streamError(f.StreamID, f.ErrCode))
- }
- return nil
-}
-
-func (sc *serverConn) closeStream(st *stream, err error) {
- sc.serveG.check()
- if st.state == stateIdle || st.state == stateClosed {
- panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
- }
- st.state = stateClosed
- if st.writeDeadline != nil {
- st.writeDeadline.Stop()
- }
- if st.isPushed() {
- sc.curPushedStreams--
- } else {
- sc.curClientStreams--
- }
- delete(sc.streams, st.id)
- if len(sc.streams) == 0 {
- sc.setConnState(http.StateIdle)
- if sc.srv.IdleTimeout != 0 {
- sc.idleTimer.Reset(sc.srv.IdleTimeout)
- }
- if h1ServerKeepAlivesDisabled(sc.hs) {
- sc.startGracefulShutdownInternal()
- }
- }
- if p := st.body; p != nil {
- // Return any buffered unread bytes worth of conn-level flow control.
- // See golang.org/issue/16481
- sc.sendWindowUpdate(nil, p.Len())
-
- p.CloseWithError(err)
- }
- st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
- sc.writeSched.CloseStream(st.id)
-}
-
-func (sc *serverConn) processSettings(f *SettingsFrame) error {
- sc.serveG.check()
- if f.IsAck() {
- sc.unackedSettings--
- if sc.unackedSettings < 0 {
- // Why is the peer ACKing settings we never sent?
- // The spec doesn't mention this case, but
- // hang up on them anyway.
- return ConnectionError(ErrCodeProtocol)
- }
- return nil
- }
- if err := f.ForeachSetting(sc.processSetting); err != nil {
- return err
- }
- sc.needToSendSettingsAck = true
- sc.scheduleFrameWrite()
- return nil
-}
-
-func (sc *serverConn) processSetting(s Setting) error {
- sc.serveG.check()
- if err := s.Valid(); err != nil {
- return err
- }
- if VerboseLogs {
- sc.vlogf("http2: server processing setting %v", s)
- }
- switch s.ID {
- case SettingHeaderTableSize:
- sc.headerTableSize = s.Val
- sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
- case SettingEnablePush:
- sc.pushEnabled = s.Val != 0
- case SettingMaxConcurrentStreams:
- sc.clientMaxStreams = s.Val
- case SettingInitialWindowSize:
- return sc.processSettingInitialWindowSize(s.Val)
- case SettingMaxFrameSize:
- sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
- case SettingMaxHeaderListSize:
- sc.peerMaxHeaderListSize = s.Val
- default:
- // Unknown setting: "An endpoint that receives a SETTINGS
- // frame with any unknown or unsupported identifier MUST
- // ignore that setting."
- if VerboseLogs {
- sc.vlogf("http2: server ignoring unknown setting %v", s)
- }
- }
- return nil
-}
-
-func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
- sc.serveG.check()
- // Note: val already validated to be within range by
- // processSetting's Valid call.
-
- // "A SETTINGS frame can alter the initial flow control window
- // size for all current streams. When the value of
- // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
- // adjust the size of all stream flow control windows that it
- // maintains by the difference between the new value and the
- // old value."
- old := sc.initialStreamSendWindowSize
- sc.initialStreamSendWindowSize = int32(val)
- growth := int32(val) - old // may be negative
- for _, st := range sc.streams {
- if !st.flow.add(growth) {
- // 6.9.2 Initial Flow Control Window Size
- // "An endpoint MUST treat a change to
- // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
- // control window to exceed the maximum size as a
- // connection error (Section 5.4.1) of type
- // FLOW_CONTROL_ERROR."
- return ConnectionError(ErrCodeFlowControl)
- }
- }
- return nil
-}
-
-func (sc *serverConn) processData(f *DataFrame) error {
- sc.serveG.check()
- if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
- return nil
- }
- data := f.Data()
-
- // "If a DATA frame is received whose stream is not in "open"
- // or "half closed (local)" state, the recipient MUST respond
- // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
- id := f.Header().StreamID
- state, st := sc.state(id)
- if id == 0 || state == stateIdle {
- // Section 5.1: "Receiving any frame other than HEADERS
- // or PRIORITY on a stream in this state MUST be
- // treated as a connection error (Section 5.4.1) of
- // type PROTOCOL_ERROR."
- return ConnectionError(ErrCodeProtocol)
- }
- if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
- // This includes sending a RST_STREAM if the stream is
- // in stateHalfClosedLocal (which currently means that
- // the http.Handler returned, so it's done reading &
- // done writing). Try to stop the client from sending
- // more DATA.
-
- // But still enforce their connection-level flow control,
- // and return any flow control bytes since we're not going
- // to consume them.
- if sc.inflow.available() < int32(f.Length) {
- return streamError(id, ErrCodeFlowControl)
- }
- // Deduct the flow control from inflow, since we're
- // going to immediately add it back in
- // sendWindowUpdate, which also schedules sending the
- // frames.
- sc.inflow.take(int32(f.Length))
- sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
-
- if st != nil && st.resetQueued {
- // Already have a stream error in flight. Don't send another.
- return nil
- }
- return streamError(id, ErrCodeStreamClosed)
- }
- if st.body == nil {
- panic("internal error: should have a body in this state")
- }
-
- // Sender sending more than they'd declared?
- if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
- st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
- return streamError(id, ErrCodeStreamClosed)
- }
- if f.Length > 0 {
- // Check whether the client has flow control quota.
- if st.inflow.available() < int32(f.Length) {
- return streamError(id, ErrCodeFlowControl)
- }
- st.inflow.take(int32(f.Length))
-
- if len(data) > 0 {
- wrote, err := st.body.Write(data)
- if err != nil {
- return streamError(id, ErrCodeStreamClosed)
- }
- if wrote != len(data) {
- panic("internal error: bad Writer")
- }
- st.bodyBytes += int64(len(data))
- }
-
- // Return any padded flow control now, since we won't
- // refund it later on body reads.
- if pad := int32(f.Length) - int32(len(data)); pad > 0 {
- sc.sendWindowUpdate32(nil, pad)
- sc.sendWindowUpdate32(st, pad)
- }
- }
- if f.StreamEnded() {
- st.endStream()
- }
- return nil
-}
-
-func (sc *serverConn) processGoAway(f *GoAwayFrame) error {
- sc.serveG.check()
- if f.ErrCode != ErrCodeNo {
- sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
- } else {
- sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
- }
- sc.startGracefulShutdownInternal()
- // http://tools.ietf.org/html/rfc7540#section-6.8
- // We should not create any new streams, which means we should disable push.
- sc.pushEnabled = false
- return nil
-}
-
-// isPushed reports whether the stream is server-initiated.
-func (st *stream) isPushed() bool {
- return st.id%2 == 0
-}
-
-// endStream closes a Request.Body's pipe. It is called when a DATA
-// frame says a request body is over (or after trailers).
-func (st *stream) endStream() {
- sc := st.sc
- sc.serveG.check()
-
- if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
- st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
- st.declBodyBytes, st.bodyBytes))
- } else {
- st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
- st.body.CloseWithError(io.EOF)
- }
- st.state = stateHalfClosedRemote
-}
-
-// copyTrailersToHandlerRequest is run in the Handler's goroutine in
-// its Request.Body.Read just before it gets io.EOF.
-func (st *stream) copyTrailersToHandlerRequest() {
- for k, vv := range st.trailer {
- if _, ok := st.reqTrailer[k]; ok {
- // Only copy it over it was pre-declared.
- st.reqTrailer[k] = vv
- }
- }
-}
-
-// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
-// when the stream's WriteTimeout has fired.
-func (st *stream) onWriteTimeout() {
- st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)})
-}
-
-func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
- sc.serveG.check()
- id := f.StreamID
- if sc.inGoAway {
- // Ignore.
- return nil
- }
- // http://tools.ietf.org/html/rfc7540#section-5.1.1
- // Streams initiated by a client MUST use odd-numbered stream
- // identifiers. [...] An endpoint that receives an unexpected
- // stream identifier MUST respond with a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- if id%2 != 1 {
- return ConnectionError(ErrCodeProtocol)
- }
- // A HEADERS frame can be used to create a new stream or
- // send a trailer for an open one. If we already have a stream
- // open, let it process its own HEADERS frame (trailers at this
- // point, if it's valid).
- if st := sc.streams[f.StreamID]; st != nil {
- if st.resetQueued {
- // We're sending RST_STREAM to close the stream, so don't bother
- // processing this frame.
- return nil
- }
- return st.processTrailerHeaders(f)
- }
-
- // [...] The identifier of a newly established stream MUST be
- // numerically greater than all streams that the initiating
- // endpoint has opened or reserved. [...] An endpoint that
- // receives an unexpected stream identifier MUST respond with
- // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
- if id <= sc.maxClientStreamID {
- return ConnectionError(ErrCodeProtocol)
- }
- sc.maxClientStreamID = id
-
- if sc.idleTimer != nil {
- sc.idleTimer.Stop()
- }
-
- // http://tools.ietf.org/html/rfc7540#section-5.1.2
- // [...] Endpoints MUST NOT exceed the limit set by their peer. An
- // endpoint that receives a HEADERS frame that causes their
- // advertised concurrent stream limit to be exceeded MUST treat
- // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
- // or REFUSED_STREAM.
- if sc.curClientStreams+1 > sc.advMaxStreams {
- if sc.unackedSettings == 0 {
- // They should know better.
- return streamError(id, ErrCodeProtocol)
- }
- // Assume it's a network race, where they just haven't
- // received our last SETTINGS update. But actually
- // this can't happen yet, because we don't yet provide
- // a way for users to adjust server parameters at
- // runtime.
- return streamError(id, ErrCodeRefusedStream)
- }
-
- initialState := stateOpen
- if f.StreamEnded() {
- initialState = stateHalfClosedRemote
- }
- st := sc.newStream(id, 0, initialState)
-
- if f.HasPriority() {
- if err := checkPriority(f.StreamID, f.Priority); err != nil {
- return err
- }
- sc.writeSched.AdjustStream(st.id, f.Priority)
- }
-
- rw, req, err := sc.newWriterAndRequest(st, f)
- if err != nil {
- return err
- }
- st.reqTrailer = req.Trailer
- if st.reqTrailer != nil {
- st.trailer = make(http.Header)
- }
- st.body = req.Body.(*requestBody).pipe // may be nil
- st.declBodyBytes = req.ContentLength
-
- handler := sc.handler.ServeHTTP
- if f.Truncated {
- // Their header list was too long. Send a 431 error.
- handler = handleHeaderListTooLong
- } else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil {
- handler = new400Handler(err)
- }
-
- // The net/http package sets the read deadline from the
- // http.Server.ReadTimeout during the TLS handshake, but then
- // passes the connection off to us with the deadline already
- // set. Disarm it here after the request headers are read,
- // similar to how the http1 server works. Here it's
- // technically more like the http1 Server's ReadHeaderTimeout
- // (in Go 1.8), though. That's a more sane option anyway.
- if sc.hs.ReadTimeout != 0 {
- sc.conn.SetReadDeadline(time.Time{})
- }
-
- go sc.runHandler(rw, req, handler)
- return nil
-}
-
-func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
- sc := st.sc
- sc.serveG.check()
- if st.gotTrailerHeader {
- return ConnectionError(ErrCodeProtocol)
- }
- st.gotTrailerHeader = true
- if !f.StreamEnded() {
- return streamError(st.id, ErrCodeProtocol)
- }
-
- if len(f.PseudoFields()) > 0 {
- return streamError(st.id, ErrCodeProtocol)
- }
- if st.trailer != nil {
- for _, hf := range f.RegularFields() {
- key := sc.canonicalHeader(hf.Name)
- if !ValidTrailerHeader(key) {
- // TODO: send more details to the peer somehow. But http2 has
- // no way to send debug data at a stream level. Discuss with
- // HTTP folk.
- return streamError(st.id, ErrCodeProtocol)
- }
- st.trailer[key] = append(st.trailer[key], hf.Value)
- }
- }
- st.endStream()
- return nil
-}
-
-func checkPriority(streamID uint32, p PriorityParam) error {
- if streamID == p.StreamDep {
- // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
- // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
- // Section 5.3.3 says that a stream can depend on one of its dependencies,
- // so it's only self-dependencies that are forbidden.
- return streamError(streamID, ErrCodeProtocol)
- }
- return nil
-}
-
-func (sc *serverConn) processPriority(f *PriorityFrame) error {
- if sc.inGoAway {
- return nil
- }
- if err := checkPriority(f.StreamID, f.PriorityParam); err != nil {
- return err
- }
- sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
- return nil
-}
-
-func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream {
- sc.serveG.check()
- if id == 0 {
- panic("internal error: cannot create stream with id 0")
- }
-
- ctx, cancelCtx := contextWithCancel(sc.baseCtx)
- st := &stream{
- sc: sc,
- id: id,
- state: state,
- ctx: ctx,
- cancelCtx: cancelCtx,
- }
- st.cw.Init()
- st.flow.conn = &sc.flow // link to conn-level counter
- st.flow.add(sc.initialStreamSendWindowSize)
- st.inflow.conn = &sc.inflow // link to conn-level counter
- st.inflow.add(sc.srv.initialStreamRecvWindowSize())
- if sc.hs.WriteTimeout != 0 {
- st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
- }
-
- sc.streams[id] = st
- sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID})
- if st.isPushed() {
- sc.curPushedStreams++
- } else {
- sc.curClientStreams++
- }
- if sc.curOpenStreams() == 1 {
- sc.setConnState(http.StateActive)
- }
-
- return st
-}
-
-func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
- sc.serveG.check()
-
- rp := requestParam{
- method: f.PseudoValue("method"),
- scheme: f.PseudoValue("scheme"),
- authority: f.PseudoValue("authority"),
- path: f.PseudoValue("path"),
- }
-
- isConnect := rp.method == "CONNECT"
- if isConnect {
- if rp.path != "" || rp.scheme != "" || rp.authority == "" {
- return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
- }
- } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
- // See 8.1.2.6 Malformed Requests and Responses:
- //
- // Malformed requests or responses that are detected
- // MUST be treated as a stream error (Section 5.4.2)
- // of type PROTOCOL_ERROR."
- //
- // 8.1.2.3 Request Pseudo-Header Fields
- // "All HTTP/2 requests MUST include exactly one valid
- // value for the :method, :scheme, and :path
- // pseudo-header fields"
- return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
- }
-
- bodyOpen := !f.StreamEnded()
- if rp.method == "HEAD" && bodyOpen {
- // HEAD requests can't have bodies
- return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
- }
-
- rp.header = make(http.Header)
- for _, hf := range f.RegularFields() {
- rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
- }
- if rp.authority == "" {
- rp.authority = rp.header.Get("Host")
- }
-
- rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
- if err != nil {
- return nil, nil, err
- }
- if bodyOpen {
- if vv, ok := rp.header["Content-Length"]; ok {
- req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
- } else {
- req.ContentLength = -1
- }
- req.Body.(*requestBody).pipe = &pipe{
- b: &dataBuffer{expected: req.ContentLength},
- }
- }
- return rw, req, nil
-}
-
-type requestParam struct {
- method string
- scheme, authority, path string
- header http.Header
-}
-
-func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) {
- sc.serveG.check()
-
- var tlsState *tls.ConnectionState // nil if not scheme https
- if rp.scheme == "https" {
- tlsState = sc.tlsState
- }
-
- needsContinue := rp.header.Get("Expect") == "100-continue"
- if needsContinue {
- rp.header.Del("Expect")
- }
- // Merge Cookie headers into one "; "-delimited value.
- if cookies := rp.header["Cookie"]; len(cookies) > 1 {
- rp.header.Set("Cookie", strings.Join(cookies, "; "))
- }
-
- // Setup Trailers
- var trailer http.Header
- for _, v := range rp.header["Trailer"] {
- for _, key := range strings.Split(v, ",") {
- key = http.CanonicalHeaderKey(strings.TrimSpace(key))
- switch key {
- case "Transfer-Encoding", "Trailer", "Content-Length":
- // Bogus. (copy of http1 rules)
- // Ignore.
- default:
- if trailer == nil {
- trailer = make(http.Header)
- }
- trailer[key] = nil
- }
- }
- }
- delete(rp.header, "Trailer")
-
- var url_ *url.URL
- var requestURI string
- if rp.method == "CONNECT" {
- url_ = &url.URL{Host: rp.authority}
- requestURI = rp.authority // mimic HTTP/1 server behavior
- } else {
- var err error
- url_, err = url.ParseRequestURI(rp.path)
- if err != nil {
- return nil, nil, streamError(st.id, ErrCodeProtocol)
- }
- requestURI = rp.path
- }
-
- body := &requestBody{
- conn: sc,
- stream: st,
- needsContinue: needsContinue,
- }
- req := &http.Request{
- Method: rp.method,
- URL: url_,
- RemoteAddr: sc.remoteAddrStr,
- Header: rp.header,
- RequestURI: requestURI,
- Proto: "HTTP/2.0",
- ProtoMajor: 2,
- ProtoMinor: 0,
- TLS: tlsState,
- Host: rp.authority,
- Body: body,
- Trailer: trailer,
- }
- req = requestWithContext(req, st.ctx)
-
- rws := responseWriterStatePool.Get().(*responseWriterState)
- bwSave := rws.bw
- *rws = responseWriterState{} // zero all the fields
- rws.conn = sc
- rws.bw = bwSave
- rws.bw.Reset(chunkWriter{rws})
- rws.stream = st
- rws.req = req
- rws.body = body
-
- rw := &responseWriter{rws: rws}
- return rw, req, nil
-}
-
-// Run on its own goroutine.
-func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
- didPanic := true
- defer func() {
- rw.rws.stream.cancelCtx()
- if didPanic {
- e := recover()
- sc.writeFrameFromHandler(FrameWriteRequest{
- write: handlerPanicRST{rw.rws.stream.id},
- stream: rw.rws.stream,
- })
- // Same as net/http:
- if shouldLogPanic(e) {
- const size = 64 << 10
- buf := make([]byte, size)
- buf = buf[:runtime.Stack(buf, false)]
- sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
- }
- return
- }
- rw.handlerDone()
- }()
- handler(rw, req)
- didPanic = false
-}
-
-func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {
- // 10.5.1 Limits on Header Block Size:
- // .. "A server that receives a larger header block than it is
- // willing to handle can send an HTTP 431 (Request Header Fields Too
- // Large) status code"
- const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
- w.WriteHeader(statusRequestHeaderFieldsTooLarge)
- io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
-}
-
-// called from handler goroutines.
-// h may be nil.
-func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {
- sc.serveG.checkNotOn() // NOT on
- var errc chan error
- if headerData.h != nil {
- // If there's a header map (which we don't own), so we have to block on
- // waiting for this frame to be written, so an http.Flush mid-handler
- // writes out the correct value of keys, before a handler later potentially
- // mutates it.
- errc = errChanPool.Get().(chan error)
- }
- if err := sc.writeFrameFromHandler(FrameWriteRequest{
- write: headerData,
- stream: st,
- done: errc,
- }); err != nil {
- return err
- }
- if errc != nil {
- select {
- case err := <-errc:
- errChanPool.Put(errc)
- return err
- case <-sc.doneServing:
- return errClientDisconnected
- case <-st.cw:
- return errStreamClosed
- }
- }
- return nil
-}
-
-// called from handler goroutines.
-func (sc *serverConn) write100ContinueHeaders(st *stream) {
- sc.writeFrameFromHandler(FrameWriteRequest{
- write: write100ContinueHeadersFrame{st.id},
- stream: st,
- })
-}
-
-// A bodyReadMsg tells the server loop that the http.Handler read n
-// bytes of the DATA from the client on the given stream.
-type bodyReadMsg struct {
- st *stream
- n int
-}
-
-// called from handler goroutines.
-// Notes that the handler for the given stream ID read n bytes of its body
-// and schedules flow control tokens to be sent.
-func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) {
- sc.serveG.checkNotOn() // NOT on
- if n > 0 {
- select {
- case sc.bodyReadCh <- bodyReadMsg{st, n}:
- case <-sc.doneServing:
- }
- }
-}
-
-func (sc *serverConn) noteBodyRead(st *stream, n int) {
- sc.serveG.check()
- sc.sendWindowUpdate(nil, n) // conn-level
- if st.state != stateHalfClosedRemote && st.state != stateClosed {
- // Don't send this WINDOW_UPDATE if the stream is closed
- // remotely.
- sc.sendWindowUpdate(st, n)
- }
-}
-
-// st may be nil for conn-level
-func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
- sc.serveG.check()
- // "The legal range for the increment to the flow control
- // window is 1 to 2^31-1 (2,147,483,647) octets."
- // A Go Read call on 64-bit machines could in theory read
- // a larger Read than this. Very unlikely, but we handle it here
- // rather than elsewhere for now.
- const maxUint31 = 1<<31 - 1
- for n >= maxUint31 {
- sc.sendWindowUpdate32(st, maxUint31)
- n -= maxUint31
- }
- sc.sendWindowUpdate32(st, int32(n))
-}
-
-// st may be nil for conn-level
-func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {
- sc.serveG.check()
- if n == 0 {
- return
- }
- if n < 0 {
- panic("negative update")
- }
- var streamID uint32
- if st != nil {
- streamID = st.id
- }
- sc.writeFrame(FrameWriteRequest{
- write: writeWindowUpdate{streamID: streamID, n: uint32(n)},
- stream: st,
- })
- var ok bool
- if st == nil {
- ok = sc.inflow.add(n)
- } else {
- ok = st.inflow.add(n)
- }
- if !ok {
- panic("internal error; sent too many window updates without decrements?")
- }
-}
-
-// requestBody is the Handler's Request.Body type.
-// Read and Close may be called concurrently.
-type requestBody struct {
- stream *stream
- conn *serverConn
- closed bool // for use by Close only
- sawEOF bool // for use by Read only
- pipe *pipe // non-nil if we have a HTTP entity message body
- needsContinue bool // need to send a 100-continue
-}
-
-func (b *requestBody) Close() error {
- if b.pipe != nil && !b.closed {
- b.pipe.BreakWithError(errClosedBody)
- }
- b.closed = true
- return nil
-}
-
-func (b *requestBody) Read(p []byte) (n int, err error) {
- if b.needsContinue {
- b.needsContinue = false
- b.conn.write100ContinueHeaders(b.stream)
- }
- if b.pipe == nil || b.sawEOF {
- return 0, io.EOF
- }
- n, err = b.pipe.Read(p)
- if err == io.EOF {
- b.sawEOF = true
- }
- if b.conn == nil && inTests {
- return
- }
- b.conn.noteBodyReadFromHandler(b.stream, n, err)
- return
-}
-
-// responseWriter is the http.ResponseWriter implementation. It's
-// intentionally small (1 pointer wide) to minimize garbage. The
-// responseWriterState pointer inside is zeroed at the end of a
-// request (in handlerDone) and calls on the responseWriter thereafter
-// simply crash (caller's mistake), but the much larger responseWriterState
-// and buffers are reused between multiple requests.
-type responseWriter struct {
- rws *responseWriterState
-}
-
-// Optional http.ResponseWriter interfaces implemented.
-var (
- _ http.CloseNotifier = (*responseWriter)(nil)
- _ http.Flusher = (*responseWriter)(nil)
- _ stringWriter = (*responseWriter)(nil)
-)
-
-type responseWriterState struct {
- // immutable within a request:
- stream *stream
- req *http.Request
- body *requestBody // to close at end of request, if DATA frames didn't
- conn *serverConn
-
- // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
- bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
-
- // mutated by http.Handler goroutine:
- handlerHeader http.Header // nil until called
- snapHeader http.Header // snapshot of handlerHeader at WriteHeader time
- trailers []string // set in writeChunk
- status int // status code passed to WriteHeader
- wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
- sentHeader bool // have we sent the header frame?
- handlerDone bool // handler has finished
-
- sentContentLen int64 // non-zero if handler set a Content-Length header
- wroteBytes int64
-
- closeNotifierMu sync.Mutex // guards closeNotifierCh
- closeNotifierCh chan bool // nil until first used
-}
-
-type chunkWriter struct{ rws *responseWriterState }
-
-func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
-
-func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 }
-
-// declareTrailer is called for each Trailer header when the
-// response header is written. It notes that a header will need to be
-// written in the trailers at the end of the response.
-func (rws *responseWriterState) declareTrailer(k string) {
- k = http.CanonicalHeaderKey(k)
- if !ValidTrailerHeader(k) {
- // Forbidden by RFC 2616 14.40.
- rws.conn.logf("ignoring invalid trailer %q", k)
- return
- }
- if !strSliceContains(rws.trailers, k) {
- rws.trailers = append(rws.trailers, k)
- }
-}
-
-// writeChunk writes chunks from the bufio.Writer. But because
-// bufio.Writer may bypass its chunking, sometimes p may be
-// arbitrarily large.
-//
-// writeChunk is also responsible (on the first chunk) for sending the
-// HEADER response.
-func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
- if !rws.wroteHeader {
- rws.writeHeader(200)
- }
-
- isHeadResp := rws.req.Method == "HEAD"
- if !rws.sentHeader {
- rws.sentHeader = true
- var ctype, clen string
- if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
- rws.snapHeader.Del("Content-Length")
- clen64, err := strconv.ParseInt(clen, 10, 64)
- if err == nil && clen64 >= 0 {
- rws.sentContentLen = clen64
- } else {
- clen = ""
- }
- }
- if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
- clen = strconv.Itoa(len(p))
- }
- _, hasContentType := rws.snapHeader["Content-Type"]
- if !hasContentType && bodyAllowedForStatus(rws.status) {
- ctype = http.DetectContentType(p)
- }
- var date string
- if _, ok := rws.snapHeader["Date"]; !ok {
- // TODO(bradfitz): be faster here, like net/http? measure.
- date = time.Now().UTC().Format(http.TimeFormat)
- }
-
- for _, v := range rws.snapHeader["Trailer"] {
- foreachHeaderElement(v, rws.declareTrailer)
- }
-
- endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
- err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
- streamID: rws.stream.id,
- httpResCode: rws.status,
- h: rws.snapHeader,
- endStream: endStream,
- contentType: ctype,
- contentLength: clen,
- date: date,
- })
- if err != nil {
- return 0, err
- }
- if endStream {
- return 0, nil
- }
- }
- if isHeadResp {
- return len(p), nil
- }
- if len(p) == 0 && !rws.handlerDone {
- return 0, nil
- }
-
- if rws.handlerDone {
- rws.promoteUndeclaredTrailers()
- }
-
- endStream := rws.handlerDone && !rws.hasTrailers()
- if len(p) > 0 || endStream {
- // only send a 0 byte DATA frame if we're ending the stream.
- if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
- return 0, err
- }
- }
-
- if rws.handlerDone && rws.hasTrailers() {
- err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{
- streamID: rws.stream.id,
- h: rws.handlerHeader,
- trailers: rws.trailers,
- endStream: true,
- })
- return len(p), err
- }
- return len(p), nil
-}
-
-// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
-// that, if present, signals that the map entry is actually for
-// the response trailers, and not the response headers. The prefix
-// is stripped after the ServeHTTP call finishes and the values are
-// sent in the trailers.
-//
-// This mechanism is intended only for trailers that are not known
-// prior to the headers being written. If the set of trailers is fixed
-// or known before the header is written, the normal Go trailers mechanism
-// is preferred:
-// https://golang.org/pkg/net/http/#ResponseWriter
-// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
-const TrailerPrefix = "Trailer:"
-
-// promoteUndeclaredTrailers permits http.Handlers to set trailers
-// after the header has already been flushed. Because the Go
-// ResponseWriter interface has no way to set Trailers (only the
-// Header), and because we didn't want to expand the ResponseWriter
-// interface, and because nobody used trailers, and because RFC 2616
-// says you SHOULD (but not must) predeclare any trailers in the
-// header, the official ResponseWriter rules said trailers in Go must
-// be predeclared, and then we reuse the same ResponseWriter.Header()
-// map to mean both Headers and Trailers. When it's time to write the
-// Trailers, we pick out the fields of Headers that were declared as
-// trailers. That worked for a while, until we found the first major
-// user of Trailers in the wild: gRPC (using them only over http2),
-// and gRPC libraries permit setting trailers mid-stream without
-// predeclarnig them. So: change of plans. We still permit the old
-// way, but we also permit this hack: if a Header() key begins with
-// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
-// invalid token byte anyway, there is no ambiguity. (And it's already
-// filtered out) It's mildly hacky, but not terrible.
-//
-// This method runs after the Handler is done and promotes any Header
-// fields to be trailers.
-func (rws *responseWriterState) promoteUndeclaredTrailers() {
- for k, vv := range rws.handlerHeader {
- if !strings.HasPrefix(k, TrailerPrefix) {
- continue
- }
- trailerKey := strings.TrimPrefix(k, TrailerPrefix)
- rws.declareTrailer(trailerKey)
- rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
- }
-
- if len(rws.trailers) > 1 {
- sorter := sorterPool.Get().(*sorter)
- sorter.SortStrings(rws.trailers)
- sorterPool.Put(sorter)
- }
-}
-
-func (w *responseWriter) Flush() {
- rws := w.rws
- if rws == nil {
- panic("Header called after Handler finished")
- }
- if rws.bw.Buffered() > 0 {
- if err := rws.bw.Flush(); err != nil {
- // Ignore the error. The frame writer already knows.
- return
- }
- } else {
- // The bufio.Writer won't call chunkWriter.Write
- // (writeChunk with zero bytes, so we have to do it
- // ourselves to force the HTTP response header and/or
- // final DATA frame (with END_STREAM) to be sent.
- rws.writeChunk(nil)
- }
-}
-
-func (w *responseWriter) CloseNotify() <-chan bool {
- rws := w.rws
- if rws == nil {
- panic("CloseNotify called after Handler finished")
- }
- rws.closeNotifierMu.Lock()
- ch := rws.closeNotifierCh
- if ch == nil {
- ch = make(chan bool, 1)
- rws.closeNotifierCh = ch
- cw := rws.stream.cw
- go func() {
- cw.Wait() // wait for close
- ch <- true
- }()
- }
- rws.closeNotifierMu.Unlock()
- return ch
-}
-
-func (w *responseWriter) Header() http.Header {
- rws := w.rws
- if rws == nil {
- panic("Header called after Handler finished")
- }
- if rws.handlerHeader == nil {
- rws.handlerHeader = make(http.Header)
- }
- return rws.handlerHeader
-}
-
-func (w *responseWriter) WriteHeader(code int) {
- rws := w.rws
- if rws == nil {
- panic("WriteHeader called after Handler finished")
- }
- rws.writeHeader(code)
-}
-
-func (rws *responseWriterState) writeHeader(code int) {
- if !rws.wroteHeader {
- rws.wroteHeader = true
- rws.status = code
- if len(rws.handlerHeader) > 0 {
- rws.snapHeader = cloneHeader(rws.handlerHeader)
- }
- }
-}
-
-func cloneHeader(h http.Header) http.Header {
- h2 := make(http.Header, len(h))
- for k, vv := range h {
- vv2 := make([]string, len(vv))
- copy(vv2, vv)
- h2[k] = vv2
- }
- return h2
-}
-
-// The Life Of A Write is like this:
-//
-// * Handler calls w.Write or w.WriteString ->
-// * -> rws.bw (*bufio.Writer) ->
-// * (Handler migth call Flush)
-// * -> chunkWriter{rws}
-// * -> responseWriterState.writeChunk(p []byte)
-// * -> responseWriterState.writeChunk (most of the magic; see comment there)
-func (w *responseWriter) Write(p []byte) (n int, err error) {
- return w.write(len(p), p, "")
-}
-
-func (w *responseWriter) WriteString(s string) (n int, err error) {
- return w.write(len(s), nil, s)
-}
-
-// either dataB or dataS is non-zero.
-func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
- rws := w.rws
- if rws == nil {
- panic("Write called after Handler finished")
- }
- if !rws.wroteHeader {
- w.WriteHeader(200)
- }
- if !bodyAllowedForStatus(rws.status) {
- return 0, http.ErrBodyNotAllowed
- }
- rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
- if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
- // TODO: send a RST_STREAM
- return 0, errors.New("http2: handler wrote more than declared Content-Length")
- }
-
- if dataB != nil {
- return rws.bw.Write(dataB)
- } else {
- return rws.bw.WriteString(dataS)
- }
-}
-
-func (w *responseWriter) handlerDone() {
- rws := w.rws
- rws.handlerDone = true
- w.Flush()
- w.rws = nil
- responseWriterStatePool.Put(rws)
-}
-
-// Push errors.
-var (
- ErrRecursivePush = errors.New("http2: recursive push not allowed")
- ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
-)
-
-// pushOptions is the internal version of http.PushOptions, which we
-// cannot include here because it's only defined in Go 1.8 and later.
-type pushOptions struct {
- Method string
- Header http.Header
-}
-
-func (w *responseWriter) push(target string, opts pushOptions) error {
- st := w.rws.stream
- sc := st.sc
- sc.serveG.checkNotOn()
-
- // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
- // http://tools.ietf.org/html/rfc7540#section-6.6
- if st.isPushed() {
- return ErrRecursivePush
- }
-
- // Default options.
- if opts.Method == "" {
- opts.Method = "GET"
- }
- if opts.Header == nil {
- opts.Header = http.Header{}
- }
- wantScheme := "http"
- if w.rws.req.TLS != nil {
- wantScheme = "https"
- }
-
- // Validate the request.
- u, err := url.Parse(target)
- if err != nil {
- return err
- }
- if u.Scheme == "" {
- if !strings.HasPrefix(target, "/") {
- return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target)
- }
- u.Scheme = wantScheme
- u.Host = w.rws.req.Host
- } else {
- if u.Scheme != wantScheme {
- return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme)
- }
- if u.Host == "" {
- return errors.New("URL must have a host")
- }
- }
- for k := range opts.Header {
- if strings.HasPrefix(k, ":") {
- return fmt.Errorf("promised request headers cannot include pseudo header %q", k)
- }
- // These headers are meaningful only if the request has a body,
- // but PUSH_PROMISE requests cannot have a body.
- // http://tools.ietf.org/html/rfc7540#section-8.2
- // Also disallow Host, since the promised URL must be absolute.
- switch strings.ToLower(k) {
- case "content-length", "content-encoding", "trailer", "te", "expect", "host":
- return fmt.Errorf("promised request headers cannot include %q", k)
- }
- }
- if err := checkValidHTTP2RequestHeaders(opts.Header); err != nil {
- return err
- }
-
- // The RFC effectively limits promised requests to GET and HEAD:
- // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
- // http://tools.ietf.org/html/rfc7540#section-8.2
- if opts.Method != "GET" && opts.Method != "HEAD" {
- return fmt.Errorf("method %q must be GET or HEAD", opts.Method)
- }
-
- msg := &startPushRequest{
- parent: st,
- method: opts.Method,
- url: u,
- header: cloneHeader(opts.Header),
- done: errChanPool.Get().(chan error),
- }
-
- select {
- case <-sc.doneServing:
- return errClientDisconnected
- case <-st.cw:
- return errStreamClosed
- case sc.serveMsgCh <- msg:
- }
-
- select {
- case <-sc.doneServing:
- return errClientDisconnected
- case <-st.cw:
- return errStreamClosed
- case err := <-msg.done:
- errChanPool.Put(msg.done)
- return err
- }
-}
-
-type startPushRequest struct {
- parent *stream
- method string
- url *url.URL
- header http.Header
- done chan error
-}
-
-func (sc *serverConn) startPush(msg *startPushRequest) {
- sc.serveG.check()
-
- // http://tools.ietf.org/html/rfc7540#section-6.6.
- // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
- // is in either the "open" or "half-closed (remote)" state.
- if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {
- // responseWriter.Push checks that the stream is peer-initiaed.
- msg.done <- errStreamClosed
- return
- }
-
- // http://tools.ietf.org/html/rfc7540#section-6.6.
- if !sc.pushEnabled {
- msg.done <- http.ErrNotSupported
- return
- }
-
- // PUSH_PROMISE frames must be sent in increasing order by stream ID, so
- // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
- // is written. Once the ID is allocated, we start the request handler.
- allocatePromisedID := func() (uint32, error) {
- sc.serveG.check()
-
- // Check this again, just in case. Technically, we might have received
- // an updated SETTINGS by the time we got around to writing this frame.
- if !sc.pushEnabled {
- return 0, http.ErrNotSupported
- }
- // http://tools.ietf.org/html/rfc7540#section-6.5.2.
- if sc.curPushedStreams+1 > sc.clientMaxStreams {
- return 0, ErrPushLimitReached
- }
-
- // http://tools.ietf.org/html/rfc7540#section-5.1.1.
- // Streams initiated by the server MUST use even-numbered identifiers.
- // A server that is unable to establish a new stream identifier can send a GOAWAY
- // frame so that the client is forced to open a new connection for new streams.
- if sc.maxPushPromiseID+2 >= 1<<31 {
- sc.startGracefulShutdownInternal()
- return 0, ErrPushLimitReached
- }
- sc.maxPushPromiseID += 2
- promisedID := sc.maxPushPromiseID
-
- // http://tools.ietf.org/html/rfc7540#section-8.2.
- // Strictly speaking, the new stream should start in "reserved (local)", then
- // transition to "half closed (remote)" after sending the initial HEADERS, but
- // we start in "half closed (remote)" for simplicity.
- // See further comments at the definition of stateHalfClosedRemote.
- promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
- rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{
- method: msg.method,
- scheme: msg.url.Scheme,
- authority: msg.url.Host,
- path: msg.url.RequestURI(),
- header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
- })
- if err != nil {
- // Should not happen, since we've already validated msg.url.
- panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
- }
-
- go sc.runHandler(rw, req, sc.handler.ServeHTTP)
- return promisedID, nil
- }
-
- sc.writeFrame(FrameWriteRequest{
- write: &writePushPromise{
- streamID: msg.parent.id,
- method: msg.method,
- url: msg.url,
- h: msg.header,
- allocatePromisedID: allocatePromisedID,
- },
- stream: msg.parent,
- done: msg.done,
- })
-}
-
-// foreachHeaderElement splits v according to the "#rule" construction
-// in RFC 2616 section 2.1 and calls fn for each non-empty element.
-func foreachHeaderElement(v string, fn func(string)) {
- v = textproto.TrimString(v)
- if v == "" {
- return
- }
- if !strings.Contains(v, ",") {
- fn(v)
- return
- }
- for _, f := range strings.Split(v, ",") {
- if f = textproto.TrimString(f); f != "" {
- fn(f)
- }
- }
-}
-
-// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
-var connHeaders = []string{
- "Connection",
- "Keep-Alive",
- "Proxy-Connection",
- "Transfer-Encoding",
- "Upgrade",
-}
-
-// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
-// per RFC 7540 Section 8.1.2.2.
-// The returned error is reported to users.
-func checkValidHTTP2RequestHeaders(h http.Header) error {
- for _, k := range connHeaders {
- if _, ok := h[k]; ok {
- return fmt.Errorf("request header %q is not valid in HTTP/2", k)
- }
- }
- te := h["Te"]
- if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
- return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
- }
- return nil
-}
-
-func new400Handler(err error) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- http.Error(w, err.Error(), http.StatusBadRequest)
- }
-}
-
-// ValidTrailerHeader reports whether name is a valid header field name to appear
-// in trailers.
-// See: http://tools.ietf.org/html/rfc7230#section-4.1.2
-func ValidTrailerHeader(name string) bool {
- name = http.CanonicalHeaderKey(name)
- if strings.HasPrefix(name, "If-") || badTrailer[name] {
- return false
- }
- return true
-}
-
-var badTrailer = map[string]bool{
- "Authorization": true,
- "Cache-Control": true,
- "Connection": true,
- "Content-Encoding": true,
- "Content-Length": true,
- "Content-Range": true,
- "Content-Type": true,
- "Expect": true,
- "Host": true,
- "Keep-Alive": true,
- "Max-Forwards": true,
- "Pragma": true,
- "Proxy-Authenticate": true,
- "Proxy-Authorization": true,
- "Proxy-Connection": true,
- "Range": true,
- "Realm": true,
- "Te": true,
- "Trailer": true,
- "Transfer-Encoding": true,
- "Www-Authenticate": true,
-}
-
-// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
-// disabled. See comments on h1ServerShutdownChan above for why
-// the code is written this way.
-func h1ServerKeepAlivesDisabled(hs *http.Server) bool {
- var x interface{} = hs
- type I interface {
- doKeepAlives() bool
- }
- if hs, ok := x.(I); ok {
- return !hs.doKeepAlives()
- }
- return false
-}
diff --git a/vendor/golang.org/x/net/http2/server_push_test.go b/vendor/golang.org/x/net/http2/server_push_test.go
deleted file mode 100644
index 918fd30dc..000000000
--- a/vendor/golang.org/x/net/http2/server_push_test.go
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.8
-
-package http2
-
-import (
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "reflect"
- "strconv"
- "sync"
- "testing"
- "time"
-)
-
-func TestServer_Push_Success(t *testing.T) {
- const (
- mainBody = "<html>index page</html>"
- pushedBody = "<html>pushed page</html>"
- userAgent = "testagent"
- cookie = "testcookie"
- )
-
- var stURL string
- checkPromisedReq := func(r *http.Request, wantMethod string, wantH http.Header) error {
- if got, want := r.Method, wantMethod; got != want {
- return fmt.Errorf("promised Req.Method=%q, want %q", got, want)
- }
- if got, want := r.Header, wantH; !reflect.DeepEqual(got, want) {
- return fmt.Errorf("promised Req.Header=%q, want %q", got, want)
- }
- if got, want := "https://"+r.Host, stURL; got != want {
- return fmt.Errorf("promised Req.Host=%q, want %q", got, want)
- }
- if r.Body == nil {
- return fmt.Errorf("nil Body")
- }
- if buf, err := ioutil.ReadAll(r.Body); err != nil || len(buf) != 0 {
- return fmt.Errorf("ReadAll(Body)=%q,%v, want '',nil", buf, err)
- }
- return nil
- }
-
- errc := make(chan error, 3)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- switch r.URL.RequestURI() {
- case "/":
- // Push "/pushed?get" as a GET request, using an absolute URL.
- opt := &http.PushOptions{
- Header: http.Header{
- "User-Agent": {userAgent},
- },
- }
- if err := w.(http.Pusher).Push(stURL+"/pushed?get", opt); err != nil {
- errc <- fmt.Errorf("error pushing /pushed?get: %v", err)
- return
- }
- // Push "/pushed?head" as a HEAD request, using a path.
- opt = &http.PushOptions{
- Method: "HEAD",
- Header: http.Header{
- "User-Agent": {userAgent},
- "Cookie": {cookie},
- },
- }
- if err := w.(http.Pusher).Push("/pushed?head", opt); err != nil {
- errc <- fmt.Errorf("error pushing /pushed?head: %v", err)
- return
- }
- w.Header().Set("Content-Type", "text/html")
- w.Header().Set("Content-Length", strconv.Itoa(len(mainBody)))
- w.WriteHeader(200)
- io.WriteString(w, mainBody)
- errc <- nil
-
- case "/pushed?get":
- wantH := http.Header{}
- wantH.Set("User-Agent", userAgent)
- if err := checkPromisedReq(r, "GET", wantH); err != nil {
- errc <- fmt.Errorf("/pushed?get: %v", err)
- return
- }
- w.Header().Set("Content-Type", "text/html")
- w.Header().Set("Content-Length", strconv.Itoa(len(pushedBody)))
- w.WriteHeader(200)
- io.WriteString(w, pushedBody)
- errc <- nil
-
- case "/pushed?head":
- wantH := http.Header{}
- wantH.Set("User-Agent", userAgent)
- wantH.Set("Cookie", cookie)
- if err := checkPromisedReq(r, "HEAD", wantH); err != nil {
- errc <- fmt.Errorf("/pushed?head: %v", err)
- return
- }
- w.WriteHeader(204)
- errc <- nil
-
- default:
- errc <- fmt.Errorf("unknown RequestURL %q", r.URL.RequestURI())
- }
- })
- stURL = st.ts.URL
-
- // Send one request, which should push two responses.
- st.greet()
- getSlash(st)
- for k := 0; k < 3; k++ {
- select {
- case <-time.After(2 * time.Second):
- t.Errorf("timeout waiting for handler %d to finish", k)
- case err := <-errc:
- if err != nil {
- t.Fatal(err)
- }
- }
- }
-
- checkPushPromise := func(f Frame, promiseID uint32, wantH [][2]string) error {
- pp, ok := f.(*PushPromiseFrame)
- if !ok {
- return fmt.Errorf("got a %T; want *PushPromiseFrame", f)
- }
- if !pp.HeadersEnded() {
- return fmt.Errorf("want END_HEADERS flag in PushPromiseFrame")
- }
- if got, want := pp.PromiseID, promiseID; got != want {
- return fmt.Errorf("got PromiseID %v; want %v", got, want)
- }
- gotH := st.decodeHeader(pp.HeaderBlockFragment())
- if !reflect.DeepEqual(gotH, wantH) {
- return fmt.Errorf("got promised headers %v; want %v", gotH, wantH)
- }
- return nil
- }
- checkHeaders := func(f Frame, wantH [][2]string) error {
- hf, ok := f.(*HeadersFrame)
- if !ok {
- return fmt.Errorf("got a %T; want *HeadersFrame", f)
- }
- gotH := st.decodeHeader(hf.HeaderBlockFragment())
- if !reflect.DeepEqual(gotH, wantH) {
- return fmt.Errorf("got response headers %v; want %v", gotH, wantH)
- }
- return nil
- }
- checkData := func(f Frame, wantData string) error {
- df, ok := f.(*DataFrame)
- if !ok {
- return fmt.Errorf("got a %T; want *DataFrame", f)
- }
- if gotData := string(df.Data()); gotData != wantData {
- return fmt.Errorf("got response data %q; want %q", gotData, wantData)
- }
- return nil
- }
-
- // Stream 1 has 2 PUSH_PROMISE + HEADERS + DATA
- // Stream 2 has HEADERS + DATA
- // Stream 4 has HEADERS
- expected := map[uint32][]func(Frame) error{
- 1: {
- func(f Frame) error {
- return checkPushPromise(f, 2, [][2]string{
- {":method", "GET"},
- {":scheme", "https"},
- {":authority", st.ts.Listener.Addr().String()},
- {":path", "/pushed?get"},
- {"user-agent", userAgent},
- })
- },
- func(f Frame) error {
- return checkPushPromise(f, 4, [][2]string{
- {":method", "HEAD"},
- {":scheme", "https"},
- {":authority", st.ts.Listener.Addr().String()},
- {":path", "/pushed?head"},
- {"cookie", cookie},
- {"user-agent", userAgent},
- })
- },
- func(f Frame) error {
- return checkHeaders(f, [][2]string{
- {":status", "200"},
- {"content-type", "text/html"},
- {"content-length", strconv.Itoa(len(mainBody))},
- })
- },
- func(f Frame) error {
- return checkData(f, mainBody)
- },
- },
- 2: {
- func(f Frame) error {
- return checkHeaders(f, [][2]string{
- {":status", "200"},
- {"content-type", "text/html"},
- {"content-length", strconv.Itoa(len(pushedBody))},
- })
- },
- func(f Frame) error {
- return checkData(f, pushedBody)
- },
- },
- 4: {
- func(f Frame) error {
- return checkHeaders(f, [][2]string{
- {":status", "204"},
- })
- },
- },
- }
-
- consumed := map[uint32]int{}
- for k := 0; len(expected) > 0; k++ {
- f, err := st.readFrame()
- if err != nil {
- for id, left := range expected {
- t.Errorf("stream %d: missing %d frames", id, len(left))
- }
- t.Fatalf("readFrame %d: %v", k, err)
- }
- id := f.Header().StreamID
- label := fmt.Sprintf("stream %d, frame %d", id, consumed[id])
- if len(expected[id]) == 0 {
- t.Fatalf("%s: unexpected frame %#+v", label, f)
- }
- check := expected[id][0]
- expected[id] = expected[id][1:]
- if len(expected[id]) == 0 {
- delete(expected, id)
- }
- if err := check(f); err != nil {
- t.Fatalf("%s: %v", label, err)
- }
- consumed[id]++
- }
-}
-
-func TestServer_Push_SuccessNoRace(t *testing.T) {
- // Regression test for issue #18326. Ensure the request handler can mutate
- // pushed request headers without racing with the PUSH_PROMISE write.
- errc := make(chan error, 2)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- switch r.URL.RequestURI() {
- case "/":
- opt := &http.PushOptions{
- Header: http.Header{"User-Agent": {"testagent"}},
- }
- if err := w.(http.Pusher).Push("/pushed", opt); err != nil {
- errc <- fmt.Errorf("error pushing: %v", err)
- return
- }
- w.WriteHeader(200)
- errc <- nil
-
- case "/pushed":
- // Update request header, ensure there is no race.
- r.Header.Set("User-Agent", "newagent")
- r.Header.Set("Cookie", "cookie")
- w.WriteHeader(200)
- errc <- nil
-
- default:
- errc <- fmt.Errorf("unknown RequestURL %q", r.URL.RequestURI())
- }
- })
-
- // Send one request, which should push one response.
- st.greet()
- getSlash(st)
- for k := 0; k < 2; k++ {
- select {
- case <-time.After(2 * time.Second):
- t.Errorf("timeout waiting for handler %d to finish", k)
- case err := <-errc:
- if err != nil {
- t.Fatal(err)
- }
- }
- }
-}
-
-func TestServer_Push_RejectRecursivePush(t *testing.T) {
- // Expect two requests, but might get three if there's a bug and the second push succeeds.
- errc := make(chan error, 3)
- handler := func(w http.ResponseWriter, r *http.Request) error {
- baseURL := "https://" + r.Host
- switch r.URL.Path {
- case "/":
- if err := w.(http.Pusher).Push(baseURL+"/push1", nil); err != nil {
- return fmt.Errorf("first Push()=%v, want nil", err)
- }
- return nil
-
- case "/push1":
- if got, want := w.(http.Pusher).Push(baseURL+"/push2", nil), ErrRecursivePush; got != want {
- return fmt.Errorf("Push()=%v, want %v", got, want)
- }
- return nil
-
- default:
- return fmt.Errorf("unexpected path: %q", r.URL.Path)
- }
- }
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- errc <- handler(w, r)
- })
- defer st.Close()
- st.greet()
- getSlash(st)
- if err := <-errc; err != nil {
- t.Errorf("First request failed: %v", err)
- }
- if err := <-errc; err != nil {
- t.Errorf("Second request failed: %v", err)
- }
-}
-
-func testServer_Push_RejectSingleRequest(t *testing.T, doPush func(http.Pusher, *http.Request) error, settings ...Setting) {
- // Expect one request, but might get two if there's a bug and the push succeeds.
- errc := make(chan error, 2)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- errc <- doPush(w.(http.Pusher), r)
- })
- defer st.Close()
- st.greet()
- if err := st.fr.WriteSettings(settings...); err != nil {
- st.t.Fatalf("WriteSettings: %v", err)
- }
- st.wantSettingsAck()
- getSlash(st)
- if err := <-errc; err != nil {
- t.Error(err)
- }
- // Should not get a PUSH_PROMISE frame.
- hf := st.wantHeaders()
- if !hf.StreamEnded() {
- t.Error("stream should end after headers")
- }
-}
-
-func TestServer_Push_RejectIfDisabled(t *testing.T) {
- testServer_Push_RejectSingleRequest(t,
- func(p http.Pusher, r *http.Request) error {
- if got, want := p.Push("https://"+r.Host+"/pushed", nil), http.ErrNotSupported; got != want {
- return fmt.Errorf("Push()=%v, want %v", got, want)
- }
- return nil
- },
- Setting{SettingEnablePush, 0})
-}
-
-func TestServer_Push_RejectWhenNoConcurrentStreams(t *testing.T) {
- testServer_Push_RejectSingleRequest(t,
- func(p http.Pusher, r *http.Request) error {
- if got, want := p.Push("https://"+r.Host+"/pushed", nil), ErrPushLimitReached; got != want {
- return fmt.Errorf("Push()=%v, want %v", got, want)
- }
- return nil
- },
- Setting{SettingMaxConcurrentStreams, 0})
-}
-
-func TestServer_Push_RejectWrongScheme(t *testing.T) {
- testServer_Push_RejectSingleRequest(t,
- func(p http.Pusher, r *http.Request) error {
- if err := p.Push("http://"+r.Host+"/pushed", nil); err == nil {
- return errors.New("Push() should have failed (push target URL is http)")
- }
- return nil
- })
-}
-
-func TestServer_Push_RejectMissingHost(t *testing.T) {
- testServer_Push_RejectSingleRequest(t,
- func(p http.Pusher, r *http.Request) error {
- if err := p.Push("https:pushed", nil); err == nil {
- return errors.New("Push() should have failed (push target URL missing host)")
- }
- return nil
- })
-}
-
-func TestServer_Push_RejectRelativePath(t *testing.T) {
- testServer_Push_RejectSingleRequest(t,
- func(p http.Pusher, r *http.Request) error {
- if err := p.Push("../test", nil); err == nil {
- return errors.New("Push() should have failed (push target is a relative path)")
- }
- return nil
- })
-}
-
-func TestServer_Push_RejectForbiddenMethod(t *testing.T) {
- testServer_Push_RejectSingleRequest(t,
- func(p http.Pusher, r *http.Request) error {
- if err := p.Push("https://"+r.Host+"/pushed", &http.PushOptions{Method: "POST"}); err == nil {
- return errors.New("Push() should have failed (cannot promise a POST)")
- }
- return nil
- })
-}
-
-func TestServer_Push_RejectForbiddenHeader(t *testing.T) {
- testServer_Push_RejectSingleRequest(t,
- func(p http.Pusher, r *http.Request) error {
- header := http.Header{
- "Content-Length": {"10"},
- "Content-Encoding": {"gzip"},
- "Trailer": {"Foo"},
- "Te": {"trailers"},
- "Host": {"test.com"},
- ":authority": {"test.com"},
- }
- if err := p.Push("https://"+r.Host+"/pushed", &http.PushOptions{Header: header}); err == nil {
- return errors.New("Push() should have failed (forbidden headers)")
- }
- return nil
- })
-}
-
-func TestServer_Push_StateTransitions(t *testing.T) {
- const body = "foo"
-
- gotPromise := make(chan bool)
- finishedPush := make(chan bool)
-
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- switch r.URL.RequestURI() {
- case "/":
- if err := w.(http.Pusher).Push("/pushed", nil); err != nil {
- t.Errorf("Push error: %v", err)
- }
- // Don't finish this request until the push finishes so we don't
- // nondeterministically interleave output frames with the push.
- <-finishedPush
- case "/pushed":
- <-gotPromise
- }
- w.Header().Set("Content-Type", "text/html")
- w.Header().Set("Content-Length", strconv.Itoa(len(body)))
- w.WriteHeader(200)
- io.WriteString(w, body)
- })
- defer st.Close()
-
- st.greet()
- if st.stream(2) != nil {
- t.Fatal("stream 2 should be empty")
- }
- if got, want := st.streamState(2), stateIdle; got != want {
- t.Fatalf("streamState(2)=%v, want %v", got, want)
- }
- getSlash(st)
- // After the PUSH_PROMISE is sent, the stream should be stateHalfClosedRemote.
- st.wantPushPromise()
- if got, want := st.streamState(2), stateHalfClosedRemote; got != want {
- t.Fatalf("streamState(2)=%v, want %v", got, want)
- }
- // We stall the HTTP handler for "/pushed" until the above check. If we don't
- // stall the handler, then the handler might write HEADERS and DATA and finish
- // the stream before we check st.streamState(2) -- should that happen, we'll
- // see stateClosed and fail the above check.
- close(gotPromise)
- st.wantHeaders()
- if df := st.wantData(); !df.StreamEnded() {
- t.Fatal("expected END_STREAM flag on DATA")
- }
- if got, want := st.streamState(2), stateClosed; got != want {
- t.Fatalf("streamState(2)=%v, want %v", got, want)
- }
- close(finishedPush)
-}
-
-func TestServer_Push_RejectAfterGoAway(t *testing.T) {
- var readyOnce sync.Once
- ready := make(chan struct{})
- errc := make(chan error, 2)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- select {
- case <-ready:
- case <-time.After(5 * time.Second):
- errc <- fmt.Errorf("timeout waiting for GOAWAY to be processed")
- }
- if got, want := w.(http.Pusher).Push("https://"+r.Host+"/pushed", nil), http.ErrNotSupported; got != want {
- errc <- fmt.Errorf("Push()=%v, want %v", got, want)
- }
- errc <- nil
- })
- defer st.Close()
- st.greet()
- getSlash(st)
-
- // Send GOAWAY and wait for it to be processed.
- st.fr.WriteGoAway(1, ErrCodeNo, nil)
- go func() {
- for {
- select {
- case <-ready:
- return
- default:
- }
- st.sc.serveMsgCh <- func(loopNum int) {
- if !st.sc.pushEnabled {
- readyOnce.Do(func() { close(ready) })
- }
- }
- }
- }()
- if err := <-errc; err != nil {
- t.Error(err)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/server_test.go b/vendor/golang.org/x/net/http2/server_test.go
deleted file mode 100644
index 638d2a4a2..000000000
--- a/vendor/golang.org/x/net/http2/server_test.go
+++ /dev/null
@@ -1,3687 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bytes"
- "crypto/tls"
- "errors"
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "net"
- "net/http"
- "net/http/httptest"
- "os"
- "os/exec"
- "reflect"
- "runtime"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "testing"
- "time"
-
- "golang.org/x/net/http2/hpack"
-)
-
-var stderrVerbose = flag.Bool("stderr_verbose", false, "Mirror verbosity to stderr, unbuffered")
-
-func stderrv() io.Writer {
- if *stderrVerbose {
- return os.Stderr
- }
-
- return ioutil.Discard
-}
-
-type serverTester struct {
- cc net.Conn // client conn
- t testing.TB
- ts *httptest.Server
- fr *Framer
- serverLogBuf bytes.Buffer // logger for httptest.Server
- logFilter []string // substrings to filter out
- scMu sync.Mutex // guards sc
- sc *serverConn
- hpackDec *hpack.Decoder
- decodedHeaders [][2]string
-
- // If http2debug!=2, then we capture Frame debug logs that will be written
- // to t.Log after a test fails. The read and write logs use separate locks
- // and buffers so we don't accidentally introduce synchronization between
- // the read and write goroutines, which may hide data races.
- frameReadLogMu sync.Mutex
- frameReadLogBuf bytes.Buffer
- frameWriteLogMu sync.Mutex
- frameWriteLogBuf bytes.Buffer
-
- // writing headers:
- headerBuf bytes.Buffer
- hpackEnc *hpack.Encoder
-}
-
-func init() {
- testHookOnPanicMu = new(sync.Mutex)
-}
-
-func resetHooks() {
- testHookOnPanicMu.Lock()
- testHookOnPanic = nil
- testHookOnPanicMu.Unlock()
-}
-
-type serverTesterOpt string
-
-var optOnlyServer = serverTesterOpt("only_server")
-var optQuiet = serverTesterOpt("quiet_logging")
-var optFramerReuseFrames = serverTesterOpt("frame_reuse_frames")
-
-func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester {
- resetHooks()
-
- ts := httptest.NewUnstartedServer(handler)
-
- tlsConfig := &tls.Config{
- InsecureSkipVerify: true,
- NextProtos: []string{NextProtoTLS},
- }
-
- var onlyServer, quiet, framerReuseFrames bool
- h2server := new(Server)
- for _, opt := range opts {
- switch v := opt.(type) {
- case func(*tls.Config):
- v(tlsConfig)
- case func(*httptest.Server):
- v(ts)
- case func(*Server):
- v(h2server)
- case serverTesterOpt:
- switch v {
- case optOnlyServer:
- onlyServer = true
- case optQuiet:
- quiet = true
- case optFramerReuseFrames:
- framerReuseFrames = true
- }
- case func(net.Conn, http.ConnState):
- ts.Config.ConnState = v
- default:
- t.Fatalf("unknown newServerTester option type %T", v)
- }
- }
-
- ConfigureServer(ts.Config, h2server)
-
- st := &serverTester{
- t: t,
- ts: ts,
- }
- st.hpackEnc = hpack.NewEncoder(&st.headerBuf)
- st.hpackDec = hpack.NewDecoder(initialHeaderTableSize, st.onHeaderField)
-
- ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config
- if quiet {
- ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
- } else {
- ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, &st.serverLogBuf), "", log.LstdFlags)
- }
- ts.StartTLS()
-
- if VerboseLogs {
- t.Logf("Running test server at: %s", ts.URL)
- }
- testHookGetServerConn = func(v *serverConn) {
- st.scMu.Lock()
- defer st.scMu.Unlock()
- st.sc = v
- }
- log.SetOutput(io.MultiWriter(stderrv(), twriter{t: t, st: st}))
- if !onlyServer {
- cc, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig)
- if err != nil {
- t.Fatal(err)
- }
- st.cc = cc
- st.fr = NewFramer(cc, cc)
- if framerReuseFrames {
- st.fr.SetReuseFrames()
- }
- if !logFrameReads && !logFrameWrites {
- st.fr.debugReadLoggerf = func(m string, v ...interface{}) {
- m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
- st.frameReadLogMu.Lock()
- fmt.Fprintf(&st.frameReadLogBuf, m, v...)
- st.frameReadLogMu.Unlock()
- }
- st.fr.debugWriteLoggerf = func(m string, v ...interface{}) {
- m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
- st.frameWriteLogMu.Lock()
- fmt.Fprintf(&st.frameWriteLogBuf, m, v...)
- st.frameWriteLogMu.Unlock()
- }
- st.fr.logReads = true
- st.fr.logWrites = true
- }
- }
- return st
-}
-
-func (st *serverTester) closeConn() {
- st.scMu.Lock()
- defer st.scMu.Unlock()
- st.sc.conn.Close()
-}
-
-func (st *serverTester) addLogFilter(phrase string) {
- st.logFilter = append(st.logFilter, phrase)
-}
-
-func (st *serverTester) stream(id uint32) *stream {
- ch := make(chan *stream, 1)
- st.sc.serveMsgCh <- func(int) {
- ch <- st.sc.streams[id]
- }
- return <-ch
-}
-
-func (st *serverTester) streamState(id uint32) streamState {
- ch := make(chan streamState, 1)
- st.sc.serveMsgCh <- func(int) {
- state, _ := st.sc.state(id)
- ch <- state
- }
- return <-ch
-}
-
-// loopNum reports how many times this conn's select loop has gone around.
-func (st *serverTester) loopNum() int {
- lastc := make(chan int, 1)
- st.sc.serveMsgCh <- func(loopNum int) {
- lastc <- loopNum
- }
- return <-lastc
-}
-
-// awaitIdle heuristically awaits for the server conn's select loop to be idle.
-// The heuristic is that the server connection's serve loop must schedule
-// 50 times in a row without any channel sends or receives occurring.
-func (st *serverTester) awaitIdle() {
- remain := 50
- last := st.loopNum()
- for remain > 0 {
- n := st.loopNum()
- if n == last+1 {
- remain--
- } else {
- remain = 50
- }
- last = n
- }
-}
-
-func (st *serverTester) Close() {
- if st.t.Failed() {
- st.frameReadLogMu.Lock()
- if st.frameReadLogBuf.Len() > 0 {
- st.t.Logf("Framer read log:\n%s", st.frameReadLogBuf.String())
- }
- st.frameReadLogMu.Unlock()
-
- st.frameWriteLogMu.Lock()
- if st.frameWriteLogBuf.Len() > 0 {
- st.t.Logf("Framer write log:\n%s", st.frameWriteLogBuf.String())
- }
- st.frameWriteLogMu.Unlock()
-
- // If we failed already (and are likely in a Fatal,
- // unwindowing), force close the connection, so the
- // httptest.Server doesn't wait forever for the conn
- // to close.
- if st.cc != nil {
- st.cc.Close()
- }
- }
- st.ts.Close()
- if st.cc != nil {
- st.cc.Close()
- }
- log.SetOutput(os.Stderr)
-}
-
-// greet initiates the client's HTTP/2 connection into a state where
-// frames may be sent.
-func (st *serverTester) greet() {
- st.greetAndCheckSettings(func(Setting) error { return nil })
-}
-
-func (st *serverTester) greetAndCheckSettings(checkSetting func(s Setting) error) {
- st.writePreface()
- st.writeInitialSettings()
- st.wantSettings().ForeachSetting(checkSetting)
- st.writeSettingsAck()
-
- // The initial WINDOW_UPDATE and SETTINGS ACK can come in any order.
- var gotSettingsAck bool
- var gotWindowUpdate bool
-
- for i := 0; i < 2; i++ {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatal(err)
- }
- switch f := f.(type) {
- case *SettingsFrame:
- if !f.Header().Flags.Has(FlagSettingsAck) {
- st.t.Fatal("Settings Frame didn't have ACK set")
- }
- gotSettingsAck = true
-
- case *WindowUpdateFrame:
- if f.FrameHeader.StreamID != 0 {
- st.t.Fatalf("WindowUpdate StreamID = %d; want 0", f.FrameHeader.StreamID, 0)
- }
- incr := uint32((&Server{}).initialConnRecvWindowSize() - initialWindowSize)
- if f.Increment != incr {
- st.t.Fatalf("WindowUpdate increment = %d; want %d", f.Increment, incr)
- }
- gotWindowUpdate = true
-
- default:
- st.t.Fatalf("Wanting a settings ACK or window update, received a %T", f)
- }
- }
-
- if !gotSettingsAck {
- st.t.Fatalf("Didn't get a settings ACK")
- }
- if !gotWindowUpdate {
- st.t.Fatalf("Didn't get a window update")
- }
-}
-
-func (st *serverTester) writePreface() {
- n, err := st.cc.Write(clientPreface)
- if err != nil {
- st.t.Fatalf("Error writing client preface: %v", err)
- }
- if n != len(clientPreface) {
- st.t.Fatalf("Writing client preface, wrote %d bytes; want %d", n, len(clientPreface))
- }
-}
-
-func (st *serverTester) writeInitialSettings() {
- if err := st.fr.WriteSettings(); err != nil {
- st.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err)
- }
-}
-
-func (st *serverTester) writeSettingsAck() {
- if err := st.fr.WriteSettingsAck(); err != nil {
- st.t.Fatalf("Error writing ACK of server's SETTINGS: %v", err)
- }
-}
-
-func (st *serverTester) writeHeaders(p HeadersFrameParam) {
- if err := st.fr.WriteHeaders(p); err != nil {
- st.t.Fatalf("Error writing HEADERS: %v", err)
- }
-}
-
-func (st *serverTester) writePriority(id uint32, p PriorityParam) {
- if err := st.fr.WritePriority(id, p); err != nil {
- st.t.Fatalf("Error writing PRIORITY: %v", err)
- }
-}
-
-func (st *serverTester) encodeHeaderField(k, v string) {
- err := st.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
- if err != nil {
- st.t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
- }
-}
-
-// encodeHeaderRaw is the magic-free version of encodeHeader.
-// It takes 0 or more (k, v) pairs and encodes them.
-func (st *serverTester) encodeHeaderRaw(headers ...string) []byte {
- if len(headers)%2 == 1 {
- panic("odd number of kv args")
- }
- st.headerBuf.Reset()
- for len(headers) > 0 {
- k, v := headers[0], headers[1]
- st.encodeHeaderField(k, v)
- headers = headers[2:]
- }
- return st.headerBuf.Bytes()
-}
-
-// encodeHeader encodes headers and returns their HPACK bytes. headers
-// must contain an even number of key/value pairs. There may be
-// multiple pairs for keys (e.g. "cookie"). The :method, :path, and
-// :scheme headers default to GET, / and https. The :authority header
-// defaults to st.ts.Listener.Addr().
-func (st *serverTester) encodeHeader(headers ...string) []byte {
- if len(headers)%2 == 1 {
- panic("odd number of kv args")
- }
-
- st.headerBuf.Reset()
- defaultAuthority := st.ts.Listener.Addr().String()
-
- if len(headers) == 0 {
- // Fast path, mostly for benchmarks, so test code doesn't pollute
- // profiles when we're looking to improve server allocations.
- st.encodeHeaderField(":method", "GET")
- st.encodeHeaderField(":scheme", "https")
- st.encodeHeaderField(":authority", defaultAuthority)
- st.encodeHeaderField(":path", "/")
- return st.headerBuf.Bytes()
- }
-
- if len(headers) == 2 && headers[0] == ":method" {
- // Another fast path for benchmarks.
- st.encodeHeaderField(":method", headers[1])
- st.encodeHeaderField(":scheme", "https")
- st.encodeHeaderField(":authority", defaultAuthority)
- st.encodeHeaderField(":path", "/")
- return st.headerBuf.Bytes()
- }
-
- pseudoCount := map[string]int{}
- keys := []string{":method", ":scheme", ":authority", ":path"}
- vals := map[string][]string{
- ":method": {"GET"},
- ":scheme": {"https"},
- ":authority": {defaultAuthority},
- ":path": {"/"},
- }
- for len(headers) > 0 {
- k, v := headers[0], headers[1]
- headers = headers[2:]
- if _, ok := vals[k]; !ok {
- keys = append(keys, k)
- }
- if strings.HasPrefix(k, ":") {
- pseudoCount[k]++
- if pseudoCount[k] == 1 {
- vals[k] = []string{v}
- } else {
- // Allows testing of invalid headers w/ dup pseudo fields.
- vals[k] = append(vals[k], v)
- }
- } else {
- vals[k] = append(vals[k], v)
- }
- }
- for _, k := range keys {
- for _, v := range vals[k] {
- st.encodeHeaderField(k, v)
- }
- }
- return st.headerBuf.Bytes()
-}
-
-// bodylessReq1 writes a HEADERS frames with StreamID 1 and EndStream and EndHeaders set.
-func (st *serverTester) bodylessReq1(headers ...string) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(headers...),
- EndStream: true,
- EndHeaders: true,
- })
-}
-
-func (st *serverTester) writeData(streamID uint32, endStream bool, data []byte) {
- if err := st.fr.WriteData(streamID, endStream, data); err != nil {
- st.t.Fatalf("Error writing DATA: %v", err)
- }
-}
-
-func (st *serverTester) writeDataPadded(streamID uint32, endStream bool, data, pad []byte) {
- if err := st.fr.WriteDataPadded(streamID, endStream, data, pad); err != nil {
- st.t.Fatalf("Error writing DATA: %v", err)
- }
-}
-
-func readFrameTimeout(fr *Framer, wait time.Duration) (Frame, error) {
- ch := make(chan interface{}, 1)
- go func() {
- fr, err := fr.ReadFrame()
- if err != nil {
- ch <- err
- } else {
- ch <- fr
- }
- }()
- t := time.NewTimer(wait)
- select {
- case v := <-ch:
- t.Stop()
- if fr, ok := v.(Frame); ok {
- return fr, nil
- }
- return nil, v.(error)
- case <-t.C:
- return nil, errors.New("timeout waiting for frame")
- }
-}
-
-func (st *serverTester) readFrame() (Frame, error) {
- return readFrameTimeout(st.fr, 2*time.Second)
-}
-
-func (st *serverTester) wantHeaders() *HeadersFrame {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatalf("Error while expecting a HEADERS frame: %v", err)
- }
- hf, ok := f.(*HeadersFrame)
- if !ok {
- st.t.Fatalf("got a %T; want *HeadersFrame", f)
- }
- return hf
-}
-
-func (st *serverTester) wantContinuation() *ContinuationFrame {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatalf("Error while expecting a CONTINUATION frame: %v", err)
- }
- cf, ok := f.(*ContinuationFrame)
- if !ok {
- st.t.Fatalf("got a %T; want *ContinuationFrame", f)
- }
- return cf
-}
-
-func (st *serverTester) wantData() *DataFrame {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatalf("Error while expecting a DATA frame: %v", err)
- }
- df, ok := f.(*DataFrame)
- if !ok {
- st.t.Fatalf("got a %T; want *DataFrame", f)
- }
- return df
-}
-
-func (st *serverTester) wantSettings() *SettingsFrame {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatalf("Error while expecting a SETTINGS frame: %v", err)
- }
- sf, ok := f.(*SettingsFrame)
- if !ok {
- st.t.Fatalf("got a %T; want *SettingsFrame", f)
- }
- return sf
-}
-
-func (st *serverTester) wantPing() *PingFrame {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatalf("Error while expecting a PING frame: %v", err)
- }
- pf, ok := f.(*PingFrame)
- if !ok {
- st.t.Fatalf("got a %T; want *PingFrame", f)
- }
- return pf
-}
-
-func (st *serverTester) wantGoAway() *GoAwayFrame {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatalf("Error while expecting a GOAWAY frame: %v", err)
- }
- gf, ok := f.(*GoAwayFrame)
- if !ok {
- st.t.Fatalf("got a %T; want *GoAwayFrame", f)
- }
- return gf
-}
-
-func (st *serverTester) wantRSTStream(streamID uint32, errCode ErrCode) {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatalf("Error while expecting an RSTStream frame: %v", err)
- }
- rs, ok := f.(*RSTStreamFrame)
- if !ok {
- st.t.Fatalf("got a %T; want *RSTStreamFrame", f)
- }
- if rs.FrameHeader.StreamID != streamID {
- st.t.Fatalf("RSTStream StreamID = %d; want %d", rs.FrameHeader.StreamID, streamID)
- }
- if rs.ErrCode != errCode {
- st.t.Fatalf("RSTStream ErrCode = %d (%s); want %d (%s)", rs.ErrCode, rs.ErrCode, errCode, errCode)
- }
-}
-
-func (st *serverTester) wantWindowUpdate(streamID, incr uint32) {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatalf("Error while expecting a WINDOW_UPDATE frame: %v", err)
- }
- wu, ok := f.(*WindowUpdateFrame)
- if !ok {
- st.t.Fatalf("got a %T; want *WindowUpdateFrame", f)
- }
- if wu.FrameHeader.StreamID != streamID {
- st.t.Fatalf("WindowUpdate StreamID = %d; want %d", wu.FrameHeader.StreamID, streamID)
- }
- if wu.Increment != incr {
- st.t.Fatalf("WindowUpdate increment = %d; want %d", wu.Increment, incr)
- }
-}
-
-func (st *serverTester) wantSettingsAck() {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatal(err)
- }
- sf, ok := f.(*SettingsFrame)
- if !ok {
- st.t.Fatalf("Wanting a settings ACK, received a %T", f)
- }
- if !sf.Header().Flags.Has(FlagSettingsAck) {
- st.t.Fatal("Settings Frame didn't have ACK set")
- }
-}
-
-func (st *serverTester) wantPushPromise() *PushPromiseFrame {
- f, err := st.readFrame()
- if err != nil {
- st.t.Fatal(err)
- }
- ppf, ok := f.(*PushPromiseFrame)
- if !ok {
- st.t.Fatalf("Wanted PushPromise, received %T", ppf)
- }
- return ppf
-}
-
-func TestServer(t *testing.T) {
- gotReq := make(chan bool, 1)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Foo", "Bar")
- gotReq <- true
- })
- defer st.Close()
-
- covers("3.5", `
- The server connection preface consists of a potentially empty
- SETTINGS frame ([SETTINGS]) that MUST be the first frame the
- server sends in the HTTP/2 connection.
- `)
-
- st.greet()
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(),
- EndStream: true, // no DATA frames
- EndHeaders: true,
- })
-
- select {
- case <-gotReq:
- case <-time.After(2 * time.Second):
- t.Error("timeout waiting for request")
- }
-}
-
-func TestServer_Request_Get(t *testing.T) {
- testServerRequest(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader("foo-bar", "some-value"),
- EndStream: true, // no DATA frames
- EndHeaders: true,
- })
- }, func(r *http.Request) {
- if r.Method != "GET" {
- t.Errorf("Method = %q; want GET", r.Method)
- }
- if r.URL.Path != "/" {
- t.Errorf("URL.Path = %q; want /", r.URL.Path)
- }
- if r.ContentLength != 0 {
- t.Errorf("ContentLength = %v; want 0", r.ContentLength)
- }
- if r.Close {
- t.Error("Close = true; want false")
- }
- if !strings.Contains(r.RemoteAddr, ":") {
- t.Errorf("RemoteAddr = %q; want something with a colon", r.RemoteAddr)
- }
- if r.Proto != "HTTP/2.0" || r.ProtoMajor != 2 || r.ProtoMinor != 0 {
- t.Errorf("Proto = %q Major=%v,Minor=%v; want HTTP/2.0", r.Proto, r.ProtoMajor, r.ProtoMinor)
- }
- wantHeader := http.Header{
- "Foo-Bar": []string{"some-value"},
- }
- if !reflect.DeepEqual(r.Header, wantHeader) {
- t.Errorf("Header = %#v; want %#v", r.Header, wantHeader)
- }
- if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
- t.Errorf("Read = %d, %v; want 0, EOF", n, err)
- }
- })
-}
-
-func TestServer_Request_Get_PathSlashes(t *testing.T) {
- testServerRequest(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":path", "/%2f/"),
- EndStream: true, // no DATA frames
- EndHeaders: true,
- })
- }, func(r *http.Request) {
- if r.RequestURI != "/%2f/" {
- t.Errorf("RequestURI = %q; want /%%2f/", r.RequestURI)
- }
- if r.URL.Path != "///" {
- t.Errorf("URL.Path = %q; want ///", r.URL.Path)
- }
- })
-}
-
-// TODO: add a test with EndStream=true on the HEADERS but setting a
-// Content-Length anyway. Should we just omit it and force it to
-// zero?
-
-func TestServer_Request_Post_NoContentLength_EndStream(t *testing.T) {
- testServerRequest(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: true,
- EndHeaders: true,
- })
- }, func(r *http.Request) {
- if r.Method != "POST" {
- t.Errorf("Method = %q; want POST", r.Method)
- }
- if r.ContentLength != 0 {
- t.Errorf("ContentLength = %v; want 0", r.ContentLength)
- }
- if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 {
- t.Errorf("Read = %d, %v; want 0, EOF", n, err)
- }
- })
-}
-
-func TestServer_Request_Post_Body_ImmediateEOF(t *testing.T) {
- testBodyContents(t, -1, "", func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false, // to say DATA frames are coming
- EndHeaders: true,
- })
- st.writeData(1, true, nil) // just kidding. empty body.
- })
-}
-
-func TestServer_Request_Post_Body_OneData(t *testing.T) {
- const content = "Some content"
- testBodyContents(t, -1, content, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false, // to say DATA frames are coming
- EndHeaders: true,
- })
- st.writeData(1, true, []byte(content))
- })
-}
-
-func TestServer_Request_Post_Body_TwoData(t *testing.T) {
- const content = "Some content"
- testBodyContents(t, -1, content, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false, // to say DATA frames are coming
- EndHeaders: true,
- })
- st.writeData(1, false, []byte(content[:5]))
- st.writeData(1, true, []byte(content[5:]))
- })
-}
-
-func TestServer_Request_Post_Body_ContentLength_Correct(t *testing.T) {
- const content = "Some content"
- testBodyContents(t, int64(len(content)), content, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(
- ":method", "POST",
- "content-length", strconv.Itoa(len(content)),
- ),
- EndStream: false, // to say DATA frames are coming
- EndHeaders: true,
- })
- st.writeData(1, true, []byte(content))
- })
-}
-
-func TestServer_Request_Post_Body_ContentLength_TooLarge(t *testing.T) {
- testBodyContentsFail(t, 3, "request declared a Content-Length of 3 but only wrote 2 bytes",
- func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(
- ":method", "POST",
- "content-length", "3",
- ),
- EndStream: false, // to say DATA frames are coming
- EndHeaders: true,
- })
- st.writeData(1, true, []byte("12"))
- })
-}
-
-func TestServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) {
- testBodyContentsFail(t, 4, "sender tried to send more than declared Content-Length of 4 bytes",
- func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(
- ":method", "POST",
- "content-length", "4",
- ),
- EndStream: false, // to say DATA frames are coming
- EndHeaders: true,
- })
- st.writeData(1, true, []byte("12345"))
- })
-}
-
-func testBodyContents(t *testing.T, wantContentLength int64, wantBody string, write func(st *serverTester)) {
- testServerRequest(t, write, func(r *http.Request) {
- if r.Method != "POST" {
- t.Errorf("Method = %q; want POST", r.Method)
- }
- if r.ContentLength != wantContentLength {
- t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength)
- }
- all, err := ioutil.ReadAll(r.Body)
- if err != nil {
- t.Fatal(err)
- }
- if string(all) != wantBody {
- t.Errorf("Read = %q; want %q", all, wantBody)
- }
- if err := r.Body.Close(); err != nil {
- t.Fatalf("Close: %v", err)
- }
- })
-}
-
-func testBodyContentsFail(t *testing.T, wantContentLength int64, wantReadError string, write func(st *serverTester)) {
- testServerRequest(t, write, func(r *http.Request) {
- if r.Method != "POST" {
- t.Errorf("Method = %q; want POST", r.Method)
- }
- if r.ContentLength != wantContentLength {
- t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength)
- }
- all, err := ioutil.ReadAll(r.Body)
- if err == nil {
- t.Fatalf("expected an error (%q) reading from the body. Successfully read %q instead.",
- wantReadError, all)
- }
- if !strings.Contains(err.Error(), wantReadError) {
- t.Fatalf("Body.Read = %v; want substring %q", err, wantReadError)
- }
- if err := r.Body.Close(); err != nil {
- t.Fatalf("Close: %v", err)
- }
- })
-}
-
-// Using a Host header, instead of :authority
-func TestServer_Request_Get_Host(t *testing.T) {
- const host = "example.com"
- testServerRequest(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":authority", "", "host", host),
- EndStream: true,
- EndHeaders: true,
- })
- }, func(r *http.Request) {
- if r.Host != host {
- t.Errorf("Host = %q; want %q", r.Host, host)
- }
- })
-}
-
-// Using an :authority pseudo-header, instead of Host
-func TestServer_Request_Get_Authority(t *testing.T) {
- const host = "example.com"
- testServerRequest(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":authority", host),
- EndStream: true,
- EndHeaders: true,
- })
- }, func(r *http.Request) {
- if r.Host != host {
- t.Errorf("Host = %q; want %q", r.Host, host)
- }
- })
-}
-
-func TestServer_Request_WithContinuation(t *testing.T) {
- wantHeader := http.Header{
- "Foo-One": []string{"value-one"},
- "Foo-Two": []string{"value-two"},
- "Foo-Three": []string{"value-three"},
- }
- testServerRequest(t, func(st *serverTester) {
- fullHeaders := st.encodeHeader(
- "foo-one", "value-one",
- "foo-two", "value-two",
- "foo-three", "value-three",
- )
- remain := fullHeaders
- chunks := 0
- for len(remain) > 0 {
- const maxChunkSize = 5
- chunk := remain
- if len(chunk) > maxChunkSize {
- chunk = chunk[:maxChunkSize]
- }
- remain = remain[len(chunk):]
-
- if chunks == 0 {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: chunk,
- EndStream: true, // no DATA frames
- EndHeaders: false, // we'll have continuation frames
- })
- } else {
- err := st.fr.WriteContinuation(1, len(remain) == 0, chunk)
- if err != nil {
- t.Fatal(err)
- }
- }
- chunks++
- }
- if chunks < 2 {
- t.Fatal("too few chunks")
- }
- }, func(r *http.Request) {
- if !reflect.DeepEqual(r.Header, wantHeader) {
- t.Errorf("Header = %#v; want %#v", r.Header, wantHeader)
- }
- })
-}
-
-// Concatenated cookie headers. ("8.1.2.5 Compressing the Cookie Header Field")
-func TestServer_Request_CookieConcat(t *testing.T) {
- const host = "example.com"
- testServerRequest(t, func(st *serverTester) {
- st.bodylessReq1(
- ":authority", host,
- "cookie", "a=b",
- "cookie", "c=d",
- "cookie", "e=f",
- )
- }, func(r *http.Request) {
- const want = "a=b; c=d; e=f"
- if got := r.Header.Get("Cookie"); got != want {
- t.Errorf("Cookie = %q; want %q", got, want)
- }
- })
-}
-
-func TestServer_Request_Reject_CapitalHeader(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("UPPER", "v") })
-}
-
-func TestServer_Request_Reject_HeaderFieldNameColon(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has:colon", "v") })
-}
-
-func TestServer_Request_Reject_HeaderFieldNameNULL(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has\x00null", "v") })
-}
-
-func TestServer_Request_Reject_HeaderFieldNameEmpty(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("", "v") })
-}
-
-func TestServer_Request_Reject_HeaderFieldValueNewline(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\nnewline") })
-}
-
-func TestServer_Request_Reject_HeaderFieldValueCR(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\rcarriage") })
-}
-
-func TestServer_Request_Reject_HeaderFieldValueDEL(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\x7fdel") })
-}
-
-func TestServer_Request_Reject_Pseudo_Missing_method(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":method", "") })
-}
-
-func TestServer_Request_Reject_Pseudo_ExactlyOne(t *testing.T) {
- // 8.1.2.3 Request Pseudo-Header Fields
- // "All HTTP/2 requests MUST include exactly one valid value" ...
- testRejectRequest(t, func(st *serverTester) {
- st.addLogFilter("duplicate pseudo-header")
- st.bodylessReq1(":method", "GET", ":method", "POST")
- })
-}
-
-func TestServer_Request_Reject_Pseudo_AfterRegular(t *testing.T) {
- // 8.1.2.3 Request Pseudo-Header Fields
- // "All pseudo-header fields MUST appear in the header block
- // before regular header fields. Any request or response that
- // contains a pseudo-header field that appears in a header
- // block after a regular header field MUST be treated as
- // malformed (Section 8.1.2.6)."
- testRejectRequest(t, func(st *serverTester) {
- st.addLogFilter("pseudo-header after regular header")
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- enc.WriteField(hpack.HeaderField{Name: ":method", Value: "GET"})
- enc.WriteField(hpack.HeaderField{Name: "regular", Value: "foobar"})
- enc.WriteField(hpack.HeaderField{Name: ":path", Value: "/"})
- enc.WriteField(hpack.HeaderField{Name: ":scheme", Value: "https"})
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: buf.Bytes(),
- EndStream: true,
- EndHeaders: true,
- })
- })
-}
-
-func TestServer_Request_Reject_Pseudo_Missing_path(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":path", "") })
-}
-
-func TestServer_Request_Reject_Pseudo_Missing_scheme(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "") })
-}
-
-func TestServer_Request_Reject_Pseudo_scheme_invalid(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "bogus") })
-}
-
-func TestServer_Request_Reject_Pseudo_Unknown(t *testing.T) {
- testRejectRequest(t, func(st *serverTester) {
- st.addLogFilter(`invalid pseudo-header ":unknown_thing"`)
- st.bodylessReq1(":unknown_thing", "")
- })
-}
-
-func testRejectRequest(t *testing.T, send func(*serverTester)) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- t.Error("server request made it to handler; should've been rejected")
- })
- defer st.Close()
-
- st.greet()
- send(st)
- st.wantRSTStream(1, ErrCodeProtocol)
-}
-
-func testRejectRequestWithProtocolError(t *testing.T, send func(*serverTester)) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- t.Error("server request made it to handler; should've been rejected")
- }, optQuiet)
- defer st.Close()
-
- st.greet()
- send(st)
- gf := st.wantGoAway()
- if gf.ErrCode != ErrCodeProtocol {
- t.Errorf("err code = %v; want %v", gf.ErrCode, ErrCodeProtocol)
- }
-}
-
-// Section 5.1, on idle connections: "Receiving any frame other than
-// HEADERS or PRIORITY on a stream in this state MUST be treated as a
-// connection error (Section 5.4.1) of type PROTOCOL_ERROR."
-func TestRejectFrameOnIdle_WindowUpdate(t *testing.T) {
- testRejectRequestWithProtocolError(t, func(st *serverTester) {
- st.fr.WriteWindowUpdate(123, 456)
- })
-}
-func TestRejectFrameOnIdle_Data(t *testing.T) {
- testRejectRequestWithProtocolError(t, func(st *serverTester) {
- st.fr.WriteData(123, true, nil)
- })
-}
-func TestRejectFrameOnIdle_RSTStream(t *testing.T) {
- testRejectRequestWithProtocolError(t, func(st *serverTester) {
- st.fr.WriteRSTStream(123, ErrCodeCancel)
- })
-}
-
-func TestServer_Request_Connect(t *testing.T) {
- testServerRequest(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeaderRaw(
- ":method", "CONNECT",
- ":authority", "example.com:123",
- ),
- EndStream: true,
- EndHeaders: true,
- })
- }, func(r *http.Request) {
- if g, w := r.Method, "CONNECT"; g != w {
- t.Errorf("Method = %q; want %q", g, w)
- }
- if g, w := r.RequestURI, "example.com:123"; g != w {
- t.Errorf("RequestURI = %q; want %q", g, w)
- }
- if g, w := r.URL.Host, "example.com:123"; g != w {
- t.Errorf("URL.Host = %q; want %q", g, w)
- }
- })
-}
-
-func TestServer_Request_Connect_InvalidPath(t *testing.T) {
- testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeaderRaw(
- ":method", "CONNECT",
- ":authority", "example.com:123",
- ":path", "/bogus",
- ),
- EndStream: true,
- EndHeaders: true,
- })
- })
-}
-
-func TestServer_Request_Connect_InvalidScheme(t *testing.T) {
- testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeaderRaw(
- ":method", "CONNECT",
- ":authority", "example.com:123",
- ":scheme", "https",
- ),
- EndStream: true,
- EndHeaders: true,
- })
- })
-}
-
-func TestServer_Ping(t *testing.T) {
- st := newServerTester(t, nil)
- defer st.Close()
- st.greet()
-
- // Server should ignore this one, since it has ACK set.
- ackPingData := [8]byte{1, 2, 4, 8, 16, 32, 64, 128}
- if err := st.fr.WritePing(true, ackPingData); err != nil {
- t.Fatal(err)
- }
-
- // But the server should reply to this one, since ACK is false.
- pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
- if err := st.fr.WritePing(false, pingData); err != nil {
- t.Fatal(err)
- }
-
- pf := st.wantPing()
- if !pf.Flags.Has(FlagPingAck) {
- t.Error("response ping doesn't have ACK set")
- }
- if pf.Data != pingData {
- t.Errorf("response ping has data %q; want %q", pf.Data, pingData)
- }
-}
-
-func TestServer_RejectsLargeFrames(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("see golang.org/issue/13434")
- }
-
- st := newServerTester(t, nil)
- defer st.Close()
- st.greet()
-
- // Write too large of a frame (too large by one byte)
- // We ignore the return value because it's expected that the server
- // will only read the first 9 bytes (the headre) and then disconnect.
- st.fr.WriteRawFrame(0xff, 0, 0, make([]byte, defaultMaxReadFrameSize+1))
-
- gf := st.wantGoAway()
- if gf.ErrCode != ErrCodeFrameSize {
- t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFrameSize)
- }
- if st.serverLogBuf.Len() != 0 {
- // Previously we spun here for a bit until the GOAWAY disconnect
- // timer fired, logging while we fired.
- t.Errorf("unexpected server output: %.500s\n", st.serverLogBuf.Bytes())
- }
-}
-
-func TestServer_Handler_Sends_WindowUpdate(t *testing.T) {
- puppet := newHandlerPuppet()
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- puppet.act(w, r)
- })
- defer st.Close()
- defer puppet.done()
-
- st.greet()
-
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false, // data coming
- EndHeaders: true,
- })
- st.writeData(1, false, []byte("abcdef"))
- puppet.do(readBodyHandler(t, "abc"))
- st.wantWindowUpdate(0, 3)
- st.wantWindowUpdate(1, 3)
-
- puppet.do(readBodyHandler(t, "def"))
- st.wantWindowUpdate(0, 3)
- st.wantWindowUpdate(1, 3)
-
- st.writeData(1, true, []byte("ghijkl")) // END_STREAM here
- puppet.do(readBodyHandler(t, "ghi"))
- puppet.do(readBodyHandler(t, "jkl"))
- st.wantWindowUpdate(0, 3)
- st.wantWindowUpdate(0, 3) // no more stream-level, since END_STREAM
-}
-
-// the version of the TestServer_Handler_Sends_WindowUpdate with padding.
-// See golang.org/issue/16556
-func TestServer_Handler_Sends_WindowUpdate_Padding(t *testing.T) {
- puppet := newHandlerPuppet()
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- puppet.act(w, r)
- })
- defer st.Close()
- defer puppet.done()
-
- st.greet()
-
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false,
- EndHeaders: true,
- })
- st.writeDataPadded(1, false, []byte("abcdef"), []byte{0, 0, 0, 0})
-
- // Expect to immediately get our 5 bytes of padding back for
- // both the connection and stream (4 bytes of padding + 1 byte of length)
- st.wantWindowUpdate(0, 5)
- st.wantWindowUpdate(1, 5)
-
- puppet.do(readBodyHandler(t, "abc"))
- st.wantWindowUpdate(0, 3)
- st.wantWindowUpdate(1, 3)
-
- puppet.do(readBodyHandler(t, "def"))
- st.wantWindowUpdate(0, 3)
- st.wantWindowUpdate(1, 3)
-}
-
-func TestServer_Send_GoAway_After_Bogus_WindowUpdate(t *testing.T) {
- st := newServerTester(t, nil)
- defer st.Close()
- st.greet()
- if err := st.fr.WriteWindowUpdate(0, 1<<31-1); err != nil {
- t.Fatal(err)
- }
- gf := st.wantGoAway()
- if gf.ErrCode != ErrCodeFlowControl {
- t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFlowControl)
- }
- if gf.LastStreamID != 0 {
- t.Errorf("GOAWAY last stream ID = %v; want %v", gf.LastStreamID, 0)
- }
-}
-
-func TestServer_Send_RstStream_After_Bogus_WindowUpdate(t *testing.T) {
- inHandler := make(chan bool)
- blockHandler := make(chan bool)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- inHandler <- true
- <-blockHandler
- })
- defer st.Close()
- defer close(blockHandler)
- st.greet()
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false, // keep it open
- EndHeaders: true,
- })
- <-inHandler
- // Send a bogus window update:
- if err := st.fr.WriteWindowUpdate(1, 1<<31-1); err != nil {
- t.Fatal(err)
- }
- st.wantRSTStream(1, ErrCodeFlowControl)
-}
-
-// testServerPostUnblock sends a hanging POST with unsent data to handler,
-// then runs fn once in the handler, and verifies that the error returned from
-// handler is acceptable. It fails if takes over 5 seconds for handler to exit.
-func testServerPostUnblock(t *testing.T,
- handler func(http.ResponseWriter, *http.Request) error,
- fn func(*serverTester),
- checkErr func(error),
- otherHeaders ...string) {
- inHandler := make(chan bool)
- errc := make(chan error, 1)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- inHandler <- true
- errc <- handler(w, r)
- })
- defer st.Close()
- st.greet()
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(append([]string{":method", "POST"}, otherHeaders...)...),
- EndStream: false, // keep it open
- EndHeaders: true,
- })
- <-inHandler
- fn(st)
- select {
- case err := <-errc:
- if checkErr != nil {
- checkErr(err)
- }
- case <-time.After(5 * time.Second):
- t.Fatal("timeout waiting for Handler to return")
- }
-}
-
-func TestServer_RSTStream_Unblocks_Read(t *testing.T) {
- testServerPostUnblock(t,
- func(w http.ResponseWriter, r *http.Request) (err error) {
- _, err = r.Body.Read(make([]byte, 1))
- return
- },
- func(st *serverTester) {
- if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
- t.Fatal(err)
- }
- },
- func(err error) {
- want := StreamError{StreamID: 0x1, Code: 0x8}
- if !reflect.DeepEqual(err, want) {
- t.Errorf("Read error = %v; want %v", err, want)
- }
- },
- )
-}
-
-func TestServer_RSTStream_Unblocks_Header_Write(t *testing.T) {
- // Run this test a bunch, because it doesn't always
- // deadlock. But with a bunch, it did.
- n := 50
- if testing.Short() {
- n = 5
- }
- for i := 0; i < n; i++ {
- testServer_RSTStream_Unblocks_Header_Write(t)
- }
-}
-
-func testServer_RSTStream_Unblocks_Header_Write(t *testing.T) {
- inHandler := make(chan bool, 1)
- unblockHandler := make(chan bool, 1)
- headerWritten := make(chan bool, 1)
- wroteRST := make(chan bool, 1)
-
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- inHandler <- true
- <-wroteRST
- w.Header().Set("foo", "bar")
- w.WriteHeader(200)
- w.(http.Flusher).Flush()
- headerWritten <- true
- <-unblockHandler
- })
- defer st.Close()
-
- st.greet()
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false, // keep it open
- EndHeaders: true,
- })
- <-inHandler
- if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
- t.Fatal(err)
- }
- wroteRST <- true
- st.awaitIdle()
- select {
- case <-headerWritten:
- case <-time.After(2 * time.Second):
- t.Error("timeout waiting for header write")
- }
- unblockHandler <- true
-}
-
-func TestServer_DeadConn_Unblocks_Read(t *testing.T) {
- testServerPostUnblock(t,
- func(w http.ResponseWriter, r *http.Request) (err error) {
- _, err = r.Body.Read(make([]byte, 1))
- return
- },
- func(st *serverTester) { st.cc.Close() },
- func(err error) {
- if err == nil {
- t.Error("unexpected nil error from Request.Body.Read")
- }
- },
- )
-}
-
-var blockUntilClosed = func(w http.ResponseWriter, r *http.Request) error {
- <-w.(http.CloseNotifier).CloseNotify()
- return nil
-}
-
-func TestServer_CloseNotify_After_RSTStream(t *testing.T) {
- testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) {
- if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
- t.Fatal(err)
- }
- }, nil)
-}
-
-func TestServer_CloseNotify_After_ConnClose(t *testing.T) {
- testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { st.cc.Close() }, nil)
-}
-
-// that CloseNotify unblocks after a stream error due to the client's
-// problem that's unrelated to them explicitly canceling it (which is
-// TestServer_CloseNotify_After_RSTStream above)
-func TestServer_CloseNotify_After_StreamError(t *testing.T) {
- testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) {
- // data longer than declared Content-Length => stream error
- st.writeData(1, true, []byte("1234"))
- }, nil, "content-length", "3")
-}
-
-func TestServer_StateTransitions(t *testing.T) {
- var st *serverTester
- inHandler := make(chan bool)
- writeData := make(chan bool)
- leaveHandler := make(chan bool)
- st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- inHandler <- true
- if st.stream(1) == nil {
- t.Errorf("nil stream 1 in handler")
- }
- if got, want := st.streamState(1), stateOpen; got != want {
- t.Errorf("in handler, state is %v; want %v", got, want)
- }
- writeData <- true
- if n, err := r.Body.Read(make([]byte, 1)); n != 0 || err != io.EOF {
- t.Errorf("body read = %d, %v; want 0, EOF", n, err)
- }
- if got, want := st.streamState(1), stateHalfClosedRemote; got != want {
- t.Errorf("in handler, state is %v; want %v", got, want)
- }
-
- <-leaveHandler
- })
- st.greet()
- if st.stream(1) != nil {
- t.Fatal("stream 1 should be empty")
- }
- if got := st.streamState(1); got != stateIdle {
- t.Fatalf("stream 1 should be idle; got %v", got)
- }
-
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false, // keep it open
- EndHeaders: true,
- })
- <-inHandler
- <-writeData
- st.writeData(1, true, nil)
-
- leaveHandler <- true
- hf := st.wantHeaders()
- if !hf.StreamEnded() {
- t.Fatal("expected END_STREAM flag")
- }
-
- if got, want := st.streamState(1), stateClosed; got != want {
- t.Errorf("at end, state is %v; want %v", got, want)
- }
- if st.stream(1) != nil {
- t.Fatal("at end, stream 1 should be gone")
- }
-}
-
-// test HEADERS w/o EndHeaders + another HEADERS (should get rejected)
-func TestServer_Rejects_HeadersNoEnd_Then_Headers(t *testing.T) {
- testServerRejectsConn(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: false,
- })
- st.writeHeaders(HeadersFrameParam{ // Not a continuation.
- StreamID: 3, // different stream.
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: true,
- })
- })
-}
-
-// test HEADERS w/o EndHeaders + PING (should get rejected)
-func TestServer_Rejects_HeadersNoEnd_Then_Ping(t *testing.T) {
- testServerRejectsConn(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: false,
- })
- if err := st.fr.WritePing(false, [8]byte{}); err != nil {
- t.Fatal(err)
- }
- })
-}
-
-// test HEADERS w/ EndHeaders + a continuation HEADERS (should get rejected)
-func TestServer_Rejects_HeadersEnd_Then_Continuation(t *testing.T) {
- testServerRejectsConn(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: true,
- })
- st.wantHeaders()
- if err := st.fr.WriteContinuation(1, true, encodeHeaderNoImplicit(t, "foo", "bar")); err != nil {
- t.Fatal(err)
- }
- })
-}
-
-// test HEADERS w/o EndHeaders + a continuation HEADERS on wrong stream ID
-func TestServer_Rejects_HeadersNoEnd_Then_ContinuationWrongStream(t *testing.T) {
- testServerRejectsConn(t, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: false,
- })
- if err := st.fr.WriteContinuation(3, true, encodeHeaderNoImplicit(t, "foo", "bar")); err != nil {
- t.Fatal(err)
- }
- })
-}
-
-// No HEADERS on stream 0.
-func TestServer_Rejects_Headers0(t *testing.T) {
- testServerRejectsConn(t, func(st *serverTester) {
- st.fr.AllowIllegalWrites = true
- st.writeHeaders(HeadersFrameParam{
- StreamID: 0,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: true,
- })
- })
-}
-
-// No CONTINUATION on stream 0.
-func TestServer_Rejects_Continuation0(t *testing.T) {
- testServerRejectsConn(t, func(st *serverTester) {
- st.fr.AllowIllegalWrites = true
- if err := st.fr.WriteContinuation(0, true, st.encodeHeader()); err != nil {
- t.Fatal(err)
- }
- })
-}
-
-// No PRIORITY on stream 0.
-func TestServer_Rejects_Priority0(t *testing.T) {
- testServerRejectsConn(t, func(st *serverTester) {
- st.fr.AllowIllegalWrites = true
- st.writePriority(0, PriorityParam{StreamDep: 1})
- })
-}
-
-// No HEADERS frame with a self-dependence.
-func TestServer_Rejects_HeadersSelfDependence(t *testing.T) {
- testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
- st.fr.AllowIllegalWrites = true
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: true,
- Priority: PriorityParam{StreamDep: 1},
- })
- })
-}
-
-// No PRIORTY frame with a self-dependence.
-func TestServer_Rejects_PrioritySelfDependence(t *testing.T) {
- testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
- st.fr.AllowIllegalWrites = true
- st.writePriority(1, PriorityParam{StreamDep: 1})
- })
-}
-
-func TestServer_Rejects_PushPromise(t *testing.T) {
- testServerRejectsConn(t, func(st *serverTester) {
- pp := PushPromiseParam{
- StreamID: 1,
- PromiseID: 3,
- }
- if err := st.fr.WritePushPromise(pp); err != nil {
- t.Fatal(err)
- }
- })
-}
-
-// testServerRejectsConn tests that the server hangs up with a GOAWAY
-// frame and a server close after the client does something
-// deserving a CONNECTION_ERROR.
-func testServerRejectsConn(t *testing.T, writeReq func(*serverTester)) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
- st.addLogFilter("connection error: PROTOCOL_ERROR")
- defer st.Close()
- st.greet()
- writeReq(st)
-
- st.wantGoAway()
- errc := make(chan error, 1)
- go func() {
- fr, err := st.fr.ReadFrame()
- if err == nil {
- err = fmt.Errorf("got frame of type %T", fr)
- }
- errc <- err
- }()
- select {
- case err := <-errc:
- if err != io.EOF {
- t.Errorf("ReadFrame = %v; want io.EOF", err)
- }
- case <-time.After(2 * time.Second):
- t.Error("timeout waiting for disconnect")
- }
-}
-
-// testServerRejectsStream tests that the server sends a RST_STREAM with the provided
-// error code after a client sends a bogus request.
-func testServerRejectsStream(t *testing.T, code ErrCode, writeReq func(*serverTester)) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
- defer st.Close()
- st.greet()
- writeReq(st)
- st.wantRSTStream(1, code)
-}
-
-// testServerRequest sets up an idle HTTP/2 connection and lets you
-// write a single request with writeReq, and then verify that the
-// *http.Request is built correctly in checkReq.
-func testServerRequest(t *testing.T, writeReq func(*serverTester), checkReq func(*http.Request)) {
- gotReq := make(chan bool, 1)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- if r.Body == nil {
- t.Fatal("nil Body")
- }
- checkReq(r)
- gotReq <- true
- })
- defer st.Close()
-
- st.greet()
- writeReq(st)
-
- select {
- case <-gotReq:
- case <-time.After(2 * time.Second):
- t.Error("timeout waiting for request")
- }
-}
-
-func getSlash(st *serverTester) { st.bodylessReq1() }
-
-func TestServer_Response_NoData(t *testing.T) {
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- // Nothing.
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if !hf.StreamEnded() {
- t.Fatal("want END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- })
-}
-
-func TestServer_Response_NoData_Header_FooBar(t *testing.T) {
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.Header().Set("Foo-Bar", "some-value")
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if !hf.StreamEnded() {
- t.Fatal("want END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"foo-bar", "some-value"},
- {"content-type", "text/plain; charset=utf-8"},
- {"content-length", "0"},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
- })
-}
-
-func TestServer_Response_Data_Sniff_DoesntOverride(t *testing.T) {
- const msg = "<html>this is HTML."
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.Header().Set("Content-Type", "foo/bar")
- io.WriteString(w, msg)
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("don't want END_STREAM, expecting data")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"content-type", "foo/bar"},
- {"content-length", strconv.Itoa(len(msg))},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
- df := st.wantData()
- if !df.StreamEnded() {
- t.Error("expected DATA to have END_STREAM flag")
- }
- if got := string(df.Data()); got != msg {
- t.Errorf("got DATA %q; want %q", got, msg)
- }
- })
-}
-
-func TestServer_Response_TransferEncoding_chunked(t *testing.T) {
- const msg = "hi"
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.Header().Set("Transfer-Encoding", "chunked") // should be stripped
- io.WriteString(w, msg)
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"content-type", "text/plain; charset=utf-8"},
- {"content-length", strconv.Itoa(len(msg))},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
- })
-}
-
-// Header accessed only after the initial write.
-func TestServer_Response_Data_IgnoreHeaderAfterWrite_After(t *testing.T) {
- const msg = "<html>this is HTML."
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- io.WriteString(w, msg)
- w.Header().Set("foo", "should be ignored")
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"content-type", "text/html; charset=utf-8"},
- {"content-length", strconv.Itoa(len(msg))},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
- })
-}
-
-// Header accessed before the initial write and later mutated.
-func TestServer_Response_Data_IgnoreHeaderAfterWrite_Overwrite(t *testing.T) {
- const msg = "<html>this is HTML."
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.Header().Set("foo", "proper value")
- io.WriteString(w, msg)
- w.Header().Set("foo", "should be ignored")
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"foo", "proper value"},
- {"content-type", "text/html; charset=utf-8"},
- {"content-length", strconv.Itoa(len(msg))},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
- })
-}
-
-func TestServer_Response_Data_SniffLenType(t *testing.T) {
- const msg = "<html>this is HTML."
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- io.WriteString(w, msg)
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("don't want END_STREAM, expecting data")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"content-type", "text/html; charset=utf-8"},
- {"content-length", strconv.Itoa(len(msg))},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
- df := st.wantData()
- if !df.StreamEnded() {
- t.Error("expected DATA to have END_STREAM flag")
- }
- if got := string(df.Data()); got != msg {
- t.Errorf("got DATA %q; want %q", got, msg)
- }
- })
-}
-
-func TestServer_Response_Header_Flush_MidWrite(t *testing.T) {
- const msg = "<html>this is HTML"
- const msg2 = ", and this is the next chunk"
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- io.WriteString(w, msg)
- w.(http.Flusher).Flush()
- io.WriteString(w, msg2)
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"content-type", "text/html; charset=utf-8"}, // sniffed
- // and no content-length
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
- {
- df := st.wantData()
- if df.StreamEnded() {
- t.Error("unexpected END_STREAM flag")
- }
- if got := string(df.Data()); got != msg {
- t.Errorf("got DATA %q; want %q", got, msg)
- }
- }
- {
- df := st.wantData()
- if !df.StreamEnded() {
- t.Error("wanted END_STREAM flag on last data chunk")
- }
- if got := string(df.Data()); got != msg2 {
- t.Errorf("got DATA %q; want %q", got, msg2)
- }
- }
- })
-}
-
-func TestServer_Response_LargeWrite(t *testing.T) {
- const size = 1 << 20
- const maxFrameSize = 16 << 10
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- n, err := w.Write(bytes.Repeat([]byte("a"), size))
- if err != nil {
- return fmt.Errorf("Write error: %v", err)
- }
- if n != size {
- return fmt.Errorf("wrong size %d from Write", n)
- }
- return nil
- }, func(st *serverTester) {
- if err := st.fr.WriteSettings(
- Setting{SettingInitialWindowSize, 0},
- Setting{SettingMaxFrameSize, maxFrameSize},
- ); err != nil {
- t.Fatal(err)
- }
- st.wantSettingsAck()
-
- getSlash(st) // make the single request
-
- // Give the handler quota to write:
- if err := st.fr.WriteWindowUpdate(1, size); err != nil {
- t.Fatal(err)
- }
- // Give the handler quota to write to connection-level
- // window as well
- if err := st.fr.WriteWindowUpdate(0, size); err != nil {
- t.Fatal(err)
- }
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"content-type", "text/plain; charset=utf-8"}, // sniffed
- // and no content-length
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
- var bytes, frames int
- for {
- df := st.wantData()
- bytes += len(df.Data())
- frames++
- for _, b := range df.Data() {
- if b != 'a' {
- t.Fatal("non-'a' byte seen in DATA")
- }
- }
- if df.StreamEnded() {
- break
- }
- }
- if bytes != size {
- t.Errorf("Got %d bytes; want %d", bytes, size)
- }
- if want := int(size / maxFrameSize); frames < want || frames > want*2 {
- t.Errorf("Got %d frames; want %d", frames, size)
- }
- })
-}
-
-// Test that the handler can't write more than the client allows
-func TestServer_Response_LargeWrite_FlowControlled(t *testing.T) {
- // Make these reads. Before each read, the client adds exactly enough
- // flow-control to satisfy the read. Numbers chosen arbitrarily.
- reads := []int{123, 1, 13, 127}
- size := 0
- for _, n := range reads {
- size += n
- }
-
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.(http.Flusher).Flush()
- n, err := w.Write(bytes.Repeat([]byte("a"), size))
- if err != nil {
- return fmt.Errorf("Write error: %v", err)
- }
- if n != size {
- return fmt.Errorf("wrong size %d from Write", n)
- }
- return nil
- }, func(st *serverTester) {
- // Set the window size to something explicit for this test.
- // It's also how much initial data we expect.
- if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, uint32(reads[0])}); err != nil {
- t.Fatal(err)
- }
- st.wantSettingsAck()
-
- getSlash(st) // make the single request
-
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
-
- df := st.wantData()
- if got := len(df.Data()); got != reads[0] {
- t.Fatalf("Initial window size = %d but got DATA with %d bytes", reads[0], got)
- }
-
- for _, quota := range reads[1:] {
- if err := st.fr.WriteWindowUpdate(1, uint32(quota)); err != nil {
- t.Fatal(err)
- }
- df := st.wantData()
- if int(quota) != len(df.Data()) {
- t.Fatalf("read %d bytes after giving %d quota", len(df.Data()), quota)
- }
- }
- })
-}
-
-// Test that the handler blocked in a Write is unblocked if the server sends a RST_STREAM.
-func TestServer_Response_RST_Unblocks_LargeWrite(t *testing.T) {
- const size = 1 << 20
- const maxFrameSize = 16 << 10
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.(http.Flusher).Flush()
- errc := make(chan error, 1)
- go func() {
- _, err := w.Write(bytes.Repeat([]byte("a"), size))
- errc <- err
- }()
- select {
- case err := <-errc:
- if err == nil {
- return errors.New("unexpected nil error from Write in handler")
- }
- return nil
- case <-time.After(2 * time.Second):
- return errors.New("timeout waiting for Write in handler")
- }
- }, func(st *serverTester) {
- if err := st.fr.WriteSettings(
- Setting{SettingInitialWindowSize, 0},
- Setting{SettingMaxFrameSize, maxFrameSize},
- ); err != nil {
- t.Fatal(err)
- }
- st.wantSettingsAck()
-
- getSlash(st) // make the single request
-
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
-
- if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil {
- t.Fatal(err)
- }
- })
-}
-
-func TestServer_Response_Empty_Data_Not_FlowControlled(t *testing.T) {
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.(http.Flusher).Flush()
- // Nothing; send empty DATA
- return nil
- }, func(st *serverTester) {
- // Handler gets no data quota:
- if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, 0}); err != nil {
- t.Fatal(err)
- }
- st.wantSettingsAck()
-
- getSlash(st) // make the single request
-
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
-
- df := st.wantData()
- if got := len(df.Data()); got != 0 {
- t.Fatalf("unexpected %d DATA bytes; want 0", got)
- }
- if !df.StreamEnded() {
- t.Fatal("DATA didn't have END_STREAM")
- }
- })
-}
-
-func TestServer_Response_Automatic100Continue(t *testing.T) {
- const msg = "foo"
- const reply = "bar"
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- if v := r.Header.Get("Expect"); v != "" {
- t.Errorf("Expect header = %q; want empty", v)
- }
- buf := make([]byte, len(msg))
- // This read should trigger the 100-continue being sent.
- if n, err := io.ReadFull(r.Body, buf); err != nil || n != len(msg) || string(buf) != msg {
- return fmt.Errorf("ReadFull = %q, %v; want %q, nil", buf[:n], err, msg)
- }
- _, err := io.WriteString(w, reply)
- return err
- }, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":method", "POST", "expect", "100-continue"),
- EndStream: false,
- EndHeaders: true,
- })
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "100"},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Fatalf("Got headers %v; want %v", goth, wanth)
- }
-
- // Okay, they sent status 100, so we can send our
- // gigantic and/or sensitive "foo" payload now.
- st.writeData(1, true, []byte(msg))
-
- st.wantWindowUpdate(0, uint32(len(msg)))
-
- hf = st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("expected data to follow")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- goth = st.decodeHeader(hf.HeaderBlockFragment())
- wanth = [][2]string{
- {":status", "200"},
- {"content-type", "text/plain; charset=utf-8"},
- {"content-length", strconv.Itoa(len(reply))},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
-
- df := st.wantData()
- if string(df.Data()) != reply {
- t.Errorf("Client read %q; want %q", df.Data(), reply)
- }
- if !df.StreamEnded() {
- t.Errorf("expect data stream end")
- }
- })
-}
-
-func TestServer_HandlerWriteErrorOnDisconnect(t *testing.T) {
- errc := make(chan error, 1)
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- p := []byte("some data.\n")
- for {
- _, err := w.Write(p)
- if err != nil {
- errc <- err
- return nil
- }
- }
- }, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(),
- EndStream: false,
- EndHeaders: true,
- })
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("unexpected END_STREAM flag")
- }
- if !hf.HeadersEnded() {
- t.Fatal("want END_HEADERS flag")
- }
- // Close the connection and wait for the handler to (hopefully) notice.
- st.cc.Close()
- select {
- case <-errc:
- case <-time.After(5 * time.Second):
- t.Error("timeout")
- }
- })
-}
-
-func TestServer_Rejects_Too_Many_Streams(t *testing.T) {
- const testPath = "/some/path"
-
- inHandler := make(chan uint32)
- leaveHandler := make(chan bool)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- id := w.(*responseWriter).rws.stream.id
- inHandler <- id
- if id == 1+(defaultMaxStreams+1)*2 && r.URL.Path != testPath {
- t.Errorf("decoded final path as %q; want %q", r.URL.Path, testPath)
- }
- <-leaveHandler
- })
- defer st.Close()
- st.greet()
- nextStreamID := uint32(1)
- streamID := func() uint32 {
- defer func() { nextStreamID += 2 }()
- return nextStreamID
- }
- sendReq := func(id uint32, headers ...string) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: id,
- BlockFragment: st.encodeHeader(headers...),
- EndStream: true,
- EndHeaders: true,
- })
- }
- for i := 0; i < defaultMaxStreams; i++ {
- sendReq(streamID())
- <-inHandler
- }
- defer func() {
- for i := 0; i < defaultMaxStreams; i++ {
- leaveHandler <- true
- }
- }()
-
- // And this one should cross the limit:
- // (It's also sent as a CONTINUATION, to verify we still track the decoder context,
- // even if we're rejecting it)
- rejectID := streamID()
- headerBlock := st.encodeHeader(":path", testPath)
- frag1, frag2 := headerBlock[:3], headerBlock[3:]
- st.writeHeaders(HeadersFrameParam{
- StreamID: rejectID,
- BlockFragment: frag1,
- EndStream: true,
- EndHeaders: false, // CONTINUATION coming
- })
- if err := st.fr.WriteContinuation(rejectID, true, frag2); err != nil {
- t.Fatal(err)
- }
- st.wantRSTStream(rejectID, ErrCodeProtocol)
-
- // But let a handler finish:
- leaveHandler <- true
- st.wantHeaders()
-
- // And now another stream should be able to start:
- goodID := streamID()
- sendReq(goodID, ":path", testPath)
- select {
- case got := <-inHandler:
- if got != goodID {
- t.Errorf("Got stream %d; want %d", got, goodID)
- }
- case <-time.After(3 * time.Second):
- t.Error("timeout waiting for handler")
- }
-}
-
-// So many response headers that the server needs to use CONTINUATION frames:
-func TestServer_Response_ManyHeaders_With_Continuation(t *testing.T) {
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- h := w.Header()
- for i := 0; i < 5000; i++ {
- h.Set(fmt.Sprintf("x-header-%d", i), fmt.Sprintf("x-value-%d", i))
- }
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if hf.HeadersEnded() {
- t.Fatal("got unwanted END_HEADERS flag")
- }
- n := 0
- for {
- n++
- cf := st.wantContinuation()
- if cf.HeadersEnded() {
- break
- }
- }
- if n < 5 {
- t.Errorf("Only got %d CONTINUATION frames; expected 5+ (currently 6)", n)
- }
- })
-}
-
-// This previously crashed (reported by Mathieu Lonjaret as observed
-// while using Camlistore) because we got a DATA frame from the client
-// after the handler exited and our logic at the time was wrong,
-// keeping a stream in the map in stateClosed, which tickled an
-// invariant check later when we tried to remove that stream (via
-// defer sc.closeAllStreamsOnConnClose) when the serverConn serve loop
-// ended.
-func TestServer_NoCrash_HandlerClose_Then_ClientClose(t *testing.T) {
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- // nothing
- return nil
- }, func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(),
- EndStream: false, // DATA is coming
- EndHeaders: true,
- })
- hf := st.wantHeaders()
- if !hf.HeadersEnded() || !hf.StreamEnded() {
- t.Fatalf("want END_HEADERS+END_STREAM, got %v", hf)
- }
-
- // Sent when the a Handler closes while a client has
- // indicated it's still sending DATA:
- st.wantRSTStream(1, ErrCodeNo)
-
- // Now the handler has ended, so it's ended its
- // stream, but the client hasn't closed its side
- // (stateClosedLocal). So send more data and verify
- // it doesn't crash with an internal invariant panic, like
- // it did before.
- st.writeData(1, true, []byte("foo"))
-
- // Get our flow control bytes back, since the handler didn't get them.
- st.wantWindowUpdate(0, uint32(len("foo")))
-
- // Sent after a peer sends data anyway (admittedly the
- // previous RST_STREAM might've still been in-flight),
- // but they'll get the more friendly 'cancel' code
- // first.
- st.wantRSTStream(1, ErrCodeStreamClosed)
-
- // Set up a bunch of machinery to record the panic we saw
- // previously.
- var (
- panMu sync.Mutex
- panicVal interface{}
- )
-
- testHookOnPanicMu.Lock()
- testHookOnPanic = func(sc *serverConn, pv interface{}) bool {
- panMu.Lock()
- panicVal = pv
- panMu.Unlock()
- return true
- }
- testHookOnPanicMu.Unlock()
-
- // Now force the serve loop to end, via closing the connection.
- st.cc.Close()
- select {
- case <-st.sc.doneServing:
- // Loop has exited.
- panMu.Lock()
- got := panicVal
- panMu.Unlock()
- if got != nil {
- t.Errorf("Got panic: %v", got)
- }
- case <-time.After(5 * time.Second):
- t.Error("timeout")
- }
- })
-}
-
-func TestServer_Rejects_TLS10(t *testing.T) { testRejectTLS(t, tls.VersionTLS10) }
-func TestServer_Rejects_TLS11(t *testing.T) { testRejectTLS(t, tls.VersionTLS11) }
-
-func testRejectTLS(t *testing.T, max uint16) {
- st := newServerTester(t, nil, func(c *tls.Config) {
- c.MaxVersion = max
- })
- defer st.Close()
- gf := st.wantGoAway()
- if got, want := gf.ErrCode, ErrCodeInadequateSecurity; got != want {
- t.Errorf("Got error code %v; want %v", got, want)
- }
-}
-
-func TestServer_Rejects_TLSBadCipher(t *testing.T) {
- st := newServerTester(t, nil, func(c *tls.Config) {
- // Only list bad ones:
- c.CipherSuites = []uint16{
- tls.TLS_RSA_WITH_RC4_128_SHA,
- tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- tls.TLS_RSA_WITH_AES_128_CBC_SHA,
- tls.TLS_RSA_WITH_AES_256_CBC_SHA,
- tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- cipher_TLS_RSA_WITH_AES_128_CBC_SHA256,
- }
- })
- defer st.Close()
- gf := st.wantGoAway()
- if got, want := gf.ErrCode, ErrCodeInadequateSecurity; got != want {
- t.Errorf("Got error code %v; want %v", got, want)
- }
-}
-
-func TestServer_Advertises_Common_Cipher(t *testing.T) {
- const requiredSuite = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- st := newServerTester(t, nil, func(c *tls.Config) {
- // Have the client only support the one required by the spec.
- c.CipherSuites = []uint16{requiredSuite}
- }, func(ts *httptest.Server) {
- var srv *http.Server = ts.Config
- // Have the server configured with no specific cipher suites.
- // This tests that Go's defaults include the required one.
- srv.TLSConfig = nil
- })
- defer st.Close()
- st.greet()
-}
-
-func (st *serverTester) onHeaderField(f hpack.HeaderField) {
- if f.Name == "date" {
- return
- }
- st.decodedHeaders = append(st.decodedHeaders, [2]string{f.Name, f.Value})
-}
-
-func (st *serverTester) decodeHeader(headerBlock []byte) (pairs [][2]string) {
- st.decodedHeaders = nil
- if _, err := st.hpackDec.Write(headerBlock); err != nil {
- st.t.Fatalf("hpack decoding error: %v", err)
- }
- if err := st.hpackDec.Close(); err != nil {
- st.t.Fatalf("hpack decoding error: %v", err)
- }
- return st.decodedHeaders
-}
-
-// testServerResponse sets up an idle HTTP/2 connection. The client function should
-// write a single request that must be handled by the handler. This waits up to 5s
-// for client to return, then up to an additional 2s for the handler to return.
-func testServerResponse(t testing.TB,
- handler func(http.ResponseWriter, *http.Request) error,
- client func(*serverTester),
-) {
- errc := make(chan error, 1)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- if r.Body == nil {
- t.Fatal("nil Body")
- }
- errc <- handler(w, r)
- })
- defer st.Close()
-
- donec := make(chan bool)
- go func() {
- defer close(donec)
- st.greet()
- client(st)
- }()
-
- select {
- case <-donec:
- case <-time.After(5 * time.Second):
- t.Fatal("timeout in client")
- }
-
- select {
- case err := <-errc:
- if err != nil {
- t.Fatalf("Error in handler: %v", err)
- }
- case <-time.After(2 * time.Second):
- t.Fatal("timeout in handler")
- }
-}
-
-// readBodyHandler returns an http Handler func that reads len(want)
-// bytes from r.Body and fails t if the contents read were not
-// the value of want.
-func readBodyHandler(t *testing.T, want string) func(w http.ResponseWriter, r *http.Request) {
- return func(w http.ResponseWriter, r *http.Request) {
- buf := make([]byte, len(want))
- _, err := io.ReadFull(r.Body, buf)
- if err != nil {
- t.Error(err)
- return
- }
- if string(buf) != want {
- t.Errorf("read %q; want %q", buf, want)
- }
- }
-}
-
-// TestServerWithCurl currently fails, hence the LenientCipherSuites test. See:
-// https://github.com/tatsuhiro-t/nghttp2/issues/140 &
-// http://sourceforge.net/p/curl/bugs/1472/
-func TestServerWithCurl(t *testing.T) { testServerWithCurl(t, false) }
-func TestServerWithCurl_LenientCipherSuites(t *testing.T) { testServerWithCurl(t, true) }
-
-func testServerWithCurl(t *testing.T, permitProhibitedCipherSuites bool) {
- if runtime.GOOS != "linux" {
- t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway")
- }
- if testing.Short() {
- t.Skip("skipping curl test in short mode")
- }
- requireCurl(t)
- var gotConn int32
- testHookOnConn = func() { atomic.StoreInt32(&gotConn, 1) }
-
- const msg = "Hello from curl!\n"
- ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Foo", "Bar")
- w.Header().Set("Client-Proto", r.Proto)
- io.WriteString(w, msg)
- }))
- ConfigureServer(ts.Config, &Server{
- PermitProhibitedCipherSuites: permitProhibitedCipherSuites,
- })
- ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config
- ts.StartTLS()
- defer ts.Close()
-
- t.Logf("Running test server for curl to hit at: %s", ts.URL)
- container := curl(t, "--silent", "--http2", "--insecure", "-v", ts.URL)
- defer kill(container)
- resc := make(chan interface{}, 1)
- go func() {
- res, err := dockerLogs(container)
- if err != nil {
- resc <- err
- } else {
- resc <- res
- }
- }()
- select {
- case res := <-resc:
- if err, ok := res.(error); ok {
- t.Fatal(err)
- }
- body := string(res.([]byte))
- // Search for both "key: value" and "key:value", since curl changed their format
- // Our Dockerfile contains the latest version (no space), but just in case people
- // didn't rebuild, check both.
- if !strings.Contains(body, "foo: Bar") && !strings.Contains(body, "foo:Bar") {
- t.Errorf("didn't see foo: Bar header")
- t.Logf("Got: %s", body)
- }
- if !strings.Contains(body, "client-proto: HTTP/2") && !strings.Contains(body, "client-proto:HTTP/2") {
- t.Errorf("didn't see client-proto: HTTP/2 header")
- t.Logf("Got: %s", res)
- }
- if !strings.Contains(string(res.([]byte)), msg) {
- t.Errorf("didn't see %q content", msg)
- t.Logf("Got: %s", res)
- }
- case <-time.After(3 * time.Second):
- t.Errorf("timeout waiting for curl")
- }
-
- if atomic.LoadInt32(&gotConn) == 0 {
- t.Error("never saw an http2 connection")
- }
-}
-
-var doh2load = flag.Bool("h2load", false, "Run h2load test")
-
-func TestServerWithH2Load(t *testing.T) {
- if !*doh2load {
- t.Skip("Skipping without --h2load flag.")
- }
- if runtime.GOOS != "linux" {
- t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway")
- }
- requireH2load(t)
-
- msg := strings.Repeat("Hello, h2load!\n", 5000)
- ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, msg)
- w.(http.Flusher).Flush()
- io.WriteString(w, msg)
- }))
- ts.StartTLS()
- defer ts.Close()
-
- cmd := exec.Command("docker", "run", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl",
- "-n100000", "-c100", "-m100", ts.URL)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- if err := cmd.Run(); err != nil {
- t.Fatal(err)
- }
-}
-
-// Issue 12843
-func TestServerDoS_MaxHeaderListSize(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})
- defer st.Close()
-
- // shake hands
- frameSize := defaultMaxReadFrameSize
- var advHeaderListSize *uint32
- st.greetAndCheckSettings(func(s Setting) error {
- switch s.ID {
- case SettingMaxFrameSize:
- if s.Val < minMaxFrameSize {
- frameSize = minMaxFrameSize
- } else if s.Val > maxFrameSize {
- frameSize = maxFrameSize
- } else {
- frameSize = int(s.Val)
- }
- case SettingMaxHeaderListSize:
- advHeaderListSize = &s.Val
- }
- return nil
- })
-
- if advHeaderListSize == nil {
- t.Errorf("server didn't advertise a max header list size")
- } else if *advHeaderListSize == 0 {
- t.Errorf("server advertised a max header list size of 0")
- }
-
- st.encodeHeaderField(":method", "GET")
- st.encodeHeaderField(":path", "/")
- st.encodeHeaderField(":scheme", "https")
- cookie := strings.Repeat("*", 4058)
- st.encodeHeaderField("cookie", cookie)
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.headerBuf.Bytes(),
- EndStream: true,
- EndHeaders: false,
- })
-
- // Capture the short encoding of a duplicate ~4K cookie, now
- // that we've already sent it once.
- st.headerBuf.Reset()
- st.encodeHeaderField("cookie", cookie)
-
- // Now send 1MB of it.
- const size = 1 << 20
- b := bytes.Repeat(st.headerBuf.Bytes(), size/st.headerBuf.Len())
- for len(b) > 0 {
- chunk := b
- if len(chunk) > frameSize {
- chunk = chunk[:frameSize]
- }
- b = b[len(chunk):]
- st.fr.WriteContinuation(1, len(b) == 0, chunk)
- }
-
- h := st.wantHeaders()
- if !h.HeadersEnded() {
- t.Fatalf("Got HEADERS without END_HEADERS set: %v", h)
- }
- headers := st.decodeHeader(h.HeaderBlockFragment())
- want := [][2]string{
- {":status", "431"},
- {"content-type", "text/html; charset=utf-8"},
- {"content-length", "63"},
- }
- if !reflect.DeepEqual(headers, want) {
- t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
- }
-}
-
-func TestCompressionErrorOnWrite(t *testing.T) {
- const maxStrLen = 8 << 10
- var serverConfig *http.Server
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- // No response body.
- }, func(ts *httptest.Server) {
- serverConfig = ts.Config
- serverConfig.MaxHeaderBytes = maxStrLen
- })
- st.addLogFilter("connection error: COMPRESSION_ERROR")
- defer st.Close()
- st.greet()
-
- maxAllowed := st.sc.framer.maxHeaderStringLen()
-
- // Crank this up, now that we have a conn connected with the
- // hpack.Decoder's max string length set has been initialized
- // from the earlier low ~8K value. We want this higher so don't
- // hit the max header list size. We only want to test hitting
- // the max string size.
- serverConfig.MaxHeaderBytes = 1 << 20
-
- // First a request with a header that's exactly the max allowed size
- // for the hpack compression. It's still too long for the header list
- // size, so we'll get the 431 error, but that keeps the compression
- // context still valid.
- hbf := st.encodeHeader("foo", strings.Repeat("a", maxAllowed))
-
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: hbf,
- EndStream: true,
- EndHeaders: true,
- })
- h := st.wantHeaders()
- if !h.HeadersEnded() {
- t.Fatalf("Got HEADERS without END_HEADERS set: %v", h)
- }
- headers := st.decodeHeader(h.HeaderBlockFragment())
- want := [][2]string{
- {":status", "431"},
- {"content-type", "text/html; charset=utf-8"},
- {"content-length", "63"},
- }
- if !reflect.DeepEqual(headers, want) {
- t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
- }
- df := st.wantData()
- if !strings.Contains(string(df.Data()), "HTTP Error 431") {
- t.Errorf("Unexpected data body: %q", df.Data())
- }
- if !df.StreamEnded() {
- t.Fatalf("expect data stream end")
- }
-
- // And now send one that's just one byte too big.
- hbf = st.encodeHeader("bar", strings.Repeat("b", maxAllowed+1))
- st.writeHeaders(HeadersFrameParam{
- StreamID: 3,
- BlockFragment: hbf,
- EndStream: true,
- EndHeaders: true,
- })
- ga := st.wantGoAway()
- if ga.ErrCode != ErrCodeCompression {
- t.Errorf("GOAWAY err = %v; want ErrCodeCompression", ga.ErrCode)
- }
-}
-
-func TestCompressionErrorOnClose(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- // No response body.
- })
- st.addLogFilter("connection error: COMPRESSION_ERROR")
- defer st.Close()
- st.greet()
-
- hbf := st.encodeHeader("foo", "bar")
- hbf = hbf[:len(hbf)-1] // truncate one byte from the end, so hpack.Decoder.Close fails.
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: hbf,
- EndStream: true,
- EndHeaders: true,
- })
- ga := st.wantGoAway()
- if ga.ErrCode != ErrCodeCompression {
- t.Errorf("GOAWAY err = %v; want ErrCodeCompression", ga.ErrCode)
- }
-}
-
-// test that a server handler can read trailers from a client
-func TestServerReadsTrailers(t *testing.T) {
- const testBody = "some test body"
- writeReq := func(st *serverTester) {
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader("trailer", "Foo, Bar", "trailer", "Baz"),
- EndStream: false,
- EndHeaders: true,
- })
- st.writeData(1, false, []byte(testBody))
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeaderRaw(
- "foo", "foov",
- "bar", "barv",
- "baz", "bazv",
- "surprise", "wasn't declared; shouldn't show up",
- ),
- EndStream: true,
- EndHeaders: true,
- })
- }
- checkReq := func(r *http.Request) {
- wantTrailer := http.Header{
- "Foo": nil,
- "Bar": nil,
- "Baz": nil,
- }
- if !reflect.DeepEqual(r.Trailer, wantTrailer) {
- t.Errorf("initial Trailer = %v; want %v", r.Trailer, wantTrailer)
- }
- slurp, err := ioutil.ReadAll(r.Body)
- if string(slurp) != testBody {
- t.Errorf("read body %q; want %q", slurp, testBody)
- }
- if err != nil {
- t.Fatalf("Body slurp: %v", err)
- }
- wantTrailerAfter := http.Header{
- "Foo": {"foov"},
- "Bar": {"barv"},
- "Baz": {"bazv"},
- }
- if !reflect.DeepEqual(r.Trailer, wantTrailerAfter) {
- t.Errorf("final Trailer = %v; want %v", r.Trailer, wantTrailerAfter)
- }
- }
- testServerRequest(t, writeReq, checkReq)
-}
-
-// test that a server handler can send trailers
-func TestServerWritesTrailers_WithFlush(t *testing.T) { testServerWritesTrailers(t, true) }
-func TestServerWritesTrailers_WithoutFlush(t *testing.T) { testServerWritesTrailers(t, false) }
-
-func testServerWritesTrailers(t *testing.T, withFlush bool) {
- // See https://httpwg.github.io/specs/rfc7540.html#rfc.section.8.1.3
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
- w.Header().Add("Trailer", "Server-Trailer-C")
- w.Header().Add("Trailer", "Transfer-Encoding, Content-Length, Trailer") // filtered
-
- // Regular headers:
- w.Header().Set("Foo", "Bar")
- w.Header().Set("Content-Length", "5") // len("Hello")
-
- io.WriteString(w, "Hello")
- if withFlush {
- w.(http.Flusher).Flush()
- }
- w.Header().Set("Server-Trailer-A", "valuea")
- w.Header().Set("Server-Trailer-C", "valuec") // skipping B
- // After a flush, random keys like Server-Surprise shouldn't show up:
- w.Header().Set("Server-Surpise", "surprise! this isn't predeclared!")
- // But we do permit promoting keys to trailers after a
- // flush if they start with the magic
- // otherwise-invalid "Trailer:" prefix:
- w.Header().Set("Trailer:Post-Header-Trailer", "hi1")
- w.Header().Set("Trailer:post-header-trailer2", "hi2")
- w.Header().Set("Trailer:Range", "invalid")
- w.Header().Set("Trailer:Foo\x01Bogus", "invalid")
- w.Header().Set("Transfer-Encoding", "should not be included; Forbidden by RFC 2616 14.40")
- w.Header().Set("Content-Length", "should not be included; Forbidden by RFC 2616 14.40")
- w.Header().Set("Trailer", "should not be included; Forbidden by RFC 2616 14.40")
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if hf.StreamEnded() {
- t.Fatal("response HEADERS had END_STREAM")
- }
- if !hf.HeadersEnded() {
- t.Fatal("response HEADERS didn't have END_HEADERS")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"foo", "Bar"},
- {"trailer", "Server-Trailer-A, Server-Trailer-B"},
- {"trailer", "Server-Trailer-C"},
- {"trailer", "Transfer-Encoding, Content-Length, Trailer"},
- {"content-type", "text/plain; charset=utf-8"},
- {"content-length", "5"},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth)
- }
- df := st.wantData()
- if string(df.Data()) != "Hello" {
- t.Fatalf("Client read %q; want Hello", df.Data())
- }
- if df.StreamEnded() {
- t.Fatalf("data frame had STREAM_ENDED")
- }
- tf := st.wantHeaders() // for the trailers
- if !tf.StreamEnded() {
- t.Fatalf("trailers HEADERS lacked END_STREAM")
- }
- if !tf.HeadersEnded() {
- t.Fatalf("trailers HEADERS lacked END_HEADERS")
- }
- wanth = [][2]string{
- {"post-header-trailer", "hi1"},
- {"post-header-trailer2", "hi2"},
- {"server-trailer-a", "valuea"},
- {"server-trailer-c", "valuec"},
- }
- goth = st.decodeHeader(tf.HeaderBlockFragment())
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth)
- }
- })
-}
-
-// validate transmitted header field names & values
-// golang.org/issue/14048
-func TestServerDoesntWriteInvalidHeaders(t *testing.T) {
- testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
- w.Header().Add("OK1", "x")
- w.Header().Add("Bad:Colon", "x") // colon (non-token byte) in key
- w.Header().Add("Bad1\x00", "x") // null in key
- w.Header().Add("Bad2", "x\x00y") // null in value
- return nil
- }, func(st *serverTester) {
- getSlash(st)
- hf := st.wantHeaders()
- if !hf.StreamEnded() {
- t.Error("response HEADERS lacked END_STREAM")
- }
- if !hf.HeadersEnded() {
- t.Fatal("response HEADERS didn't have END_HEADERS")
- }
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "200"},
- {"ok1", "x"},
- {"content-type", "text/plain; charset=utf-8"},
- {"content-length", "0"},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth)
- }
- })
-}
-
-func BenchmarkServerGets(b *testing.B) {
- defer disableGoroutineTracking()()
- b.ReportAllocs()
-
- const msg = "Hello, world"
- st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, msg)
- })
- defer st.Close()
- st.greet()
-
- // Give the server quota to reply. (plus it has the the 64KB)
- if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
- b.Fatal(err)
- }
-
- for i := 0; i < b.N; i++ {
- id := 1 + uint32(i)*2
- st.writeHeaders(HeadersFrameParam{
- StreamID: id,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: true,
- })
- st.wantHeaders()
- df := st.wantData()
- if !df.StreamEnded() {
- b.Fatalf("DATA didn't have END_STREAM; got %v", df)
- }
- }
-}
-
-func BenchmarkServerPosts(b *testing.B) {
- defer disableGoroutineTracking()()
- b.ReportAllocs()
-
- const msg = "Hello, world"
- st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
- // Consume the (empty) body from th peer before replying, otherwise
- // the server will sometimes (depending on scheduling) send the peer a
- // a RST_STREAM with the CANCEL error code.
- if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil {
- b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
- }
- io.WriteString(w, msg)
- })
- defer st.Close()
- st.greet()
-
- // Give the server quota to reply. (plus it has the the 64KB)
- if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
- b.Fatal(err)
- }
-
- for i := 0; i < b.N; i++ {
- id := 1 + uint32(i)*2
- st.writeHeaders(HeadersFrameParam{
- StreamID: id,
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false,
- EndHeaders: true,
- })
- st.writeData(id, true, nil)
- st.wantHeaders()
- df := st.wantData()
- if !df.StreamEnded() {
- b.Fatalf("DATA didn't have END_STREAM; got %v", df)
- }
- }
-}
-
-// Send a stream of messages from server to client in separate data frames.
-// Brings up performance issues seen in long streams.
-// Created to show problem in go issue #18502
-func BenchmarkServerToClientStreamDefaultOptions(b *testing.B) {
- benchmarkServerToClientStream(b)
-}
-
-// Justification for Change-Id: Iad93420ef6c3918f54249d867098f1dadfa324d8
-// Expect to see memory/alloc reduction by opting in to Frame reuse with the Framer.
-func BenchmarkServerToClientStreamReuseFrames(b *testing.B) {
- benchmarkServerToClientStream(b, optFramerReuseFrames)
-}
-
-func benchmarkServerToClientStream(b *testing.B, newServerOpts ...interface{}) {
- defer disableGoroutineTracking()()
- b.ReportAllocs()
- const msgLen = 1
- // default window size
- const windowSize = 1<<16 - 1
-
- // next message to send from the server and for the client to expect
- nextMsg := func(i int) []byte {
- msg := make([]byte, msgLen)
- msg[0] = byte(i)
- if len(msg) != msgLen {
- panic("invalid test setup msg length")
- }
- return msg
- }
-
- st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
- // Consume the (empty) body from th peer before replying, otherwise
- // the server will sometimes (depending on scheduling) send the peer a
- // a RST_STREAM with the CANCEL error code.
- if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil {
- b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
- }
- for i := 0; i < b.N; i += 1 {
- w.Write(nextMsg(i))
- w.(http.Flusher).Flush()
- }
- }, newServerOpts...)
- defer st.Close()
- st.greet()
-
- const id = uint32(1)
-
- st.writeHeaders(HeadersFrameParam{
- StreamID: id,
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false,
- EndHeaders: true,
- })
-
- st.writeData(id, true, nil)
- st.wantHeaders()
-
- var pendingWindowUpdate = uint32(0)
-
- for i := 0; i < b.N; i += 1 {
- expected := nextMsg(i)
- df := st.wantData()
- if bytes.Compare(expected, df.data) != 0 {
- b.Fatalf("Bad message received; want %v; got %v", expected, df.data)
- }
- // try to send infrequent but large window updates so they don't overwhelm the test
- pendingWindowUpdate += uint32(len(df.data))
- if pendingWindowUpdate >= windowSize/2 {
- if err := st.fr.WriteWindowUpdate(0, pendingWindowUpdate); err != nil {
- b.Fatal(err)
- }
- if err := st.fr.WriteWindowUpdate(id, pendingWindowUpdate); err != nil {
- b.Fatal(err)
- }
- pendingWindowUpdate = 0
- }
- }
- df := st.wantData()
- if !df.StreamEnded() {
- b.Fatalf("DATA didn't have END_STREAM; got %v", df)
- }
-}
-
-// go-fuzz bug, originally reported at https://github.com/bradfitz/http2/issues/53
-// Verify we don't hang.
-func TestIssue53(t *testing.T) {
- const data = "PRI * HTTP/2.0\r\n\r\nSM" +
- "\r\n\r\n\x00\x00\x00\x01\ainfinfin\ad"
- s := &http.Server{
- ErrorLog: log.New(io.MultiWriter(stderrv(), twriter{t: t}), "", log.LstdFlags),
- Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- w.Write([]byte("hello"))
- }),
- }
- s2 := &Server{
- MaxReadFrameSize: 1 << 16,
- PermitProhibitedCipherSuites: true,
- }
- c := &issue53Conn{[]byte(data), false, false}
- s2.ServeConn(c, &ServeConnOpts{BaseConfig: s})
- if !c.closed {
- t.Fatal("connection is not closed")
- }
-}
-
-type issue53Conn struct {
- data []byte
- closed bool
- written bool
-}
-
-func (c *issue53Conn) Read(b []byte) (n int, err error) {
- if len(c.data) == 0 {
- return 0, io.EOF
- }
- n = copy(b, c.data)
- c.data = c.data[n:]
- return
-}
-
-func (c *issue53Conn) Write(b []byte) (n int, err error) {
- c.written = true
- return len(b), nil
-}
-
-func (c *issue53Conn) Close() error {
- c.closed = true
- return nil
-}
-
-func (c *issue53Conn) LocalAddr() net.Addr {
- return &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 49706}
-}
-func (c *issue53Conn) RemoteAddr() net.Addr {
- return &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 49706}
-}
-func (c *issue53Conn) SetDeadline(t time.Time) error { return nil }
-func (c *issue53Conn) SetReadDeadline(t time.Time) error { return nil }
-func (c *issue53Conn) SetWriteDeadline(t time.Time) error { return nil }
-
-// golang.org/issue/12895
-func TestConfigureServer(t *testing.T) {
- tests := []struct {
- name string
- tlsConfig *tls.Config
- wantErr string
- }{
- {
- name: "empty server",
- },
- {
- name: "just the required cipher suite",
- tlsConfig: &tls.Config{
- CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- },
- },
- {
- name: "missing required cipher suite",
- tlsConfig: &tls.Config{
- CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
- },
- wantErr: "is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
- },
- {
- name: "required after bad",
- tlsConfig: &tls.Config{
- CipherSuites: []uint16{tls.TLS_RSA_WITH_RC4_128_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- },
- wantErr: "contains an HTTP/2-approved cipher suite (0xc02f), but it comes after",
- },
- {
- name: "bad after required",
- tlsConfig: &tls.Config{
- CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_RC4_128_SHA},
- },
- },
- }
- for _, tt := range tests {
- srv := &http.Server{TLSConfig: tt.tlsConfig}
- err := ConfigureServer(srv, nil)
- if (err != nil) != (tt.wantErr != "") {
- if tt.wantErr != "" {
- t.Errorf("%s: success, but want error", tt.name)
- } else {
- t.Errorf("%s: unexpected error: %v", tt.name, err)
- }
- }
- if err != nil && tt.wantErr != "" && !strings.Contains(err.Error(), tt.wantErr) {
- t.Errorf("%s: err = %v; want substring %q", tt.name, err, tt.wantErr)
- }
- if err == nil && !srv.TLSConfig.PreferServerCipherSuites {
- t.Errorf("%s: PreferServerCipherSuite is false; want true", tt.name)
- }
- }
-}
-
-func TestServerRejectHeadWithBody(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- // No response body.
- })
- defer st.Close()
- st.greet()
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":method", "HEAD"),
- EndStream: false, // what we're testing, a bogus HEAD request with body
- EndHeaders: true,
- })
- st.wantRSTStream(1, ErrCodeProtocol)
-}
-
-func TestServerNoAutoContentLengthOnHead(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- // No response body. (or smaller than one frame)
- })
- defer st.Close()
- st.greet()
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1, // clients send odd numbers
- BlockFragment: st.encodeHeader(":method", "HEAD"),
- EndStream: true,
- EndHeaders: true,
- })
- h := st.wantHeaders()
- headers := st.decodeHeader(h.HeaderBlockFragment())
- want := [][2]string{
- {":status", "200"},
- {"content-type", "text/plain; charset=utf-8"},
- }
- if !reflect.DeepEqual(headers, want) {
- t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
- }
-}
-
-// golang.org/issue/13495
-func TestServerNoDuplicateContentType(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- w.Header()["Content-Type"] = []string{""}
- fmt.Fprintf(w, "<html><head></head><body>hi</body></html>")
- })
- defer st.Close()
- st.greet()
- st.writeHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: true,
- })
- h := st.wantHeaders()
- headers := st.decodeHeader(h.HeaderBlockFragment())
- want := [][2]string{
- {":status", "200"},
- {"content-type", ""},
- {"content-length", "41"},
- }
- if !reflect.DeepEqual(headers, want) {
- t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
- }
-}
-
-func disableGoroutineTracking() (restore func()) {
- old := DebugGoroutines
- DebugGoroutines = false
- return func() { DebugGoroutines = old }
-}
-
-func BenchmarkServer_GetRequest(b *testing.B) {
- defer disableGoroutineTracking()()
- b.ReportAllocs()
- const msg = "Hello, world."
- st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
- n, err := io.Copy(ioutil.Discard, r.Body)
- if err != nil || n > 0 {
- b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err)
- }
- io.WriteString(w, msg)
- })
- defer st.Close()
-
- st.greet()
- // Give the server quota to reply. (plus it has the the 64KB)
- if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
- b.Fatal(err)
- }
- hbf := st.encodeHeader(":method", "GET")
- for i := 0; i < b.N; i++ {
- streamID := uint32(1 + 2*i)
- st.writeHeaders(HeadersFrameParam{
- StreamID: streamID,
- BlockFragment: hbf,
- EndStream: true,
- EndHeaders: true,
- })
- st.wantHeaders()
- st.wantData()
- }
-}
-
-func BenchmarkServer_PostRequest(b *testing.B) {
- defer disableGoroutineTracking()()
- b.ReportAllocs()
- const msg = "Hello, world."
- st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
- n, err := io.Copy(ioutil.Discard, r.Body)
- if err != nil || n > 0 {
- b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err)
- }
- io.WriteString(w, msg)
- })
- defer st.Close()
- st.greet()
- // Give the server quota to reply. (plus it has the the 64KB)
- if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
- b.Fatal(err)
- }
- hbf := st.encodeHeader(":method", "POST")
- for i := 0; i < b.N; i++ {
- streamID := uint32(1 + 2*i)
- st.writeHeaders(HeadersFrameParam{
- StreamID: streamID,
- BlockFragment: hbf,
- EndStream: false,
- EndHeaders: true,
- })
- st.writeData(streamID, true, nil)
- st.wantHeaders()
- st.wantData()
- }
-}
-
-type connStateConn struct {
- net.Conn
- cs tls.ConnectionState
-}
-
-func (c connStateConn) ConnectionState() tls.ConnectionState { return c.cs }
-
-// golang.org/issue/12737 -- handle any net.Conn, not just
-// *tls.Conn.
-func TestServerHandleCustomConn(t *testing.T) {
- var s Server
- c1, c2 := net.Pipe()
- clientDone := make(chan struct{})
- handlerDone := make(chan struct{})
- var req *http.Request
- go func() {
- defer close(clientDone)
- defer c2.Close()
- fr := NewFramer(c2, c2)
- io.WriteString(c2, ClientPreface)
- fr.WriteSettings()
- fr.WriteSettingsAck()
- f, err := fr.ReadFrame()
- if err != nil {
- t.Error(err)
- return
- }
- if sf, ok := f.(*SettingsFrame); !ok || sf.IsAck() {
- t.Errorf("Got %v; want non-ACK SettingsFrame", summarizeFrame(f))
- return
- }
- f, err = fr.ReadFrame()
- if err != nil {
- t.Error(err)
- return
- }
- if sf, ok := f.(*SettingsFrame); !ok || !sf.IsAck() {
- t.Errorf("Got %v; want ACK SettingsFrame", summarizeFrame(f))
- return
- }
- var henc hpackEncoder
- fr.WriteHeaders(HeadersFrameParam{
- StreamID: 1,
- BlockFragment: henc.encodeHeaderRaw(t, ":method", "GET", ":path", "/", ":scheme", "https", ":authority", "foo.com"),
- EndStream: true,
- EndHeaders: true,
- })
- go io.Copy(ioutil.Discard, c2)
- <-handlerDone
- }()
- const testString = "my custom ConnectionState"
- fakeConnState := tls.ConnectionState{
- ServerName: testString,
- Version: tls.VersionTLS12,
- CipherSuite: cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- }
- go s.ServeConn(connStateConn{c1, fakeConnState}, &ServeConnOpts{
- BaseConfig: &http.Server{
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- defer close(handlerDone)
- req = r
- }),
- }})
- select {
- case <-clientDone:
- case <-time.After(5 * time.Second):
- t.Fatal("timeout waiting for handler")
- }
- if req.TLS == nil {
- t.Fatalf("Request.TLS is nil. Got: %#v", req)
- }
- if req.TLS.ServerName != testString {
- t.Fatalf("Request.TLS = %+v; want ServerName of %q", req.TLS, testString)
- }
-}
-
-// golang.org/issue/14214
-func TestServer_Rejects_ConnHeaders(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- t.Error("should not get to Handler")
- })
- defer st.Close()
- st.greet()
- st.bodylessReq1("connection", "foo")
- hf := st.wantHeaders()
- goth := st.decodeHeader(hf.HeaderBlockFragment())
- wanth := [][2]string{
- {":status", "400"},
- {"content-type", "text/plain; charset=utf-8"},
- {"x-content-type-options", "nosniff"},
- {"content-length", "51"},
- }
- if !reflect.DeepEqual(goth, wanth) {
- t.Errorf("Got headers %v; want %v", goth, wanth)
- }
-}
-
-type hpackEncoder struct {
- enc *hpack.Encoder
- buf bytes.Buffer
-}
-
-func (he *hpackEncoder) encodeHeaderRaw(t *testing.T, headers ...string) []byte {
- if len(headers)%2 == 1 {
- panic("odd number of kv args")
- }
- he.buf.Reset()
- if he.enc == nil {
- he.enc = hpack.NewEncoder(&he.buf)
- }
- for len(headers) > 0 {
- k, v := headers[0], headers[1]
- err := he.enc.WriteField(hpack.HeaderField{Name: k, Value: v})
- if err != nil {
- t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err)
- }
- headers = headers[2:]
- }
- return he.buf.Bytes()
-}
-
-func TestCheckValidHTTP2Request(t *testing.T) {
- tests := []struct {
- h http.Header
- want error
- }{
- {
- h: http.Header{"Te": {"trailers"}},
- want: nil,
- },
- {
- h: http.Header{"Te": {"trailers", "bogus"}},
- want: errors.New(`request header "TE" may only be "trailers" in HTTP/2`),
- },
- {
- h: http.Header{"Foo": {""}},
- want: nil,
- },
- {
- h: http.Header{"Connection": {""}},
- want: errors.New(`request header "Connection" is not valid in HTTP/2`),
- },
- {
- h: http.Header{"Proxy-Connection": {""}},
- want: errors.New(`request header "Proxy-Connection" is not valid in HTTP/2`),
- },
- {
- h: http.Header{"Keep-Alive": {""}},
- want: errors.New(`request header "Keep-Alive" is not valid in HTTP/2`),
- },
- {
- h: http.Header{"Upgrade": {""}},
- want: errors.New(`request header "Upgrade" is not valid in HTTP/2`),
- },
- }
- for i, tt := range tests {
- got := checkValidHTTP2RequestHeaders(tt.h)
- if !reflect.DeepEqual(got, tt.want) {
- t.Errorf("%d. checkValidHTTP2Request = %v; want %v", i, got, tt.want)
- }
- }
-}
-
-// golang.org/issue/14030
-func TestExpect100ContinueAfterHandlerWrites(t *testing.T) {
- const msg = "Hello"
- const msg2 = "World"
-
- doRead := make(chan bool, 1)
- defer close(doRead) // fallback cleanup
-
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, msg)
- w.(http.Flusher).Flush()
-
- // Do a read, which might force a 100-continue status to be sent.
- <-doRead
- r.Body.Read(make([]byte, 10))
-
- io.WriteString(w, msg2)
-
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- req, _ := http.NewRequest("POST", st.ts.URL, io.LimitReader(neverEnding('A'), 2<<20))
- req.Header.Set("Expect", "100-continue")
-
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
-
- buf := make([]byte, len(msg))
- if _, err := io.ReadFull(res.Body, buf); err != nil {
- t.Fatal(err)
- }
- if string(buf) != msg {
- t.Fatalf("msg = %q; want %q", buf, msg)
- }
-
- doRead <- true
-
- if _, err := io.ReadFull(res.Body, buf); err != nil {
- t.Fatal(err)
- }
- if string(buf) != msg2 {
- t.Fatalf("second msg = %q; want %q", buf, msg2)
- }
-}
-
-type funcReader func([]byte) (n int, err error)
-
-func (f funcReader) Read(p []byte) (n int, err error) { return f(p) }
-
-// golang.org/issue/16481 -- return flow control when streams close with unread data.
-// (The Server version of the bug. See also TestUnreadFlowControlReturned_Transport)
-func TestUnreadFlowControlReturned_Server(t *testing.T) {
- unblock := make(chan bool, 1)
- defer close(unblock)
-
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- // Don't read the 16KB request body. Wait until the client's
- // done sending it and then return. This should cause the Server
- // to then return those 16KB of flow control to the client.
- <-unblock
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- // This previously hung on the 4th iteration.
- for i := 0; i < 6; i++ {
- body := io.MultiReader(
- io.LimitReader(neverEnding('A'), 16<<10),
- funcReader(func([]byte) (n int, err error) {
- unblock <- true
- return 0, io.EOF
- }),
- )
- req, _ := http.NewRequest("POST", st.ts.URL, body)
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal(err)
- }
- res.Body.Close()
- }
-
-}
-
-func TestServerIdleTimeout(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping in short mode")
- }
-
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- }, func(h2s *Server) {
- h2s.IdleTimeout = 500 * time.Millisecond
- })
- defer st.Close()
-
- st.greet()
- ga := st.wantGoAway()
- if ga.ErrCode != ErrCodeNo {
- t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
- }
-}
-
-func TestServerIdleTimeout_AfterRequest(t *testing.T) {
- if testing.Short() {
- t.Skip("skipping in short mode")
- }
- const timeout = 250 * time.Millisecond
-
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- time.Sleep(timeout * 2)
- }, func(h2s *Server) {
- h2s.IdleTimeout = timeout
- })
- defer st.Close()
-
- st.greet()
-
- // Send a request which takes twice the timeout. Verifies the
- // idle timeout doesn't fire while we're in a request:
- st.bodylessReq1()
- st.wantHeaders()
-
- // But the idle timeout should be rearmed after the request
- // is done:
- ga := st.wantGoAway()
- if ga.ErrCode != ErrCodeNo {
- t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
- }
-}
-
-// grpc-go closes the Request.Body currently with a Read.
-// Verify that it doesn't race.
-// See https://github.com/grpc/grpc-go/pull/938
-func TestRequestBodyReadCloseRace(t *testing.T) {
- for i := 0; i < 100; i++ {
- body := &requestBody{
- pipe: &pipe{
- b: new(bytes.Buffer),
- },
- }
- body.pipe.CloseWithError(io.EOF)
-
- done := make(chan bool, 1)
- buf := make([]byte, 10)
- go func() {
- time.Sleep(1 * time.Millisecond)
- body.Close()
- done <- true
- }()
- body.Read(buf)
- <-done
- }
-}
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
deleted file mode 100644
index 3a85f25a2..000000000
--- a/vendor/golang.org/x/net/http2/transport.go
+++ /dev/null
@@ -1,2123 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Transport code.
-
-package http2
-
-import (
- "bufio"
- "bytes"
- "compress/gzip"
- "crypto/rand"
- "crypto/tls"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "math"
- "net"
- "net/http"
- "sort"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/http2/hpack"
- "golang.org/x/net/idna"
- "golang.org/x/net/lex/httplex"
-)
-
-const (
- // transportDefaultConnFlow is how many connection-level flow control
- // tokens we give the server at start-up, past the default 64k.
- transportDefaultConnFlow = 1 << 30
-
- // transportDefaultStreamFlow is how many stream-level flow
- // control tokens we announce to the peer, and how many bytes
- // we buffer per stream.
- transportDefaultStreamFlow = 4 << 20
-
- // transportDefaultStreamMinRefresh is the minimum number of bytes we'll send
- // a stream-level WINDOW_UPDATE for at a time.
- transportDefaultStreamMinRefresh = 4 << 10
-
- defaultUserAgent = "Go-http-client/2.0"
-)
-
-// Transport is an HTTP/2 Transport.
-//
-// A Transport internally caches connections to servers. It is safe
-// for concurrent use by multiple goroutines.
-type Transport struct {
- // DialTLS specifies an optional dial function for creating
- // TLS connections for requests.
- //
- // If DialTLS is nil, tls.Dial is used.
- //
- // If the returned net.Conn has a ConnectionState method like tls.Conn,
- // it will be used to set http.Response.TLS.
- DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
-
- // TLSClientConfig specifies the TLS configuration to use with
- // tls.Client. If nil, the default configuration is used.
- TLSClientConfig *tls.Config
-
- // ConnPool optionally specifies an alternate connection pool to use.
- // If nil, the default is used.
- ConnPool ClientConnPool
-
- // DisableCompression, if true, prevents the Transport from
- // requesting compression with an "Accept-Encoding: gzip"
- // request header when the Request contains no existing
- // Accept-Encoding value. If the Transport requests gzip on
- // its own and gets a gzipped response, it's transparently
- // decoded in the Response.Body. However, if the user
- // explicitly requested gzip it is not automatically
- // uncompressed.
- DisableCompression bool
-
- // AllowHTTP, if true, permits HTTP/2 requests using the insecure,
- // plain-text "http" scheme. Note that this does not enable h2c support.
- AllowHTTP bool
-
- // MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
- // send in the initial settings frame. It is how many bytes
- // of response headers are allow. Unlike the http2 spec, zero here
- // means to use a default limit (currently 10MB). If you actually
- // want to advertise an ulimited value to the peer, Transport
- // interprets the highest possible value here (0xffffffff or 1<<32-1)
- // to mean no limit.
- MaxHeaderListSize uint32
-
- // t1, if non-nil, is the standard library Transport using
- // this transport. Its settings are used (but not its
- // RoundTrip method, etc).
- t1 *http.Transport
-
- connPoolOnce sync.Once
- connPoolOrDef ClientConnPool // non-nil version of ConnPool
-}
-
-func (t *Transport) maxHeaderListSize() uint32 {
- if t.MaxHeaderListSize == 0 {
- return 10 << 20
- }
- if t.MaxHeaderListSize == 0xffffffff {
- return 0
- }
- return t.MaxHeaderListSize
-}
-
-func (t *Transport) disableCompression() bool {
- return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
-}
-
-var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6")
-
-// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
-// It requires Go 1.6 or later and returns an error if the net/http package is too old
-// or if t1 has already been HTTP/2-enabled.
-func ConfigureTransport(t1 *http.Transport) error {
- _, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go
- return err
-}
-
-func (t *Transport) connPool() ClientConnPool {
- t.connPoolOnce.Do(t.initConnPool)
- return t.connPoolOrDef
-}
-
-func (t *Transport) initConnPool() {
- if t.ConnPool != nil {
- t.connPoolOrDef = t.ConnPool
- } else {
- t.connPoolOrDef = &clientConnPool{t: t}
- }
-}
-
-// ClientConn is the state of a single HTTP/2 client connection to an
-// HTTP/2 server.
-type ClientConn struct {
- t *Transport
- tconn net.Conn // usually *tls.Conn, except specialized impls
- tlsState *tls.ConnectionState // nil only for specialized impls
- singleUse bool // whether being used for a single http.Request
-
- // readLoop goroutine fields:
- readerDone chan struct{} // closed on error
- readerErr error // set before readerDone is closed
-
- idleTimeout time.Duration // or 0 for never
- idleTimer *time.Timer
-
- mu sync.Mutex // guards following
- cond *sync.Cond // hold mu; broadcast on flow/closed changes
- flow flow // our conn-level flow control quota (cs.flow is per stream)
- inflow flow // peer's conn-level flow control
- closed bool
- wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back
- goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received
- goAwayDebug string // goAway frame's debug data, retained as a string
- streams map[uint32]*clientStream // client-initiated
- nextStreamID uint32
- pings map[[8]byte]chan struct{} // in flight ping data to notification channel
- bw *bufio.Writer
- br *bufio.Reader
- fr *Framer
- lastActive time.Time
- // Settings from peer: (also guarded by mu)
- maxFrameSize uint32
- maxConcurrentStreams uint32
- initialWindowSize uint32
-
- hbuf bytes.Buffer // HPACK encoder writes into this
- henc *hpack.Encoder
- freeBuf [][]byte
-
- wmu sync.Mutex // held while writing; acquire AFTER mu if holding both
- werr error // first write error that has occurred
-}
-
-// clientStream is the state for a single HTTP/2 stream. One of these
-// is created for each Transport.RoundTrip call.
-type clientStream struct {
- cc *ClientConn
- req *http.Request
- trace *clientTrace // or nil
- ID uint32
- resc chan resAndError
- bufPipe pipe // buffered pipe with the flow-controlled response payload
- startedWrite bool // started request body write; guarded by cc.mu
- requestedGzip bool
- on100 func() // optional code to run if get a 100 continue response
-
- flow flow // guarded by cc.mu
- inflow flow // guarded by cc.mu
- bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
- readErr error // sticky read error; owned by transportResponseBody.Read
- stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu
- didReset bool // whether we sent a RST_STREAM to the server; guarded by cc.mu
-
- peerReset chan struct{} // closed on peer reset
- resetErr error // populated before peerReset is closed
-
- done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
-
- // owned by clientConnReadLoop:
- firstByte bool // got the first response byte
- pastHeaders bool // got first MetaHeadersFrame (actual headers)
- pastTrailers bool // got optional second MetaHeadersFrame (trailers)
-
- trailer http.Header // accumulated trailers
- resTrailer *http.Header // client's Response.Trailer
-}
-
-// awaitRequestCancel runs in its own goroutine and waits for the user
-// to cancel a RoundTrip request, its context to expire, or for the
-// request to be done (any way it might be removed from the cc.streams
-// map: peer reset, successful completion, TCP connection breakage,
-// etc)
-func (cs *clientStream) awaitRequestCancel(req *http.Request) {
- ctx := reqContext(req)
- if req.Cancel == nil && ctx.Done() == nil {
- return
- }
- select {
- case <-req.Cancel:
- cs.cancelStream()
- cs.bufPipe.CloseWithError(errRequestCanceled)
- case <-ctx.Done():
- cs.cancelStream()
- cs.bufPipe.CloseWithError(ctx.Err())
- case <-cs.done:
- }
-}
-
-func (cs *clientStream) cancelStream() {
- cs.cc.mu.Lock()
- didReset := cs.didReset
- cs.didReset = true
- cs.cc.mu.Unlock()
-
- if !didReset {
- cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- }
-}
-
-// checkResetOrDone reports any error sent in a RST_STREAM frame by the
-// server, or errStreamClosed if the stream is complete.
-func (cs *clientStream) checkResetOrDone() error {
- select {
- case <-cs.peerReset:
- return cs.resetErr
- case <-cs.done:
- return errStreamClosed
- default:
- return nil
- }
-}
-
-func (cs *clientStream) abortRequestBodyWrite(err error) {
- if err == nil {
- panic("nil error")
- }
- cc := cs.cc
- cc.mu.Lock()
- cs.stopReqBody = err
- cc.cond.Broadcast()
- cc.mu.Unlock()
-}
-
-type stickyErrWriter struct {
- w io.Writer
- err *error
-}
-
-func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
- if *sew.err != nil {
- return 0, *sew.err
- }
- n, err = sew.w.Write(p)
- *sew.err = err
- return
-}
-
-var ErrNoCachedConn = errors.New("http2: no cached connection was available")
-
-// RoundTripOpt are options for the Transport.RoundTripOpt method.
-type RoundTripOpt struct {
- // OnlyCachedConn controls whether RoundTripOpt may
- // create a new TCP connection. If set true and
- // no cached connection is available, RoundTripOpt
- // will return ErrNoCachedConn.
- OnlyCachedConn bool
-}
-
-func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
- return t.RoundTripOpt(req, RoundTripOpt{})
-}
-
-// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
-// and returns a host:port. The port 443 is added if needed.
-func authorityAddr(scheme string, authority string) (addr string) {
- host, port, err := net.SplitHostPort(authority)
- if err != nil { // authority didn't have a port
- port = "443"
- if scheme == "http" {
- port = "80"
- }
- host = authority
- }
- if a, err := idna.ToASCII(host); err == nil {
- host = a
- }
- // IPv6 address literal, without a port:
- if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
- return host + ":" + port
- }
- return net.JoinHostPort(host, port)
-}
-
-// RoundTripOpt is like RoundTrip, but takes options.
-func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
- if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
- return nil, errors.New("http2: unsupported scheme")
- }
-
- addr := authorityAddr(req.URL.Scheme, req.URL.Host)
- for {
- cc, err := t.connPool().GetClientConn(req, addr)
- if err != nil {
- t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err)
- return nil, err
- }
- traceGotConn(req, cc)
- res, err := cc.RoundTrip(req)
- if err != nil {
- if req, err = shouldRetryRequest(req, err); err == nil {
- continue
- }
- }
- if err != nil {
- t.vlogf("RoundTrip failure: %v", err)
- return nil, err
- }
- return res, nil
- }
-}
-
-// CloseIdleConnections closes any connections which were previously
-// connected from previous requests but are now sitting idle.
-// It does not interrupt any connections currently in use.
-func (t *Transport) CloseIdleConnections() {
- if cp, ok := t.connPool().(clientConnPoolIdleCloser); ok {
- cp.closeIdleConnections()
- }
-}
-
-var (
- errClientConnClosed = errors.New("http2: client conn is closed")
- errClientConnUnusable = errors.New("http2: client conn not usable")
-
- errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
- errClientConnGotGoAwayAfterSomeReqBody = errors.New("http2: Transport received Server's graceful shutdown GOAWAY; some request body already written")
-)
-
-// shouldRetryRequest is called by RoundTrip when a request fails to get
-// response headers. It is always called with a non-nil error.
-// It returns either a request to retry (either the same request, or a
-// modified clone), or an error if the request can't be replayed.
-func shouldRetryRequest(req *http.Request, err error) (*http.Request, error) {
- switch err {
- default:
- return nil, err
- case errClientConnUnusable, errClientConnGotGoAway:
- return req, nil
- case errClientConnGotGoAwayAfterSomeReqBody:
- // If the Body is nil (or http.NoBody), it's safe to reuse
- // this request and its Body.
- if req.Body == nil || reqBodyIsNoBody(req.Body) {
- return req, nil
- }
- // Otherwise we depend on the Request having its GetBody
- // func defined.
- getBody := reqGetBody(req) // Go 1.8: getBody = req.GetBody
- if getBody == nil {
- return nil, errors.New("http2: Transport: peer server initiated graceful shutdown after some of Request.Body was written; define Request.GetBody to avoid this error")
- }
- body, err := getBody()
- if err != nil {
- return nil, err
- }
- newReq := *req
- newReq.Body = body
- return &newReq, nil
- }
-}
-
-func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, error) {
- host, _, err := net.SplitHostPort(addr)
- if err != nil {
- return nil, err
- }
- tconn, err := t.dialTLS()("tcp", addr, t.newTLSConfig(host))
- if err != nil {
- return nil, err
- }
- return t.newClientConn(tconn, singleUse)
-}
-
-func (t *Transport) newTLSConfig(host string) *tls.Config {
- cfg := new(tls.Config)
- if t.TLSClientConfig != nil {
- *cfg = *cloneTLSConfig(t.TLSClientConfig)
- }
- if !strSliceContains(cfg.NextProtos, NextProtoTLS) {
- cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)
- }
- if cfg.ServerName == "" {
- cfg.ServerName = host
- }
- return cfg
-}
-
-func (t *Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) {
- if t.DialTLS != nil {
- return t.DialTLS
- }
- return t.dialTLSDefault
-}
-
-func (t *Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) {
- cn, err := tls.Dial(network, addr, cfg)
- if err != nil {
- return nil, err
- }
- if err := cn.Handshake(); err != nil {
- return nil, err
- }
- if !cfg.InsecureSkipVerify {
- if err := cn.VerifyHostname(cfg.ServerName); err != nil {
- return nil, err
- }
- }
- state := cn.ConnectionState()
- if p := state.NegotiatedProtocol; p != NextProtoTLS {
- return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS)
- }
- if !state.NegotiatedProtocolIsMutual {
- return nil, errors.New("http2: could not negotiate protocol mutually")
- }
- return cn, nil
-}
-
-// disableKeepAlives reports whether connections should be closed as
-// soon as possible after handling the first request.
-func (t *Transport) disableKeepAlives() bool {
- return t.t1 != nil && t.t1.DisableKeepAlives
-}
-
-func (t *Transport) expectContinueTimeout() time.Duration {
- if t.t1 == nil {
- return 0
- }
- return transportExpectContinueTimeout(t.t1)
-}
-
-func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
- return t.newClientConn(c, false)
-}
-
-func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {
- cc := &ClientConn{
- t: t,
- tconn: c,
- readerDone: make(chan struct{}),
- nextStreamID: 1,
- maxFrameSize: 16 << 10, // spec default
- initialWindowSize: 65535, // spec default
- maxConcurrentStreams: 1000, // "infinite", per spec. 1000 seems good enough.
- streams: make(map[uint32]*clientStream),
- singleUse: singleUse,
- wantSettingsAck: true,
- pings: make(map[[8]byte]chan struct{}),
- }
- if d := t.idleConnTimeout(); d != 0 {
- cc.idleTimeout = d
- cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
- }
- if VerboseLogs {
- t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
- }
-
- cc.cond = sync.NewCond(&cc.mu)
- cc.flow.add(int32(initialWindowSize))
-
- // TODO: adjust this writer size to account for frame size +
- // MTU + crypto/tls record padding.
- cc.bw = bufio.NewWriter(stickyErrWriter{c, &cc.werr})
- cc.br = bufio.NewReader(c)
- cc.fr = NewFramer(cc.bw, cc.br)
- cc.fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
- cc.fr.MaxHeaderListSize = t.maxHeaderListSize()
-
- // TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on
- // henc in response to SETTINGS frames?
- cc.henc = hpack.NewEncoder(&cc.hbuf)
-
- if cs, ok := c.(connectionStater); ok {
- state := cs.ConnectionState()
- cc.tlsState = &state
- }
-
- initialSettings := []Setting{
- {ID: SettingEnablePush, Val: 0},
- {ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow},
- }
- if max := t.maxHeaderListSize(); max != 0 {
- initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max})
- }
-
- cc.bw.Write(clientPreface)
- cc.fr.WriteSettings(initialSettings...)
- cc.fr.WriteWindowUpdate(0, transportDefaultConnFlow)
- cc.inflow.add(transportDefaultConnFlow + initialWindowSize)
- cc.bw.Flush()
- if cc.werr != nil {
- return nil, cc.werr
- }
-
- go cc.readLoop()
- return cc, nil
-}
-
-func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- old := cc.goAway
- cc.goAway = f
-
- // Merge the previous and current GoAway error frames.
- if cc.goAwayDebug == "" {
- cc.goAwayDebug = string(f.DebugData())
- }
- if old != nil && old.ErrCode != ErrCodeNo {
- cc.goAway.ErrCode = old.ErrCode
- }
- last := f.LastStreamID
- for streamID, cs := range cc.streams {
- if streamID > last {
- select {
- case cs.resc <- resAndError{err: errClientConnGotGoAway}:
- default:
- }
- }
- }
-}
-
-func (cc *ClientConn) CanTakeNewRequest() bool {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- return cc.canTakeNewRequestLocked()
-}
-
-func (cc *ClientConn) canTakeNewRequestLocked() bool {
- if cc.singleUse && cc.nextStreamID > 1 {
- return false
- }
- return cc.goAway == nil && !cc.closed &&
- int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) &&
- cc.nextStreamID < math.MaxInt32
-}
-
-// onIdleTimeout is called from a time.AfterFunc goroutine. It will
-// only be called when we're idle, but because we're coming from a new
-// goroutine, there could be a new request coming in at the same time,
-// so this simply calls the synchronized closeIfIdle to shut down this
-// connection. The timer could just call closeIfIdle, but this is more
-// clear.
-func (cc *ClientConn) onIdleTimeout() {
- cc.closeIfIdle()
-}
-
-func (cc *ClientConn) closeIfIdle() {
- cc.mu.Lock()
- if len(cc.streams) > 0 {
- cc.mu.Unlock()
- return
- }
- cc.closed = true
- nextID := cc.nextStreamID
- // TODO: do clients send GOAWAY too? maybe? Just Close:
- cc.mu.Unlock()
-
- if VerboseLogs {
- cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2)
- }
- cc.tconn.Close()
-}
-
-const maxAllocFrameSize = 512 << 10
-
-// frameBuffer returns a scratch buffer suitable for writing DATA frames.
-// They're capped at the min of the peer's max frame size or 512KB
-// (kinda arbitrarily), but definitely capped so we don't allocate 4GB
-// bufers.
-func (cc *ClientConn) frameScratchBuffer() []byte {
- cc.mu.Lock()
- size := cc.maxFrameSize
- if size > maxAllocFrameSize {
- size = maxAllocFrameSize
- }
- for i, buf := range cc.freeBuf {
- if len(buf) >= int(size) {
- cc.freeBuf[i] = nil
- cc.mu.Unlock()
- return buf[:size]
- }
- }
- cc.mu.Unlock()
- return make([]byte, size)
-}
-
-func (cc *ClientConn) putFrameScratchBuffer(buf []byte) {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- const maxBufs = 4 // arbitrary; 4 concurrent requests per conn? investigate.
- if len(cc.freeBuf) < maxBufs {
- cc.freeBuf = append(cc.freeBuf, buf)
- return
- }
- for i, old := range cc.freeBuf {
- if old == nil {
- cc.freeBuf[i] = buf
- return
- }
- }
- // forget about it.
-}
-
-// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
-// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.
-var errRequestCanceled = errors.New("net/http: request canceled")
-
-func commaSeparatedTrailers(req *http.Request) (string, error) {
- keys := make([]string, 0, len(req.Trailer))
- for k := range req.Trailer {
- k = http.CanonicalHeaderKey(k)
- switch k {
- case "Transfer-Encoding", "Trailer", "Content-Length":
- return "", &badStringError{"invalid Trailer key", k}
- }
- keys = append(keys, k)
- }
- if len(keys) > 0 {
- sort.Strings(keys)
- return strings.Join(keys, ","), nil
- }
- return "", nil
-}
-
-func (cc *ClientConn) responseHeaderTimeout() time.Duration {
- if cc.t.t1 != nil {
- return cc.t.t1.ResponseHeaderTimeout
- }
- // No way to do this (yet?) with just an http2.Transport. Probably
- // no need. Request.Cancel this is the new way. We only need to support
- // this for compatibility with the old http.Transport fields when
- // we're doing transparent http2.
- return 0
-}
-
-// checkConnHeaders checks whether req has any invalid connection-level headers.
-// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields.
-// Certain headers are special-cased as okay but not transmitted later.
-func checkConnHeaders(req *http.Request) error {
- if v := req.Header.Get("Upgrade"); v != "" {
- return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"])
- }
- if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
- return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv)
- }
- if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "close" && vv[0] != "keep-alive") {
- return fmt.Errorf("http2: invalid Connection request header: %q", vv)
- }
- return nil
-}
-
-// actualContentLength returns a sanitized version of
-// req.ContentLength, where 0 actually means zero (not unknown) and -1
-// means unknown.
-func actualContentLength(req *http.Request) int64 {
- if req.Body == nil {
- return 0
- }
- if req.ContentLength != 0 {
- return req.ContentLength
- }
- return -1
-}
-
-func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
- if err := checkConnHeaders(req); err != nil {
- return nil, err
- }
- if cc.idleTimer != nil {
- cc.idleTimer.Stop()
- }
-
- trailers, err := commaSeparatedTrailers(req)
- if err != nil {
- return nil, err
- }
- hasTrailers := trailers != ""
-
- cc.mu.Lock()
- cc.lastActive = time.Now()
- if cc.closed || !cc.canTakeNewRequestLocked() {
- cc.mu.Unlock()
- return nil, errClientConnUnusable
- }
-
- body := req.Body
- hasBody := body != nil
- contentLen := actualContentLength(req)
-
- // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
- var requestedGzip bool
- if !cc.t.disableCompression() &&
- req.Header.Get("Accept-Encoding") == "" &&
- req.Header.Get("Range") == "" &&
- req.Method != "HEAD" {
- // Request gzip only, not deflate. Deflate is ambiguous and
- // not as universally supported anyway.
- // See: http://www.gzip.org/zlib/zlib_faq.html#faq38
- //
- // Note that we don't request this for HEAD requests,
- // due to a bug in nginx:
- // http://trac.nginx.org/nginx/ticket/358
- // https://golang.org/issue/5522
- //
- // We don't request gzip if the request is for a range, since
- // auto-decoding a portion of a gzipped document will just fail
- // anyway. See https://golang.org/issue/8923
- requestedGzip = true
- }
-
- // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
- // sent by writeRequestBody below, along with any Trailers,
- // again in form HEADERS{1}, CONTINUATION{0,})
- hdrs, err := cc.encodeHeaders(req, requestedGzip, trailers, contentLen)
- if err != nil {
- cc.mu.Unlock()
- return nil, err
- }
-
- cs := cc.newStream()
- cs.req = req
- cs.trace = requestTrace(req)
- cs.requestedGzip = requestedGzip
- bodyWriter := cc.t.getBodyWriterState(cs, body)
- cs.on100 = bodyWriter.on100
-
- cc.wmu.Lock()
- endStream := !hasBody && !hasTrailers
- werr := cc.writeHeaders(cs.ID, endStream, hdrs)
- cc.wmu.Unlock()
- traceWroteHeaders(cs.trace)
- cc.mu.Unlock()
-
- if werr != nil {
- if hasBody {
- req.Body.Close() // per RoundTripper contract
- bodyWriter.cancel()
- }
- cc.forgetStreamID(cs.ID)
- // Don't bother sending a RST_STREAM (our write already failed;
- // no need to keep writing)
- traceWroteRequest(cs.trace, werr)
- return nil, werr
- }
-
- var respHeaderTimer <-chan time.Time
- if hasBody {
- bodyWriter.scheduleBodyWrite()
- } else {
- traceWroteRequest(cs.trace, nil)
- if d := cc.responseHeaderTimeout(); d != 0 {
- timer := time.NewTimer(d)
- defer timer.Stop()
- respHeaderTimer = timer.C
- }
- }
-
- readLoopResCh := cs.resc
- bodyWritten := false
- ctx := reqContext(req)
-
- handleReadLoopResponse := func(re resAndError) (*http.Response, error) {
- res := re.res
- if re.err != nil || res.StatusCode > 299 {
- // On error or status code 3xx, 4xx, 5xx, etc abort any
- // ongoing write, assuming that the server doesn't care
- // about our request body. If the server replied with 1xx or
- // 2xx, however, then assume the server DOES potentially
- // want our body (e.g. full-duplex streaming:
- // golang.org/issue/13444). If it turns out the server
- // doesn't, they'll RST_STREAM us soon enough. This is a
- // heuristic to avoid adding knobs to Transport. Hopefully
- // we can keep it.
- bodyWriter.cancel()
- cs.abortRequestBodyWrite(errStopReqBodyWrite)
- }
- if re.err != nil {
- if re.err == errClientConnGotGoAway {
- cc.mu.Lock()
- if cs.startedWrite {
- re.err = errClientConnGotGoAwayAfterSomeReqBody
- }
- cc.mu.Unlock()
- }
- cc.forgetStreamID(cs.ID)
- return nil, re.err
- }
- res.Request = req
- res.TLS = cc.tlsState
- return res, nil
- }
-
- for {
- select {
- case re := <-readLoopResCh:
- return handleReadLoopResponse(re)
- case <-respHeaderTimer:
- cc.forgetStreamID(cs.ID)
- if !hasBody || bodyWritten {
- cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- } else {
- bodyWriter.cancel()
- cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
- }
- return nil, errTimeout
- case <-ctx.Done():
- cc.forgetStreamID(cs.ID)
- if !hasBody || bodyWritten {
- cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- } else {
- bodyWriter.cancel()
- cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
- }
- return nil, ctx.Err()
- case <-req.Cancel:
- cc.forgetStreamID(cs.ID)
- if !hasBody || bodyWritten {
- cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- } else {
- bodyWriter.cancel()
- cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel)
- }
- return nil, errRequestCanceled
- case <-cs.peerReset:
- // processResetStream already removed the
- // stream from the streams map; no need for
- // forgetStreamID.
- return nil, cs.resetErr
- case err := <-bodyWriter.resc:
- // Prefer the read loop's response, if available. Issue 16102.
- select {
- case re := <-readLoopResCh:
- return handleReadLoopResponse(re)
- default:
- }
- if err != nil {
- return nil, err
- }
- bodyWritten = true
- if d := cc.responseHeaderTimeout(); d != 0 {
- timer := time.NewTimer(d)
- defer timer.Stop()
- respHeaderTimer = timer.C
- }
- }
- }
-}
-
-// requires cc.wmu be held
-func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error {
- first := true // first frame written (HEADERS is first, then CONTINUATION)
- frameSize := int(cc.maxFrameSize)
- for len(hdrs) > 0 && cc.werr == nil {
- chunk := hdrs
- if len(chunk) > frameSize {
- chunk = chunk[:frameSize]
- }
- hdrs = hdrs[len(chunk):]
- endHeaders := len(hdrs) == 0
- if first {
- cc.fr.WriteHeaders(HeadersFrameParam{
- StreamID: streamID,
- BlockFragment: chunk,
- EndStream: endStream,
- EndHeaders: endHeaders,
- })
- first = false
- } else {
- cc.fr.WriteContinuation(streamID, endHeaders, chunk)
- }
- }
- // TODO(bradfitz): this Flush could potentially block (as
- // could the WriteHeaders call(s) above), which means they
- // wouldn't respond to Request.Cancel being readable. That's
- // rare, but this should probably be in a goroutine.
- cc.bw.Flush()
- return cc.werr
-}
-
-// internal error values; they don't escape to callers
-var (
- // abort request body write; don't send cancel
- errStopReqBodyWrite = errors.New("http2: aborting request body write")
-
- // abort request body write, but send stream reset of cancel.
- errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
-)
-
-func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) {
- cc := cs.cc
- sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
- buf := cc.frameScratchBuffer()
- defer cc.putFrameScratchBuffer(buf)
-
- defer func() {
- traceWroteRequest(cs.trace, err)
- // TODO: write h12Compare test showing whether
- // Request.Body is closed by the Transport,
- // and in multiple cases: server replies <=299 and >299
- // while still writing request body
- cerr := bodyCloser.Close()
- if err == nil {
- err = cerr
- }
- }()
-
- req := cs.req
- hasTrailers := req.Trailer != nil
-
- var sawEOF bool
- for !sawEOF {
- n, err := body.Read(buf)
- if err == io.EOF {
- sawEOF = true
- err = nil
- } else if err != nil {
- return err
- }
-
- remain := buf[:n]
- for len(remain) > 0 && err == nil {
- var allowed int32
- allowed, err = cs.awaitFlowControl(len(remain))
- switch {
- case err == errStopReqBodyWrite:
- return err
- case err == errStopReqBodyWriteAndCancel:
- cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
- return err
- case err != nil:
- return err
- }
- cc.wmu.Lock()
- data := remain[:allowed]
- remain = remain[allowed:]
- sentEnd = sawEOF && len(remain) == 0 && !hasTrailers
- err = cc.fr.WriteData(cs.ID, sentEnd, data)
- if err == nil {
- // TODO(bradfitz): this flush is for latency, not bandwidth.
- // Most requests won't need this. Make this opt-in or
- // opt-out? Use some heuristic on the body type? Nagel-like
- // timers? Based on 'n'? Only last chunk of this for loop,
- // unless flow control tokens are low? For now, always.
- // If we change this, see comment below.
- err = cc.bw.Flush()
- }
- cc.wmu.Unlock()
- }
- if err != nil {
- return err
- }
- }
-
- if sentEnd {
- // Already sent END_STREAM (which implies we have no
- // trailers) and flushed, because currently all
- // WriteData frames above get a flush. So we're done.
- return nil
- }
-
- var trls []byte
- if hasTrailers {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- trls = cc.encodeTrailers(req)
- }
-
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
-
- // Two ways to send END_STREAM: either with trailers, or
- // with an empty DATA frame.
- if len(trls) > 0 {
- err = cc.writeHeaders(cs.ID, true, trls)
- } else {
- err = cc.fr.WriteData(cs.ID, true, nil)
- }
- if ferr := cc.bw.Flush(); ferr != nil && err == nil {
- err = ferr
- }
- return err
-}
-
-// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow
-// control tokens from the server.
-// It returns either the non-zero number of tokens taken or an error
-// if the stream is dead.
-func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
- cc := cs.cc
- cc.mu.Lock()
- defer cc.mu.Unlock()
- for {
- if cc.closed {
- return 0, errClientConnClosed
- }
- if cs.stopReqBody != nil {
- return 0, cs.stopReqBody
- }
- if err := cs.checkResetOrDone(); err != nil {
- return 0, err
- }
- if a := cs.flow.available(); a > 0 {
- take := a
- if int(take) > maxBytes {
-
- take = int32(maxBytes) // can't truncate int; take is int32
- }
- if take > int32(cc.maxFrameSize) {
- take = int32(cc.maxFrameSize)
- }
- cs.flow.take(take)
- return take, nil
- }
- cc.cond.Wait()
- }
-}
-
-type badStringError struct {
- what string
- str string
-}
-
-func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
-
-// requires cc.mu be held.
-func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) {
- cc.hbuf.Reset()
-
- host := req.Host
- if host == "" {
- host = req.URL.Host
- }
- host, err := httplex.PunycodeHostPort(host)
- if err != nil {
- return nil, err
- }
-
- var path string
- if req.Method != "CONNECT" {
- path = req.URL.RequestURI()
- if !validPseudoPath(path) {
- orig := path
- path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host)
- if !validPseudoPath(path) {
- if req.URL.Opaque != "" {
- return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque)
- } else {
- return nil, fmt.Errorf("invalid request :path %q", orig)
- }
- }
- }
- }
-
- // Check for any invalid headers and return an error before we
- // potentially pollute our hpack state. (We want to be able to
- // continue to reuse the hpack encoder for future requests)
- for k, vv := range req.Header {
- if !httplex.ValidHeaderFieldName(k) {
- return nil, fmt.Errorf("invalid HTTP header name %q", k)
- }
- for _, v := range vv {
- if !httplex.ValidHeaderFieldValue(v) {
- return nil, fmt.Errorf("invalid HTTP header value %q for header %q", v, k)
- }
- }
- }
-
- // 8.1.2.3 Request Pseudo-Header Fields
- // The :path pseudo-header field includes the path and query parts of the
- // target URI (the path-absolute production and optionally a '?' character
- // followed by the query production (see Sections 3.3 and 3.4 of
- // [RFC3986]).
- cc.writeHeader(":authority", host)
- cc.writeHeader(":method", req.Method)
- if req.Method != "CONNECT" {
- cc.writeHeader(":path", path)
- cc.writeHeader(":scheme", req.URL.Scheme)
- }
- if trailers != "" {
- cc.writeHeader("trailer", trailers)
- }
-
- var didUA bool
- for k, vv := range req.Header {
- lowKey := strings.ToLower(k)
- switch lowKey {
- case "host", "content-length":
- // Host is :authority, already sent.
- // Content-Length is automatic, set below.
- continue
- case "connection", "proxy-connection", "transfer-encoding", "upgrade", "keep-alive":
- // Per 8.1.2.2 Connection-Specific Header
- // Fields, don't send connection-specific
- // fields. We have already checked if any
- // are error-worthy so just ignore the rest.
- continue
- case "user-agent":
- // Match Go's http1 behavior: at most one
- // User-Agent. If set to nil or empty string,
- // then omit it. Otherwise if not mentioned,
- // include the default (below).
- didUA = true
- if len(vv) < 1 {
- continue
- }
- vv = vv[:1]
- if vv[0] == "" {
- continue
- }
- }
- for _, v := range vv {
- cc.writeHeader(lowKey, v)
- }
- }
- if shouldSendReqContentLength(req.Method, contentLength) {
- cc.writeHeader("content-length", strconv.FormatInt(contentLength, 10))
- }
- if addGzipHeader {
- cc.writeHeader("accept-encoding", "gzip")
- }
- if !didUA {
- cc.writeHeader("user-agent", defaultUserAgent)
- }
- return cc.hbuf.Bytes(), nil
-}
-
-// shouldSendReqContentLength reports whether the http2.Transport should send
-// a "content-length" request header. This logic is basically a copy of the net/http
-// transferWriter.shouldSendContentLength.
-// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown).
-// -1 means unknown.
-func shouldSendReqContentLength(method string, contentLength int64) bool {
- if contentLength > 0 {
- return true
- }
- if contentLength < 0 {
- return false
- }
- // For zero bodies, whether we send a content-length depends on the method.
- // It also kinda doesn't matter for http2 either way, with END_STREAM.
- switch method {
- case "POST", "PUT", "PATCH":
- return true
- default:
- return false
- }
-}
-
-// requires cc.mu be held.
-func (cc *ClientConn) encodeTrailers(req *http.Request) []byte {
- cc.hbuf.Reset()
- for k, vv := range req.Trailer {
- // Transfer-Encoding, etc.. have already been filter at the
- // start of RoundTrip
- lowKey := strings.ToLower(k)
- for _, v := range vv {
- cc.writeHeader(lowKey, v)
- }
- }
- return cc.hbuf.Bytes()
-}
-
-func (cc *ClientConn) writeHeader(name, value string) {
- if VerboseLogs {
- log.Printf("http2: Transport encoding header %q = %q", name, value)
- }
- cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
-}
-
-type resAndError struct {
- res *http.Response
- err error
-}
-
-// requires cc.mu be held.
-func (cc *ClientConn) newStream() *clientStream {
- cs := &clientStream{
- cc: cc,
- ID: cc.nextStreamID,
- resc: make(chan resAndError, 1),
- peerReset: make(chan struct{}),
- done: make(chan struct{}),
- }
- cs.flow.add(int32(cc.initialWindowSize))
- cs.flow.setConnFlow(&cc.flow)
- cs.inflow.add(transportDefaultStreamFlow)
- cs.inflow.setConnFlow(&cc.inflow)
- cc.nextStreamID += 2
- cc.streams[cs.ID] = cs
- return cs
-}
-
-func (cc *ClientConn) forgetStreamID(id uint32) {
- cc.streamByID(id, true)
-}
-
-func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- cs := cc.streams[id]
- if andRemove && cs != nil && !cc.closed {
- cc.lastActive = time.Now()
- delete(cc.streams, id)
- if len(cc.streams) == 0 && cc.idleTimer != nil {
- cc.idleTimer.Reset(cc.idleTimeout)
- }
- close(cs.done)
- cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
- }
- return cs
-}
-
-// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
-type clientConnReadLoop struct {
- cc *ClientConn
- activeRes map[uint32]*clientStream // keyed by streamID
- closeWhenIdle bool
-}
-
-// readLoop runs in its own goroutine and reads and dispatches frames.
-func (cc *ClientConn) readLoop() {
- rl := &clientConnReadLoop{
- cc: cc,
- activeRes: make(map[uint32]*clientStream),
- }
-
- defer rl.cleanup()
- cc.readerErr = rl.run()
- if ce, ok := cc.readerErr.(ConnectionError); ok {
- cc.wmu.Lock()
- cc.fr.WriteGoAway(0, ErrCode(ce), nil)
- cc.wmu.Unlock()
- }
-}
-
-// GoAwayError is returned by the Transport when the server closes the
-// TCP connection after sending a GOAWAY frame.
-type GoAwayError struct {
- LastStreamID uint32
- ErrCode ErrCode
- DebugData string
-}
-
-func (e GoAwayError) Error() string {
- return fmt.Sprintf("http2: server sent GOAWAY and closed the connection; LastStreamID=%v, ErrCode=%v, debug=%q",
- e.LastStreamID, e.ErrCode, e.DebugData)
-}
-
-func isEOFOrNetReadError(err error) bool {
- if err == io.EOF {
- return true
- }
- ne, ok := err.(*net.OpError)
- return ok && ne.Op == "read"
-}
-
-func (rl *clientConnReadLoop) cleanup() {
- cc := rl.cc
- defer cc.tconn.Close()
- defer cc.t.connPool().MarkDead(cc)
- defer close(cc.readerDone)
-
- if cc.idleTimer != nil {
- cc.idleTimer.Stop()
- }
-
- // Close any response bodies if the server closes prematurely.
- // TODO: also do this if we've written the headers but not
- // gotten a response yet.
- err := cc.readerErr
- cc.mu.Lock()
- if cc.goAway != nil && isEOFOrNetReadError(err) {
- err = GoAwayError{
- LastStreamID: cc.goAway.LastStreamID,
- ErrCode: cc.goAway.ErrCode,
- DebugData: cc.goAwayDebug,
- }
- } else if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- for _, cs := range rl.activeRes {
- cs.bufPipe.CloseWithError(err)
- }
- for _, cs := range cc.streams {
- select {
- case cs.resc <- resAndError{err: err}:
- default:
- }
- close(cs.done)
- }
- cc.closed = true
- cc.cond.Broadcast()
- cc.mu.Unlock()
-}
-
-func (rl *clientConnReadLoop) run() error {
- cc := rl.cc
- rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
- gotReply := false // ever saw a HEADERS reply
- gotSettings := false
- for {
- f, err := cc.fr.ReadFrame()
- if err != nil {
- cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
- }
- if se, ok := err.(StreamError); ok {
- if cs := cc.streamByID(se.StreamID, true /*ended; remove it*/); cs != nil {
- cs.cc.writeStreamReset(cs.ID, se.Code, err)
- if se.Cause == nil {
- se.Cause = cc.fr.errDetail
- }
- rl.endStreamError(cs, se)
- }
- continue
- } else if err != nil {
- return err
- }
- if VerboseLogs {
- cc.vlogf("http2: Transport received %s", summarizeFrame(f))
- }
- if !gotSettings {
- if _, ok := f.(*SettingsFrame); !ok {
- cc.logf("protocol error: received %T before a SETTINGS frame", f)
- return ConnectionError(ErrCodeProtocol)
- }
- gotSettings = true
- }
- maybeIdle := false // whether frame might transition us to idle
-
- switch f := f.(type) {
- case *MetaHeadersFrame:
- err = rl.processHeaders(f)
- maybeIdle = true
- gotReply = true
- case *DataFrame:
- err = rl.processData(f)
- maybeIdle = true
- case *GoAwayFrame:
- err = rl.processGoAway(f)
- maybeIdle = true
- case *RSTStreamFrame:
- err = rl.processResetStream(f)
- maybeIdle = true
- case *SettingsFrame:
- err = rl.processSettings(f)
- case *PushPromiseFrame:
- err = rl.processPushPromise(f)
- case *WindowUpdateFrame:
- err = rl.processWindowUpdate(f)
- case *PingFrame:
- err = rl.processPing(f)
- default:
- cc.logf("Transport: unhandled response frame type %T", f)
- }
- if err != nil {
- if VerboseLogs {
- cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, summarizeFrame(f), err)
- }
- return err
- }
- if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 {
- cc.closeIfIdle()
- }
- }
-}
-
-func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error {
- cc := rl.cc
- cs := cc.streamByID(f.StreamID, f.StreamEnded())
- if cs == nil {
- // We'd get here if we canceled a request while the
- // server had its response still in flight. So if this
- // was just something we canceled, ignore it.
- return nil
- }
- if !cs.firstByte {
- if cs.trace != nil {
- // TODO(bradfitz): move first response byte earlier,
- // when we first read the 9 byte header, not waiting
- // until all the HEADERS+CONTINUATION frames have been
- // merged. This works for now.
- traceFirstResponseByte(cs.trace)
- }
- cs.firstByte = true
- }
- if !cs.pastHeaders {
- cs.pastHeaders = true
- } else {
- return rl.processTrailers(cs, f)
- }
-
- res, err := rl.handleResponse(cs, f)
- if err != nil {
- if _, ok := err.(ConnectionError); ok {
- return err
- }
- // Any other error type is a stream error.
- cs.cc.writeStreamReset(f.StreamID, ErrCodeProtocol, err)
- cs.resc <- resAndError{err: err}
- return nil // return nil from process* funcs to keep conn alive
- }
- if res == nil {
- // (nil, nil) special case. See handleResponse docs.
- return nil
- }
- if res.Body != noBody {
- rl.activeRes[cs.ID] = cs
- }
- cs.resTrailer = &res.Trailer
- cs.resc <- resAndError{res: res}
- return nil
-}
-
-// may return error types nil, or ConnectionError. Any other error value
-// is a StreamError of type ErrCodeProtocol. The returned error in that case
-// is the detail.
-//
-// As a special case, handleResponse may return (nil, nil) to skip the
-// frame (currently only used for 100 expect continue). This special
-// case is going away after Issue 13851 is fixed.
-func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {
- if f.Truncated {
- return nil, errResponseHeaderListSize
- }
-
- status := f.PseudoValue("status")
- if status == "" {
- return nil, errors.New("missing status pseudo header")
- }
- statusCode, err := strconv.Atoi(status)
- if err != nil {
- return nil, errors.New("malformed non-numeric status pseudo header")
- }
-
- if statusCode == 100 {
- traceGot100Continue(cs.trace)
- if cs.on100 != nil {
- cs.on100() // forces any write delay timer to fire
- }
- cs.pastHeaders = false // do it all again
- return nil, nil
- }
-
- header := make(http.Header)
- res := &http.Response{
- Proto: "HTTP/2.0",
- ProtoMajor: 2,
- Header: header,
- StatusCode: statusCode,
- Status: status + " " + http.StatusText(statusCode),
- }
- for _, hf := range f.RegularFields() {
- key := http.CanonicalHeaderKey(hf.Name)
- if key == "Trailer" {
- t := res.Trailer
- if t == nil {
- t = make(http.Header)
- res.Trailer = t
- }
- foreachHeaderElement(hf.Value, func(v string) {
- t[http.CanonicalHeaderKey(v)] = nil
- })
- } else {
- header[key] = append(header[key], hf.Value)
- }
- }
-
- streamEnded := f.StreamEnded()
- isHead := cs.req.Method == "HEAD"
- if !streamEnded || isHead {
- res.ContentLength = -1
- if clens := res.Header["Content-Length"]; len(clens) == 1 {
- if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
- res.ContentLength = clen64
- } else {
- // TODO: care? unlike http/1, it won't mess up our framing, so it's
- // more safe smuggling-wise to ignore.
- }
- } else if len(clens) > 1 {
- // TODO: care? unlike http/1, it won't mess up our framing, so it's
- // more safe smuggling-wise to ignore.
- }
- }
-
- if streamEnded || isHead {
- res.Body = noBody
- return res, nil
- }
-
- cs.bufPipe = pipe{b: &dataBuffer{expected: res.ContentLength}}
- cs.bytesRemain = res.ContentLength
- res.Body = transportResponseBody{cs}
- go cs.awaitRequestCancel(cs.req)
-
- if cs.requestedGzip && res.Header.Get("Content-Encoding") == "gzip" {
- res.Header.Del("Content-Encoding")
- res.Header.Del("Content-Length")
- res.ContentLength = -1
- res.Body = &gzipReader{body: res.Body}
- setResponseUncompressed(res)
- }
- return res, nil
-}
-
-func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFrame) error {
- if cs.pastTrailers {
- // Too many HEADERS frames for this stream.
- return ConnectionError(ErrCodeProtocol)
- }
- cs.pastTrailers = true
- if !f.StreamEnded() {
- // We expect that any headers for trailers also
- // has END_STREAM.
- return ConnectionError(ErrCodeProtocol)
- }
- if len(f.PseudoFields()) > 0 {
- // No pseudo header fields are defined for trailers.
- // TODO: ConnectionError might be overly harsh? Check.
- return ConnectionError(ErrCodeProtocol)
- }
-
- trailer := make(http.Header)
- for _, hf := range f.RegularFields() {
- key := http.CanonicalHeaderKey(hf.Name)
- trailer[key] = append(trailer[key], hf.Value)
- }
- cs.trailer = trailer
-
- rl.endStream(cs)
- return nil
-}
-
-// transportResponseBody is the concrete type of Transport.RoundTrip's
-// Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body.
-// On Close it sends RST_STREAM if EOF wasn't already seen.
-type transportResponseBody struct {
- cs *clientStream
-}
-
-func (b transportResponseBody) Read(p []byte) (n int, err error) {
- cs := b.cs
- cc := cs.cc
-
- if cs.readErr != nil {
- return 0, cs.readErr
- }
- n, err = b.cs.bufPipe.Read(p)
- if cs.bytesRemain != -1 {
- if int64(n) > cs.bytesRemain {
- n = int(cs.bytesRemain)
- if err == nil {
- err = errors.New("net/http: server replied with more than declared Content-Length; truncated")
- cc.writeStreamReset(cs.ID, ErrCodeProtocol, err)
- }
- cs.readErr = err
- return int(cs.bytesRemain), err
- }
- cs.bytesRemain -= int64(n)
- if err == io.EOF && cs.bytesRemain > 0 {
- err = io.ErrUnexpectedEOF
- cs.readErr = err
- return n, err
- }
- }
- if n == 0 {
- // No flow control tokens to send back.
- return
- }
-
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- var connAdd, streamAdd int32
- // Check the conn-level first, before the stream-level.
- if v := cc.inflow.available(); v < transportDefaultConnFlow/2 {
- connAdd = transportDefaultConnFlow - v
- cc.inflow.add(connAdd)
- }
- if err == nil { // No need to refresh if the stream is over or failed.
- // Consider any buffered body data (read from the conn but not
- // consumed by the client) when computing flow control for this
- // stream.
- v := int(cs.inflow.available()) + cs.bufPipe.Len()
- if v < transportDefaultStreamFlow-transportDefaultStreamMinRefresh {
- streamAdd = int32(transportDefaultStreamFlow - v)
- cs.inflow.add(streamAdd)
- }
- }
- if connAdd != 0 || streamAdd != 0 {
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- if connAdd != 0 {
- cc.fr.WriteWindowUpdate(0, mustUint31(connAdd))
- }
- if streamAdd != 0 {
- cc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd))
- }
- cc.bw.Flush()
- }
- return
-}
-
-var errClosedResponseBody = errors.New("http2: response body closed")
-
-func (b transportResponseBody) Close() error {
- cs := b.cs
- cc := cs.cc
-
- serverSentStreamEnd := cs.bufPipe.Err() == io.EOF
- unread := cs.bufPipe.Len()
-
- if unread > 0 || !serverSentStreamEnd {
- cc.mu.Lock()
- cc.wmu.Lock()
- if !serverSentStreamEnd {
- cc.fr.WriteRSTStream(cs.ID, ErrCodeCancel)
- cs.didReset = true
- }
- // Return connection-level flow control.
- if unread > 0 {
- cc.inflow.add(int32(unread))
- cc.fr.WriteWindowUpdate(0, uint32(unread))
- }
- cc.bw.Flush()
- cc.wmu.Unlock()
- cc.mu.Unlock()
- }
-
- cs.bufPipe.BreakWithError(errClosedResponseBody)
- return nil
-}
-
-func (rl *clientConnReadLoop) processData(f *DataFrame) error {
- cc := rl.cc
- cs := cc.streamByID(f.StreamID, f.StreamEnded())
- data := f.Data()
- if cs == nil {
- cc.mu.Lock()
- neverSent := cc.nextStreamID
- cc.mu.Unlock()
- if f.StreamID >= neverSent {
- // We never asked for this.
- cc.logf("http2: Transport received unsolicited DATA frame; closing connection")
- return ConnectionError(ErrCodeProtocol)
- }
- // We probably did ask for this, but canceled. Just ignore it.
- // TODO: be stricter here? only silently ignore things which
- // we canceled, but not things which were closed normally
- // by the peer? Tough without accumulating too much state.
-
- // But at least return their flow control:
- if f.Length > 0 {
- cc.mu.Lock()
- cc.inflow.add(int32(f.Length))
- cc.mu.Unlock()
-
- cc.wmu.Lock()
- cc.fr.WriteWindowUpdate(0, uint32(f.Length))
- cc.bw.Flush()
- cc.wmu.Unlock()
- }
- return nil
- }
- if f.Length > 0 {
- // Check connection-level flow control.
- cc.mu.Lock()
- if cs.inflow.available() >= int32(f.Length) {
- cs.inflow.take(int32(f.Length))
- } else {
- cc.mu.Unlock()
- return ConnectionError(ErrCodeFlowControl)
- }
- // Return any padded flow control now, since we won't
- // refund it later on body reads.
- if pad := int32(f.Length) - int32(len(data)); pad > 0 {
- cs.inflow.add(pad)
- cc.inflow.add(pad)
- cc.wmu.Lock()
- cc.fr.WriteWindowUpdate(0, uint32(pad))
- cc.fr.WriteWindowUpdate(cs.ID, uint32(pad))
- cc.bw.Flush()
- cc.wmu.Unlock()
- }
- didReset := cs.didReset
- cc.mu.Unlock()
-
- if len(data) > 0 && !didReset {
- if _, err := cs.bufPipe.Write(data); err != nil {
- rl.endStreamError(cs, err)
- return err
- }
- }
- }
-
- if f.StreamEnded() {
- rl.endStream(cs)
- }
- return nil
-}
-
-var errInvalidTrailers = errors.New("http2: invalid trailers")
-
-func (rl *clientConnReadLoop) endStream(cs *clientStream) {
- // TODO: check that any declared content-length matches, like
- // server.go's (*stream).endStream method.
- rl.endStreamError(cs, nil)
-}
-
-func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) {
- var code func()
- if err == nil {
- err = io.EOF
- code = cs.copyTrailers
- }
- cs.bufPipe.closeWithErrorAndCode(err, code)
- delete(rl.activeRes, cs.ID)
- if isConnectionCloseRequest(cs.req) {
- rl.closeWhenIdle = true
- }
-
- select {
- case cs.resc <- resAndError{err: err}:
- default:
- }
-}
-
-func (cs *clientStream) copyTrailers() {
- for k, vv := range cs.trailer {
- t := cs.resTrailer
- if *t == nil {
- *t = make(http.Header)
- }
- (*t)[k] = vv
- }
-}
-
-func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {
- cc := rl.cc
- cc.t.connPool().MarkDead(cc)
- if f.ErrCode != 0 {
- // TODO: deal with GOAWAY more. particularly the error code
- cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode)
- }
- cc.setGoAway(f)
- return nil
-}
-
-func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error {
- cc := rl.cc
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- if f.IsAck() {
- if cc.wantSettingsAck {
- cc.wantSettingsAck = false
- return nil
- }
- return ConnectionError(ErrCodeProtocol)
- }
-
- err := f.ForeachSetting(func(s Setting) error {
- switch s.ID {
- case SettingMaxFrameSize:
- cc.maxFrameSize = s.Val
- case SettingMaxConcurrentStreams:
- cc.maxConcurrentStreams = s.Val
- case SettingInitialWindowSize:
- // Values above the maximum flow-control
- // window size of 2^31-1 MUST be treated as a
- // connection error (Section 5.4.1) of type
- // FLOW_CONTROL_ERROR.
- if s.Val > math.MaxInt32 {
- return ConnectionError(ErrCodeFlowControl)
- }
-
- // Adjust flow control of currently-open
- // frames by the difference of the old initial
- // window size and this one.
- delta := int32(s.Val) - int32(cc.initialWindowSize)
- for _, cs := range cc.streams {
- cs.flow.add(delta)
- }
- cc.cond.Broadcast()
-
- cc.initialWindowSize = s.Val
- default:
- // TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably.
- cc.vlogf("Unhandled Setting: %v", s)
- }
- return nil
- })
- if err != nil {
- return err
- }
-
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
-
- cc.fr.WriteSettingsAck()
- cc.bw.Flush()
- return cc.werr
-}
-
-func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
- cc := rl.cc
- cs := cc.streamByID(f.StreamID, false)
- if f.StreamID != 0 && cs == nil {
- return nil
- }
-
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- fl := &cc.flow
- if cs != nil {
- fl = &cs.flow
- }
- if !fl.add(int32(f.Increment)) {
- return ConnectionError(ErrCodeFlowControl)
- }
- cc.cond.Broadcast()
- return nil
-}
-
-func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {
- cs := rl.cc.streamByID(f.StreamID, true)
- if cs == nil {
- // TODO: return error if server tries to RST_STEAM an idle stream
- return nil
- }
- select {
- case <-cs.peerReset:
- // Already reset.
- // This is the only goroutine
- // which closes this, so there
- // isn't a race.
- default:
- err := streamError(cs.ID, f.ErrCode)
- cs.resetErr = err
- close(cs.peerReset)
- cs.bufPipe.CloseWithError(err)
- cs.cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
- }
- delete(rl.activeRes, cs.ID)
- return nil
-}
-
-// Ping sends a PING frame to the server and waits for the ack.
-// Public implementation is in go17.go and not_go17.go
-func (cc *ClientConn) ping(ctx contextContext) error {
- c := make(chan struct{})
- // Generate a random payload
- var p [8]byte
- for {
- if _, err := rand.Read(p[:]); err != nil {
- return err
- }
- cc.mu.Lock()
- // check for dup before insert
- if _, found := cc.pings[p]; !found {
- cc.pings[p] = c
- cc.mu.Unlock()
- break
- }
- cc.mu.Unlock()
- }
- cc.wmu.Lock()
- if err := cc.fr.WritePing(false, p); err != nil {
- cc.wmu.Unlock()
- return err
- }
- if err := cc.bw.Flush(); err != nil {
- cc.wmu.Unlock()
- return err
- }
- cc.wmu.Unlock()
- select {
- case <-c:
- return nil
- case <-ctx.Done():
- return ctx.Err()
- case <-cc.readerDone:
- // connection closed
- return cc.readerErr
- }
-}
-
-func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
- if f.IsAck() {
- cc := rl.cc
- cc.mu.Lock()
- defer cc.mu.Unlock()
- // If ack, notify listener if any
- if c, ok := cc.pings[f.Data]; ok {
- close(c)
- delete(cc.pings, f.Data)
- }
- return nil
- }
- cc := rl.cc
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- if err := cc.fr.WritePing(true, f.Data); err != nil {
- return err
- }
- return cc.bw.Flush()
-}
-
-func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error {
- // We told the peer we don't want them.
- // Spec says:
- // "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH
- // setting of the peer endpoint is set to 0. An endpoint that
- // has set this setting and has received acknowledgement MUST
- // treat the receipt of a PUSH_PROMISE frame as a connection
- // error (Section 5.4.1) of type PROTOCOL_ERROR."
- return ConnectionError(ErrCodeProtocol)
-}
-
-func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) {
- // TODO: map err to more interesting error codes, once the
- // HTTP community comes up with some. But currently for
- // RST_STREAM there's no equivalent to GOAWAY frame's debug
- // data, and the error codes are all pretty vague ("cancel").
- cc.wmu.Lock()
- cc.fr.WriteRSTStream(streamID, code)
- cc.bw.Flush()
- cc.wmu.Unlock()
-}
-
-var (
- errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
- errPseudoTrailers = errors.New("http2: invalid pseudo header in trailers")
-)
-
-func (cc *ClientConn) logf(format string, args ...interface{}) {
- cc.t.logf(format, args...)
-}
-
-func (cc *ClientConn) vlogf(format string, args ...interface{}) {
- cc.t.vlogf(format, args...)
-}
-
-func (t *Transport) vlogf(format string, args ...interface{}) {
- if VerboseLogs {
- t.logf(format, args...)
- }
-}
-
-func (t *Transport) logf(format string, args ...interface{}) {
- log.Printf(format, args...)
-}
-
-var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil))
-
-func strSliceContains(ss []string, s string) bool {
- for _, v := range ss {
- if v == s {
- return true
- }
- }
- return false
-}
-
-type erringRoundTripper struct{ err error }
-
-func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }
-
-// gzipReader wraps a response body so it can lazily
-// call gzip.NewReader on the first call to Read
-type gzipReader struct {
- body io.ReadCloser // underlying Response.Body
- zr *gzip.Reader // lazily-initialized gzip reader
- zerr error // sticky error
-}
-
-func (gz *gzipReader) Read(p []byte) (n int, err error) {
- if gz.zerr != nil {
- return 0, gz.zerr
- }
- if gz.zr == nil {
- gz.zr, err = gzip.NewReader(gz.body)
- if err != nil {
- gz.zerr = err
- return 0, err
- }
- }
- return gz.zr.Read(p)
-}
-
-func (gz *gzipReader) Close() error {
- return gz.body.Close()
-}
-
-type errorReader struct{ err error }
-
-func (r errorReader) Read(p []byte) (int, error) { return 0, r.err }
-
-// bodyWriterState encapsulates various state around the Transport's writing
-// of the request body, particularly regarding doing delayed writes of the body
-// when the request contains "Expect: 100-continue".
-type bodyWriterState struct {
- cs *clientStream
- timer *time.Timer // if non-nil, we're doing a delayed write
- fnonce *sync.Once // to call fn with
- fn func() // the code to run in the goroutine, writing the body
- resc chan error // result of fn's execution
- delay time.Duration // how long we should delay a delayed write for
-}
-
-func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s bodyWriterState) {
- s.cs = cs
- if body == nil {
- return
- }
- resc := make(chan error, 1)
- s.resc = resc
- s.fn = func() {
- cs.cc.mu.Lock()
- cs.startedWrite = true
- cs.cc.mu.Unlock()
- resc <- cs.writeRequestBody(body, cs.req.Body)
- }
- s.delay = t.expectContinueTimeout()
- if s.delay == 0 ||
- !httplex.HeaderValuesContainsToken(
- cs.req.Header["Expect"],
- "100-continue") {
- return
- }
- s.fnonce = new(sync.Once)
-
- // Arm the timer with a very large duration, which we'll
- // intentionally lower later. It has to be large now because
- // we need a handle to it before writing the headers, but the
- // s.delay value is defined to not start until after the
- // request headers were written.
- const hugeDuration = 365 * 24 * time.Hour
- s.timer = time.AfterFunc(hugeDuration, func() {
- s.fnonce.Do(s.fn)
- })
- return
-}
-
-func (s bodyWriterState) cancel() {
- if s.timer != nil {
- s.timer.Stop()
- }
-}
-
-func (s bodyWriterState) on100() {
- if s.timer == nil {
- // If we didn't do a delayed write, ignore the server's
- // bogus 100 continue response.
- return
- }
- s.timer.Stop()
- go func() { s.fnonce.Do(s.fn) }()
-}
-
-// scheduleBodyWrite starts writing the body, either immediately (in
-// the common case) or after the delay timeout. It should not be
-// called until after the headers have been written.
-func (s bodyWriterState) scheduleBodyWrite() {
- if s.timer == nil {
- // We're not doing a delayed write (see
- // getBodyWriterState), so just start the writing
- // goroutine immediately.
- go s.fn()
- return
- }
- traceWait100Continue(s.cs.trace)
- if s.timer.Stop() {
- s.timer.Reset(s.delay)
- }
-}
-
-// isConnectionCloseRequest reports whether req should use its own
-// connection for a single request and then close the connection.
-func isConnectionCloseRequest(req *http.Request) bool {
- return req.Close || httplex.HeaderValuesContainsToken(req.Header["Connection"], "close")
-}
diff --git a/vendor/golang.org/x/net/http2/transport_test.go b/vendor/golang.org/x/net/http2/transport_test.go
deleted file mode 100644
index 128ed0dd6..000000000
--- a/vendor/golang.org/x/net/http2/transport_test.go
+++ /dev/null
@@ -1,2971 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bufio"
- "bytes"
- "crypto/tls"
- "errors"
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "math/rand"
- "net"
- "net/http"
- "net/url"
- "os"
- "reflect"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "testing"
- "time"
-
- "golang.org/x/net/http2/hpack"
-)
-
-var (
- extNet = flag.Bool("extnet", false, "do external network tests")
- transportHost = flag.String("transporthost", "http2.golang.org", "hostname to use for TestTransport")
- insecure = flag.Bool("insecure", false, "insecure TLS dials") // TODO: dead code. remove?
-)
-
-var tlsConfigInsecure = &tls.Config{InsecureSkipVerify: true}
-
-type testContext struct{}
-
-func (testContext) Done() <-chan struct{} { return make(chan struct{}) }
-func (testContext) Err() error { panic("should not be called") }
-func (testContext) Deadline() (deadline time.Time, ok bool) { return time.Time{}, false }
-func (testContext) Value(key interface{}) interface{} { return nil }
-
-func TestTransportExternal(t *testing.T) {
- if !*extNet {
- t.Skip("skipping external network test")
- }
- req, _ := http.NewRequest("GET", "https://"+*transportHost+"/", nil)
- rt := &Transport{TLSClientConfig: tlsConfigInsecure}
- res, err := rt.RoundTrip(req)
- if err != nil {
- t.Fatalf("%v", err)
- }
- res.Write(os.Stdout)
-}
-
-type fakeTLSConn struct {
- net.Conn
-}
-
-func (c *fakeTLSConn) ConnectionState() tls.ConnectionState {
- return tls.ConnectionState{
- Version: tls.VersionTLS12,
- CipherSuite: cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- }
-}
-
-func startH2cServer(t *testing.T) net.Listener {
- h2Server := &Server{}
- l := newLocalListener(t)
- go func() {
- conn, err := l.Accept()
- if err != nil {
- t.Error(err)
- return
- }
- h2Server.ServeConn(&fakeTLSConn{conn}, &ServeConnOpts{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, "Hello, %v, http: %v", r.URL.Path, r.TLS == nil)
- })})
- }()
- return l
-}
-
-func TestTransportH2c(t *testing.T) {
- l := startH2cServer(t)
- defer l.Close()
- req, err := http.NewRequest("GET", "http://"+l.Addr().String()+"/foobar", nil)
- if err != nil {
- t.Fatal(err)
- }
- tr := &Transport{
- AllowHTTP: true,
- DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
- return net.Dial(network, addr)
- },
- }
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal(err)
- }
- if res.ProtoMajor != 2 {
- t.Fatal("proto not h2c")
- }
- body, err := ioutil.ReadAll(res.Body)
- if err != nil {
- t.Fatal(err)
- }
- if got, want := string(body), "Hello, /foobar, http: true"; got != want {
- t.Fatalf("response got %v, want %v", got, want)
- }
-}
-
-func TestTransport(t *testing.T) {
- const body = "sup"
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, body)
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- req, err := http.NewRequest("GET", st.ts.URL, nil)
- if err != nil {
- t.Fatal(err)
- }
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
-
- t.Logf("Got res: %+v", res)
- if g, w := res.StatusCode, 200; g != w {
- t.Errorf("StatusCode = %v; want %v", g, w)
- }
- if g, w := res.Status, "200 OK"; g != w {
- t.Errorf("Status = %q; want %q", g, w)
- }
- wantHeader := http.Header{
- "Content-Length": []string{"3"},
- "Content-Type": []string{"text/plain; charset=utf-8"},
- "Date": []string{"XXX"}, // see cleanDate
- }
- cleanDate(res)
- if !reflect.DeepEqual(res.Header, wantHeader) {
- t.Errorf("res Header = %v; want %v", res.Header, wantHeader)
- }
- if res.Request != req {
- t.Errorf("Response.Request = %p; want %p", res.Request, req)
- }
- if res.TLS == nil {
- t.Error("Response.TLS = nil; want non-nil")
- }
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- t.Errorf("Body read: %v", err)
- } else if string(slurp) != body {
- t.Errorf("Body = %q; want %q", slurp, body)
- }
-}
-
-func onSameConn(t *testing.T, modReq func(*http.Request)) bool {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, r.RemoteAddr)
- }, optOnlyServer, func(c net.Conn, st http.ConnState) {
- t.Logf("conn %v is now state %v", c.RemoteAddr(), st)
- })
- defer st.Close()
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
- get := func() string {
- req, err := http.NewRequest("GET", st.ts.URL, nil)
- if err != nil {
- t.Fatal(err)
- }
- modReq(req)
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- t.Fatalf("Body read: %v", err)
- }
- addr := strings.TrimSpace(string(slurp))
- if addr == "" {
- t.Fatalf("didn't get an addr in response")
- }
- return addr
- }
- first := get()
- second := get()
- return first == second
-}
-
-func TestTransportReusesConns(t *testing.T) {
- if !onSameConn(t, func(*http.Request) {}) {
- t.Errorf("first and second responses were on different connections")
- }
-}
-
-func TestTransportReusesConn_RequestClose(t *testing.T) {
- if onSameConn(t, func(r *http.Request) { r.Close = true }) {
- t.Errorf("first and second responses were not on different connections")
- }
-}
-
-func TestTransportReusesConn_ConnClose(t *testing.T) {
- if onSameConn(t, func(r *http.Request) { r.Header.Set("Connection", "close") }) {
- t.Errorf("first and second responses were not on different connections")
- }
-}
-
-// Tests that the Transport only keeps one pending dial open per destination address.
-// https://golang.org/issue/13397
-func TestTransportGroupsPendingDials(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, r.RemoteAddr)
- }, optOnlyServer)
- defer st.Close()
- tr := &Transport{
- TLSClientConfig: tlsConfigInsecure,
- }
- defer tr.CloseIdleConnections()
- var (
- mu sync.Mutex
- dials = map[string]int{}
- )
- var wg sync.WaitGroup
- for i := 0; i < 10; i++ {
- wg.Add(1)
- go func() {
- defer wg.Done()
- req, err := http.NewRequest("GET", st.ts.URL, nil)
- if err != nil {
- t.Error(err)
- return
- }
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Error(err)
- return
- }
- defer res.Body.Close()
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- t.Errorf("Body read: %v", err)
- }
- addr := strings.TrimSpace(string(slurp))
- if addr == "" {
- t.Errorf("didn't get an addr in response")
- }
- mu.Lock()
- dials[addr]++
- mu.Unlock()
- }()
- }
- wg.Wait()
- if len(dials) != 1 {
- t.Errorf("saw %d dials; want 1: %v", len(dials), dials)
- }
- tr.CloseIdleConnections()
- if err := retry(50, 10*time.Millisecond, func() error {
- cp, ok := tr.connPool().(*clientConnPool)
- if !ok {
- return fmt.Errorf("Conn pool is %T; want *clientConnPool", tr.connPool())
- }
- cp.mu.Lock()
- defer cp.mu.Unlock()
- if len(cp.dialing) != 0 {
- return fmt.Errorf("dialing map = %v; want empty", cp.dialing)
- }
- if len(cp.conns) != 0 {
- return fmt.Errorf("conns = %v; want empty", cp.conns)
- }
- if len(cp.keys) != 0 {
- return fmt.Errorf("keys = %v; want empty", cp.keys)
- }
- return nil
- }); err != nil {
- t.Errorf("State of pool after CloseIdleConnections: %v", err)
- }
-}
-
-func retry(tries int, delay time.Duration, fn func() error) error {
- var err error
- for i := 0; i < tries; i++ {
- err = fn()
- if err == nil {
- return nil
- }
- time.Sleep(delay)
- }
- return err
-}
-
-func TestTransportAbortClosesPipes(t *testing.T) {
- shutdown := make(chan struct{})
- st := newServerTester(t,
- func(w http.ResponseWriter, r *http.Request) {
- w.(http.Flusher).Flush()
- <-shutdown
- },
- optOnlyServer,
- )
- defer st.Close()
- defer close(shutdown) // we must shutdown before st.Close() to avoid hanging
-
- done := make(chan struct{})
- requestMade := make(chan struct{})
- go func() {
- defer close(done)
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- req, err := http.NewRequest("GET", st.ts.URL, nil)
- if err != nil {
- t.Fatal(err)
- }
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
- close(requestMade)
- _, err = ioutil.ReadAll(res.Body)
- if err == nil {
- t.Error("expected error from res.Body.Read")
- }
- }()
-
- <-requestMade
- // Now force the serve loop to end, via closing the connection.
- st.closeConn()
- // deadlock? that's a bug.
- select {
- case <-done:
- case <-time.After(3 * time.Second):
- t.Fatal("timeout")
- }
-}
-
-// TODO: merge this with TestTransportBody to make TestTransportRequest? This
-// could be a table-driven test with extra goodies.
-func TestTransportPath(t *testing.T) {
- gotc := make(chan *url.URL, 1)
- st := newServerTester(t,
- func(w http.ResponseWriter, r *http.Request) {
- gotc <- r.URL
- },
- optOnlyServer,
- )
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
- const (
- path = "/testpath"
- query = "q=1"
- )
- surl := st.ts.URL + path + "?" + query
- req, err := http.NewRequest("POST", surl, nil)
- if err != nil {
- t.Fatal(err)
- }
- c := &http.Client{Transport: tr}
- res, err := c.Do(req)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
- got := <-gotc
- if got.Path != path {
- t.Errorf("Read Path = %q; want %q", got.Path, path)
- }
- if got.RawQuery != query {
- t.Errorf("Read RawQuery = %q; want %q", got.RawQuery, query)
- }
-}
-
-func randString(n int) string {
- rnd := rand.New(rand.NewSource(int64(n)))
- b := make([]byte, n)
- for i := range b {
- b[i] = byte(rnd.Intn(256))
- }
- return string(b)
-}
-
-type panicReader struct{}
-
-func (panicReader) Read([]byte) (int, error) { panic("unexpected Read") }
-func (panicReader) Close() error { panic("unexpected Close") }
-
-func TestActualContentLength(t *testing.T) {
- tests := []struct {
- req *http.Request
- want int64
- }{
- // Verify we don't read from Body:
- 0: {
- req: &http.Request{Body: panicReader{}},
- want: -1,
- },
- // nil Body means 0, regardless of ContentLength:
- 1: {
- req: &http.Request{Body: nil, ContentLength: 5},
- want: 0,
- },
- // ContentLength is used if set.
- 2: {
- req: &http.Request{Body: panicReader{}, ContentLength: 5},
- want: 5,
- },
- }
- for i, tt := range tests {
- got := actualContentLength(tt.req)
- if got != tt.want {
- t.Errorf("test[%d]: got %d; want %d", i, got, tt.want)
- }
- }
-}
-
-func TestTransportBody(t *testing.T) {
- bodyTests := []struct {
- body string
- noContentLen bool
- }{
- {body: "some message"},
- {body: "some message", noContentLen: true},
- {body: strings.Repeat("a", 1<<20), noContentLen: true},
- {body: strings.Repeat("a", 1<<20)},
- {body: randString(16<<10 - 1)},
- {body: randString(16 << 10)},
- {body: randString(16<<10 + 1)},
- {body: randString(512<<10 - 1)},
- {body: randString(512 << 10)},
- {body: randString(512<<10 + 1)},
- {body: randString(1<<20 - 1)},
- {body: randString(1 << 20)},
- {body: randString(1<<20 + 2)},
- }
-
- type reqInfo struct {
- req *http.Request
- slurp []byte
- err error
- }
- gotc := make(chan reqInfo, 1)
- st := newServerTester(t,
- func(w http.ResponseWriter, r *http.Request) {
- slurp, err := ioutil.ReadAll(r.Body)
- if err != nil {
- gotc <- reqInfo{err: err}
- } else {
- gotc <- reqInfo{req: r, slurp: slurp}
- }
- },
- optOnlyServer,
- )
- defer st.Close()
-
- for i, tt := range bodyTests {
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- var body io.Reader = strings.NewReader(tt.body)
- if tt.noContentLen {
- body = struct{ io.Reader }{body} // just a Reader, hiding concrete type and other methods
- }
- req, err := http.NewRequest("POST", st.ts.URL, body)
- if err != nil {
- t.Fatalf("#%d: %v", i, err)
- }
- c := &http.Client{Transport: tr}
- res, err := c.Do(req)
- if err != nil {
- t.Fatalf("#%d: %v", i, err)
- }
- defer res.Body.Close()
- ri := <-gotc
- if ri.err != nil {
- t.Errorf("#%d: read error: %v", i, ri.err)
- continue
- }
- if got := string(ri.slurp); got != tt.body {
- t.Errorf("#%d: Read body mismatch.\n got: %q (len %d)\nwant: %q (len %d)", i, shortString(got), len(got), shortString(tt.body), len(tt.body))
- }
- wantLen := int64(len(tt.body))
- if tt.noContentLen && tt.body != "" {
- wantLen = -1
- }
- if ri.req.ContentLength != wantLen {
- t.Errorf("#%d. handler got ContentLength = %v; want %v", i, ri.req.ContentLength, wantLen)
- }
- }
-}
-
-func shortString(v string) string {
- const maxLen = 100
- if len(v) <= maxLen {
- return v
- }
- return fmt.Sprintf("%v[...%d bytes omitted...]%v", v[:maxLen/2], len(v)-maxLen, v[len(v)-maxLen/2:])
-}
-
-func TestTransportDialTLS(t *testing.T) {
- var mu sync.Mutex // guards following
- var gotReq, didDial bool
-
- ts := newServerTester(t,
- func(w http.ResponseWriter, r *http.Request) {
- mu.Lock()
- gotReq = true
- mu.Unlock()
- },
- optOnlyServer,
- )
- defer ts.Close()
- tr := &Transport{
- DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) {
- mu.Lock()
- didDial = true
- mu.Unlock()
- cfg.InsecureSkipVerify = true
- c, err := tls.Dial(netw, addr, cfg)
- if err != nil {
- return nil, err
- }
- return c, c.Handshake()
- },
- }
- defer tr.CloseIdleConnections()
- client := &http.Client{Transport: tr}
- res, err := client.Get(ts.ts.URL)
- if err != nil {
- t.Fatal(err)
- }
- res.Body.Close()
- mu.Lock()
- if !gotReq {
- t.Error("didn't get request")
- }
- if !didDial {
- t.Error("didn't use dial hook")
- }
-}
-
-func TestConfigureTransport(t *testing.T) {
- t1 := &http.Transport{}
- err := ConfigureTransport(t1)
- if err == errTransportVersion {
- t.Skip(err)
- }
- if err != nil {
- t.Fatal(err)
- }
- if got := fmt.Sprintf("%#v", t1); !strings.Contains(got, `"h2"`) {
- // Laziness, to avoid buildtags.
- t.Errorf("stringification of HTTP/1 transport didn't contain \"h2\": %v", got)
- }
- wantNextProtos := []string{"h2", "http/1.1"}
- if t1.TLSClientConfig == nil {
- t.Errorf("nil t1.TLSClientConfig")
- } else if !reflect.DeepEqual(t1.TLSClientConfig.NextProtos, wantNextProtos) {
- t.Errorf("TLSClientConfig.NextProtos = %q; want %q", t1.TLSClientConfig.NextProtos, wantNextProtos)
- }
- if err := ConfigureTransport(t1); err == nil {
- t.Error("unexpected success on second call to ConfigureTransport")
- }
-
- // And does it work?
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, r.Proto)
- }, optOnlyServer)
- defer st.Close()
-
- t1.TLSClientConfig.InsecureSkipVerify = true
- c := &http.Client{Transport: t1}
- res, err := c.Get(st.ts.URL)
- if err != nil {
- t.Fatal(err)
- }
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- t.Fatal(err)
- }
- if got, want := string(slurp), "HTTP/2.0"; got != want {
- t.Errorf("body = %q; want %q", got, want)
- }
-}
-
-type capitalizeReader struct {
- r io.Reader
-}
-
-func (cr capitalizeReader) Read(p []byte) (n int, err error) {
- n, err = cr.r.Read(p)
- for i, b := range p[:n] {
- if b >= 'a' && b <= 'z' {
- p[i] = b - ('a' - 'A')
- }
- }
- return
-}
-
-type flushWriter struct {
- w io.Writer
-}
-
-func (fw flushWriter) Write(p []byte) (n int, err error) {
- n, err = fw.w.Write(p)
- if f, ok := fw.w.(http.Flusher); ok {
- f.Flush()
- }
- return
-}
-
-type clientTester struct {
- t *testing.T
- tr *Transport
- sc, cc net.Conn // server and client conn
- fr *Framer // server's framer
- client func() error
- server func() error
-}
-
-func newClientTester(t *testing.T) *clientTester {
- var dialOnce struct {
- sync.Mutex
- dialed bool
- }
- ct := &clientTester{
- t: t,
- }
- ct.tr = &Transport{
- TLSClientConfig: tlsConfigInsecure,
- DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
- dialOnce.Lock()
- defer dialOnce.Unlock()
- if dialOnce.dialed {
- return nil, errors.New("only one dial allowed in test mode")
- }
- dialOnce.dialed = true
- return ct.cc, nil
- },
- }
-
- ln := newLocalListener(t)
- cc, err := net.Dial("tcp", ln.Addr().String())
- if err != nil {
- t.Fatal(err)
-
- }
- sc, err := ln.Accept()
- if err != nil {
- t.Fatal(err)
- }
- ln.Close()
- ct.cc = cc
- ct.sc = sc
- ct.fr = NewFramer(sc, sc)
- return ct
-}
-
-func newLocalListener(t *testing.T) net.Listener {
- ln, err := net.Listen("tcp4", "127.0.0.1:0")
- if err == nil {
- return ln
- }
- ln, err = net.Listen("tcp6", "[::1]:0")
- if err != nil {
- t.Fatal(err)
- }
- return ln
-}
-
-func (ct *clientTester) greet() {
- buf := make([]byte, len(ClientPreface))
- _, err := io.ReadFull(ct.sc, buf)
- if err != nil {
- ct.t.Fatalf("reading client preface: %v", err)
- }
- f, err := ct.fr.ReadFrame()
- if err != nil {
- ct.t.Fatalf("Reading client settings frame: %v", err)
- }
- if sf, ok := f.(*SettingsFrame); !ok {
- ct.t.Fatalf("Wanted client settings frame; got %v", f)
- _ = sf // stash it away?
- }
- if err := ct.fr.WriteSettings(); err != nil {
- ct.t.Fatal(err)
- }
- if err := ct.fr.WriteSettingsAck(); err != nil {
- ct.t.Fatal(err)
- }
-}
-
-func (ct *clientTester) readNonSettingsFrame() (Frame, error) {
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- return nil, err
- }
- if _, ok := f.(*SettingsFrame); ok {
- continue
- }
- return f, nil
- }
-}
-
-func (ct *clientTester) cleanup() {
- ct.tr.CloseIdleConnections()
-}
-
-func (ct *clientTester) run() {
- errc := make(chan error, 2)
- ct.start("client", errc, ct.client)
- ct.start("server", errc, ct.server)
- defer ct.cleanup()
- for i := 0; i < 2; i++ {
- if err := <-errc; err != nil {
- ct.t.Error(err)
- return
- }
- }
-}
-
-func (ct *clientTester) start(which string, errc chan<- error, fn func() error) {
- go func() {
- finished := false
- var err error
- defer func() {
- if !finished {
- err = fmt.Errorf("%s goroutine didn't finish.", which)
- } else if err != nil {
- err = fmt.Errorf("%s: %v", which, err)
- }
- errc <- err
- }()
- err = fn()
- finished = true
- }()
-}
-
-func (ct *clientTester) readFrame() (Frame, error) {
- return readFrameTimeout(ct.fr, 2*time.Second)
-}
-
-func (ct *clientTester) firstHeaders() (*HeadersFrame, error) {
- for {
- f, err := ct.readFrame()
- if err != nil {
- return nil, fmt.Errorf("ReadFrame while waiting for Headers: %v", err)
- }
- switch f.(type) {
- case *WindowUpdateFrame, *SettingsFrame:
- continue
- }
- hf, ok := f.(*HeadersFrame)
- if !ok {
- return nil, fmt.Errorf("Got %T; want HeadersFrame", f)
- }
- return hf, nil
- }
-}
-
-type countingReader struct {
- n *int64
-}
-
-func (r countingReader) Read(p []byte) (n int, err error) {
- for i := range p {
- p[i] = byte(i)
- }
- atomic.AddInt64(r.n, int64(len(p)))
- return len(p), err
-}
-
-func TestTransportReqBodyAfterResponse_200(t *testing.T) { testTransportReqBodyAfterResponse(t, 200) }
-func TestTransportReqBodyAfterResponse_403(t *testing.T) { testTransportReqBodyAfterResponse(t, 403) }
-
-func testTransportReqBodyAfterResponse(t *testing.T, status int) {
- const bodySize = 10 << 20
- clientDone := make(chan struct{})
- ct := newClientTester(t)
- ct.client = func() error {
- defer ct.cc.(*net.TCPConn).CloseWrite()
- defer close(clientDone)
-
- var n int64 // atomic
- req, err := http.NewRequest("PUT", "https://dummy.tld/", io.LimitReader(countingReader{&n}, bodySize))
- if err != nil {
- return err
- }
- res, err := ct.tr.RoundTrip(req)
- if err != nil {
- return fmt.Errorf("RoundTrip: %v", err)
- }
- defer res.Body.Close()
- if res.StatusCode != status {
- return fmt.Errorf("status code = %v; want %v", res.StatusCode, status)
- }
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return fmt.Errorf("Slurp: %v", err)
- }
- if len(slurp) > 0 {
- return fmt.Errorf("unexpected body: %q", slurp)
- }
- if status == 200 {
- if got := atomic.LoadInt64(&n); got != bodySize {
- return fmt.Errorf("For 200 response, Transport wrote %d bytes; want %d", got, bodySize)
- }
- } else {
- if got := atomic.LoadInt64(&n); got == 0 || got >= bodySize {
- return fmt.Errorf("For %d response, Transport wrote %d bytes; want (0,%d) exclusive", status, got, bodySize)
- }
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- var dataRecv int64
- var closed bool
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- select {
- case <-clientDone:
- // If the client's done, it
- // will have reported any
- // errors on its side.
- return nil
- default:
- return err
- }
- }
- //println(fmt.Sprintf("server got frame: %v", f))
- switch f := f.(type) {
- case *WindowUpdateFrame, *SettingsFrame:
- case *HeadersFrame:
- if !f.HeadersEnded() {
- return fmt.Errorf("headers should have END_HEADERS be ended: %v", f)
- }
- if f.StreamEnded() {
- return fmt.Errorf("headers contains END_STREAM unexpectedly: %v", f)
- }
- case *DataFrame:
- dataLen := len(f.Data())
- if dataLen > 0 {
- if dataRecv == 0 {
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: strconv.Itoa(status)})
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: f.StreamID,
- EndHeaders: true,
- EndStream: false,
- BlockFragment: buf.Bytes(),
- })
- }
- if err := ct.fr.WriteWindowUpdate(0, uint32(dataLen)); err != nil {
- return err
- }
- if err := ct.fr.WriteWindowUpdate(f.StreamID, uint32(dataLen)); err != nil {
- return err
- }
- }
- dataRecv += int64(dataLen)
-
- if !closed && ((status != 200 && dataRecv > 0) ||
- (status == 200 && dataRecv == bodySize)) {
- closed = true
- if err := ct.fr.WriteData(f.StreamID, true, nil); err != nil {
- return err
- }
- }
- default:
- return fmt.Errorf("Unexpected client frame %v", f)
- }
- }
- }
- ct.run()
-}
-
-// See golang.org/issue/13444
-func TestTransportFullDuplex(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(200) // redundant but for clarity
- w.(http.Flusher).Flush()
- io.Copy(flushWriter{w}, capitalizeReader{r.Body})
- fmt.Fprintf(w, "bye.\n")
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
- c := &http.Client{Transport: tr}
-
- pr, pw := io.Pipe()
- req, err := http.NewRequest("PUT", st.ts.URL, ioutil.NopCloser(pr))
- if err != nil {
- t.Fatal(err)
- }
- req.ContentLength = -1
- res, err := c.Do(req)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
- if res.StatusCode != 200 {
- t.Fatalf("StatusCode = %v; want %v", res.StatusCode, 200)
- }
- bs := bufio.NewScanner(res.Body)
- want := func(v string) {
- if !bs.Scan() {
- t.Fatalf("wanted to read %q but Scan() = false, err = %v", v, bs.Err())
- }
- }
- write := func(v string) {
- _, err := io.WriteString(pw, v)
- if err != nil {
- t.Fatalf("pipe write: %v", err)
- }
- }
- write("foo\n")
- want("FOO")
- write("bar\n")
- want("BAR")
- pw.Close()
- want("bye.")
- if err := bs.Err(); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestTransportConnectRequest(t *testing.T) {
- gotc := make(chan *http.Request, 1)
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- gotc <- r
- }, optOnlyServer)
- defer st.Close()
-
- u, err := url.Parse(st.ts.URL)
- if err != nil {
- t.Fatal(err)
- }
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
- c := &http.Client{Transport: tr}
-
- tests := []struct {
- req *http.Request
- want string
- }{
- {
- req: &http.Request{
- Method: "CONNECT",
- Header: http.Header{},
- URL: u,
- },
- want: u.Host,
- },
- {
- req: &http.Request{
- Method: "CONNECT",
- Header: http.Header{},
- URL: u,
- Host: "example.com:123",
- },
- want: "example.com:123",
- },
- }
-
- for i, tt := range tests {
- res, err := c.Do(tt.req)
- if err != nil {
- t.Errorf("%d. RoundTrip = %v", i, err)
- continue
- }
- res.Body.Close()
- req := <-gotc
- if req.Method != "CONNECT" {
- t.Errorf("method = %q; want CONNECT", req.Method)
- }
- if req.Host != tt.want {
- t.Errorf("Host = %q; want %q", req.Host, tt.want)
- }
- if req.URL.Host != tt.want {
- t.Errorf("URL.Host = %q; want %q", req.URL.Host, tt.want)
- }
- }
-}
-
-type headerType int
-
-const (
- noHeader headerType = iota // omitted
- oneHeader
- splitHeader // broken into continuation on purpose
-)
-
-const (
- f0 = noHeader
- f1 = oneHeader
- f2 = splitHeader
- d0 = false
- d1 = true
-)
-
-// Test all 36 combinations of response frame orders:
-// (3 ways of 100-continue) * (2 ways of headers) * (2 ways of data) * (3 ways of trailers):func TestTransportResponsePattern_00f0(t *testing.T) { testTransportResponsePattern(h0, h1, false, h0) }
-// Generated by http://play.golang.org/p/SScqYKJYXd
-func TestTransportResPattern_c0h1d0t0(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f0) }
-func TestTransportResPattern_c0h1d0t1(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f1) }
-func TestTransportResPattern_c0h1d0t2(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f2) }
-func TestTransportResPattern_c0h1d1t0(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f0) }
-func TestTransportResPattern_c0h1d1t1(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f1) }
-func TestTransportResPattern_c0h1d1t2(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f2) }
-func TestTransportResPattern_c0h2d0t0(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f0) }
-func TestTransportResPattern_c0h2d0t1(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f1) }
-func TestTransportResPattern_c0h2d0t2(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f2) }
-func TestTransportResPattern_c0h2d1t0(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f0) }
-func TestTransportResPattern_c0h2d1t1(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f1) }
-func TestTransportResPattern_c0h2d1t2(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f2) }
-func TestTransportResPattern_c1h1d0t0(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f0) }
-func TestTransportResPattern_c1h1d0t1(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f1) }
-func TestTransportResPattern_c1h1d0t2(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f2) }
-func TestTransportResPattern_c1h1d1t0(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f0) }
-func TestTransportResPattern_c1h1d1t1(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f1) }
-func TestTransportResPattern_c1h1d1t2(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f2) }
-func TestTransportResPattern_c1h2d0t0(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f0) }
-func TestTransportResPattern_c1h2d0t1(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f1) }
-func TestTransportResPattern_c1h2d0t2(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f2) }
-func TestTransportResPattern_c1h2d1t0(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f0) }
-func TestTransportResPattern_c1h2d1t1(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f1) }
-func TestTransportResPattern_c1h2d1t2(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f2) }
-func TestTransportResPattern_c2h1d0t0(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f0) }
-func TestTransportResPattern_c2h1d0t1(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f1) }
-func TestTransportResPattern_c2h1d0t2(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f2) }
-func TestTransportResPattern_c2h1d1t0(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f0) }
-func TestTransportResPattern_c2h1d1t1(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f1) }
-func TestTransportResPattern_c2h1d1t2(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f2) }
-func TestTransportResPattern_c2h2d0t0(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f0) }
-func TestTransportResPattern_c2h2d0t1(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f1) }
-func TestTransportResPattern_c2h2d0t2(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f2) }
-func TestTransportResPattern_c2h2d1t0(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f0) }
-func TestTransportResPattern_c2h2d1t1(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f1) }
-func TestTransportResPattern_c2h2d1t2(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f2) }
-
-func testTransportResPattern(t *testing.T, expect100Continue, resHeader headerType, withData bool, trailers headerType) {
- const reqBody = "some request body"
- const resBody = "some response body"
-
- if resHeader == noHeader {
- // TODO: test 100-continue followed by immediate
- // server stream reset, without headers in the middle?
- panic("invalid combination")
- }
-
- ct := newClientTester(t)
- ct.client = func() error {
- req, _ := http.NewRequest("POST", "https://dummy.tld/", strings.NewReader(reqBody))
- if expect100Continue != noHeader {
- req.Header.Set("Expect", "100-continue")
- }
- res, err := ct.tr.RoundTrip(req)
- if err != nil {
- return fmt.Errorf("RoundTrip: %v", err)
- }
- defer res.Body.Close()
- if res.StatusCode != 200 {
- return fmt.Errorf("status code = %v; want 200", res.StatusCode)
- }
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return fmt.Errorf("Slurp: %v", err)
- }
- wantBody := resBody
- if !withData {
- wantBody = ""
- }
- if string(slurp) != wantBody {
- return fmt.Errorf("body = %q; want %q", slurp, wantBody)
- }
- if trailers == noHeader {
- if len(res.Trailer) > 0 {
- t.Errorf("Trailer = %v; want none", res.Trailer)
- }
- } else {
- want := http.Header{"Some-Trailer": {"some-value"}}
- if !reflect.DeepEqual(res.Trailer, want) {
- t.Errorf("Trailer = %v; want %v", res.Trailer, want)
- }
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
-
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- return err
- }
- endStream := false
- send := func(mode headerType) {
- hbf := buf.Bytes()
- switch mode {
- case oneHeader:
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: f.Header().StreamID,
- EndHeaders: true,
- EndStream: endStream,
- BlockFragment: hbf,
- })
- case splitHeader:
- if len(hbf) < 2 {
- panic("too small")
- }
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: f.Header().StreamID,
- EndHeaders: false,
- EndStream: endStream,
- BlockFragment: hbf[:1],
- })
- ct.fr.WriteContinuation(f.Header().StreamID, true, hbf[1:])
- default:
- panic("bogus mode")
- }
- }
- switch f := f.(type) {
- case *WindowUpdateFrame, *SettingsFrame:
- case *DataFrame:
- if !f.StreamEnded() {
- // No need to send flow control tokens. The test request body is tiny.
- continue
- }
- // Response headers (1+ frames; 1 or 2 in this test, but never 0)
- {
- buf.Reset()
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- enc.WriteField(hpack.HeaderField{Name: "x-foo", Value: "blah"})
- enc.WriteField(hpack.HeaderField{Name: "x-bar", Value: "more"})
- if trailers != noHeader {
- enc.WriteField(hpack.HeaderField{Name: "trailer", Value: "some-trailer"})
- }
- endStream = withData == false && trailers == noHeader
- send(resHeader)
- }
- if withData {
- endStream = trailers == noHeader
- ct.fr.WriteData(f.StreamID, endStream, []byte(resBody))
- }
- if trailers != noHeader {
- endStream = true
- buf.Reset()
- enc.WriteField(hpack.HeaderField{Name: "some-trailer", Value: "some-value"})
- send(trailers)
- }
- if endStream {
- return nil
- }
- case *HeadersFrame:
- if expect100Continue != noHeader {
- buf.Reset()
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "100"})
- send(expect100Continue)
- }
- }
- }
- }
- ct.run()
-}
-
-func TestTransportReceiveUndeclaredTrailer(t *testing.T) {
- ct := newClientTester(t)
- ct.client = func() error {
- req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
- res, err := ct.tr.RoundTrip(req)
- if err != nil {
- return fmt.Errorf("RoundTrip: %v", err)
- }
- defer res.Body.Close()
- if res.StatusCode != 200 {
- return fmt.Errorf("status code = %v; want 200", res.StatusCode)
- }
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return fmt.Errorf("res.Body ReadAll error = %q, %v; want %v", slurp, err, nil)
- }
- if len(slurp) > 0 {
- return fmt.Errorf("body = %q; want nothing", slurp)
- }
- if _, ok := res.Trailer["Some-Trailer"]; !ok {
- return fmt.Errorf("expected Some-Trailer")
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
-
- var n int
- var hf *HeadersFrame
- for hf == nil && n < 10 {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- return err
- }
- hf, _ = f.(*HeadersFrame)
- n++
- }
-
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
-
- // send headers without Trailer header
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: hf.StreamID,
- EndHeaders: true,
- EndStream: false,
- BlockFragment: buf.Bytes(),
- })
-
- // send trailers
- buf.Reset()
- enc.WriteField(hpack.HeaderField{Name: "some-trailer", Value: "I'm an undeclared Trailer!"})
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: hf.StreamID,
- EndHeaders: true,
- EndStream: true,
- BlockFragment: buf.Bytes(),
- })
- return nil
- }
- ct.run()
-}
-
-func TestTransportInvalidTrailer_Pseudo1(t *testing.T) {
- testTransportInvalidTrailer_Pseudo(t, oneHeader)
-}
-func TestTransportInvalidTrailer_Pseudo2(t *testing.T) {
- testTransportInvalidTrailer_Pseudo(t, splitHeader)
-}
-func testTransportInvalidTrailer_Pseudo(t *testing.T, trailers headerType) {
- testInvalidTrailer(t, trailers, pseudoHeaderError(":colon"), func(enc *hpack.Encoder) {
- enc.WriteField(hpack.HeaderField{Name: ":colon", Value: "foo"})
- enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"})
- })
-}
-
-func TestTransportInvalidTrailer_Capital1(t *testing.T) {
- testTransportInvalidTrailer_Capital(t, oneHeader)
-}
-func TestTransportInvalidTrailer_Capital2(t *testing.T) {
- testTransportInvalidTrailer_Capital(t, splitHeader)
-}
-func testTransportInvalidTrailer_Capital(t *testing.T, trailers headerType) {
- testInvalidTrailer(t, trailers, headerFieldNameError("Capital"), func(enc *hpack.Encoder) {
- enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"})
- enc.WriteField(hpack.HeaderField{Name: "Capital", Value: "bad"})
- })
-}
-func TestTransportInvalidTrailer_EmptyFieldName(t *testing.T) {
- testInvalidTrailer(t, oneHeader, headerFieldNameError(""), func(enc *hpack.Encoder) {
- enc.WriteField(hpack.HeaderField{Name: "", Value: "bad"})
- })
-}
-func TestTransportInvalidTrailer_BinaryFieldValue(t *testing.T) {
- testInvalidTrailer(t, oneHeader, headerFieldValueError("has\nnewline"), func(enc *hpack.Encoder) {
- enc.WriteField(hpack.HeaderField{Name: "x", Value: "has\nnewline"})
- })
-}
-
-func testInvalidTrailer(t *testing.T, trailers headerType, wantErr error, writeTrailer func(*hpack.Encoder)) {
- ct := newClientTester(t)
- ct.client = func() error {
- req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
- res, err := ct.tr.RoundTrip(req)
- if err != nil {
- return fmt.Errorf("RoundTrip: %v", err)
- }
- defer res.Body.Close()
- if res.StatusCode != 200 {
- return fmt.Errorf("status code = %v; want 200", res.StatusCode)
- }
- slurp, err := ioutil.ReadAll(res.Body)
- se, ok := err.(StreamError)
- if !ok || se.Cause != wantErr {
- return fmt.Errorf("res.Body ReadAll error = %q, %#v; want StreamError with cause %T, %#v", slurp, err, wantErr, wantErr)
- }
- if len(slurp) > 0 {
- return fmt.Errorf("body = %q; want nothing", slurp)
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
-
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- return err
- }
- switch f := f.(type) {
- case *HeadersFrame:
- var endStream bool
- send := func(mode headerType) {
- hbf := buf.Bytes()
- switch mode {
- case oneHeader:
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: f.StreamID,
- EndHeaders: true,
- EndStream: endStream,
- BlockFragment: hbf,
- })
- case splitHeader:
- if len(hbf) < 2 {
- panic("too small")
- }
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: f.StreamID,
- EndHeaders: false,
- EndStream: endStream,
- BlockFragment: hbf[:1],
- })
- ct.fr.WriteContinuation(f.StreamID, true, hbf[1:])
- default:
- panic("bogus mode")
- }
- }
- // Response headers (1+ frames; 1 or 2 in this test, but never 0)
- {
- buf.Reset()
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- enc.WriteField(hpack.HeaderField{Name: "trailer", Value: "declared"})
- endStream = false
- send(oneHeader)
- }
- // Trailers:
- {
- endStream = true
- buf.Reset()
- writeTrailer(enc)
- send(trailers)
- }
- return nil
- }
- }
- }
- ct.run()
-}
-
-func TestTransportChecksResponseHeaderListSize(t *testing.T) {
- ct := newClientTester(t)
- ct.client = func() error {
- req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
- res, err := ct.tr.RoundTrip(req)
- if err != errResponseHeaderListSize {
- if res != nil {
- res.Body.Close()
- }
- size := int64(0)
- for k, vv := range res.Header {
- for _, v := range vv {
- size += int64(len(k)) + int64(len(v)) + 32
- }
- }
- return fmt.Errorf("RoundTrip Error = %v (and %d bytes of response headers); want errResponseHeaderListSize", err, size)
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
-
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- return err
- }
- switch f := f.(type) {
- case *HeadersFrame:
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- large := strings.Repeat("a", 1<<10)
- for i := 0; i < 5042; i++ {
- enc.WriteField(hpack.HeaderField{Name: large, Value: large})
- }
- if size, want := buf.Len(), 6329; size != want {
- // Note: this number might change if
- // our hpack implementation
- // changes. That's fine. This is
- // just a sanity check that our
- // response can fit in a single
- // header block fragment frame.
- return fmt.Errorf("encoding over 10MB of duplicate keypairs took %d bytes; expected %d", size, want)
- }
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: f.StreamID,
- EndHeaders: true,
- EndStream: true,
- BlockFragment: buf.Bytes(),
- })
- return nil
- }
- }
- }
- ct.run()
-}
-
-// Test that the the Transport returns a typed error from Response.Body.Read calls
-// when the server sends an error. (here we use a panic, since that should generate
-// a stream error, but others like cancel should be similar)
-func TestTransportBodyReadErrorType(t *testing.T) {
- doPanic := make(chan bool, 1)
- st := newServerTester(t,
- func(w http.ResponseWriter, r *http.Request) {
- w.(http.Flusher).Flush() // force headers out
- <-doPanic
- panic("boom")
- },
- optOnlyServer,
- optQuiet,
- )
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
- c := &http.Client{Transport: tr}
-
- res, err := c.Get(st.ts.URL)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
- doPanic <- true
- buf := make([]byte, 100)
- n, err := res.Body.Read(buf)
- want := StreamError{StreamID: 0x1, Code: 0x2}
- if !reflect.DeepEqual(want, err) {
- t.Errorf("Read = %v, %#v; want error %#v", n, err, want)
- }
-}
-
-// golang.org/issue/13924
-// This used to fail after many iterations, especially with -race:
-// go test -v -run=TestTransportDoubleCloseOnWriteError -count=500 -race
-func TestTransportDoubleCloseOnWriteError(t *testing.T) {
- var (
- mu sync.Mutex
- conn net.Conn // to close if set
- )
-
- st := newServerTester(t,
- func(w http.ResponseWriter, r *http.Request) {
- mu.Lock()
- defer mu.Unlock()
- if conn != nil {
- conn.Close()
- }
- },
- optOnlyServer,
- )
- defer st.Close()
-
- tr := &Transport{
- TLSClientConfig: tlsConfigInsecure,
- DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
- tc, err := tls.Dial(network, addr, cfg)
- if err != nil {
- return nil, err
- }
- mu.Lock()
- defer mu.Unlock()
- conn = tc
- return tc, nil
- },
- }
- defer tr.CloseIdleConnections()
- c := &http.Client{Transport: tr}
- c.Get(st.ts.URL)
-}
-
-// Test that the http1 Transport.DisableKeepAlives option is respected
-// and connections are closed as soon as idle.
-// See golang.org/issue/14008
-func TestTransportDisableKeepAlives(t *testing.T) {
- st := newServerTester(t,
- func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, "hi")
- },
- optOnlyServer,
- )
- defer st.Close()
-
- connClosed := make(chan struct{}) // closed on tls.Conn.Close
- tr := &Transport{
- t1: &http.Transport{
- DisableKeepAlives: true,
- },
- TLSClientConfig: tlsConfigInsecure,
- DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
- tc, err := tls.Dial(network, addr, cfg)
- if err != nil {
- return nil, err
- }
- return &noteCloseConn{Conn: tc, closefn: func() { close(connClosed) }}, nil
- },
- }
- c := &http.Client{Transport: tr}
- res, err := c.Get(st.ts.URL)
- if err != nil {
- t.Fatal(err)
- }
- if _, err := ioutil.ReadAll(res.Body); err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
-
- select {
- case <-connClosed:
- case <-time.After(1 * time.Second):
- t.Errorf("timeout")
- }
-
-}
-
-// Test concurrent requests with Transport.DisableKeepAlives. We can share connections,
-// but when things are totally idle, it still needs to close.
-func TestTransportDisableKeepAlives_Concurrency(t *testing.T) {
- const D = 25 * time.Millisecond
- st := newServerTester(t,
- func(w http.ResponseWriter, r *http.Request) {
- time.Sleep(D)
- io.WriteString(w, "hi")
- },
- optOnlyServer,
- )
- defer st.Close()
-
- var dials int32
- var conns sync.WaitGroup
- tr := &Transport{
- t1: &http.Transport{
- DisableKeepAlives: true,
- },
- TLSClientConfig: tlsConfigInsecure,
- DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
- tc, err := tls.Dial(network, addr, cfg)
- if err != nil {
- return nil, err
- }
- atomic.AddInt32(&dials, 1)
- conns.Add(1)
- return &noteCloseConn{Conn: tc, closefn: func() { conns.Done() }}, nil
- },
- }
- c := &http.Client{Transport: tr}
- var reqs sync.WaitGroup
- const N = 20
- for i := 0; i < N; i++ {
- reqs.Add(1)
- if i == N-1 {
- // For the final request, try to make all the
- // others close. This isn't verified in the
- // count, other than the Log statement, since
- // it's so timing dependent. This test is
- // really to make sure we don't interrupt a
- // valid request.
- time.Sleep(D * 2)
- }
- go func() {
- defer reqs.Done()
- res, err := c.Get(st.ts.URL)
- if err != nil {
- t.Error(err)
- return
- }
- if _, err := ioutil.ReadAll(res.Body); err != nil {
- t.Error(err)
- return
- }
- res.Body.Close()
- }()
- }
- reqs.Wait()
- conns.Wait()
- t.Logf("did %d dials, %d requests", atomic.LoadInt32(&dials), N)
-}
-
-type noteCloseConn struct {
- net.Conn
- onceClose sync.Once
- closefn func()
-}
-
-func (c *noteCloseConn) Close() error {
- c.onceClose.Do(c.closefn)
- return c.Conn.Close()
-}
-
-func isTimeout(err error) bool {
- switch err := err.(type) {
- case nil:
- return false
- case *url.Error:
- return isTimeout(err.Err)
- case net.Error:
- return err.Timeout()
- }
- return false
-}
-
-// Test that the http1 Transport.ResponseHeaderTimeout option and cancel is sent.
-func TestTransportResponseHeaderTimeout_NoBody(t *testing.T) {
- testTransportResponseHeaderTimeout(t, false)
-}
-func TestTransportResponseHeaderTimeout_Body(t *testing.T) {
- testTransportResponseHeaderTimeout(t, true)
-}
-
-func testTransportResponseHeaderTimeout(t *testing.T, body bool) {
- ct := newClientTester(t)
- ct.tr.t1 = &http.Transport{
- ResponseHeaderTimeout: 5 * time.Millisecond,
- }
- ct.client = func() error {
- c := &http.Client{Transport: ct.tr}
- var err error
- var n int64
- const bodySize = 4 << 20
- if body {
- _, err = c.Post("https://dummy.tld/", "text/foo", io.LimitReader(countingReader{&n}, bodySize))
- } else {
- _, err = c.Get("https://dummy.tld/")
- }
- if !isTimeout(err) {
- t.Errorf("client expected timeout error; got %#v", err)
- }
- if body && n != bodySize {
- t.Errorf("only read %d bytes of body; want %d", n, bodySize)
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- t.Logf("ReadFrame: %v", err)
- return nil
- }
- switch f := f.(type) {
- case *DataFrame:
- dataLen := len(f.Data())
- if dataLen > 0 {
- if err := ct.fr.WriteWindowUpdate(0, uint32(dataLen)); err != nil {
- return err
- }
- if err := ct.fr.WriteWindowUpdate(f.StreamID, uint32(dataLen)); err != nil {
- return err
- }
- }
- case *RSTStreamFrame:
- if f.StreamID == 1 && f.ErrCode == ErrCodeCancel {
- return nil
- }
- }
- }
- }
- ct.run()
-}
-
-func TestTransportDisableCompression(t *testing.T) {
- const body = "sup"
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- want := http.Header{
- "User-Agent": []string{"Go-http-client/2.0"},
- }
- if !reflect.DeepEqual(r.Header, want) {
- t.Errorf("request headers = %v; want %v", r.Header, want)
- }
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{
- TLSClientConfig: tlsConfigInsecure,
- t1: &http.Transport{
- DisableCompression: true,
- },
- }
- defer tr.CloseIdleConnections()
-
- req, err := http.NewRequest("GET", st.ts.URL, nil)
- if err != nil {
- t.Fatal(err)
- }
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal(err)
- }
- defer res.Body.Close()
-}
-
-// RFC 7540 section 8.1.2.2
-func TestTransportRejectsConnHeaders(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- var got []string
- for k := range r.Header {
- got = append(got, k)
- }
- sort.Strings(got)
- w.Header().Set("Got-Header", strings.Join(got, ","))
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- tests := []struct {
- key string
- value []string
- want string
- }{
- {
- key: "Upgrade",
- value: []string{"anything"},
- want: "ERROR: http2: invalid Upgrade request header: [\"anything\"]",
- },
- {
- key: "Connection",
- value: []string{"foo"},
- want: "ERROR: http2: invalid Connection request header: [\"foo\"]",
- },
- {
- key: "Connection",
- value: []string{"close"},
- want: "Accept-Encoding,User-Agent",
- },
- {
- key: "Connection",
- value: []string{"close", "something-else"},
- want: "ERROR: http2: invalid Connection request header: [\"close\" \"something-else\"]",
- },
- {
- key: "Connection",
- value: []string{"keep-alive"},
- want: "Accept-Encoding,User-Agent",
- },
- {
- key: "Proxy-Connection", // just deleted and ignored
- value: []string{"keep-alive"},
- want: "Accept-Encoding,User-Agent",
- },
- {
- key: "Transfer-Encoding",
- value: []string{""},
- want: "Accept-Encoding,User-Agent",
- },
- {
- key: "Transfer-Encoding",
- value: []string{"foo"},
- want: "ERROR: http2: invalid Transfer-Encoding request header: [\"foo\"]",
- },
- {
- key: "Transfer-Encoding",
- value: []string{"chunked"},
- want: "Accept-Encoding,User-Agent",
- },
- {
- key: "Transfer-Encoding",
- value: []string{"chunked", "other"},
- want: "ERROR: http2: invalid Transfer-Encoding request header: [\"chunked\" \"other\"]",
- },
- {
- key: "Content-Length",
- value: []string{"123"},
- want: "Accept-Encoding,User-Agent",
- },
- {
- key: "Keep-Alive",
- value: []string{"doop"},
- want: "Accept-Encoding,User-Agent",
- },
- }
-
- for _, tt := range tests {
- req, _ := http.NewRequest("GET", st.ts.URL, nil)
- req.Header[tt.key] = tt.value
- res, err := tr.RoundTrip(req)
- var got string
- if err != nil {
- got = fmt.Sprintf("ERROR: %v", err)
- } else {
- got = res.Header.Get("Got-Header")
- res.Body.Close()
- }
- if got != tt.want {
- t.Errorf("For key %q, value %q, got = %q; want %q", tt.key, tt.value, got, tt.want)
- }
- }
-}
-
-// golang.org/issue/14048
-func TestTransportFailsOnInvalidHeaders(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- var got []string
- for k := range r.Header {
- got = append(got, k)
- }
- sort.Strings(got)
- w.Header().Set("Got-Header", strings.Join(got, ","))
- }, optOnlyServer)
- defer st.Close()
-
- tests := [...]struct {
- h http.Header
- wantErr string
- }{
- 0: {
- h: http.Header{"with space": {"foo"}},
- wantErr: `invalid HTTP header name "with space"`,
- },
- 1: {
- h: http.Header{"name": {"Брэд"}},
- wantErr: "", // okay
- },
- 2: {
- h: http.Header{"имя": {"Brad"}},
- wantErr: `invalid HTTP header name "имя"`,
- },
- 3: {
- h: http.Header{"foo": {"foo\x01bar"}},
- wantErr: `invalid HTTP header value "foo\x01bar" for header "foo"`,
- },
- }
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- for i, tt := range tests {
- req, _ := http.NewRequest("GET", st.ts.URL, nil)
- req.Header = tt.h
- res, err := tr.RoundTrip(req)
- var bad bool
- if tt.wantErr == "" {
- if err != nil {
- bad = true
- t.Errorf("case %d: error = %v; want no error", i, err)
- }
- } else {
- if !strings.Contains(fmt.Sprint(err), tt.wantErr) {
- bad = true
- t.Errorf("case %d: error = %v; want error %q", i, err, tt.wantErr)
- }
- }
- if err == nil {
- if bad {
- t.Logf("case %d: server got headers %q", i, res.Header.Get("Got-Header"))
- }
- res.Body.Close()
- }
- }
-}
-
-// Tests that gzipReader doesn't crash on a second Read call following
-// the first Read call's gzip.NewReader returning an error.
-func TestGzipReader_DoubleReadCrash(t *testing.T) {
- gz := &gzipReader{
- body: ioutil.NopCloser(strings.NewReader("0123456789")),
- }
- var buf [1]byte
- n, err1 := gz.Read(buf[:])
- if n != 0 || !strings.Contains(fmt.Sprint(err1), "invalid header") {
- t.Fatalf("Read = %v, %v; want 0, invalid header", n, err1)
- }
- n, err2 := gz.Read(buf[:])
- if n != 0 || err2 != err1 {
- t.Fatalf("second Read = %v, %v; want 0, %v", n, err2, err1)
- }
-}
-
-func TestTransportNewTLSConfig(t *testing.T) {
- tests := [...]struct {
- conf *tls.Config
- host string
- want *tls.Config
- }{
- // Normal case.
- 0: {
- conf: nil,
- host: "foo.com",
- want: &tls.Config{
- ServerName: "foo.com",
- NextProtos: []string{NextProtoTLS},
- },
- },
-
- // User-provided name (bar.com) takes precedence:
- 1: {
- conf: &tls.Config{
- ServerName: "bar.com",
- },
- host: "foo.com",
- want: &tls.Config{
- ServerName: "bar.com",
- NextProtos: []string{NextProtoTLS},
- },
- },
-
- // NextProto is prepended:
- 2: {
- conf: &tls.Config{
- NextProtos: []string{"foo", "bar"},
- },
- host: "example.com",
- want: &tls.Config{
- ServerName: "example.com",
- NextProtos: []string{NextProtoTLS, "foo", "bar"},
- },
- },
-
- // NextProto is not duplicated:
- 3: {
- conf: &tls.Config{
- NextProtos: []string{"foo", "bar", NextProtoTLS},
- },
- host: "example.com",
- want: &tls.Config{
- ServerName: "example.com",
- NextProtos: []string{"foo", "bar", NextProtoTLS},
- },
- },
- }
- for i, tt := range tests {
- // Ignore the session ticket keys part, which ends up populating
- // unexported fields in the Config:
- if tt.conf != nil {
- tt.conf.SessionTicketsDisabled = true
- }
-
- tr := &Transport{TLSClientConfig: tt.conf}
- got := tr.newTLSConfig(tt.host)
-
- got.SessionTicketsDisabled = false
-
- if !reflect.DeepEqual(got, tt.want) {
- t.Errorf("%d. got %#v; want %#v", i, got, tt.want)
- }
- }
-}
-
-// The Google GFE responds to HEAD requests with a HEADERS frame
-// without END_STREAM, followed by a 0-length DATA frame with
-// END_STREAM. Make sure we don't get confused by that. (We did.)
-func TestTransportReadHeadResponse(t *testing.T) {
- ct := newClientTester(t)
- clientDone := make(chan struct{})
- ct.client = func() error {
- defer close(clientDone)
- req, _ := http.NewRequest("HEAD", "https://dummy.tld/", nil)
- res, err := ct.tr.RoundTrip(req)
- if err != nil {
- return err
- }
- if res.ContentLength != 123 {
- return fmt.Errorf("Content-Length = %d; want 123", res.ContentLength)
- }
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return fmt.Errorf("ReadAll: %v", err)
- }
- if len(slurp) > 0 {
- return fmt.Errorf("Unexpected non-empty ReadAll body: %q", slurp)
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- t.Logf("ReadFrame: %v", err)
- return nil
- }
- hf, ok := f.(*HeadersFrame)
- if !ok {
- continue
- }
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "123"})
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: hf.StreamID,
- EndHeaders: true,
- EndStream: false, // as the GFE does
- BlockFragment: buf.Bytes(),
- })
- ct.fr.WriteData(hf.StreamID, true, nil)
-
- <-clientDone
- return nil
- }
- }
- ct.run()
-}
-
-type neverEnding byte
-
-func (b neverEnding) Read(p []byte) (int, error) {
- for i := range p {
- p[i] = byte(b)
- }
- return len(p), nil
-}
-
-// golang.org/issue/15425: test that a handler closing the request
-// body doesn't terminate the stream to the peer. (It just stops
-// readability from the handler's side, and eventually the client
-// runs out of flow control tokens)
-func TestTransportHandlerBodyClose(t *testing.T) {
- const bodySize = 10 << 20
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- r.Body.Close()
- io.Copy(w, io.LimitReader(neverEnding('A'), bodySize))
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- g0 := runtime.NumGoroutine()
-
- const numReq = 10
- for i := 0; i < numReq; i++ {
- req, err := http.NewRequest("POST", st.ts.URL, struct{ io.Reader }{io.LimitReader(neverEnding('A'), bodySize)})
- if err != nil {
- t.Fatal(err)
- }
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal(err)
- }
- n, err := io.Copy(ioutil.Discard, res.Body)
- res.Body.Close()
- if n != bodySize || err != nil {
- t.Fatalf("req#%d: Copy = %d, %v; want %d, nil", i, n, err, bodySize)
- }
- }
- tr.CloseIdleConnections()
-
- gd := runtime.NumGoroutine() - g0
- if gd > numReq/2 {
- t.Errorf("appeared to leak goroutines")
- }
-
-}
-
-// https://golang.org/issue/15930
-func TestTransportFlowControl(t *testing.T) {
- const bufLen = 64 << 10
- var total int64 = 100 << 20 // 100MB
- if testing.Short() {
- total = 10 << 20
- }
-
- var wrote int64 // updated atomically
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- b := make([]byte, bufLen)
- for wrote < total {
- n, err := w.Write(b)
- atomic.AddInt64(&wrote, int64(n))
- if err != nil {
- t.Errorf("ResponseWriter.Write error: %v", err)
- break
- }
- w.(http.Flusher).Flush()
- }
- }, optOnlyServer)
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
- req, err := http.NewRequest("GET", st.ts.URL, nil)
- if err != nil {
- t.Fatal("NewRequest error:", err)
- }
- resp, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatal("RoundTrip error:", err)
- }
- defer resp.Body.Close()
-
- var read int64
- b := make([]byte, bufLen)
- for {
- n, err := resp.Body.Read(b)
- if err == io.EOF {
- break
- }
- if err != nil {
- t.Fatal("Read error:", err)
- }
- read += int64(n)
-
- const max = transportDefaultStreamFlow
- if w := atomic.LoadInt64(&wrote); -max > read-w || read-w > max {
- t.Fatalf("Too much data inflight: server wrote %v bytes but client only received %v", w, read)
- }
-
- // Let the server get ahead of the client.
- time.Sleep(1 * time.Millisecond)
- }
-}
-
-// golang.org/issue/14627 -- if the server sends a GOAWAY frame, make
-// the Transport remember it and return it back to users (via
-// RoundTrip or request body reads) if needed (e.g. if the server
-// proceeds to close the TCP connection before the client gets its
-// response)
-func TestTransportUsesGoAwayDebugError_RoundTrip(t *testing.T) {
- testTransportUsesGoAwayDebugError(t, false)
-}
-
-func TestTransportUsesGoAwayDebugError_Body(t *testing.T) {
- testTransportUsesGoAwayDebugError(t, true)
-}
-
-func testTransportUsesGoAwayDebugError(t *testing.T, failMidBody bool) {
- ct := newClientTester(t)
- clientDone := make(chan struct{})
-
- const goAwayErrCode = ErrCodeHTTP11Required // arbitrary
- const goAwayDebugData = "some debug data"
-
- ct.client = func() error {
- defer close(clientDone)
- req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
- res, err := ct.tr.RoundTrip(req)
- if failMidBody {
- if err != nil {
- return fmt.Errorf("unexpected client RoundTrip error: %v", err)
- }
- _, err = io.Copy(ioutil.Discard, res.Body)
- res.Body.Close()
- }
- want := GoAwayError{
- LastStreamID: 5,
- ErrCode: goAwayErrCode,
- DebugData: goAwayDebugData,
- }
- if !reflect.DeepEqual(err, want) {
- t.Errorf("RoundTrip error = %T: %#v, want %T (%#v)", err, err, want, want)
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- t.Logf("ReadFrame: %v", err)
- return nil
- }
- hf, ok := f.(*HeadersFrame)
- if !ok {
- continue
- }
- if failMidBody {
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "123"})
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: hf.StreamID,
- EndHeaders: true,
- EndStream: false,
- BlockFragment: buf.Bytes(),
- })
- }
- // Write two GOAWAY frames, to test that the Transport takes
- // the interesting parts of both.
- ct.fr.WriteGoAway(5, ErrCodeNo, []byte(goAwayDebugData))
- ct.fr.WriteGoAway(5, goAwayErrCode, nil)
- ct.sc.(*net.TCPConn).CloseWrite()
- <-clientDone
- return nil
- }
- }
- ct.run()
-}
-
-// See golang.org/issue/16481
-func TestTransportReturnsUnusedFlowControl(t *testing.T) {
- ct := newClientTester(t)
-
- clientClosed := make(chan bool, 1)
- serverWroteBody := make(chan bool, 1)
-
- ct.client = func() error {
- req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
- res, err := ct.tr.RoundTrip(req)
- if err != nil {
- return err
- }
- <-serverWroteBody
-
- if n, err := res.Body.Read(make([]byte, 1)); err != nil || n != 1 {
- return fmt.Errorf("body read = %v, %v; want 1, nil", n, err)
- }
- res.Body.Close() // leaving 4999 bytes unread
- clientClosed <- true
-
- return nil
- }
- ct.server = func() error {
- ct.greet()
-
- var hf *HeadersFrame
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- return fmt.Errorf("ReadFrame while waiting for Headers: %v", err)
- }
- switch f.(type) {
- case *WindowUpdateFrame, *SettingsFrame:
- continue
- }
- var ok bool
- hf, ok = f.(*HeadersFrame)
- if !ok {
- return fmt.Errorf("Got %T; want HeadersFrame", f)
- }
- break
- }
-
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "5000"})
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: hf.StreamID,
- EndHeaders: true,
- EndStream: false,
- BlockFragment: buf.Bytes(),
- })
- ct.fr.WriteData(hf.StreamID, false, make([]byte, 5000)) // without ending stream
- serverWroteBody <- true
-
- <-clientClosed
-
- waitingFor := "RSTStreamFrame"
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- return fmt.Errorf("ReadFrame while waiting for %s: %v", waitingFor, err)
- }
- if _, ok := f.(*SettingsFrame); ok {
- continue
- }
- switch waitingFor {
- case "RSTStreamFrame":
- if rf, ok := f.(*RSTStreamFrame); !ok || rf.ErrCode != ErrCodeCancel {
- return fmt.Errorf("Expected a WindowUpdateFrame with code cancel; got %v", summarizeFrame(f))
- }
- waitingFor = "WindowUpdateFrame"
- case "WindowUpdateFrame":
- if wuf, ok := f.(*WindowUpdateFrame); !ok || wuf.Increment != 4999 {
- return fmt.Errorf("Expected WindowUpdateFrame for 4999 bytes; got %v", summarizeFrame(f))
- }
- return nil
- }
- }
- }
- ct.run()
-}
-
-// Issue 16612: adjust flow control on open streams when transport
-// receives SETTINGS with INITIAL_WINDOW_SIZE from server.
-func TestTransportAdjustsFlowControl(t *testing.T) {
- ct := newClientTester(t)
- clientDone := make(chan struct{})
-
- const bodySize = 1 << 20
-
- ct.client = func() error {
- defer ct.cc.(*net.TCPConn).CloseWrite()
- defer close(clientDone)
-
- req, _ := http.NewRequest("POST", "https://dummy.tld/", struct{ io.Reader }{io.LimitReader(neverEnding('A'), bodySize)})
- res, err := ct.tr.RoundTrip(req)
- if err != nil {
- return err
- }
- res.Body.Close()
- return nil
- }
- ct.server = func() error {
- _, err := io.ReadFull(ct.sc, make([]byte, len(ClientPreface)))
- if err != nil {
- return fmt.Errorf("reading client preface: %v", err)
- }
-
- var gotBytes int64
- var sentSettings bool
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- select {
- case <-clientDone:
- return nil
- default:
- return fmt.Errorf("ReadFrame while waiting for Headers: %v", err)
- }
- }
- switch f := f.(type) {
- case *DataFrame:
- gotBytes += int64(len(f.Data()))
- // After we've got half the client's
- // initial flow control window's worth
- // of request body data, give it just
- // enough flow control to finish.
- if gotBytes >= initialWindowSize/2 && !sentSettings {
- sentSettings = true
-
- ct.fr.WriteSettings(Setting{ID: SettingInitialWindowSize, Val: bodySize})
- ct.fr.WriteWindowUpdate(0, bodySize)
- ct.fr.WriteSettingsAck()
- }
-
- if f.StreamEnded() {
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: f.StreamID,
- EndHeaders: true,
- EndStream: true,
- BlockFragment: buf.Bytes(),
- })
- }
- }
- }
- }
- ct.run()
-}
-
-// See golang.org/issue/16556
-func TestTransportReturnsDataPaddingFlowControl(t *testing.T) {
- ct := newClientTester(t)
-
- unblockClient := make(chan bool, 1)
-
- ct.client = func() error {
- req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
- res, err := ct.tr.RoundTrip(req)
- if err != nil {
- return err
- }
- defer res.Body.Close()
- <-unblockClient
- return nil
- }
- ct.server = func() error {
- ct.greet()
-
- var hf *HeadersFrame
- for {
- f, err := ct.fr.ReadFrame()
- if err != nil {
- return fmt.Errorf("ReadFrame while waiting for Headers: %v", err)
- }
- switch f.(type) {
- case *WindowUpdateFrame, *SettingsFrame:
- continue
- }
- var ok bool
- hf, ok = f.(*HeadersFrame)
- if !ok {
- return fmt.Errorf("Got %T; want HeadersFrame", f)
- }
- break
- }
-
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "5000"})
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: hf.StreamID,
- EndHeaders: true,
- EndStream: false,
- BlockFragment: buf.Bytes(),
- })
- pad := make([]byte, 5)
- ct.fr.WriteDataPadded(hf.StreamID, false, make([]byte, 5000), pad) // without ending stream
-
- f, err := ct.readNonSettingsFrame()
- if err != nil {
- return fmt.Errorf("ReadFrame while waiting for first WindowUpdateFrame: %v", err)
- }
- wantBack := uint32(len(pad)) + 1 // one byte for the length of the padding
- if wuf, ok := f.(*WindowUpdateFrame); !ok || wuf.Increment != wantBack || wuf.StreamID != 0 {
- return fmt.Errorf("Expected conn WindowUpdateFrame for %d bytes; got %v", wantBack, summarizeFrame(f))
- }
-
- f, err = ct.readNonSettingsFrame()
- if err != nil {
- return fmt.Errorf("ReadFrame while waiting for second WindowUpdateFrame: %v", err)
- }
- if wuf, ok := f.(*WindowUpdateFrame); !ok || wuf.Increment != wantBack || wuf.StreamID == 0 {
- return fmt.Errorf("Expected stream WindowUpdateFrame for %d bytes; got %v", wantBack, summarizeFrame(f))
- }
- unblockClient <- true
- return nil
- }
- ct.run()
-}
-
-// golang.org/issue/16572 -- RoundTrip shouldn't hang when it gets a
-// StreamError as a result of the response HEADERS
-func TestTransportReturnsErrorOnBadResponseHeaders(t *testing.T) {
- ct := newClientTester(t)
-
- ct.client = func() error {
- req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
- res, err := ct.tr.RoundTrip(req)
- if err == nil {
- res.Body.Close()
- return errors.New("unexpected successful GET")
- }
- want := StreamError{1, ErrCodeProtocol, headerFieldNameError(" content-type")}
- if !reflect.DeepEqual(want, err) {
- t.Errorf("RoundTrip error = %#v; want %#v", err, want)
- }
- return nil
- }
- ct.server = func() error {
- ct.greet()
-
- hf, err := ct.firstHeaders()
- if err != nil {
- return err
- }
-
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- enc.WriteField(hpack.HeaderField{Name: " content-type", Value: "bogus"}) // bogus spaces
- ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: hf.StreamID,
- EndHeaders: true,
- EndStream: false,
- BlockFragment: buf.Bytes(),
- })
-
- for {
- fr, err := ct.readFrame()
- if err != nil {
- return fmt.Errorf("error waiting for RST_STREAM from client: %v", err)
- }
- if _, ok := fr.(*SettingsFrame); ok {
- continue
- }
- if rst, ok := fr.(*RSTStreamFrame); !ok || rst.StreamID != 1 || rst.ErrCode != ErrCodeProtocol {
- t.Errorf("Frame = %v; want RST_STREAM for stream 1 with ErrCodeProtocol", summarizeFrame(fr))
- }
- break
- }
-
- return nil
- }
- ct.run()
-}
-
-// byteAndEOFReader returns is in an io.Reader which reads one byte
-// (the underlying byte) and io.EOF at once in its Read call.
-type byteAndEOFReader byte
-
-func (b byteAndEOFReader) Read(p []byte) (n int, err error) {
- if len(p) == 0 {
- panic("unexpected useless call")
- }
- p[0] = byte(b)
- return 1, io.EOF
-}
-
-// Issue 16788: the Transport had a regression where it started
-// sending a spurious DATA frame with a duplicate END_STREAM bit after
-// the request body writer goroutine had already read an EOF from the
-// Request.Body and included the END_STREAM on a data-carrying DATA
-// frame.
-//
-// Notably, to trigger this, the requests need to use a Request.Body
-// which returns (non-0, io.EOF) and also needs to set the ContentLength
-// explicitly.
-func TestTransportBodyDoubleEndStream(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- // Nothing.
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- for i := 0; i < 2; i++ {
- req, _ := http.NewRequest("POST", st.ts.URL, byteAndEOFReader('a'))
- req.ContentLength = 1
- res, err := tr.RoundTrip(req)
- if err != nil {
- t.Fatalf("failure on req %d: %v", i+1, err)
- }
- defer res.Body.Close()
- }
-}
-
-// golangorg/issue/16847
-func TestTransportRequestPathPseudo(t *testing.T) {
- type result struct {
- path string
- err string
- }
- tests := []struct {
- req *http.Request
- want result
- }{
- 0: {
- req: &http.Request{
- Method: "GET",
- URL: &url.URL{
- Host: "foo.com",
- Path: "/foo",
- },
- },
- want: result{path: "/foo"},
- },
- // I guess we just don't let users request "//foo" as
- // a path, since it's illegal to start with two
- // slashes....
- 1: {
- req: &http.Request{
- Method: "GET",
- URL: &url.URL{
- Host: "foo.com",
- Path: "//foo",
- },
- },
- want: result{err: `invalid request :path "//foo"`},
- },
-
- // Opaque with //$Matching_Hostname/path
- 2: {
- req: &http.Request{
- Method: "GET",
- URL: &url.URL{
- Scheme: "https",
- Opaque: "//foo.com/path",
- Host: "foo.com",
- Path: "/ignored",
- },
- },
- want: result{path: "/path"},
- },
-
- // Opaque with some other Request.Host instead:
- 3: {
- req: &http.Request{
- Method: "GET",
- Host: "bar.com",
- URL: &url.URL{
- Scheme: "https",
- Opaque: "//bar.com/path",
- Host: "foo.com",
- Path: "/ignored",
- },
- },
- want: result{path: "/path"},
- },
-
- // Opaque without the leading "//":
- 4: {
- req: &http.Request{
- Method: "GET",
- URL: &url.URL{
- Opaque: "/path",
- Host: "foo.com",
- Path: "/ignored",
- },
- },
- want: result{path: "/path"},
- },
-
- // Opaque we can't handle:
- 5: {
- req: &http.Request{
- Method: "GET",
- URL: &url.URL{
- Scheme: "https",
- Opaque: "//unknown_host/path",
- Host: "foo.com",
- Path: "/ignored",
- },
- },
- want: result{err: `invalid request :path "https://unknown_host/path" from URL.Opaque = "//unknown_host/path"`},
- },
-
- // A CONNECT request:
- 6: {
- req: &http.Request{
- Method: "CONNECT",
- URL: &url.URL{
- Host: "foo.com",
- },
- },
- want: result{},
- },
- }
- for i, tt := range tests {
- cc := &ClientConn{}
- cc.henc = hpack.NewEncoder(&cc.hbuf)
- cc.mu.Lock()
- hdrs, err := cc.encodeHeaders(tt.req, false, "", -1)
- cc.mu.Unlock()
- var got result
- hpackDec := hpack.NewDecoder(initialHeaderTableSize, func(f hpack.HeaderField) {
- if f.Name == ":path" {
- got.path = f.Value
- }
- })
- if err != nil {
- got.err = err.Error()
- } else if len(hdrs) > 0 {
- if _, err := hpackDec.Write(hdrs); err != nil {
- t.Errorf("%d. bogus hpack: %v", i, err)
- continue
- }
- }
- if got != tt.want {
- t.Errorf("%d. got %+v; want %+v", i, got, tt.want)
- }
-
- }
-
-}
-
-// golang.org/issue/17071 -- don't sniff the first byte of the request body
-// before we've determined that the ClientConn is usable.
-func TestRoundTripDoesntConsumeRequestBodyEarly(t *testing.T) {
- const body = "foo"
- req, _ := http.NewRequest("POST", "http://foo.com/", ioutil.NopCloser(strings.NewReader(body)))
- cc := &ClientConn{
- closed: true,
- }
- _, err := cc.RoundTrip(req)
- if err != errClientConnUnusable {
- t.Fatalf("RoundTrip = %v; want errClientConnUnusable", err)
- }
- slurp, err := ioutil.ReadAll(req.Body)
- if err != nil {
- t.Errorf("ReadAll = %v", err)
- }
- if string(slurp) != body {
- t.Errorf("Body = %q; want %q", slurp, body)
- }
-}
-
-func TestClientConnPing(t *testing.T) {
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, optOnlyServer)
- defer st.Close()
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
- cc, err := tr.dialClientConn(st.ts.Listener.Addr().String(), false)
- if err != nil {
- t.Fatal(err)
- }
- if err = cc.Ping(testContext{}); err != nil {
- t.Fatal(err)
- }
-}
-
-// Issue 16974: if the server sent a DATA frame after the user
-// canceled the Transport's Request, the Transport previously wrote to a
-// closed pipe, got an error, and ended up closing the whole TCP
-// connection.
-func TestTransportCancelDataResponseRace(t *testing.T) {
- cancel := make(chan struct{})
- clientGotError := make(chan bool, 1)
-
- const msg = "Hello."
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- if strings.Contains(r.URL.Path, "/hello") {
- time.Sleep(50 * time.Millisecond)
- io.WriteString(w, msg)
- return
- }
- for i := 0; i < 50; i++ {
- io.WriteString(w, "Some data.")
- w.(http.Flusher).Flush()
- if i == 2 {
- close(cancel)
- <-clientGotError
- }
- time.Sleep(10 * time.Millisecond)
- }
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
-
- c := &http.Client{Transport: tr}
- req, _ := http.NewRequest("GET", st.ts.URL, nil)
- req.Cancel = cancel
- res, err := c.Do(req)
- if err != nil {
- t.Fatal(err)
- }
- if _, err = io.Copy(ioutil.Discard, res.Body); err == nil {
- t.Fatal("unexpected success")
- }
- clientGotError <- true
-
- res, err = c.Get(st.ts.URL + "/hello")
- if err != nil {
- t.Fatal(err)
- }
- slurp, err := ioutil.ReadAll(res.Body)
- if err != nil {
- t.Fatal(err)
- }
- if string(slurp) != msg {
- t.Errorf("Got = %q; want %q", slurp, msg)
- }
-}
-
-func TestTransportRetryAfterGOAWAY(t *testing.T) {
- var dialer struct {
- sync.Mutex
- count int
- }
- ct1 := make(chan *clientTester)
- ct2 := make(chan *clientTester)
-
- ln := newLocalListener(t)
- defer ln.Close()
-
- tr := &Transport{
- TLSClientConfig: tlsConfigInsecure,
- }
- tr.DialTLS = func(network, addr string, cfg *tls.Config) (net.Conn, error) {
- dialer.Lock()
- defer dialer.Unlock()
- dialer.count++
- if dialer.count == 3 {
- return nil, errors.New("unexpected number of dials")
- }
- cc, err := net.Dial("tcp", ln.Addr().String())
- if err != nil {
- return nil, fmt.Errorf("dial error: %v", err)
- }
- sc, err := ln.Accept()
- if err != nil {
- return nil, fmt.Errorf("accept error: %v", err)
- }
- ct := &clientTester{
- t: t,
- tr: tr,
- cc: cc,
- sc: sc,
- fr: NewFramer(sc, sc),
- }
- switch dialer.count {
- case 1:
- ct1 <- ct
- case 2:
- ct2 <- ct
- }
- return cc, nil
- }
-
- errs := make(chan error, 3)
- done := make(chan struct{})
- defer close(done)
-
- // Client.
- go func() {
- req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
- res, err := tr.RoundTrip(req)
- if res != nil {
- res.Body.Close()
- if got := res.Header.Get("Foo"); got != "bar" {
- err = fmt.Errorf("foo header = %q; want bar", got)
- }
- }
- if err != nil {
- err = fmt.Errorf("RoundTrip: %v", err)
- }
- errs <- err
- }()
-
- connToClose := make(chan io.Closer, 2)
-
- // Server for the first request.
- go func() {
- var ct *clientTester
- select {
- case ct = <-ct1:
- case <-done:
- return
- }
-
- connToClose <- ct.cc
- ct.greet()
- hf, err := ct.firstHeaders()
- if err != nil {
- errs <- fmt.Errorf("server1 failed reading HEADERS: %v", err)
- return
- }
- t.Logf("server1 got %v", hf)
- if err := ct.fr.WriteGoAway(0 /*max id*/, ErrCodeNo, nil); err != nil {
- errs <- fmt.Errorf("server1 failed writing GOAWAY: %v", err)
- return
- }
- errs <- nil
- }()
-
- // Server for the second request.
- go func() {
- var ct *clientTester
- select {
- case ct = <-ct2:
- case <-done:
- return
- }
-
- connToClose <- ct.cc
- ct.greet()
- hf, err := ct.firstHeaders()
- if err != nil {
- errs <- fmt.Errorf("server2 failed reading HEADERS: %v", err)
- return
- }
- t.Logf("server2 got %v", hf)
-
- var buf bytes.Buffer
- enc := hpack.NewEncoder(&buf)
- enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
- enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"})
- err = ct.fr.WriteHeaders(HeadersFrameParam{
- StreamID: hf.StreamID,
- EndHeaders: true,
- EndStream: false,
- BlockFragment: buf.Bytes(),
- })
- if err != nil {
- errs <- fmt.Errorf("server2 failed writing response HEADERS: %v", err)
- } else {
- errs <- nil
- }
- }()
-
- for k := 0; k < 3; k++ {
- select {
- case err := <-errs:
- if err != nil {
- t.Error(err)
- }
- case <-time.After(1 * time.Second):
- t.Errorf("timed out")
- }
- }
-
- for {
- select {
- case c := <-connToClose:
- c.Close()
- default:
- return
- }
- }
-}
-
-func TestAuthorityAddr(t *testing.T) {
- tests := []struct {
- scheme, authority string
- want string
- }{
- {"http", "foo.com", "foo.com:80"},
- {"https", "foo.com", "foo.com:443"},
- {"https", "foo.com:1234", "foo.com:1234"},
- {"https", "1.2.3.4:1234", "1.2.3.4:1234"},
- {"https", "1.2.3.4", "1.2.3.4:443"},
- {"https", "[::1]:1234", "[::1]:1234"},
- {"https", "[::1]", "[::1]:443"},
- }
- for _, tt := range tests {
- got := authorityAddr(tt.scheme, tt.authority)
- if got != tt.want {
- t.Errorf("authorityAddr(%q, %q) = %q; want %q", tt.scheme, tt.authority, got, tt.want)
- }
- }
-}
-
-// Issue 20448: stop allocating for DATA frames' payload after
-// Response.Body.Close is called.
-func TestTransportAllocationsAfterResponseBodyClose(t *testing.T) {
- megabyteZero := make([]byte, 1<<20)
-
- writeErr := make(chan error, 1)
-
- st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
- w.(http.Flusher).Flush()
- var sum int64
- for i := 0; i < 100; i++ {
- n, err := w.Write(megabyteZero)
- sum += int64(n)
- if err != nil {
- writeErr <- err
- return
- }
- }
- t.Logf("wrote all %d bytes", sum)
- writeErr <- nil
- }, optOnlyServer)
- defer st.Close()
-
- tr := &Transport{TLSClientConfig: tlsConfigInsecure}
- defer tr.CloseIdleConnections()
- c := &http.Client{Transport: tr}
- res, err := c.Get(st.ts.URL)
- if err != nil {
- t.Fatal(err)
- }
- var buf [1]byte
- if _, err := res.Body.Read(buf[:]); err != nil {
- t.Error(err)
- }
- if err := res.Body.Close(); err != nil {
- t.Error(err)
- }
-
- trb, ok := res.Body.(transportResponseBody)
- if !ok {
- t.Fatalf("res.Body = %T; want transportResponseBody", res.Body)
- }
- if trb.cs.bufPipe.b != nil {
- t.Errorf("response body pipe is still open")
- }
-
- gotErr := <-writeErr
- if gotErr == nil {
- t.Errorf("Handler unexpectedly managed to write its entire response without getting an error")
- } else if gotErr != errStreamClosed {
- t.Errorf("Handler Write err = %v; want errStreamClosed", gotErr)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go
deleted file mode 100644
index 6b0dfae31..000000000
--- a/vendor/golang.org/x/net/http2/write.go
+++ /dev/null
@@ -1,370 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bytes"
- "fmt"
- "log"
- "net/http"
- "net/url"
- "time"
-
- "golang.org/x/net/http2/hpack"
- "golang.org/x/net/lex/httplex"
-)
-
-// writeFramer is implemented by any type that is used to write frames.
-type writeFramer interface {
- writeFrame(writeContext) error
-
- // staysWithinBuffer reports whether this writer promises that
- // it will only write less than or equal to size bytes, and it
- // won't Flush the write context.
- staysWithinBuffer(size int) bool
-}
-
-// writeContext is the interface needed by the various frame writer
-// types below. All the writeFrame methods below are scheduled via the
-// frame writing scheduler (see writeScheduler in writesched.go).
-//
-// This interface is implemented by *serverConn.
-//
-// TODO: decide whether to a) use this in the client code (which didn't
-// end up using this yet, because it has a simpler design, not
-// currently implementing priorities), or b) delete this and
-// make the server code a bit more concrete.
-type writeContext interface {
- Framer() *Framer
- Flush() error
- CloseConn() error
- // HeaderEncoder returns an HPACK encoder that writes to the
- // returned buffer.
- HeaderEncoder() (*hpack.Encoder, *bytes.Buffer)
-}
-
-// writeEndsStream reports whether w writes a frame that will transition
-// the stream to a half-closed local state. This returns false for RST_STREAM,
-// which closes the entire stream (not just the local half).
-func writeEndsStream(w writeFramer) bool {
- switch v := w.(type) {
- case *writeData:
- return v.endStream
- case *writeResHeaders:
- return v.endStream
- case nil:
- // This can only happen if the caller reuses w after it's
- // been intentionally nil'ed out to prevent use. Keep this
- // here to catch future refactoring breaking it.
- panic("writeEndsStream called on nil writeFramer")
- }
- return false
-}
-
-type flushFrameWriter struct{}
-
-func (flushFrameWriter) writeFrame(ctx writeContext) error {
- return ctx.Flush()
-}
-
-func (flushFrameWriter) staysWithinBuffer(max int) bool { return false }
-
-type writeSettings []Setting
-
-func (s writeSettings) staysWithinBuffer(max int) bool {
- const settingSize = 6 // uint16 + uint32
- return frameHeaderLen+settingSize*len(s) <= max
-
-}
-
-func (s writeSettings) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteSettings([]Setting(s)...)
-}
-
-type writeGoAway struct {
- maxStreamID uint32
- code ErrCode
-}
-
-func (p *writeGoAway) writeFrame(ctx writeContext) error {
- err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)
- if p.code != 0 {
- ctx.Flush() // ignore error: we're hanging up on them anyway
- time.Sleep(50 * time.Millisecond)
- ctx.CloseConn()
- }
- return err
-}
-
-func (*writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes
-
-type writeData struct {
- streamID uint32
- p []byte
- endStream bool
-}
-
-func (w *writeData) String() string {
- return fmt.Sprintf("writeData(stream=%d, p=%d, endStream=%v)", w.streamID, len(w.p), w.endStream)
-}
-
-func (w *writeData) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteData(w.streamID, w.endStream, w.p)
-}
-
-func (w *writeData) staysWithinBuffer(max int) bool {
- return frameHeaderLen+len(w.p) <= max
-}
-
-// handlerPanicRST is the message sent from handler goroutines when
-// the handler panics.
-type handlerPanicRST struct {
- StreamID uint32
-}
-
-func (hp handlerPanicRST) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal)
-}
-
-func (hp handlerPanicRST) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
-
-func (se StreamError) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteRSTStream(se.StreamID, se.Code)
-}
-
-func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
-
-type writePingAck struct{ pf *PingFrame }
-
-func (w writePingAck) writeFrame(ctx writeContext) error {
- return ctx.Framer().WritePing(true, w.pf.Data)
-}
-
-func (w writePingAck) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.pf.Data) <= max }
-
-type writeSettingsAck struct{}
-
-func (writeSettingsAck) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteSettingsAck()
-}
-
-func (writeSettingsAck) staysWithinBuffer(max int) bool { return frameHeaderLen <= max }
-
-// splitHeaderBlock splits headerBlock into fragments so that each fragment fits
-// in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true
-// for the first/last fragment, respectively.
-func splitHeaderBlock(ctx writeContext, headerBlock []byte, fn func(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error) error {
- // For now we're lazy and just pick the minimum MAX_FRAME_SIZE
- // that all peers must support (16KB). Later we could care
- // more and send larger frames if the peer advertised it, but
- // there's little point. Most headers are small anyway (so we
- // generally won't have CONTINUATION frames), and extra frames
- // only waste 9 bytes anyway.
- const maxFrameSize = 16384
-
- first := true
- for len(headerBlock) > 0 {
- frag := headerBlock
- if len(frag) > maxFrameSize {
- frag = frag[:maxFrameSize]
- }
- headerBlock = headerBlock[len(frag):]
- if err := fn(ctx, frag, first, len(headerBlock) == 0); err != nil {
- return err
- }
- first = false
- }
- return nil
-}
-
-// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames
-// for HTTP response headers or trailers from a server handler.
-type writeResHeaders struct {
- streamID uint32
- httpResCode int // 0 means no ":status" line
- h http.Header // may be nil
- trailers []string // if non-nil, which keys of h to write. nil means all.
- endStream bool
-
- date string
- contentType string
- contentLength string
-}
-
-func encKV(enc *hpack.Encoder, k, v string) {
- if VerboseLogs {
- log.Printf("http2: server encoding header %q = %q", k, v)
- }
- enc.WriteField(hpack.HeaderField{Name: k, Value: v})
-}
-
-func (w *writeResHeaders) staysWithinBuffer(max int) bool {
- // TODO: this is a common one. It'd be nice to return true
- // here and get into the fast path if we could be clever and
- // calculate the size fast enough, or at least a conservative
- // uppper bound that usually fires. (Maybe if w.h and
- // w.trailers are nil, so we don't need to enumerate it.)
- // Otherwise I'm afraid that just calculating the length to
- // answer this question would be slower than the ~2µs benefit.
- return false
-}
-
-func (w *writeResHeaders) writeFrame(ctx writeContext) error {
- enc, buf := ctx.HeaderEncoder()
- buf.Reset()
-
- if w.httpResCode != 0 {
- encKV(enc, ":status", httpCodeString(w.httpResCode))
- }
-
- encodeHeaders(enc, w.h, w.trailers)
-
- if w.contentType != "" {
- encKV(enc, "content-type", w.contentType)
- }
- if w.contentLength != "" {
- encKV(enc, "content-length", w.contentLength)
- }
- if w.date != "" {
- encKV(enc, "date", w.date)
- }
-
- headerBlock := buf.Bytes()
- if len(headerBlock) == 0 && w.trailers == nil {
- panic("unexpected empty hpack")
- }
-
- return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
-}
-
-func (w *writeResHeaders) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error {
- if firstFrag {
- return ctx.Framer().WriteHeaders(HeadersFrameParam{
- StreamID: w.streamID,
- BlockFragment: frag,
- EndStream: w.endStream,
- EndHeaders: lastFrag,
- })
- } else {
- return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
- }
-}
-
-// writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames.
-type writePushPromise struct {
- streamID uint32 // pusher stream
- method string // for :method
- url *url.URL // for :scheme, :authority, :path
- h http.Header
-
- // Creates an ID for a pushed stream. This runs on serveG just before
- // the frame is written. The returned ID is copied to promisedID.
- allocatePromisedID func() (uint32, error)
- promisedID uint32
-}
-
-func (w *writePushPromise) staysWithinBuffer(max int) bool {
- // TODO: see writeResHeaders.staysWithinBuffer
- return false
-}
-
-func (w *writePushPromise) writeFrame(ctx writeContext) error {
- enc, buf := ctx.HeaderEncoder()
- buf.Reset()
-
- encKV(enc, ":method", w.method)
- encKV(enc, ":scheme", w.url.Scheme)
- encKV(enc, ":authority", w.url.Host)
- encKV(enc, ":path", w.url.RequestURI())
- encodeHeaders(enc, w.h, nil)
-
- headerBlock := buf.Bytes()
- if len(headerBlock) == 0 {
- panic("unexpected empty hpack")
- }
-
- return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
-}
-
-func (w *writePushPromise) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error {
- if firstFrag {
- return ctx.Framer().WritePushPromise(PushPromiseParam{
- StreamID: w.streamID,
- PromiseID: w.promisedID,
- BlockFragment: frag,
- EndHeaders: lastFrag,
- })
- } else {
- return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
- }
-}
-
-type write100ContinueHeadersFrame struct {
- streamID uint32
-}
-
-func (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error {
- enc, buf := ctx.HeaderEncoder()
- buf.Reset()
- encKV(enc, ":status", "100")
- return ctx.Framer().WriteHeaders(HeadersFrameParam{
- StreamID: w.streamID,
- BlockFragment: buf.Bytes(),
- EndStream: false,
- EndHeaders: true,
- })
-}
-
-func (w write100ContinueHeadersFrame) staysWithinBuffer(max int) bool {
- // Sloppy but conservative:
- return 9+2*(len(":status")+len("100")) <= max
-}
-
-type writeWindowUpdate struct {
- streamID uint32 // or 0 for conn-level
- n uint32
-}
-
-func (wu writeWindowUpdate) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
-
-func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
- return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n)
-}
-
-// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])
-// is encoded only only if k is in keys.
-func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
- if keys == nil {
- sorter := sorterPool.Get().(*sorter)
- // Using defer here, since the returned keys from the
- // sorter.Keys method is only valid until the sorter
- // is returned:
- defer sorterPool.Put(sorter)
- keys = sorter.Keys(h)
- }
- for _, k := range keys {
- vv := h[k]
- k = lowerHeader(k)
- if !validWireHeaderFieldName(k) {
- // Skip it as backup paranoia. Per
- // golang.org/issue/14048, these should
- // already be rejected at a higher level.
- continue
- }
- isTE := k == "transfer-encoding"
- for _, v := range vv {
- if !httplex.ValidHeaderFieldValue(v) {
- // TODO: return an error? golang.org/issue/14048
- // For now just omit it.
- continue
- }
- // TODO: more of "8.1.2.2 Connection-Specific Header Fields"
- if isTE && v != "trailers" {
- continue
- }
- encKV(enc, k, v)
- }
- }
-}
diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go
deleted file mode 100644
index 4fe307307..000000000
--- a/vendor/golang.org/x/net/http2/writesched.go
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import "fmt"
-
-// WriteScheduler is the interface implemented by HTTP/2 write schedulers.
-// Methods are never called concurrently.
-type WriteScheduler interface {
- // OpenStream opens a new stream in the write scheduler.
- // It is illegal to call this with streamID=0 or with a streamID that is
- // already open -- the call may panic.
- OpenStream(streamID uint32, options OpenStreamOptions)
-
- // CloseStream closes a stream in the write scheduler. Any frames queued on
- // this stream should be discarded. It is illegal to call this on a stream
- // that is not open -- the call may panic.
- CloseStream(streamID uint32)
-
- // AdjustStream adjusts the priority of the given stream. This may be called
- // on a stream that has not yet been opened or has been closed. Note that
- // RFC 7540 allows PRIORITY frames to be sent on streams in any state. See:
- // https://tools.ietf.org/html/rfc7540#section-5.1
- AdjustStream(streamID uint32, priority PriorityParam)
-
- // Push queues a frame in the scheduler. In most cases, this will not be
- // called with wr.StreamID()!=0 unless that stream is currently open. The one
- // exception is RST_STREAM frames, which may be sent on idle or closed streams.
- Push(wr FrameWriteRequest)
-
- // Pop dequeues the next frame to write. Returns false if no frames can
- // be written. Frames with a given wr.StreamID() are Pop'd in the same
- // order they are Push'd.
- Pop() (wr FrameWriteRequest, ok bool)
-}
-
-// OpenStreamOptions specifies extra options for WriteScheduler.OpenStream.
-type OpenStreamOptions struct {
- // PusherID is zero if the stream was initiated by the client. Otherwise,
- // PusherID names the stream that pushed the newly opened stream.
- PusherID uint32
-}
-
-// FrameWriteRequest is a request to write a frame.
-type FrameWriteRequest struct {
- // write is the interface value that does the writing, once the
- // WriteScheduler has selected this frame to write. The write
- // functions are all defined in write.go.
- write writeFramer
-
- // stream is the stream on which this frame will be written.
- // nil for non-stream frames like PING and SETTINGS.
- stream *stream
-
- // done, if non-nil, must be a buffered channel with space for
- // 1 message and is sent the return value from write (or an
- // earlier error) when the frame has been written.
- done chan error
-}
-
-// StreamID returns the id of the stream this frame will be written to.
-// 0 is used for non-stream frames such as PING and SETTINGS.
-func (wr FrameWriteRequest) StreamID() uint32 {
- if wr.stream == nil {
- if se, ok := wr.write.(StreamError); ok {
- // (*serverConn).resetStream doesn't set
- // stream because it doesn't necessarily have
- // one. So special case this type of write
- // message.
- return se.StreamID
- }
- return 0
- }
- return wr.stream.id
-}
-
-// DataSize returns the number of flow control bytes that must be consumed
-// to write this entire frame. This is 0 for non-DATA frames.
-func (wr FrameWriteRequest) DataSize() int {
- if wd, ok := wr.write.(*writeData); ok {
- return len(wd.p)
- }
- return 0
-}
-
-// Consume consumes min(n, available) bytes from this frame, where available
-// is the number of flow control bytes available on the stream. Consume returns
-// 0, 1, or 2 frames, where the integer return value gives the number of frames
-// returned.
-//
-// If flow control prevents consuming any bytes, this returns (_, _, 0). If
-// the entire frame was consumed, this returns (wr, _, 1). Otherwise, this
-// returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and
-// 'rest' contains the remaining bytes. The consumed bytes are deducted from the
-// underlying stream's flow control budget.
-func (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteRequest, int) {
- var empty FrameWriteRequest
-
- // Non-DATA frames are always consumed whole.
- wd, ok := wr.write.(*writeData)
- if !ok || len(wd.p) == 0 {
- return wr, empty, 1
- }
-
- // Might need to split after applying limits.
- allowed := wr.stream.flow.available()
- if n < allowed {
- allowed = n
- }
- if wr.stream.sc.maxFrameSize < allowed {
- allowed = wr.stream.sc.maxFrameSize
- }
- if allowed <= 0 {
- return empty, empty, 0
- }
- if len(wd.p) > int(allowed) {
- wr.stream.flow.take(allowed)
- consumed := FrameWriteRequest{
- stream: wr.stream,
- write: &writeData{
- streamID: wd.streamID,
- p: wd.p[:allowed],
- // Even if the original had endStream set, there
- // are bytes remaining because len(wd.p) > allowed,
- // so we know endStream is false.
- endStream: false,
- },
- // Our caller is blocking on the final DATA frame, not
- // this intermediate frame, so no need to wait.
- done: nil,
- }
- rest := FrameWriteRequest{
- stream: wr.stream,
- write: &writeData{
- streamID: wd.streamID,
- p: wd.p[allowed:],
- endStream: wd.endStream,
- },
- done: wr.done,
- }
- return consumed, rest, 2
- }
-
- // The frame is consumed whole.
- // NB: This cast cannot overflow because allowed is <= math.MaxInt32.
- wr.stream.flow.take(int32(len(wd.p)))
- return wr, empty, 1
-}
-
-// String is for debugging only.
-func (wr FrameWriteRequest) String() string {
- var des string
- if s, ok := wr.write.(fmt.Stringer); ok {
- des = s.String()
- } else {
- des = fmt.Sprintf("%T", wr.write)
- }
- return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des)
-}
-
-// replyToWriter sends err to wr.done and panics if the send must block
-// This does nothing if wr.done is nil.
-func (wr *FrameWriteRequest) replyToWriter(err error) {
- if wr.done == nil {
- return
- }
- select {
- case wr.done <- err:
- default:
- panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wr.write))
- }
- wr.write = nil // prevent use (assume it's tainted after wr.done send)
-}
-
-// writeQueue is used by implementations of WriteScheduler.
-type writeQueue struct {
- s []FrameWriteRequest
-}
-
-func (q *writeQueue) empty() bool { return len(q.s) == 0 }
-
-func (q *writeQueue) push(wr FrameWriteRequest) {
- q.s = append(q.s, wr)
-}
-
-func (q *writeQueue) shift() FrameWriteRequest {
- if len(q.s) == 0 {
- panic("invalid use of queue")
- }
- wr := q.s[0]
- // TODO: less copy-happy queue.
- copy(q.s, q.s[1:])
- q.s[len(q.s)-1] = FrameWriteRequest{}
- q.s = q.s[:len(q.s)-1]
- return wr
-}
-
-// consume consumes up to n bytes from q.s[0]. If the frame is
-// entirely consumed, it is removed from the queue. If the frame
-// is partially consumed, the frame is kept with the consumed
-// bytes removed. Returns true iff any bytes were consumed.
-func (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) {
- if len(q.s) == 0 {
- return FrameWriteRequest{}, false
- }
- consumed, rest, numresult := q.s[0].Consume(n)
- switch numresult {
- case 0:
- return FrameWriteRequest{}, false
- case 1:
- q.shift()
- case 2:
- q.s[0] = rest
- }
- return consumed, true
-}
-
-type writeQueuePool []*writeQueue
-
-// put inserts an unused writeQueue into the pool.
-func (p *writeQueuePool) put(q *writeQueue) {
- for i := range q.s {
- q.s[i] = FrameWriteRequest{}
- }
- q.s = q.s[:0]
- *p = append(*p, q)
-}
-
-// get returns an empty writeQueue.
-func (p *writeQueuePool) get() *writeQueue {
- ln := len(*p)
- if ln == 0 {
- return new(writeQueue)
- }
- x := ln - 1
- q := (*p)[x]
- (*p)[x] = nil
- *p = (*p)[:x]
- return q
-}
diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go
deleted file mode 100644
index 848fed6ec..000000000
--- a/vendor/golang.org/x/net/http2/writesched_priority.go
+++ /dev/null
@@ -1,452 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "fmt"
- "math"
- "sort"
-)
-
-// RFC 7540, Section 5.3.5: the default weight is 16.
-const priorityDefaultWeight = 15 // 16 = 15 + 1
-
-// PriorityWriteSchedulerConfig configures a priorityWriteScheduler.
-type PriorityWriteSchedulerConfig struct {
- // MaxClosedNodesInTree controls the maximum number of closed streams to
- // retain in the priority tree. Setting this to zero saves a small amount
- // of memory at the cost of performance.
- //
- // See RFC 7540, Section 5.3.4:
- // "It is possible for a stream to become closed while prioritization
- // information ... is in transit. ... This potentially creates suboptimal
- // prioritization, since the stream could be given a priority that is
- // different from what is intended. To avoid these problems, an endpoint
- // SHOULD retain stream prioritization state for a period after streams
- // become closed. The longer state is retained, the lower the chance that
- // streams are assigned incorrect or default priority values."
- MaxClosedNodesInTree int
-
- // MaxIdleNodesInTree controls the maximum number of idle streams to
- // retain in the priority tree. Setting this to zero saves a small amount
- // of memory at the cost of performance.
- //
- // See RFC 7540, Section 5.3.4:
- // Similarly, streams that are in the "idle" state can be assigned
- // priority or become a parent of other streams. This allows for the
- // creation of a grouping node in the dependency tree, which enables
- // more flexible expressions of priority. Idle streams begin with a
- // default priority (Section 5.3.5).
- MaxIdleNodesInTree int
-
- // ThrottleOutOfOrderWrites enables write throttling to help ensure that
- // data is delivered in priority order. This works around a race where
- // stream B depends on stream A and both streams are about to call Write
- // to queue DATA frames. If B wins the race, a naive scheduler would eagerly
- // write as much data from B as possible, but this is suboptimal because A
- // is a higher-priority stream. With throttling enabled, we write a small
- // amount of data from B to minimize the amount of bandwidth that B can
- // steal from A.
- ThrottleOutOfOrderWrites bool
-}
-
-// NewPriorityWriteScheduler constructs a WriteScheduler that schedules
-// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.
-// If cfg is nil, default options are used.
-func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
- if cfg == nil {
- // For justification of these defaults, see:
- // https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
- cfg = &PriorityWriteSchedulerConfig{
- MaxClosedNodesInTree: 10,
- MaxIdleNodesInTree: 10,
- ThrottleOutOfOrderWrites: false,
- }
- }
-
- ws := &priorityWriteScheduler{
- nodes: make(map[uint32]*priorityNode),
- maxClosedNodesInTree: cfg.MaxClosedNodesInTree,
- maxIdleNodesInTree: cfg.MaxIdleNodesInTree,
- enableWriteThrottle: cfg.ThrottleOutOfOrderWrites,
- }
- ws.nodes[0] = &ws.root
- if cfg.ThrottleOutOfOrderWrites {
- ws.writeThrottleLimit = 1024
- } else {
- ws.writeThrottleLimit = math.MaxInt32
- }
- return ws
-}
-
-type priorityNodeState int
-
-const (
- priorityNodeOpen priorityNodeState = iota
- priorityNodeClosed
- priorityNodeIdle
-)
-
-// priorityNode is a node in an HTTP/2 priority tree.
-// Each node is associated with a single stream ID.
-// See RFC 7540, Section 5.3.
-type priorityNode struct {
- q writeQueue // queue of pending frames to write
- id uint32 // id of the stream, or 0 for the root of the tree
- weight uint8 // the actual weight is weight+1, so the value is in [1,256]
- state priorityNodeState // open | closed | idle
- bytes int64 // number of bytes written by this node, or 0 if closed
- subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree
-
- // These links form the priority tree.
- parent *priorityNode
- kids *priorityNode // start of the kids list
- prev, next *priorityNode // doubly-linked list of siblings
-}
-
-func (n *priorityNode) setParent(parent *priorityNode) {
- if n == parent {
- panic("setParent to self")
- }
- if n.parent == parent {
- return
- }
- // Unlink from current parent.
- if parent := n.parent; parent != nil {
- if n.prev == nil {
- parent.kids = n.next
- } else {
- n.prev.next = n.next
- }
- if n.next != nil {
- n.next.prev = n.prev
- }
- }
- // Link to new parent.
- // If parent=nil, remove n from the tree.
- // Always insert at the head of parent.kids (this is assumed by walkReadyInOrder).
- n.parent = parent
- if parent == nil {
- n.next = nil
- n.prev = nil
- } else {
- n.next = parent.kids
- n.prev = nil
- if n.next != nil {
- n.next.prev = n
- }
- parent.kids = n
- }
-}
-
-func (n *priorityNode) addBytes(b int64) {
- n.bytes += b
- for ; n != nil; n = n.parent {
- n.subtreeBytes += b
- }
-}
-
-// walkReadyInOrder iterates over the tree in priority order, calling f for each node
-// with a non-empty write queue. When f returns true, this funcion returns true and the
-// walk halts. tmp is used as scratch space for sorting.
-//
-// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
-// if any ancestor p of n is still open (ignoring the root node).
-func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool {
- if !n.q.empty() && f(n, openParent) {
- return true
- }
- if n.kids == nil {
- return false
- }
-
- // Don't consider the root "open" when updating openParent since
- // we can't send data frames on the root stream (only control frames).
- if n.id != 0 {
- openParent = openParent || (n.state == priorityNodeOpen)
- }
-
- // Common case: only one kid or all kids have the same weight.
- // Some clients don't use weights; other clients (like web browsers)
- // use mostly-linear priority trees.
- w := n.kids.weight
- needSort := false
- for k := n.kids.next; k != nil; k = k.next {
- if k.weight != w {
- needSort = true
- break
- }
- }
- if !needSort {
- for k := n.kids; k != nil; k = k.next {
- if k.walkReadyInOrder(openParent, tmp, f) {
- return true
- }
- }
- return false
- }
-
- // Uncommon case: sort the child nodes. We remove the kids from the parent,
- // then re-insert after sorting so we can reuse tmp for future sort calls.
- *tmp = (*tmp)[:0]
- for n.kids != nil {
- *tmp = append(*tmp, n.kids)
- n.kids.setParent(nil)
- }
- sort.Sort(sortPriorityNodeSiblings(*tmp))
- for i := len(*tmp) - 1; i >= 0; i-- {
- (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids
- }
- for k := n.kids; k != nil; k = k.next {
- if k.walkReadyInOrder(openParent, tmp, f) {
- return true
- }
- }
- return false
-}
-
-type sortPriorityNodeSiblings []*priorityNode
-
-func (z sortPriorityNodeSiblings) Len() int { return len(z) }
-func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
-func (z sortPriorityNodeSiblings) Less(i, k int) bool {
- // Prefer the subtree that has sent fewer bytes relative to its weight.
- // See sections 5.3.2 and 5.3.4.
- wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes)
- wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes)
- if bi == 0 && bk == 0 {
- return wi >= wk
- }
- if bk == 0 {
- return false
- }
- return bi/bk <= wi/wk
-}
-
-type priorityWriteScheduler struct {
- // root is the root of the priority tree, where root.id = 0.
- // The root queues control frames that are not associated with any stream.
- root priorityNode
-
- // nodes maps stream ids to priority tree nodes.
- nodes map[uint32]*priorityNode
-
- // maxID is the maximum stream id in nodes.
- maxID uint32
-
- // lists of nodes that have been closed or are idle, but are kept in
- // the tree for improved prioritization. When the lengths exceed either
- // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.
- closedNodes, idleNodes []*priorityNode
-
- // From the config.
- maxClosedNodesInTree int
- maxIdleNodesInTree int
- writeThrottleLimit int32
- enableWriteThrottle bool
-
- // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.
- tmp []*priorityNode
-
- // pool of empty queues for reuse.
- queuePool writeQueuePool
-}
-
-func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {
- // The stream may be currently idle but cannot be opened or closed.
- if curr := ws.nodes[streamID]; curr != nil {
- if curr.state != priorityNodeIdle {
- panic(fmt.Sprintf("stream %d already opened", streamID))
- }
- curr.state = priorityNodeOpen
- return
- }
-
- // RFC 7540, Section 5.3.5:
- // "All streams are initially assigned a non-exclusive dependency on stream 0x0.
- // Pushed streams initially depend on their associated stream. In both cases,
- // streams are assigned a default weight of 16."
- parent := ws.nodes[options.PusherID]
- if parent == nil {
- parent = &ws.root
- }
- n := &priorityNode{
- q: *ws.queuePool.get(),
- id: streamID,
- weight: priorityDefaultWeight,
- state: priorityNodeOpen,
- }
- n.setParent(parent)
- ws.nodes[streamID] = n
- if streamID > ws.maxID {
- ws.maxID = streamID
- }
-}
-
-func (ws *priorityWriteScheduler) CloseStream(streamID uint32) {
- if streamID == 0 {
- panic("violation of WriteScheduler interface: cannot close stream 0")
- }
- if ws.nodes[streamID] == nil {
- panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID))
- }
- if ws.nodes[streamID].state != priorityNodeOpen {
- panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID))
- }
-
- n := ws.nodes[streamID]
- n.state = priorityNodeClosed
- n.addBytes(-n.bytes)
-
- q := n.q
- ws.queuePool.put(&q)
- n.q.s = nil
- if ws.maxClosedNodesInTree > 0 {
- ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n)
- } else {
- ws.removeNode(n)
- }
-}
-
-func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {
- if streamID == 0 {
- panic("adjustPriority on root")
- }
-
- // If streamID does not exist, there are two cases:
- // - A closed stream that has been removed (this will have ID <= maxID)
- // - An idle stream that is being used for "grouping" (this will have ID > maxID)
- n := ws.nodes[streamID]
- if n == nil {
- if streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 {
- return
- }
- ws.maxID = streamID
- n = &priorityNode{
- q: *ws.queuePool.get(),
- id: streamID,
- weight: priorityDefaultWeight,
- state: priorityNodeIdle,
- }
- n.setParent(&ws.root)
- ws.nodes[streamID] = n
- ws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n)
- }
-
- // Section 5.3.1: A dependency on a stream that is not currently in the tree
- // results in that stream being given a default priority (Section 5.3.5).
- parent := ws.nodes[priority.StreamDep]
- if parent == nil {
- n.setParent(&ws.root)
- n.weight = priorityDefaultWeight
- return
- }
-
- // Ignore if the client tries to make a node its own parent.
- if n == parent {
- return
- }
-
- // Section 5.3.3:
- // "If a stream is made dependent on one of its own dependencies, the
- // formerly dependent stream is first moved to be dependent on the
- // reprioritized stream's previous parent. The moved dependency retains
- // its weight."
- //
- // That is: if parent depends on n, move parent to depend on n.parent.
- for x := parent.parent; x != nil; x = x.parent {
- if x == n {
- parent.setParent(n.parent)
- break
- }
- }
-
- // Section 5.3.3: The exclusive flag causes the stream to become the sole
- // dependency of its parent stream, causing other dependencies to become
- // dependent on the exclusive stream.
- if priority.Exclusive {
- k := parent.kids
- for k != nil {
- next := k.next
- if k != n {
- k.setParent(n)
- }
- k = next
- }
- }
-
- n.setParent(parent)
- n.weight = priority.Weight
-}
-
-func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
- var n *priorityNode
- if id := wr.StreamID(); id == 0 {
- n = &ws.root
- } else {
- n = ws.nodes[id]
- if n == nil {
- // id is an idle or closed stream. wr should not be a HEADERS or
- // DATA frame. However, wr can be a RST_STREAM. In this case, we
- // push wr onto the root, rather than creating a new priorityNode,
- // since RST_STREAM is tiny and the stream's priority is unknown
- // anyway. See issue #17919.
- if wr.DataSize() > 0 {
- panic("add DATA on non-open stream")
- }
- n = &ws.root
- }
- }
- n.q.push(wr)
-}
-
-func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) {
- ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool {
- limit := int32(math.MaxInt32)
- if openParent {
- limit = ws.writeThrottleLimit
- }
- wr, ok = n.q.consume(limit)
- if !ok {
- return false
- }
- n.addBytes(int64(wr.DataSize()))
- // If B depends on A and B continuously has data available but A
- // does not, gradually increase the throttling limit to allow B to
- // steal more and more bandwidth from A.
- if openParent {
- ws.writeThrottleLimit += 1024
- if ws.writeThrottleLimit < 0 {
- ws.writeThrottleLimit = math.MaxInt32
- }
- } else if ws.enableWriteThrottle {
- ws.writeThrottleLimit = 1024
- }
- return true
- })
- return wr, ok
-}
-
-func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) {
- if maxSize == 0 {
- return
- }
- if len(*list) == maxSize {
- // Remove the oldest node, then shift left.
- ws.removeNode((*list)[0])
- x := (*list)[1:]
- copy(*list, x)
- *list = (*list)[:len(x)]
- }
- *list = append(*list, n)
-}
-
-func (ws *priorityWriteScheduler) removeNode(n *priorityNode) {
- for k := n.kids; k != nil; k = k.next {
- k.setParent(n.parent)
- }
- n.setParent(nil)
- delete(ws.nodes, n.id)
-}
diff --git a/vendor/golang.org/x/net/http2/writesched_priority_test.go b/vendor/golang.org/x/net/http2/writesched_priority_test.go
deleted file mode 100644
index f2b535a2c..000000000
--- a/vendor/golang.org/x/net/http2/writesched_priority_test.go
+++ /dev/null
@@ -1,541 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bytes"
- "fmt"
- "sort"
- "testing"
-)
-
-func defaultPriorityWriteScheduler() *priorityWriteScheduler {
- return NewPriorityWriteScheduler(nil).(*priorityWriteScheduler)
-}
-
-func checkPriorityWellFormed(ws *priorityWriteScheduler) error {
- for id, n := range ws.nodes {
- if id != n.id {
- return fmt.Errorf("bad ws.nodes: ws.nodes[%d] = %d", id, n.id)
- }
- if n.parent == nil {
- if n.next != nil || n.prev != nil {
- return fmt.Errorf("bad node %d: nil parent but prev/next not nil", id)
- }
- continue
- }
- found := false
- for k := n.parent.kids; k != nil; k = k.next {
- if k.id == id {
- found = true
- break
- }
- }
- if !found {
- return fmt.Errorf("bad node %d: not found in parent %d kids list", id, n.parent.id)
- }
- }
- return nil
-}
-
-func fmtTree(ws *priorityWriteScheduler, fmtNode func(*priorityNode) string) string {
- var ids []int
- for _, n := range ws.nodes {
- ids = append(ids, int(n.id))
- }
- sort.Ints(ids)
-
- var buf bytes.Buffer
- for _, id := range ids {
- if buf.Len() != 0 {
- buf.WriteString(" ")
- }
- if id == 0 {
- buf.WriteString(fmtNode(&ws.root))
- } else {
- buf.WriteString(fmtNode(ws.nodes[uint32(id)]))
- }
- }
- return buf.String()
-}
-
-func fmtNodeParentSkipRoot(n *priorityNode) string {
- switch {
- case n.id == 0:
- return ""
- case n.parent == nil:
- return fmt.Sprintf("%d{parent:nil}", n.id)
- default:
- return fmt.Sprintf("%d{parent:%d}", n.id, n.parent.id)
- }
-}
-
-func fmtNodeWeightParentSkipRoot(n *priorityNode) string {
- switch {
- case n.id == 0:
- return ""
- case n.parent == nil:
- return fmt.Sprintf("%d{weight:%d,parent:nil}", n.id, n.weight)
- default:
- return fmt.Sprintf("%d{weight:%d,parent:%d}", n.id, n.weight, n.parent.id)
- }
-}
-
-func TestPriorityTwoStreams(t *testing.T) {
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{})
-
- want := "1{weight:15,parent:0} 2{weight:15,parent:0}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After open\ngot %q\nwant %q", got, want)
- }
-
- // Move 1's parent to 2.
- ws.AdjustStream(1, PriorityParam{
- StreamDep: 2,
- Weight: 32,
- Exclusive: false,
- })
- want = "1{weight:32,parent:2} 2{weight:15,parent:0}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After adjust\ngot %q\nwant %q", got, want)
- }
-
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityAdjustExclusiveZero(t *testing.T) {
- // 1, 2, and 3 are all children of the 0 stream.
- // Exclusive reprioritization to any of the streams should bring
- // the rest of the streams under the reprioritized stream.
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{})
- ws.OpenStream(3, OpenStreamOptions{})
-
- want := "1{weight:15,parent:0} 2{weight:15,parent:0} 3{weight:15,parent:0}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After open\ngot %q\nwant %q", got, want)
- }
-
- ws.AdjustStream(2, PriorityParam{
- StreamDep: 0,
- Weight: 20,
- Exclusive: true,
- })
- want = "1{weight:15,parent:2} 2{weight:20,parent:0} 3{weight:15,parent:2}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After adjust\ngot %q\nwant %q", got, want)
- }
-
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityAdjustOwnParent(t *testing.T) {
- // Assigning a node as its own parent should have no effect.
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{})
- ws.AdjustStream(2, PriorityParam{
- StreamDep: 2,
- Weight: 20,
- Exclusive: true,
- })
- want := "1{weight:15,parent:0} 2{weight:15,parent:0}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After adjust\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityClosedStreams(t *testing.T) {
- ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{MaxClosedNodesInTree: 2}).(*priorityWriteScheduler)
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(3, OpenStreamOptions{PusherID: 2})
- ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
-
- // Close the first three streams. We lose 1, but keep 2 and 3.
- ws.CloseStream(1)
- ws.CloseStream(2)
- ws.CloseStream(3)
-
- want := "2{weight:15,parent:0} 3{weight:15,parent:2} 4{weight:15,parent:3}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After close\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-
- // Adding a stream as an exclusive child of 1 gives it default
- // priorities, since 1 is gone.
- ws.OpenStream(5, OpenStreamOptions{})
- ws.AdjustStream(5, PriorityParam{StreamDep: 1, Weight: 15, Exclusive: true})
-
- // Adding a stream as an exclusive child of 2 should work, since 2 is not gone.
- ws.OpenStream(6, OpenStreamOptions{})
- ws.AdjustStream(6, PriorityParam{StreamDep: 2, Weight: 15, Exclusive: true})
-
- want = "2{weight:15,parent:0} 3{weight:15,parent:6} 4{weight:15,parent:3} 5{weight:15,parent:0} 6{weight:15,parent:2}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After add streams\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityClosedStreamsDisabled(t *testing.T) {
- ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{}).(*priorityWriteScheduler)
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(3, OpenStreamOptions{PusherID: 2})
-
- // Close the first two streams. We keep only 3.
- ws.CloseStream(1)
- ws.CloseStream(2)
-
- want := "3{weight:15,parent:0}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After close\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityIdleStreams(t *testing.T) {
- ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{MaxIdleNodesInTree: 2}).(*priorityWriteScheduler)
- ws.AdjustStream(1, PriorityParam{StreamDep: 0, Weight: 15}) // idle
- ws.AdjustStream(2, PriorityParam{StreamDep: 0, Weight: 15}) // idle
- ws.AdjustStream(3, PriorityParam{StreamDep: 2, Weight: 20}) // idle
- ws.OpenStream(4, OpenStreamOptions{})
- ws.OpenStream(5, OpenStreamOptions{})
- ws.OpenStream(6, OpenStreamOptions{})
- ws.AdjustStream(4, PriorityParam{StreamDep: 1, Weight: 15})
- ws.AdjustStream(5, PriorityParam{StreamDep: 2, Weight: 15})
- ws.AdjustStream(6, PriorityParam{StreamDep: 3, Weight: 15})
-
- want := "2{weight:15,parent:0} 3{weight:20,parent:2} 4{weight:15,parent:0} 5{weight:15,parent:2} 6{weight:15,parent:3}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After open\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityIdleStreamsDisabled(t *testing.T) {
- ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{}).(*priorityWriteScheduler)
- ws.AdjustStream(1, PriorityParam{StreamDep: 0, Weight: 15}) // idle
- ws.AdjustStream(2, PriorityParam{StreamDep: 0, Weight: 15}) // idle
- ws.AdjustStream(3, PriorityParam{StreamDep: 2, Weight: 20}) // idle
- ws.OpenStream(4, OpenStreamOptions{})
-
- want := "4{weight:15,parent:0}"
- if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
- t.Errorf("After open\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPrioritySection531NonExclusive(t *testing.T) {
- // Example from RFC 7540 Section 5.3.1.
- // A,B,C,D = 1,2,3,4
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(4, OpenStreamOptions{})
- ws.AdjustStream(4, PriorityParam{
- StreamDep: 1,
- Weight: 15,
- Exclusive: false,
- })
- want := "1{parent:0} 2{parent:1} 3{parent:1} 4{parent:1}"
- if got := fmtTree(ws, fmtNodeParentSkipRoot); got != want {
- t.Errorf("After adjust\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPrioritySection531Exclusive(t *testing.T) {
- // Example from RFC 7540 Section 5.3.1.
- // A,B,C,D = 1,2,3,4
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(4, OpenStreamOptions{})
- ws.AdjustStream(4, PriorityParam{
- StreamDep: 1,
- Weight: 15,
- Exclusive: true,
- })
- want := "1{parent:0} 2{parent:4} 3{parent:4} 4{parent:1}"
- if got := fmtTree(ws, fmtNodeParentSkipRoot); got != want {
- t.Errorf("After adjust\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func makeSection533Tree() *priorityWriteScheduler {
- // Initial tree from RFC 7540 Section 5.3.3.
- // A,B,C,D,E,F = 1,2,3,4,5,6
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
- ws.OpenStream(5, OpenStreamOptions{PusherID: 3})
- ws.OpenStream(6, OpenStreamOptions{PusherID: 4})
- return ws
-}
-
-func TestPrioritySection533NonExclusive(t *testing.T) {
- // Example from RFC 7540 Section 5.3.3.
- // A,B,C,D,E,F = 1,2,3,4,5,6
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
- ws.OpenStream(5, OpenStreamOptions{PusherID: 3})
- ws.OpenStream(6, OpenStreamOptions{PusherID: 4})
- ws.AdjustStream(1, PriorityParam{
- StreamDep: 4,
- Weight: 15,
- Exclusive: false,
- })
- want := "1{parent:4} 2{parent:1} 3{parent:1} 4{parent:0} 5{parent:3} 6{parent:4}"
- if got := fmtTree(ws, fmtNodeParentSkipRoot); got != want {
- t.Errorf("After adjust\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func TestPrioritySection533Exclusive(t *testing.T) {
- // Example from RFC 7540 Section 5.3.3.
- // A,B,C,D,E,F = 1,2,3,4,5,6
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
- ws.OpenStream(5, OpenStreamOptions{PusherID: 3})
- ws.OpenStream(6, OpenStreamOptions{PusherID: 4})
- ws.AdjustStream(1, PriorityParam{
- StreamDep: 4,
- Weight: 15,
- Exclusive: true,
- })
- want := "1{parent:4} 2{parent:1} 3{parent:1} 4{parent:0} 5{parent:3} 6{parent:1}"
- if got := fmtTree(ws, fmtNodeParentSkipRoot); got != want {
- t.Errorf("After adjust\ngot %q\nwant %q", got, want)
- }
- if err := checkPriorityWellFormed(ws); err != nil {
- t.Error(err)
- }
-}
-
-func checkPopAll(ws WriteScheduler, order []uint32) error {
- for k, id := range order {
- wr, ok := ws.Pop()
- if !ok {
- return fmt.Errorf("Pop[%d]: got ok=false, want %d (order=%v)", k, id, order)
- }
- if got := wr.StreamID(); got != id {
- return fmt.Errorf("Pop[%d]: got %v, want %d (order=%v)", k, got, id, order)
- }
- }
- wr, ok := ws.Pop()
- if ok {
- return fmt.Errorf("Pop[%d]: got %v, want ok=false (order=%v)", len(order), wr.StreamID(), order)
- }
- return nil
-}
-
-func TestPriorityPopFrom533Tree(t *testing.T) {
- ws := makeSection533Tree()
-
- ws.Push(makeWriteHeadersRequest(3 /*C*/))
- ws.Push(makeWriteNonStreamRequest())
- ws.Push(makeWriteHeadersRequest(5 /*E*/))
- ws.Push(makeWriteHeadersRequest(1 /*A*/))
- t.Log("tree:", fmtTree(ws, fmtNodeParentSkipRoot))
-
- if err := checkPopAll(ws, []uint32{0 /*NonStream*/, 1, 3, 5}); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityPopFromLinearTree(t *testing.T) {
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
- ws.OpenStream(3, OpenStreamOptions{PusherID: 2})
- ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
-
- ws.Push(makeWriteHeadersRequest(3))
- ws.Push(makeWriteHeadersRequest(4))
- ws.Push(makeWriteHeadersRequest(1))
- ws.Push(makeWriteHeadersRequest(2))
- ws.Push(makeWriteNonStreamRequest())
- ws.Push(makeWriteNonStreamRequest())
- t.Log("tree:", fmtTree(ws, fmtNodeParentSkipRoot))
-
- if err := checkPopAll(ws, []uint32{0, 0 /*NonStreams*/, 1, 2, 3, 4}); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityFlowControl(t *testing.T) {
- ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{ThrottleOutOfOrderWrites: false})
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
-
- sc := &serverConn{maxFrameSize: 16}
- st1 := &stream{id: 1, sc: sc}
- st2 := &stream{id: 2, sc: sc}
-
- ws.Push(FrameWriteRequest{&writeData{1, make([]byte, 16), false}, st1, nil})
- ws.Push(FrameWriteRequest{&writeData{2, make([]byte, 16), false}, st2, nil})
- ws.AdjustStream(2, PriorityParam{StreamDep: 1})
-
- // No flow-control bytes available.
- if wr, ok := ws.Pop(); ok {
- t.Fatalf("Pop(limited by flow control)=%v,true, want false", wr)
- }
-
- // Add enough flow-control bytes to write st2 in two Pop calls.
- // Should write data from st2 even though it's lower priority than st1.
- for i := 1; i <= 2; i++ {
- st2.flow.add(8)
- wr, ok := ws.Pop()
- if !ok {
- t.Fatalf("Pop(%d)=false, want true", i)
- }
- if got, want := wr.DataSize(), 8; got != want {
- t.Fatalf("Pop(%d)=%d bytes, want %d bytes", i, got, want)
- }
- }
-}
-
-func TestPriorityThrottleOutOfOrderWrites(t *testing.T) {
- ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{ThrottleOutOfOrderWrites: true})
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
-
- sc := &serverConn{maxFrameSize: 4096}
- st1 := &stream{id: 1, sc: sc}
- st2 := &stream{id: 2, sc: sc}
- st1.flow.add(4096)
- st2.flow.add(4096)
- ws.Push(FrameWriteRequest{&writeData{2, make([]byte, 4096), false}, st2, nil})
- ws.AdjustStream(2, PriorityParam{StreamDep: 1})
-
- // We have enough flow-control bytes to write st2 in a single Pop call.
- // However, due to out-of-order write throttling, the first call should
- // only write 1KB.
- wr, ok := ws.Pop()
- if !ok {
- t.Fatalf("Pop(st2.first)=false, want true")
- }
- if got, want := wr.StreamID(), uint32(2); got != want {
- t.Fatalf("Pop(st2.first)=stream %d, want stream %d", got, want)
- }
- if got, want := wr.DataSize(), 1024; got != want {
- t.Fatalf("Pop(st2.first)=%d bytes, want %d bytes", got, want)
- }
-
- // Now add data on st1. This should take precedence.
- ws.Push(FrameWriteRequest{&writeData{1, make([]byte, 4096), false}, st1, nil})
- wr, ok = ws.Pop()
- if !ok {
- t.Fatalf("Pop(st1)=false, want true")
- }
- if got, want := wr.StreamID(), uint32(1); got != want {
- t.Fatalf("Pop(st1)=stream %d, want stream %d", got, want)
- }
- if got, want := wr.DataSize(), 4096; got != want {
- t.Fatalf("Pop(st1)=%d bytes, want %d bytes", got, want)
- }
-
- // Should go back to writing 1KB from st2.
- wr, ok = ws.Pop()
- if !ok {
- t.Fatalf("Pop(st2.last)=false, want true")
- }
- if got, want := wr.StreamID(), uint32(2); got != want {
- t.Fatalf("Pop(st2.last)=stream %d, want stream %d", got, want)
- }
- if got, want := wr.DataSize(), 1024; got != want {
- t.Fatalf("Pop(st2.last)=%d bytes, want %d bytes", got, want)
- }
-}
-
-func TestPriorityWeights(t *testing.T) {
- ws := defaultPriorityWriteScheduler()
- ws.OpenStream(1, OpenStreamOptions{})
- ws.OpenStream(2, OpenStreamOptions{})
-
- sc := &serverConn{maxFrameSize: 8}
- st1 := &stream{id: 1, sc: sc}
- st2 := &stream{id: 2, sc: sc}
- st1.flow.add(40)
- st2.flow.add(40)
-
- ws.Push(FrameWriteRequest{&writeData{1, make([]byte, 40), false}, st1, nil})
- ws.Push(FrameWriteRequest{&writeData{2, make([]byte, 40), false}, st2, nil})
- ws.AdjustStream(1, PriorityParam{StreamDep: 0, Weight: 34})
- ws.AdjustStream(2, PriorityParam{StreamDep: 0, Weight: 9})
-
- // st1 gets 3.5x the bandwidth of st2 (3.5 = (34+1)/(9+1)).
- // The maximum frame size is 8 bytes. The write sequence should be:
- // st1, total bytes so far is (st1=8, st=0)
- // st2, total bytes so far is (st1=8, st=8)
- // st1, total bytes so far is (st1=16, st=8)
- // st1, total bytes so far is (st1=24, st=8) // 3x bandwidth
- // st1, total bytes so far is (st1=32, st=8) // 4x bandwidth
- // st2, total bytes so far is (st1=32, st=16) // 2x bandwidth
- // st1, total bytes so far is (st1=40, st=16)
- // st2, total bytes so far is (st1=40, st=24)
- // st2, total bytes so far is (st1=40, st=32)
- // st2, total bytes so far is (st1=40, st=40)
- if err := checkPopAll(ws, []uint32{1, 2, 1, 1, 1, 2, 1, 2, 2, 2}); err != nil {
- t.Error(err)
- }
-}
-
-func TestPriorityRstStreamOnNonOpenStreams(t *testing.T) {
- ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{
- MaxClosedNodesInTree: 0,
- MaxIdleNodesInTree: 0,
- })
- ws.OpenStream(1, OpenStreamOptions{})
- ws.CloseStream(1)
- ws.Push(FrameWriteRequest{write: streamError(1, ErrCodeProtocol)})
- ws.Push(FrameWriteRequest{write: streamError(2, ErrCodeProtocol)})
-
- if err := checkPopAll(ws, []uint32{1, 2}); err != nil {
- t.Error(err)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/writesched_random.go b/vendor/golang.org/x/net/http2/writesched_random.go
deleted file mode 100644
index 36d7919f1..000000000
--- a/vendor/golang.org/x/net/http2/writesched_random.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import "math"
-
-// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2
-// priorities. Control frames like SETTINGS and PING are written before DATA
-// frames, but if no control frames are queued and multiple streams have queued
-// HEADERS or DATA frames, Pop selects a ready stream arbitrarily.
-func NewRandomWriteScheduler() WriteScheduler {
- return &randomWriteScheduler{sq: make(map[uint32]*writeQueue)}
-}
-
-type randomWriteScheduler struct {
- // zero are frames not associated with a specific stream.
- zero writeQueue
-
- // sq contains the stream-specific queues, keyed by stream ID.
- // When a stream is idle or closed, it's deleted from the map.
- sq map[uint32]*writeQueue
-
- // pool of empty queues for reuse.
- queuePool writeQueuePool
-}
-
-func (ws *randomWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {
- // no-op: idle streams are not tracked
-}
-
-func (ws *randomWriteScheduler) CloseStream(streamID uint32) {
- q, ok := ws.sq[streamID]
- if !ok {
- return
- }
- delete(ws.sq, streamID)
- ws.queuePool.put(q)
-}
-
-func (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {
- // no-op: priorities are ignored
-}
-
-func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) {
- id := wr.StreamID()
- if id == 0 {
- ws.zero.push(wr)
- return
- }
- q, ok := ws.sq[id]
- if !ok {
- q = ws.queuePool.get()
- ws.sq[id] = q
- }
- q.push(wr)
-}
-
-func (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) {
- // Control frames first.
- if !ws.zero.empty() {
- return ws.zero.shift(), true
- }
- // Iterate over all non-idle streams until finding one that can be consumed.
- for _, q := range ws.sq {
- if wr, ok := q.consume(math.MaxInt32); ok {
- return wr, true
- }
- }
- return FrameWriteRequest{}, false
-}
diff --git a/vendor/golang.org/x/net/http2/writesched_random_test.go b/vendor/golang.org/x/net/http2/writesched_random_test.go
deleted file mode 100644
index 3bf4aa36a..000000000
--- a/vendor/golang.org/x/net/http2/writesched_random_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import "testing"
-
-func TestRandomScheduler(t *testing.T) {
- ws := NewRandomWriteScheduler()
- ws.Push(makeWriteHeadersRequest(3))
- ws.Push(makeWriteHeadersRequest(4))
- ws.Push(makeWriteHeadersRequest(1))
- ws.Push(makeWriteHeadersRequest(2))
- ws.Push(makeWriteNonStreamRequest())
- ws.Push(makeWriteNonStreamRequest())
-
- // Pop all frames. Should get the non-stream requests first,
- // followed by the stream requests in any order.
- var order []FrameWriteRequest
- for {
- wr, ok := ws.Pop()
- if !ok {
- break
- }
- order = append(order, wr)
- }
- t.Logf("got frames: %v", order)
- if len(order) != 6 {
- t.Fatalf("got %d frames, expected 6", len(order))
- }
- if order[0].StreamID() != 0 || order[1].StreamID() != 0 {
- t.Fatal("expected non-stream frames first", order[0], order[1])
- }
- got := make(map[uint32]bool)
- for _, wr := range order[2:] {
- got[wr.StreamID()] = true
- }
- for id := uint32(1); id <= 4; id++ {
- if !got[id] {
- t.Errorf("frame not found for stream %d", id)
- }
- }
-}
diff --git a/vendor/golang.org/x/net/http2/writesched_test.go b/vendor/golang.org/x/net/http2/writesched_test.go
deleted file mode 100644
index 0807056bc..000000000
--- a/vendor/golang.org/x/net/http2/writesched_test.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "fmt"
- "math"
- "reflect"
- "testing"
-)
-
-func makeWriteNonStreamRequest() FrameWriteRequest {
- return FrameWriteRequest{writeSettingsAck{}, nil, nil}
-}
-
-func makeWriteHeadersRequest(streamID uint32) FrameWriteRequest {
- st := &stream{id: streamID}
- return FrameWriteRequest{&writeResHeaders{streamID: streamID, httpResCode: 200}, st, nil}
-}
-
-func checkConsume(wr FrameWriteRequest, nbytes int32, want []FrameWriteRequest) error {
- consumed, rest, n := wr.Consume(nbytes)
- var wantConsumed, wantRest FrameWriteRequest
- switch len(want) {
- case 0:
- case 1:
- wantConsumed = want[0]
- case 2:
- wantConsumed = want[0]
- wantRest = want[1]
- }
- if !reflect.DeepEqual(consumed, wantConsumed) || !reflect.DeepEqual(rest, wantRest) || n != len(want) {
- return fmt.Errorf("got %v, %v, %v\nwant %v, %v, %v", consumed, rest, n, wantConsumed, wantRest, len(want))
- }
- return nil
-}
-
-func TestFrameWriteRequestNonData(t *testing.T) {
- wr := makeWriteNonStreamRequest()
- if got, want := wr.DataSize(), 0; got != want {
- t.Errorf("DataSize: got %v, want %v", got, want)
- }
-
- // Non-DATA frames are always consumed whole.
- if err := checkConsume(wr, 0, []FrameWriteRequest{wr}); err != nil {
- t.Errorf("Consume:\n%v", err)
- }
-}
-
-func TestFrameWriteRequestData(t *testing.T) {
- st := &stream{
- id: 1,
- sc: &serverConn{maxFrameSize: 16},
- }
- const size = 32
- wr := FrameWriteRequest{&writeData{st.id, make([]byte, size), true}, st, make(chan error)}
- if got, want := wr.DataSize(), size; got != want {
- t.Errorf("DataSize: got %v, want %v", got, want)
- }
-
- // No flow-control bytes available: cannot consume anything.
- if err := checkConsume(wr, math.MaxInt32, []FrameWriteRequest{}); err != nil {
- t.Errorf("Consume(limited by flow control):\n%v", err)
- }
-
- // Add enough flow-control bytes to consume the entire frame,
- // but we're now restricted by st.sc.maxFrameSize.
- st.flow.add(size)
- want := []FrameWriteRequest{
- {
- write: &writeData{st.id, make([]byte, st.sc.maxFrameSize), false},
- stream: st,
- done: nil,
- },
- {
- write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize), true},
- stream: st,
- done: wr.done,
- },
- }
- if err := checkConsume(wr, math.MaxInt32, want); err != nil {
- t.Errorf("Consume(limited by maxFrameSize):\n%v", err)
- }
- rest := want[1]
-
- // Consume 8 bytes from the remaining frame.
- want = []FrameWriteRequest{
- {
- write: &writeData{st.id, make([]byte, 8), false},
- stream: st,
- done: nil,
- },
- {
- write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize-8), true},
- stream: st,
- done: wr.done,
- },
- }
- if err := checkConsume(rest, 8, want); err != nil {
- t.Errorf("Consume(8):\n%v", err)
- }
- rest = want[1]
-
- // Consume all remaining bytes.
- want = []FrameWriteRequest{
- {
- write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize-8), true},
- stream: st,
- done: wr.done,
- },
- }
- if err := checkConsume(rest, math.MaxInt32, want); err != nil {
- t.Errorf("Consume(remainder):\n%v", err)
- }
-}
-
-func TestFrameWriteRequest_StreamID(t *testing.T) {
- const streamID = 123
- wr := FrameWriteRequest{write: streamError(streamID, ErrCodeNo)}
- if got := wr.StreamID(); got != streamID {
- t.Errorf("FrameWriteRequest(StreamError) = %v; want %v", got, streamID)
- }
-}
diff --git a/vendor/golang.org/x/net/http2/z_spec_test.go b/vendor/golang.org/x/net/http2/z_spec_test.go
deleted file mode 100644
index 610b2cdbc..000000000
--- a/vendor/golang.org/x/net/http2/z_spec_test.go
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http2
-
-import (
- "bytes"
- "encoding/xml"
- "flag"
- "fmt"
- "io"
- "os"
- "reflect"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "sync"
- "testing"
-)
-
-var coverSpec = flag.Bool("coverspec", false, "Run spec coverage tests")
-
-// The global map of sentence coverage for the http2 spec.
-var defaultSpecCoverage specCoverage
-
-var loadSpecOnce sync.Once
-
-func loadSpec() {
- if f, err := os.Open("testdata/draft-ietf-httpbis-http2.xml"); err != nil {
- panic(err)
- } else {
- defaultSpecCoverage = readSpecCov(f)
- f.Close()
- }
-}
-
-// covers marks all sentences for section sec in defaultSpecCoverage. Sentences not
-// "covered" will be included in report outputted by TestSpecCoverage.
-func covers(sec, sentences string) {
- loadSpecOnce.Do(loadSpec)
- defaultSpecCoverage.cover(sec, sentences)
-}
-
-type specPart struct {
- section string
- sentence string
-}
-
-func (ss specPart) Less(oo specPart) bool {
- atoi := func(s string) int {
- n, err := strconv.Atoi(s)
- if err != nil {
- panic(err)
- }
- return n
- }
- a := strings.Split(ss.section, ".")
- b := strings.Split(oo.section, ".")
- for len(a) > 0 {
- if len(b) == 0 {
- return false
- }
- x, y := atoi(a[0]), atoi(b[0])
- if x == y {
- a, b = a[1:], b[1:]
- continue
- }
- return x < y
- }
- if len(b) > 0 {
- return true
- }
- return false
-}
-
-type bySpecSection []specPart
-
-func (a bySpecSection) Len() int { return len(a) }
-func (a bySpecSection) Less(i, j int) bool { return a[i].Less(a[j]) }
-func (a bySpecSection) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
-type specCoverage struct {
- coverage map[specPart]bool
- d *xml.Decoder
-}
-
-func joinSection(sec []int) string {
- s := fmt.Sprintf("%d", sec[0])
- for _, n := range sec[1:] {
- s = fmt.Sprintf("%s.%d", s, n)
- }
- return s
-}
-
-func (sc specCoverage) readSection(sec []int) {
- var (
- buf = new(bytes.Buffer)
- sub = 0
- )
- for {
- tk, err := sc.d.Token()
- if err != nil {
- if err == io.EOF {
- return
- }
- panic(err)
- }
- switch v := tk.(type) {
- case xml.StartElement:
- if skipElement(v) {
- if err := sc.d.Skip(); err != nil {
- panic(err)
- }
- if v.Name.Local == "section" {
- sub++
- }
- break
- }
- switch v.Name.Local {
- case "section":
- sub++
- sc.readSection(append(sec, sub))
- case "xref":
- buf.Write(sc.readXRef(v))
- }
- case xml.CharData:
- if len(sec) == 0 {
- break
- }
- buf.Write(v)
- case xml.EndElement:
- if v.Name.Local == "section" {
- sc.addSentences(joinSection(sec), buf.String())
- return
- }
- }
- }
-}
-
-func (sc specCoverage) readXRef(se xml.StartElement) []byte {
- var b []byte
- for {
- tk, err := sc.d.Token()
- if err != nil {
- panic(err)
- }
- switch v := tk.(type) {
- case xml.CharData:
- if b != nil {
- panic("unexpected CharData")
- }
- b = []byte(string(v))
- case xml.EndElement:
- if v.Name.Local != "xref" {
- panic("expected </xref>")
- }
- if b != nil {
- return b
- }
- sig := attrSig(se)
- switch sig {
- case "target":
- return []byte(fmt.Sprintf("[%s]", attrValue(se, "target")))
- case "fmt-of,rel,target", "fmt-,,rel,target":
- return []byte(fmt.Sprintf("[%s, %s]", attrValue(se, "target"), attrValue(se, "rel")))
- case "fmt-of,sec,target", "fmt-,,sec,target":
- return []byte(fmt.Sprintf("[section %s of %s]", attrValue(se, "sec"), attrValue(se, "target")))
- case "fmt-of,rel,sec,target":
- return []byte(fmt.Sprintf("[section %s of %s, %s]", attrValue(se, "sec"), attrValue(se, "target"), attrValue(se, "rel")))
- default:
- panic(fmt.Sprintf("unknown attribute signature %q in %#v", sig, fmt.Sprintf("%#v", se)))
- }
- default:
- panic(fmt.Sprintf("unexpected tag %q", v))
- }
- }
-}
-
-var skipAnchor = map[string]bool{
- "intro": true,
- "Overview": true,
-}
-
-var skipTitle = map[string]bool{
- "Acknowledgements": true,
- "Change Log": true,
- "Document Organization": true,
- "Conventions and Terminology": true,
-}
-
-func skipElement(s xml.StartElement) bool {
- switch s.Name.Local {
- case "artwork":
- return true
- case "section":
- for _, attr := range s.Attr {
- switch attr.Name.Local {
- case "anchor":
- if skipAnchor[attr.Value] || strings.HasPrefix(attr.Value, "changes.since.") {
- return true
- }
- case "title":
- if skipTitle[attr.Value] {
- return true
- }
- }
- }
- }
- return false
-}
-
-func readSpecCov(r io.Reader) specCoverage {
- sc := specCoverage{
- coverage: map[specPart]bool{},
- d: xml.NewDecoder(r)}
- sc.readSection(nil)
- return sc
-}
-
-func (sc specCoverage) addSentences(sec string, sentence string) {
- for _, s := range parseSentences(sentence) {
- sc.coverage[specPart{sec, s}] = false
- }
-}
-
-func (sc specCoverage) cover(sec string, sentence string) {
- for _, s := range parseSentences(sentence) {
- p := specPart{sec, s}
- if _, ok := sc.coverage[p]; !ok {
- panic(fmt.Sprintf("Not found in spec: %q, %q", sec, s))
- }
- sc.coverage[specPart{sec, s}] = true
- }
-
-}
-
-var whitespaceRx = regexp.MustCompile(`\s+`)
-
-func parseSentences(sens string) []string {
- sens = strings.TrimSpace(sens)
- if sens == "" {
- return nil
- }
- ss := strings.Split(whitespaceRx.ReplaceAllString(sens, " "), ". ")
- for i, s := range ss {
- s = strings.TrimSpace(s)
- if !strings.HasSuffix(s, ".") {
- s += "."
- }
- ss[i] = s
- }
- return ss
-}
-
-func TestSpecParseSentences(t *testing.T) {
- tests := []struct {
- ss string
- want []string
- }{
- {"Sentence 1. Sentence 2.",
- []string{
- "Sentence 1.",
- "Sentence 2.",
- }},
- {"Sentence 1. \nSentence 2.\tSentence 3.",
- []string{
- "Sentence 1.",
- "Sentence 2.",
- "Sentence 3.",
- }},
- }
-
- for i, tt := range tests {
- got := parseSentences(tt.ss)
- if !reflect.DeepEqual(got, tt.want) {
- t.Errorf("%d: got = %q, want %q", i, got, tt.want)
- }
- }
-}
-
-func TestSpecCoverage(t *testing.T) {
- if !*coverSpec {
- t.Skip()
- }
-
- loadSpecOnce.Do(loadSpec)
-
- var (
- list []specPart
- cv = defaultSpecCoverage.coverage
- total = len(cv)
- complete = 0
- )
-
- for sp, touched := range defaultSpecCoverage.coverage {
- if touched {
- complete++
- } else {
- list = append(list, sp)
- }
- }
- sort.Stable(bySpecSection(list))
-
- if testing.Short() && len(list) > 5 {
- list = list[:5]
- }
-
- for _, p := range list {
- t.Errorf("\tSECTION %s: %s", p.section, p.sentence)
- }
-
- t.Logf("%d/%d (%d%%) sentences covered", complete, total, (complete/total)*100)
-}
-
-func attrSig(se xml.StartElement) string {
- var names []string
- for _, attr := range se.Attr {
- if attr.Name.Local == "fmt" {
- names = append(names, "fmt-"+attr.Value)
- } else {
- names = append(names, attr.Name.Local)
- }
- }
- sort.Strings(names)
- return strings.Join(names, ",")
-}
-
-func attrValue(se xml.StartElement, attr string) string {
- for _, a := range se.Attr {
- if a.Name.Local == attr {
- return a.Value
- }
- }
- panic("unknown attribute " + attr)
-}
-
-func TestSpecPartLess(t *testing.T) {
- tests := []struct {
- sec1, sec2 string
- want bool
- }{
- {"6.2.1", "6.2", false},
- {"6.2", "6.2.1", true},
- {"6.10", "6.10.1", true},
- {"6.10", "6.1.1", false}, // 10, not 1
- {"6.1", "6.1", false}, // equal, so not less
- }
- for _, tt := range tests {
- got := (specPart{tt.sec1, "foo"}).Less(specPart{tt.sec2, "foo"})
- if got != tt.want {
- t.Errorf("Less(%q, %q) = %v; want %v", tt.sec1, tt.sec2, got, tt.want)
- }
- }
-}
diff --git a/vendor/golang.org/x/net/idna/example_test.go b/vendor/golang.org/x/net/idna/example_test.go
deleted file mode 100644
index 941e707d8..000000000
--- a/vendor/golang.org/x/net/idna/example_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package idna_test
-
-import (
- "fmt"
-
- "golang.org/x/net/idna"
-)
-
-func ExampleProfile() {
- // Raw Punycode has no restrictions and does no mappings.
- fmt.Println(idna.ToASCII(""))
- fmt.Println(idna.ToASCII("*.faß.com"))
- fmt.Println(idna.Punycode.ToASCII("*.faß.com"))
-
- // Rewrite IDN for lookup. This (currently) uses transitional mappings to
- // find a balance between IDNA2003 and IDNA2008 compatibility.
- fmt.Println(idna.Lookup.ToASCII(""))
- fmt.Println(idna.Lookup.ToASCII("www.faß.com"))
-
- // Convert an IDN to ASCII for registration purposes. This changes the
- // encoding, but reports an error if the input was illformed.
- fmt.Println(idna.Registration.ToASCII(""))
- fmt.Println(idna.Registration.ToASCII("www.faß.com"))
-
- // Output:
- // <nil>
- // *.xn--fa-hia.com <nil>
- // *.xn--fa-hia.com <nil>
- // <nil>
- // www.fass.com <nil>
- // idna: invalid label ""
- // www.xn--fa-hia.com <nil>
-}
-
-func ExampleNew() {
- var p *idna.Profile
-
- // Raw Punycode has no restrictions and does no mappings.
- p = idna.New()
- fmt.Println(p.ToASCII("*.faß.com"))
-
- // Do mappings. Note that star is not allowed in a DNS lookup.
- p = idna.New(
- idna.MapForLookup(),
- idna.Transitional(true)) // Map ß -> ss
- fmt.Println(p.ToASCII("*.faß.com"))
-
- // Set up a profile maps for lookup, but allows wild cards.
- p = idna.New(
- idna.MapForLookup(),
- idna.Transitional(true), // Map ß -> ss
- idna.StrictDomainName(false)) // Set more permissive ASCII rules.
- fmt.Println(p.ToASCII("*.faß.com"))
-
- // Output:
- // *.xn--fa-hia.com <nil>
- // *.fass.com idna: disallowed rune U+002E
- // *.fass.com <nil>
-}
diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go
deleted file mode 100644
index ee2dbda6d..000000000
--- a/vendor/golang.org/x/net/idna/idna.go
+++ /dev/null
@@ -1,668 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package idna implements IDNA2008 using the compatibility processing
-// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
-// deal with the transition from IDNA2003.
-//
-// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC
-// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.
-// UTS #46 is defined in http://www.unicode.org/reports/tr46.
-// See http://unicode.org/cldr/utility/idna.jsp for a visualization of the
-// differences between these two standards.
-package idna // import "golang.org/x/net/idna"
-
-import (
- "fmt"
- "strings"
- "unicode/utf8"
-
- "golang.org/x/text/secure/bidirule"
- "golang.org/x/text/unicode/norm"
-)
-
-// NOTE: Unlike common practice in Go APIs, the functions will return a
-// sanitized domain name in case of errors. Browsers sometimes use a partially
-// evaluated string as lookup.
-// TODO: the current error handling is, in my opinion, the least opinionated.
-// Other strategies are also viable, though:
-// Option 1) Return an empty string in case of error, but allow the user to
-// specify explicitly which errors to ignore.
-// Option 2) Return the partially evaluated string if it is itself a valid
-// string, otherwise return the empty string in case of error.
-// Option 3) Option 1 and 2.
-// Option 4) Always return an empty string for now and implement Option 1 as
-// needed, and document that the return string may not be empty in case of
-// error in the future.
-// I think Option 1 is best, but it is quite opinionated.
-
-// ToASCII is a wrapper for Punycode.ToASCII.
-func ToASCII(s string) (string, error) {
- return Punycode.process(s, true)
-}
-
-// ToUnicode is a wrapper for Punycode.ToUnicode.
-func ToUnicode(s string) (string, error) {
- return Punycode.process(s, false)
-}
-
-// An Option configures a Profile at creation time.
-type Option func(*options)
-
-// Transitional sets a Profile to use the Transitional mapping as defined in UTS
-// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
-// transitional mapping provides a compromise between IDNA2003 and IDNA2008
-// compatibility. It is used by most browsers when resolving domain names. This
-// option is only meaningful if combined with MapForLookup.
-func Transitional(transitional bool) Option {
- return func(o *options) { o.transitional = true }
-}
-
-// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
-// are longer than allowed by the RFC.
-func VerifyDNSLength(verify bool) Option {
- return func(o *options) { o.verifyDNSLength = verify }
-}
-
-// ValidateLabels sets whether to check the mandatory label validation criteria
-// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
-// of hyphens ('-'), normalization, validity of runes, and the context rules.
-func ValidateLabels(enable bool) Option {
- return func(o *options) {
- // Don't override existing mappings, but set one that at least checks
- // normalization if it is not set.
- if o.mapping == nil && enable {
- o.mapping = normalize
- }
- o.trie = trie
- o.validateLabels = enable
- o.fromPuny = validateFromPunycode
- }
-}
-
-// StrictDomainName limits the set of permissable ASCII characters to those
-// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
-// hyphen). This is set by default for MapForLookup and ValidateForRegistration.
-//
-// This option is useful, for instance, for browsers that allow characters
-// outside this range, for example a '_' (U+005F LOW LINE). See
-// http://www.rfc-editor.org/std/std3.txt for more details This option
-// corresponds to the UseSTD3ASCIIRules option in UTS #46.
-func StrictDomainName(use bool) Option {
- return func(o *options) {
- o.trie = trie
- o.useSTD3Rules = use
- o.fromPuny = validateFromPunycode
- }
-}
-
-// NOTE: the following options pull in tables. The tables should not be linked
-// in as long as the options are not used.
-
-// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
-// that relies on proper validation of labels should include this rule.
-func BidiRule() Option {
- return func(o *options) { o.bidirule = bidirule.ValidString }
-}
-
-// ValidateForRegistration sets validation options to verify that a given IDN is
-// properly formatted for registration as defined by Section 4 of RFC 5891.
-func ValidateForRegistration() Option {
- return func(o *options) {
- o.mapping = validateRegistration
- StrictDomainName(true)(o)
- ValidateLabels(true)(o)
- VerifyDNSLength(true)(o)
- BidiRule()(o)
- }
-}
-
-// MapForLookup sets validation and mapping options such that a given IDN is
-// transformed for domain name lookup according to the requirements set out in
-// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,
-// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option
-// to add this check.
-//
-// The mappings include normalization and mapping case, width and other
-// compatibility mappings.
-func MapForLookup() Option {
- return func(o *options) {
- o.mapping = validateAndMap
- StrictDomainName(true)(o)
- ValidateLabels(true)(o)
- }
-}
-
-type options struct {
- transitional bool
- useSTD3Rules bool
- validateLabels bool
- verifyDNSLength bool
-
- trie *idnaTrie
-
- // fromPuny calls validation rules when converting A-labels to U-labels.
- fromPuny func(p *Profile, s string) error
-
- // mapping implements a validation and mapping step as defined in RFC 5895
- // or UTS 46, tailored to, for example, domain registration or lookup.
- mapping func(p *Profile, s string) (string, error)
-
- // bidirule, if specified, checks whether s conforms to the Bidi Rule
- // defined in RFC 5893.
- bidirule func(s string) bool
-}
-
-// A Profile defines the configuration of a IDNA mapper.
-type Profile struct {
- options
-}
-
-func apply(o *options, opts []Option) {
- for _, f := range opts {
- f(o)
- }
-}
-
-// New creates a new Profile.
-//
-// With no options, the returned Profile is the most permissive and equals the
-// Punycode Profile. Options can be passed to further restrict the Profile. The
-// MapForLookup and ValidateForRegistration options set a collection of options,
-// for lookup and registration purposes respectively, which can be tailored by
-// adding more fine-grained options, where later options override earlier
-// options.
-func New(o ...Option) *Profile {
- p := &Profile{}
- apply(&p.options, o)
- return p
-}
-
-// ToASCII converts a domain or domain label to its ASCII form. For example,
-// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
-// ToASCII("golang") is "golang". If an error is encountered it will return
-// an error and a (partially) processed result.
-func (p *Profile) ToASCII(s string) (string, error) {
- return p.process(s, true)
-}
-
-// ToUnicode converts a domain or domain label to its Unicode form. For example,
-// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
-// ToUnicode("golang") is "golang". If an error is encountered it will return
-// an error and a (partially) processed result.
-func (p *Profile) ToUnicode(s string) (string, error) {
- pp := *p
- pp.transitional = false
- return pp.process(s, false)
-}
-
-// String reports a string with a description of the profile for debugging
-// purposes. The string format may change with different versions.
-func (p *Profile) String() string {
- s := ""
- if p.transitional {
- s = "Transitional"
- } else {
- s = "NonTransitional"
- }
- if p.useSTD3Rules {
- s += ":UseSTD3Rules"
- }
- if p.validateLabels {
- s += ":ValidateLabels"
- }
- if p.verifyDNSLength {
- s += ":VerifyDNSLength"
- }
- return s
-}
-
-var (
- // Punycode is a Profile that does raw punycode processing with a minimum
- // of validation.
- Punycode *Profile = punycode
-
- // Lookup is the recommended profile for looking up domain names, according
- // to Section 5 of RFC 5891. The exact configuration of this profile may
- // change over time.
- Lookup *Profile = lookup
-
- // Display is the recommended profile for displaying domain names.
- // The configuration of this profile may change over time.
- Display *Profile = display
-
- // Registration is the recommended profile for checking whether a given
- // IDN is valid for registration, according to Section 4 of RFC 5891.
- Registration *Profile = registration
-
- punycode = &Profile{}
- lookup = &Profile{options{
- transitional: true,
- useSTD3Rules: true,
- validateLabels: true,
- trie: trie,
- fromPuny: validateFromPunycode,
- mapping: validateAndMap,
- bidirule: bidirule.ValidString,
- }}
- display = &Profile{options{
- useSTD3Rules: true,
- validateLabels: true,
- trie: trie,
- fromPuny: validateFromPunycode,
- mapping: validateAndMap,
- bidirule: bidirule.ValidString,
- }}
- registration = &Profile{options{
- useSTD3Rules: true,
- validateLabels: true,
- verifyDNSLength: true,
- trie: trie,
- fromPuny: validateFromPunycode,
- mapping: validateRegistration,
- bidirule: bidirule.ValidString,
- }}
-
- // TODO: profiles
- // Register: recommended for approving domain names: don't do any mappings
- // but rather reject on invalid input. Bundle or block deviation characters.
-)
-
-type labelError struct{ label, code_ string }
-
-func (e labelError) code() string { return e.code_ }
-func (e labelError) Error() string {
- return fmt.Sprintf("idna: invalid label %q", e.label)
-}
-
-type runeError rune
-
-func (e runeError) code() string { return "P1" }
-func (e runeError) Error() string {
- return fmt.Sprintf("idna: disallowed rune %U", e)
-}
-
-// process implements the algorithm described in section 4 of UTS #46,
-// see http://www.unicode.org/reports/tr46.
-func (p *Profile) process(s string, toASCII bool) (string, error) {
- var err error
- if p.mapping != nil {
- s, err = p.mapping(p, s)
- }
- // Remove leading empty labels.
- for ; len(s) > 0 && s[0] == '.'; s = s[1:] {
- }
- // It seems like we should only create this error on ToASCII, but the
- // UTS 46 conformance tests suggests we should always check this.
- if err == nil && p.verifyDNSLength && s == "" {
- err = &labelError{s, "A4"}
- }
- labels := labelIter{orig: s}
- for ; !labels.done(); labels.next() {
- label := labels.label()
- if label == "" {
- // Empty labels are not okay. The label iterator skips the last
- // label if it is empty.
- if err == nil && p.verifyDNSLength {
- err = &labelError{s, "A4"}
- }
- continue
- }
- if strings.HasPrefix(label, acePrefix) {
- u, err2 := decode(label[len(acePrefix):])
- if err2 != nil {
- if err == nil {
- err = err2
- }
- // Spec says keep the old label.
- continue
- }
- labels.set(u)
- if err == nil && p.validateLabels {
- err = p.fromPuny(p, u)
- }
- if err == nil {
- // This should be called on NonTransitional, according to the
- // spec, but that currently does not have any effect. Use the
- // original profile to preserve options.
- err = p.validateLabel(u)
- }
- } else if err == nil {
- err = p.validateLabel(label)
- }
- }
- if toASCII {
- for labels.reset(); !labels.done(); labels.next() {
- label := labels.label()
- if !ascii(label) {
- a, err2 := encode(acePrefix, label)
- if err == nil {
- err = err2
- }
- label = a
- labels.set(a)
- }
- n := len(label)
- if p.verifyDNSLength && err == nil && (n == 0 || n > 63) {
- err = &labelError{label, "A4"}
- }
- }
- }
- s = labels.result()
- if toASCII && p.verifyDNSLength && err == nil {
- // Compute the length of the domain name minus the root label and its dot.
- n := len(s)
- if n > 0 && s[n-1] == '.' {
- n--
- }
- if len(s) < 1 || n > 253 {
- err = &labelError{s, "A4"}
- }
- }
- return s, err
-}
-
-func normalize(p *Profile, s string) (string, error) {
- return norm.NFC.String(s), nil
-}
-
-func validateRegistration(p *Profile, s string) (string, error) {
- if !norm.NFC.IsNormalString(s) {
- return s, &labelError{s, "V1"}
- }
- var err error
- for i := 0; i < len(s); {
- v, sz := trie.lookupString(s[i:])
- i += sz
- // Copy bytes not copied so far.
- switch p.simplify(info(v).category()) {
- // TODO: handle the NV8 defined in the Unicode idna data set to allow
- // for strict conformance to IDNA2008.
- case valid, deviation:
- case disallowed, mapped, unknown, ignored:
- if err == nil {
- r, _ := utf8.DecodeRuneInString(s[i:])
- err = runeError(r)
- }
- }
- }
- return s, err
-}
-
-func validateAndMap(p *Profile, s string) (string, error) {
- var (
- err error
- b []byte
- k int
- )
- for i := 0; i < len(s); {
- v, sz := trie.lookupString(s[i:])
- start := i
- i += sz
- // Copy bytes not copied so far.
- switch p.simplify(info(v).category()) {
- case valid:
- continue
- case disallowed:
- if err == nil {
- r, _ := utf8.DecodeRuneInString(s[i:])
- err = runeError(r)
- }
- continue
- case mapped, deviation:
- b = append(b, s[k:start]...)
- b = info(v).appendMapping(b, s[start:i])
- case ignored:
- b = append(b, s[k:start]...)
- // drop the rune
- case unknown:
- b = append(b, s[k:start]...)
- b = append(b, "\ufffd"...)
- }
- k = i
- }
- if k == 0 {
- // No changes so far.
- s = norm.NFC.String(s)
- } else {
- b = append(b, s[k:]...)
- if norm.NFC.QuickSpan(b) != len(b) {
- b = norm.NFC.Bytes(b)
- }
- // TODO: the punycode converters require strings as input.
- s = string(b)
- }
- return s, err
-}
-
-// A labelIter allows iterating over domain name labels.
-type labelIter struct {
- orig string
- slice []string
- curStart int
- curEnd int
- i int
-}
-
-func (l *labelIter) reset() {
- l.curStart = 0
- l.curEnd = 0
- l.i = 0
-}
-
-func (l *labelIter) done() bool {
- return l.curStart >= len(l.orig)
-}
-
-func (l *labelIter) result() string {
- if l.slice != nil {
- return strings.Join(l.slice, ".")
- }
- return l.orig
-}
-
-func (l *labelIter) label() string {
- if l.slice != nil {
- return l.slice[l.i]
- }
- p := strings.IndexByte(l.orig[l.curStart:], '.')
- l.curEnd = l.curStart + p
- if p == -1 {
- l.curEnd = len(l.orig)
- }
- return l.orig[l.curStart:l.curEnd]
-}
-
-// next sets the value to the next label. It skips the last label if it is empty.
-func (l *labelIter) next() {
- l.i++
- if l.slice != nil {
- if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" {
- l.curStart = len(l.orig)
- }
- } else {
- l.curStart = l.curEnd + 1
- if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
- l.curStart = len(l.orig)
- }
- }
-}
-
-func (l *labelIter) set(s string) {
- if l.slice == nil {
- l.slice = strings.Split(l.orig, ".")
- }
- l.slice[l.i] = s
-}
-
-// acePrefix is the ASCII Compatible Encoding prefix.
-const acePrefix = "xn--"
-
-func (p *Profile) simplify(cat category) category {
- switch cat {
- case disallowedSTD3Mapped:
- if p.useSTD3Rules {
- cat = disallowed
- } else {
- cat = mapped
- }
- case disallowedSTD3Valid:
- if p.useSTD3Rules {
- cat = disallowed
- } else {
- cat = valid
- }
- case deviation:
- if !p.transitional {
- cat = valid
- }
- case validNV8, validXV8:
- // TODO: handle V2008
- cat = valid
- }
- return cat
-}
-
-func validateFromPunycode(p *Profile, s string) error {
- if !norm.NFC.IsNormalString(s) {
- return &labelError{s, "V1"}
- }
- for i := 0; i < len(s); {
- v, sz := trie.lookupString(s[i:])
- if c := p.simplify(info(v).category()); c != valid && c != deviation {
- return &labelError{s, "V6"}
- }
- i += sz
- }
- return nil
-}
-
-const (
- zwnj = "\u200c"
- zwj = "\u200d"
-)
-
-type joinState int8
-
-const (
- stateStart joinState = iota
- stateVirama
- stateBefore
- stateBeforeVirama
- stateAfter
- stateFAIL
-)
-
-var joinStates = [][numJoinTypes]joinState{
- stateStart: {
- joiningL: stateBefore,
- joiningD: stateBefore,
- joinZWNJ: stateFAIL,
- joinZWJ: stateFAIL,
- joinVirama: stateVirama,
- },
- stateVirama: {
- joiningL: stateBefore,
- joiningD: stateBefore,
- },
- stateBefore: {
- joiningL: stateBefore,
- joiningD: stateBefore,
- joiningT: stateBefore,
- joinZWNJ: stateAfter,
- joinZWJ: stateFAIL,
- joinVirama: stateBeforeVirama,
- },
- stateBeforeVirama: {
- joiningL: stateBefore,
- joiningD: stateBefore,
- joiningT: stateBefore,
- },
- stateAfter: {
- joiningL: stateFAIL,
- joiningD: stateBefore,
- joiningT: stateAfter,
- joiningR: stateStart,
- joinZWNJ: stateFAIL,
- joinZWJ: stateFAIL,
- joinVirama: stateAfter, // no-op as we can't accept joiners here
- },
- stateFAIL: {
- 0: stateFAIL,
- joiningL: stateFAIL,
- joiningD: stateFAIL,
- joiningT: stateFAIL,
- joiningR: stateFAIL,
- joinZWNJ: stateFAIL,
- joinZWJ: stateFAIL,
- joinVirama: stateFAIL,
- },
-}
-
-// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
-// already implicitly satisfied by the overall implementation.
-func (p *Profile) validateLabel(s string) error {
- if s == "" {
- if p.verifyDNSLength {
- return &labelError{s, "A4"}
- }
- return nil
- }
- if p.bidirule != nil && !p.bidirule(s) {
- return &labelError{s, "B"}
- }
- if !p.validateLabels {
- return nil
- }
- trie := p.trie // p.validateLabels is only set if trie is set.
- if len(s) > 4 && s[2] == '-' && s[3] == '-' {
- return &labelError{s, "V2"}
- }
- if s[0] == '-' || s[len(s)-1] == '-' {
- return &labelError{s, "V3"}
- }
- // TODO: merge the use of this in the trie.
- v, sz := trie.lookupString(s)
- x := info(v)
- if x.isModifier() {
- return &labelError{s, "V5"}
- }
- // Quickly return in the absence of zero-width (non) joiners.
- if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 {
- return nil
- }
- st := stateStart
- for i := 0; ; {
- jt := x.joinType()
- if s[i:i+sz] == zwj {
- jt = joinZWJ
- } else if s[i:i+sz] == zwnj {
- jt = joinZWNJ
- }
- st = joinStates[st][jt]
- if x.isViramaModifier() {
- st = joinStates[st][joinVirama]
- }
- if i += sz; i == len(s) {
- break
- }
- v, sz = trie.lookupString(s[i:])
- x = info(v)
- }
- if st == stateFAIL || st == stateAfter {
- return &labelError{s, "C"}
- }
- return nil
-}
-
-func ascii(s string) bool {
- for i := 0; i < len(s); i++ {
- if s[i] >= utf8.RuneSelf {
- return false
- }
- }
- return true
-}
diff --git a/vendor/golang.org/x/net/idna/idna_test.go b/vendor/golang.org/x/net/idna/idna_test.go
deleted file mode 100644
index b1bc6fa22..000000000
--- a/vendor/golang.org/x/net/idna/idna_test.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package idna
-
-import (
- "testing"
-)
-
-var idnaTestCases = [...]struct {
- ascii, unicode string
-}{
- // Labels.
- {"books", "books"},
- {"xn--bcher-kva", "bücher"},
-
- // Domains.
- {"foo--xn--bar.org", "foo--xn--bar.org"},
- {"golang.org", "golang.org"},
- {"example.xn--p1ai", "example.рф"},
- {"xn--czrw28b.tw", "商業.tw"},
- {"www.xn--mller-kva.de", "www.müller.de"},
-}
-
-func TestIDNA(t *testing.T) {
- for _, tc := range idnaTestCases {
- if a, err := ToASCII(tc.unicode); err != nil {
- t.Errorf("ToASCII(%q): %v", tc.unicode, err)
- } else if a != tc.ascii {
- t.Errorf("ToASCII(%q): got %q, want %q", tc.unicode, a, tc.ascii)
- }
-
- if u, err := ToUnicode(tc.ascii); err != nil {
- t.Errorf("ToUnicode(%q): %v", tc.ascii, err)
- } else if u != tc.unicode {
- t.Errorf("ToUnicode(%q): got %q, want %q", tc.ascii, u, tc.unicode)
- }
- }
-}
-
-// TODO(nigeltao): test errors, once we've specified when ToASCII and ToUnicode
-// return errors.
diff --git a/vendor/golang.org/x/net/idna/punycode.go b/vendor/golang.org/x/net/idna/punycode.go
deleted file mode 100644
index 02c7d59af..000000000
--- a/vendor/golang.org/x/net/idna/punycode.go
+++ /dev/null
@@ -1,203 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package idna
-
-// This file implements the Punycode algorithm from RFC 3492.
-
-import (
- "math"
- "strings"
- "unicode/utf8"
-)
-
-// These parameter values are specified in section 5.
-//
-// All computation is done with int32s, so that overflow behavior is identical
-// regardless of whether int is 32-bit or 64-bit.
-const (
- base int32 = 36
- damp int32 = 700
- initialBias int32 = 72
- initialN int32 = 128
- skew int32 = 38
- tmax int32 = 26
- tmin int32 = 1
-)
-
-func punyError(s string) error { return &labelError{s, "A3"} }
-
-// decode decodes a string as specified in section 6.2.
-func decode(encoded string) (string, error) {
- if encoded == "" {
- return "", nil
- }
- pos := 1 + strings.LastIndex(encoded, "-")
- if pos == 1 {
- return "", punyError(encoded)
- }
- if pos == len(encoded) {
- return encoded[:len(encoded)-1], nil
- }
- output := make([]rune, 0, len(encoded))
- if pos != 0 {
- for _, r := range encoded[:pos-1] {
- output = append(output, r)
- }
- }
- i, n, bias := int32(0), initialN, initialBias
- for pos < len(encoded) {
- oldI, w := i, int32(1)
- for k := base; ; k += base {
- if pos == len(encoded) {
- return "", punyError(encoded)
- }
- digit, ok := decodeDigit(encoded[pos])
- if !ok {
- return "", punyError(encoded)
- }
- pos++
- i += digit * w
- if i < 0 {
- return "", punyError(encoded)
- }
- t := k - bias
- if t < tmin {
- t = tmin
- } else if t > tmax {
- t = tmax
- }
- if digit < t {
- break
- }
- w *= base - t
- if w >= math.MaxInt32/base {
- return "", punyError(encoded)
- }
- }
- x := int32(len(output) + 1)
- bias = adapt(i-oldI, x, oldI == 0)
- n += i / x
- i %= x
- if n > utf8.MaxRune || len(output) >= 1024 {
- return "", punyError(encoded)
- }
- output = append(output, 0)
- copy(output[i+1:], output[i:])
- output[i] = n
- i++
- }
- return string(output), nil
-}
-
-// encode encodes a string as specified in section 6.3 and prepends prefix to
-// the result.
-//
-// The "while h < length(input)" line in the specification becomes "for
-// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
-func encode(prefix, s string) (string, error) {
- output := make([]byte, len(prefix), len(prefix)+1+2*len(s))
- copy(output, prefix)
- delta, n, bias := int32(0), initialN, initialBias
- b, remaining := int32(0), int32(0)
- for _, r := range s {
- if r < 0x80 {
- b++
- output = append(output, byte(r))
- } else {
- remaining++
- }
- }
- h := b
- if b > 0 {
- output = append(output, '-')
- }
- for remaining != 0 {
- m := int32(0x7fffffff)
- for _, r := range s {
- if m > r && r >= n {
- m = r
- }
- }
- delta += (m - n) * (h + 1)
- if delta < 0 {
- return "", punyError(s)
- }
- n = m
- for _, r := range s {
- if r < n {
- delta++
- if delta < 0 {
- return "", punyError(s)
- }
- continue
- }
- if r > n {
- continue
- }
- q := delta
- for k := base; ; k += base {
- t := k - bias
- if t < tmin {
- t = tmin
- } else if t > tmax {
- t = tmax
- }
- if q < t {
- break
- }
- output = append(output, encodeDigit(t+(q-t)%(base-t)))
- q = (q - t) / (base - t)
- }
- output = append(output, encodeDigit(q))
- bias = adapt(delta, h+1, h == b)
- delta = 0
- h++
- remaining--
- }
- delta++
- n++
- }
- return string(output), nil
-}
-
-func decodeDigit(x byte) (digit int32, ok bool) {
- switch {
- case '0' <= x && x <= '9':
- return int32(x - ('0' - 26)), true
- case 'A' <= x && x <= 'Z':
- return int32(x - 'A'), true
- case 'a' <= x && x <= 'z':
- return int32(x - 'a'), true
- }
- return 0, false
-}
-
-func encodeDigit(digit int32) byte {
- switch {
- case 0 <= digit && digit < 26:
- return byte(digit + 'a')
- case 26 <= digit && digit < 36:
- return byte(digit + ('0' - 26))
- }
- panic("idna: internal error in punycode encoding")
-}
-
-// adapt is the bias adaptation function specified in section 6.1.
-func adapt(delta, numPoints int32, firstTime bool) int32 {
- if firstTime {
- delta /= damp
- } else {
- delta /= 2
- }
- delta += delta / numPoints
- k := int32(0)
- for delta > ((base-tmin)*tmax)/2 {
- delta /= base - tmin
- k += base
- }
- return k + (base-tmin+1)*delta/(delta+skew)
-}
diff --git a/vendor/golang.org/x/net/idna/punycode_test.go b/vendor/golang.org/x/net/idna/punycode_test.go
deleted file mode 100644
index bfec81dec..000000000
--- a/vendor/golang.org/x/net/idna/punycode_test.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package idna
-
-import (
- "strings"
- "testing"
-)
-
-var punycodeTestCases = [...]struct {
- s, encoded string
-}{
- {"", ""},
- {"-", "--"},
- {"-a", "-a-"},
- {"-a-", "-a--"},
- {"a", "a-"},
- {"a-", "a--"},
- {"a-b", "a-b-"},
- {"books", "books-"},
- {"bücher", "bcher-kva"},
- {"Hello世界", "Hello-ck1hg65u"},
- {"ü", "tda"},
- {"üý", "tdac"},
-
- // The test cases below come from RFC 3492 section 7.1 with Errata 3026.
- {
- // (A) Arabic (Egyptian).
- "\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" +
- "\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F",
- "egbpdaj6bu4bxfgehfvwxn",
- },
- {
- // (B) Chinese (simplified).
- "\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587",
- "ihqwcrb4cv8a8dqg056pqjye",
- },
- {
- // (C) Chinese (traditional).
- "\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587",
- "ihqwctvzc91f659drss3x8bo0yb",
- },
- {
- // (D) Czech.
- "\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074" +
- "\u011B\u006E\u0065\u006D\u006C\u0075\u0076\u00ED\u010D" +
- "\u0065\u0073\u006B\u0079",
- "Proprostnemluvesky-uyb24dma41a",
- },
- {
- // (E) Hebrew.
- "\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8" +
- "\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2" +
- "\u05D1\u05E8\u05D9\u05EA",
- "4dbcagdahymbxekheh6e0a7fei0b",
- },
- {
- // (F) Hindi (Devanagari).
- "\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D" +
- "\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939" +
- "\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947" +
- "\u0939\u0948\u0902",
- "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd",
- },
- {
- // (G) Japanese (kanji and hiragana).
- "\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092" +
- "\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B",
- "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa",
- },
- {
- // (H) Korean (Hangul syllables).
- "\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774" +
- "\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74" +
- "\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C",
- "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5j" +
- "psd879ccm6fea98c",
- },
- {
- // (I) Russian (Cyrillic).
- "\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E" +
- "\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440" +
- "\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A" +
- "\u0438",
- "b1abfaaepdrnnbgefbadotcwatmq2g4l",
- },
- {
- // (J) Spanish.
- "\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070" +
- "\u0075\u0065\u0064\u0065\u006E\u0073\u0069\u006D\u0070" +
- "\u006C\u0065\u006D\u0065\u006E\u0074\u0065\u0068\u0061" +
- "\u0062\u006C\u0061\u0072\u0065\u006E\u0045\u0073\u0070" +
- "\u0061\u00F1\u006F\u006C",
- "PorqunopuedensimplementehablarenEspaol-fmd56a",
- },
- {
- // (K) Vietnamese.
- "\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B" +
- "\u0068\u00F4\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068" +
- "\u1EC9\u006E\u00F3\u0069\u0074\u0069\u1EBF\u006E\u0067" +
- "\u0056\u0069\u1EC7\u0074",
- "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g",
- },
- {
- // (L) 3<nen>B<gumi><kinpachi><sensei>.
- "\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F",
- "3B-ww4c5e180e575a65lsy2b",
- },
- {
- // (M) <amuro><namie>-with-SUPER-MONKEYS.
- "\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074" +
- "\u0068\u002D\u0053\u0055\u0050\u0045\u0052\u002D\u004D" +
- "\u004F\u004E\u004B\u0045\u0059\u0053",
- "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n",
- },
- {
- // (N) Hello-Another-Way-<sorezore><no><basho>.
- "\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F" +
- "\u0074\u0068\u0065\u0072\u002D\u0057\u0061\u0079\u002D" +
- "\u305D\u308C\u305E\u308C\u306E\u5834\u6240",
- "Hello-Another-Way--fc4qua05auwb3674vfr0b",
- },
- {
- // (O) <hitotsu><yane><no><shita>2.
- "\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032",
- "2-u9tlzr9756bt3uc0v",
- },
- {
- // (P) Maji<de>Koi<suru>5<byou><mae>
- "\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059" +
- "\u308B\u0035\u79D2\u524D",
- "MajiKoi5-783gue6qz075azm5e",
- },
- {
- // (Q) <pafii>de<runba>
- "\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0",
- "de-jg4avhby1noc0d",
- },
- {
- // (R) <sono><supiido><de>
- "\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067",
- "d9juau41awczczp",
- },
- {
- // (S) -> $1.00 <-
- "\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020" +
- "\u003C\u002D",
- "-> $1.00 <--",
- },
-}
-
-func TestPunycode(t *testing.T) {
- for _, tc := range punycodeTestCases {
- if got, err := decode(tc.encoded); err != nil {
- t.Errorf("decode(%q): %v", tc.encoded, err)
- } else if got != tc.s {
- t.Errorf("decode(%q): got %q, want %q", tc.encoded, got, tc.s)
- }
-
- if got, err := encode("", tc.s); err != nil {
- t.Errorf(`encode("", %q): %v`, tc.s, err)
- } else if got != tc.encoded {
- t.Errorf(`encode("", %q): got %q, want %q`, tc.s, got, tc.encoded)
- }
- }
-}
-
-var punycodeErrorTestCases = [...]string{
- "decode -", // A sole '-' is invalid.
- "decode foo\x00bar", // '\x00' is not in [0-9A-Za-z].
- "decode foo#bar", // '#' is not in [0-9A-Za-z].
- "decode foo\u00A3bar", // '\u00A3' is not in [0-9A-Za-z].
- "decode 9", // "9a" decodes to codepoint \u00A3; "9" is truncated.
- "decode 99999a", // "99999a" decodes to codepoint \U0048A3C1, which is > \U0010FFFF.
- "decode 9999999999a", // "9999999999a" overflows the int32 calculation.
-
- "encode " + strings.Repeat("x", 65536) + "\uff00", // int32 overflow.
-}
-
-func TestPunycodeErrors(t *testing.T) {
- for _, tc := range punycodeErrorTestCases {
- var err error
- switch {
- case strings.HasPrefix(tc, "decode "):
- _, err = decode(tc[7:])
- case strings.HasPrefix(tc, "encode "):
- _, err = encode("", tc[7:])
- }
- if err == nil {
- if len(tc) > 256 {
- tc = tc[:100] + "..." + tc[len(tc)-100:]
- }
- t.Errorf("no error for %s", tc)
- }
- }
-}
diff --git a/vendor/golang.org/x/net/idna/tables.go b/vendor/golang.org/x/net/idna/tables.go
deleted file mode 100644
index d2819345f..000000000
--- a/vendor/golang.org/x/net/idna/tables.go
+++ /dev/null
@@ -1,4477 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-package idna
-
-// UnicodeVersion is the Unicode version from which the tables in this package are derived.
-const UnicodeVersion = "9.0.0"
-
-var mappings string = "" + // Size: 8176 bytes
- "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" +
- "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" +
- "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" +
- "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" +
- "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" +
- "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" +
- "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" +
- "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" +
- "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" +
- "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" +
- "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" +
- "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" +
- "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" +
- "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" +
- "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" +
- "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" +
- "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" +
- "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" +
- "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" +
- "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" +
- "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" +
- "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" +
- "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" +
- "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" +
- "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" +
- "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" +
- ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" +
- "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" +
- "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" +
- "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" +
- "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" +
- "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" +
- "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" +
- "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" +
- "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" +
- "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" +
- "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" +
- "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" +
- "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" +
- "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" +
- "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" +
- "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" +
- "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" +
- "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" +
- "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" +
- "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" +
- "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" +
- "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" +
- "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" +
- "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" +
- "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" +
- "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" +
- "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" +
- "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" +
- "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" +
- "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" +
- "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" +
- "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" +
- "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" +
- "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" +
- "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" +
- "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" +
- "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" +
- "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" +
- "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" +
- "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" +
- "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" +
- "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" +
- "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" +
- "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" +
- "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" +
- "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" +
- "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" +
- " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" +
- "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" +
- "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" +
- "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" +
- "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" +
- "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" +
- "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" +
- "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" +
- "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" +
- "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" +
- "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" +
- "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" +
- "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" +
- "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" +
- "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" +
- "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" +
- "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" +
- "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" +
- "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" +
- "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" +
- "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" +
- "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" +
- "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" +
- "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" +
- "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" +
- "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" +
- "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" +
- "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" +
- "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" +
- "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" +
- "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" +
- "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" +
- "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" +
- "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" +
- "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" +
- "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" +
- "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" +
- "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" +
- "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" +
- "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" +
- "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" +
- "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" +
- "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" +
- "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" +
- "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" +
- "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" +
- "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" +
- "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" +
- "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" +
- "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" +
- "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" +
- "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" +
- "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" +
- "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" +
- "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" +
- "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" +
- "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" +
- "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" +
- "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" +
- "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" +
- "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" +
- "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" +
- "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" +
- "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻"
-
-var xorData string = "" + // Size: 4855 bytes
- "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" +
- "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" +
- "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" +
- "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" +
- "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" +
- "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" +
- "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" +
- "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" +
- "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" +
- "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" +
- "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" +
- "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" +
- "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" +
- "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" +
- "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" +
- "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" +
- "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" +
- "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" +
- "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" +
- "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" +
- "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" +
- "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" +
- "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" +
- "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" +
- "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" +
- "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" +
- "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" +
- "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" +
- "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" +
- "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" +
- "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" +
- "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" +
- "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" +
- "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" +
- "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" +
- "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" +
- "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " +
- "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" +
- "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" +
- "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" +
- "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" +
- "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" +
- ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" +
- "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" +
- "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" +
- "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" +
- "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" +
- "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" +
- "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" +
- "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" +
- "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" +
- "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" +
- "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" +
- "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" +
- "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" +
- "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" +
- "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" +
- "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" +
- "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" +
- "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" +
- "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" +
- "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" +
- "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" +
- "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" +
- "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" +
- "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" +
- "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" +
- "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" +
- "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" +
- "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" +
- "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" +
- "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" +
- "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" +
- "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" +
- "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" +
- "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" +
- "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" +
- "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" +
- "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" +
- "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" +
- "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" +
- "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" +
- "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" +
- "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" +
- "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" +
- "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" +
- "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" +
- "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" +
- "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," +
- "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" +
- "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" +
- "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" +
- "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" +
- ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" +
- "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" +
- "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" +
- "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" +
- "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" +
- "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" +
- "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" +
- "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" +
- "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" +
- "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" +
- "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" +
- "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" +
- "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" +
- "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" +
- "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" +
- "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" +
- "\x08\x1a\x0a\x03\x07</\x03\x07:+\x03\x07\x07*\x03\x06&\x1c\x03\x09\x0c" +
- "\x16\x03\x09\x10\x0e\x03\x08'\x0f\x03\x08+\x09\x03\x074%\x03\x06!3\x03" +
- "\x06\x03+\x03\x0b\x1e\x19\x03\x0a))\x03\x09\x08\x19\x03\x08,\x05\x03\x07" +
- "<2\x03\x06\x1c>\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" +
- "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" +
- "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" +
- "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" +
- "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" +
- "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" +
- "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" +
- "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" +
- "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" +
- "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" +
- "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" +
- "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" +
- "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" +
- "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" +
- "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" +
- "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" +
- "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" +
- "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." +
- "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" +
- "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" +
- "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " +
- "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" +
- "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" +
- "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" +
- "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" +
- "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" +
- "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" +
- "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," +
- "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" +
- "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" +
- "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" +
- "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" +
- "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" +
- "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" +
- "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" +
- "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" +
- "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" +
- "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" +
- "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" +
- "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" +
- "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" +
- "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" +
- "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" +
- "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" +
- "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" +
- "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" +
- "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" +
- "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" +
- "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" +
- "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" +
- "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" +
- "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" +
- "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" +
- "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" +
- "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" +
- "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" +
- "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" +
- "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" +
- "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" +
- "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" +
- "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" +
- "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" +
- "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" +
- "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" +
- "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" +
- "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" +
- "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," +
- "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" +
- "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" +
- "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" +
- "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" +
- "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" +
- "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" +
- "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" +
- "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" +
- "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" +
- "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" +
- "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" +
- "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" +
- "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" +
- "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" +
- "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" +
- "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" +
- "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" +
- "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" +
- "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" +
- "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" +
- "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" +
- "\x04\x03\x0c?\x05\x03\x0c<?\x03\x0c=\x00\x03\x0c=\x06\x03\x0c=\x05\x03" +
- "\x0c=\x0c\x03\x0c=\x0f\x03\x0c=\x0d\x03\x0c=\x0b\x03\x0c=\x07\x03\x0c=" +
- "\x19\x03\x0c=\x15\x03\x0c=\x11\x03\x0c=1\x03\x0c=3\x03\x0c=0\x03\x0c=>" +
- "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" +
- "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" +
- "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" +
- "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" +
- "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" +
- "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" +
- "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" +
- "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" +
- "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" +
- "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" +
- "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" +
- "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" +
- "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" +
- "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" +
- "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" +
- "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" +
- "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" +
- "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" +
- "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" +
- "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" +
- "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" +
- "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" +
- "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" +
- "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" +
- "\x05\x22\x05\x03\x050\x1d"
-
-// lookup returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return idnaValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = idnaIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = idnaIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = idnaIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *idnaTrie) lookupUnsafe(s []byte) uint16 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return idnaValues[c0]
- }
- i := idnaIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = idnaIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = idnaIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// lookupString returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *idnaTrie) lookupString(s string) (v uint16, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return idnaValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = idnaIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = idnaIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = idnaIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *idnaTrie) lookupStringUnsafe(s string) uint16 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return idnaValues[c0]
- }
- i := idnaIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = idnaIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = idnaIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// idnaTrie. Total size: 28496 bytes (27.83 KiB). Checksum: 43288b883596640e.
-type idnaTrie struct{}
-
-func newIdnaTrie(i int) *idnaTrie {
- return &idnaTrie{}
-}
-
-// lookupValue determines the type of block n and looks up the value for b.
-func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {
- switch {
- case n < 123:
- return uint16(idnaValues[n<<6+uint32(b)])
- default:
- n -= 123
- return uint16(idnaSparse.lookup(n, b))
- }
-}
-
-// idnaValues: 125 blocks, 8000 entries, 16000 bytes
-// The third block is the zero block.
-var idnaValues = [8000]uint16{
- // Block 0x0, offset 0x0
- 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,
- 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,
- 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,
- 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,
- 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,
- 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,
- 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,
- 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,
- 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,
- 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,
- 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,
- // Block 0x1, offset 0x40
- 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,
- 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,
- 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,
- 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,
- 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,
- 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,
- 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,
- 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,
- 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,
- 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,
- 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,
- 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,
- 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,
- 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,
- 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,
- 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,
- 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,
- 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,
- 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,
- 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,
- 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,
- // Block 0x4, offset 0x100
- 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,
- 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,
- 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,
- 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,
- 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,
- 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,
- 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,
- 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,
- 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,
- 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,
- 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,
- // Block 0x5, offset 0x140
- 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,
- 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,
- 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,
- 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,
- 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,
- 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,
- 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,
- 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,
- 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,
- 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,
- 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,
- // Block 0x6, offset 0x180
- 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,
- 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,
- 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,
- 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,
- 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,
- 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,
- 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,
- 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,
- 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,
- 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,
- 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,
- 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,
- 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,
- 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,
- 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,
- 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,
- 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,
- 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,
- 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,
- 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,
- 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,
- // Block 0x8, offset 0x200
- 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,
- 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,
- 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,
- 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,
- 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,
- 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,
- 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,
- 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,
- 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,
- 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,
- 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,
- // Block 0x9, offset 0x240
- 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,
- 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,
- 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,
- 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,
- 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,
- 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,
- 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,
- 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,
- 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,
- 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,
- 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,
- // Block 0xa, offset 0x280
- 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x1308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,
- 0x286: 0x1308, 0x287: 0x1308, 0x288: 0x1308, 0x289: 0x1308, 0x28a: 0x1308, 0x28b: 0x1308,
- 0x28c: 0x1308, 0x28d: 0x1308, 0x28e: 0x1308, 0x28f: 0x13c0, 0x290: 0x1308, 0x291: 0x1308,
- 0x292: 0x1308, 0x293: 0x1308, 0x294: 0x1308, 0x295: 0x1308, 0x296: 0x1308, 0x297: 0x1308,
- 0x298: 0x1308, 0x299: 0x1308, 0x29a: 0x1308, 0x29b: 0x1308, 0x29c: 0x1308, 0x29d: 0x1308,
- 0x29e: 0x1308, 0x29f: 0x1308, 0x2a0: 0x1308, 0x2a1: 0x1308, 0x2a2: 0x1308, 0x2a3: 0x1308,
- 0x2a4: 0x1308, 0x2a5: 0x1308, 0x2a6: 0x1308, 0x2a7: 0x1308, 0x2a8: 0x1308, 0x2a9: 0x1308,
- 0x2aa: 0x1308, 0x2ab: 0x1308, 0x2ac: 0x1308, 0x2ad: 0x1308, 0x2ae: 0x1308, 0x2af: 0x1308,
- 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,
- 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,
- 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,
- // Block 0xb, offset 0x2c0
- 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,
- 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,
- 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,
- 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,
- 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,
- 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,
- 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,
- 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,
- 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,
- 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,
- 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,
- // Block 0xc, offset 0x300
- 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,
- 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,
- 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,
- 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,
- 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,
- 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,
- 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,
- 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,
- 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,
- 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,
- 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,
- // Block 0xd, offset 0x340
- 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,
- 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,
- 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,
- 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,
- 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,
- 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,
- 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,
- 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,
- 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,
- 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,
- 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,
- // Block 0xe, offset 0x380
- 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x1308, 0x384: 0x1308, 0x385: 0x1308,
- 0x386: 0x1308, 0x387: 0x1308, 0x388: 0x1318, 0x389: 0x1318, 0x38a: 0xe00d, 0x38b: 0x0008,
- 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,
- 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,
- 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,
- 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,
- 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,
- 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,
- 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,
- 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,
- 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,
- // Block 0xf, offset 0x3c0
- 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,
- 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,
- 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,
- 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,
- 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,
- 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,
- 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,
- 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,
- 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,
- 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,
- 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,
- // Block 0x10, offset 0x400
- 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,
- 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,
- 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,
- 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,
- 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,
- 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,
- 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,
- 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,
- 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,
- 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,
- 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,
- // Block 0x11, offset 0x440
- 0x440: 0x0040, 0x441: 0x0040, 0x442: 0x0040, 0x443: 0x0040, 0x444: 0x0040, 0x445: 0x0040,
- 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0018, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0018,
- 0x44c: 0x0018, 0x44d: 0x0018, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x1308, 0x451: 0x1308,
- 0x452: 0x1308, 0x453: 0x1308, 0x454: 0x1308, 0x455: 0x1308, 0x456: 0x1308, 0x457: 0x1308,
- 0x458: 0x1308, 0x459: 0x1308, 0x45a: 0x1308, 0x45b: 0x0018, 0x45c: 0x0340, 0x45d: 0x0040,
- 0x45e: 0x0018, 0x45f: 0x0018, 0x460: 0x0208, 0x461: 0x0008, 0x462: 0x0408, 0x463: 0x0408,
- 0x464: 0x0408, 0x465: 0x0408, 0x466: 0x0208, 0x467: 0x0408, 0x468: 0x0208, 0x469: 0x0408,
- 0x46a: 0x0208, 0x46b: 0x0208, 0x46c: 0x0208, 0x46d: 0x0208, 0x46e: 0x0208, 0x46f: 0x0408,
- 0x470: 0x0408, 0x471: 0x0408, 0x472: 0x0408, 0x473: 0x0208, 0x474: 0x0208, 0x475: 0x0208,
- 0x476: 0x0208, 0x477: 0x0208, 0x478: 0x0208, 0x479: 0x0208, 0x47a: 0x0208, 0x47b: 0x0208,
- 0x47c: 0x0208, 0x47d: 0x0208, 0x47e: 0x0208, 0x47f: 0x0208,
- // Block 0x12, offset 0x480
- 0x480: 0x0408, 0x481: 0x0208, 0x482: 0x0208, 0x483: 0x0408, 0x484: 0x0408, 0x485: 0x0408,
- 0x486: 0x0408, 0x487: 0x0408, 0x488: 0x0408, 0x489: 0x0408, 0x48a: 0x0408, 0x48b: 0x0408,
- 0x48c: 0x0208, 0x48d: 0x0408, 0x48e: 0x0208, 0x48f: 0x0408, 0x490: 0x0208, 0x491: 0x0208,
- 0x492: 0x0408, 0x493: 0x0408, 0x494: 0x0018, 0x495: 0x0408, 0x496: 0x1308, 0x497: 0x1308,
- 0x498: 0x1308, 0x499: 0x1308, 0x49a: 0x1308, 0x49b: 0x1308, 0x49c: 0x1308, 0x49d: 0x0040,
- 0x49e: 0x0018, 0x49f: 0x1308, 0x4a0: 0x1308, 0x4a1: 0x1308, 0x4a2: 0x1308, 0x4a3: 0x1308,
- 0x4a4: 0x1308, 0x4a5: 0x0008, 0x4a6: 0x0008, 0x4a7: 0x1308, 0x4a8: 0x1308, 0x4a9: 0x0018,
- 0x4aa: 0x1308, 0x4ab: 0x1308, 0x4ac: 0x1308, 0x4ad: 0x1308, 0x4ae: 0x0408, 0x4af: 0x0408,
- 0x4b0: 0x0008, 0x4b1: 0x0008, 0x4b2: 0x0008, 0x4b3: 0x0008, 0x4b4: 0x0008, 0x4b5: 0x0008,
- 0x4b6: 0x0008, 0x4b7: 0x0008, 0x4b8: 0x0008, 0x4b9: 0x0008, 0x4ba: 0x0208, 0x4bb: 0x0208,
- 0x4bc: 0x0208, 0x4bd: 0x0008, 0x4be: 0x0008, 0x4bf: 0x0208,
- // Block 0x13, offset 0x4c0
- 0x4c0: 0x0018, 0x4c1: 0x0018, 0x4c2: 0x0018, 0x4c3: 0x0018, 0x4c4: 0x0018, 0x4c5: 0x0018,
- 0x4c6: 0x0018, 0x4c7: 0x0018, 0x4c8: 0x0018, 0x4c9: 0x0018, 0x4ca: 0x0018, 0x4cb: 0x0018,
- 0x4cc: 0x0018, 0x4cd: 0x0018, 0x4ce: 0x0040, 0x4cf: 0x0340, 0x4d0: 0x0408, 0x4d1: 0x1308,
- 0x4d2: 0x0208, 0x4d3: 0x0208, 0x4d4: 0x0208, 0x4d5: 0x0408, 0x4d6: 0x0408, 0x4d7: 0x0408,
- 0x4d8: 0x0408, 0x4d9: 0x0408, 0x4da: 0x0208, 0x4db: 0x0208, 0x4dc: 0x0208, 0x4dd: 0x0208,
- 0x4de: 0x0408, 0x4df: 0x0208, 0x4e0: 0x0208, 0x4e1: 0x0208, 0x4e2: 0x0208, 0x4e3: 0x0208,
- 0x4e4: 0x0208, 0x4e5: 0x0208, 0x4e6: 0x0208, 0x4e7: 0x0208, 0x4e8: 0x0408, 0x4e9: 0x0208,
- 0x4ea: 0x0408, 0x4eb: 0x0208, 0x4ec: 0x0408, 0x4ed: 0x0208, 0x4ee: 0x0208, 0x4ef: 0x0408,
- 0x4f0: 0x1308, 0x4f1: 0x1308, 0x4f2: 0x1308, 0x4f3: 0x1308, 0x4f4: 0x1308, 0x4f5: 0x1308,
- 0x4f6: 0x1308, 0x4f7: 0x1308, 0x4f8: 0x1308, 0x4f9: 0x1308, 0x4fa: 0x1308, 0x4fb: 0x1308,
- 0x4fc: 0x1308, 0x4fd: 0x1308, 0x4fe: 0x1308, 0x4ff: 0x1308,
- // Block 0x14, offset 0x500
- 0x500: 0x1008, 0x501: 0x1308, 0x502: 0x1308, 0x503: 0x1308, 0x504: 0x1308, 0x505: 0x1308,
- 0x506: 0x1308, 0x507: 0x1308, 0x508: 0x1308, 0x509: 0x1008, 0x50a: 0x1008, 0x50b: 0x1008,
- 0x50c: 0x1008, 0x50d: 0x1b08, 0x50e: 0x1008, 0x50f: 0x1008, 0x510: 0x0008, 0x511: 0x1308,
- 0x512: 0x1308, 0x513: 0x1308, 0x514: 0x1308, 0x515: 0x1308, 0x516: 0x1308, 0x517: 0x1308,
- 0x518: 0x04c9, 0x519: 0x0501, 0x51a: 0x0539, 0x51b: 0x0571, 0x51c: 0x05a9, 0x51d: 0x05e1,
- 0x51e: 0x0619, 0x51f: 0x0651, 0x520: 0x0008, 0x521: 0x0008, 0x522: 0x1308, 0x523: 0x1308,
- 0x524: 0x0018, 0x525: 0x0018, 0x526: 0x0008, 0x527: 0x0008, 0x528: 0x0008, 0x529: 0x0008,
- 0x52a: 0x0008, 0x52b: 0x0008, 0x52c: 0x0008, 0x52d: 0x0008, 0x52e: 0x0008, 0x52f: 0x0008,
- 0x530: 0x0018, 0x531: 0x0008, 0x532: 0x0008, 0x533: 0x0008, 0x534: 0x0008, 0x535: 0x0008,
- 0x536: 0x0008, 0x537: 0x0008, 0x538: 0x0008, 0x539: 0x0008, 0x53a: 0x0008, 0x53b: 0x0008,
- 0x53c: 0x0008, 0x53d: 0x0008, 0x53e: 0x0008, 0x53f: 0x0008,
- // Block 0x15, offset 0x540
- 0x540: 0x0008, 0x541: 0x1308, 0x542: 0x1008, 0x543: 0x1008, 0x544: 0x0040, 0x545: 0x0008,
- 0x546: 0x0008, 0x547: 0x0008, 0x548: 0x0008, 0x549: 0x0008, 0x54a: 0x0008, 0x54b: 0x0008,
- 0x54c: 0x0008, 0x54d: 0x0040, 0x54e: 0x0040, 0x54f: 0x0008, 0x550: 0x0008, 0x551: 0x0040,
- 0x552: 0x0040, 0x553: 0x0008, 0x554: 0x0008, 0x555: 0x0008, 0x556: 0x0008, 0x557: 0x0008,
- 0x558: 0x0008, 0x559: 0x0008, 0x55a: 0x0008, 0x55b: 0x0008, 0x55c: 0x0008, 0x55d: 0x0008,
- 0x55e: 0x0008, 0x55f: 0x0008, 0x560: 0x0008, 0x561: 0x0008, 0x562: 0x0008, 0x563: 0x0008,
- 0x564: 0x0008, 0x565: 0x0008, 0x566: 0x0008, 0x567: 0x0008, 0x568: 0x0008, 0x569: 0x0040,
- 0x56a: 0x0008, 0x56b: 0x0008, 0x56c: 0x0008, 0x56d: 0x0008, 0x56e: 0x0008, 0x56f: 0x0008,
- 0x570: 0x0008, 0x571: 0x0040, 0x572: 0x0008, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,
- 0x576: 0x0008, 0x577: 0x0008, 0x578: 0x0008, 0x579: 0x0008, 0x57a: 0x0040, 0x57b: 0x0040,
- 0x57c: 0x1308, 0x57d: 0x0008, 0x57e: 0x1008, 0x57f: 0x1008,
- // Block 0x16, offset 0x580
- 0x580: 0x1008, 0x581: 0x1308, 0x582: 0x1308, 0x583: 0x1308, 0x584: 0x1308, 0x585: 0x0040,
- 0x586: 0x0040, 0x587: 0x1008, 0x588: 0x1008, 0x589: 0x0040, 0x58a: 0x0040, 0x58b: 0x1008,
- 0x58c: 0x1008, 0x58d: 0x1b08, 0x58e: 0x0008, 0x58f: 0x0040, 0x590: 0x0040, 0x591: 0x0040,
- 0x592: 0x0040, 0x593: 0x0040, 0x594: 0x0040, 0x595: 0x0040, 0x596: 0x0040, 0x597: 0x1008,
- 0x598: 0x0040, 0x599: 0x0040, 0x59a: 0x0040, 0x59b: 0x0040, 0x59c: 0x0689, 0x59d: 0x06c1,
- 0x59e: 0x0040, 0x59f: 0x06f9, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x1308, 0x5a3: 0x1308,
- 0x5a4: 0x0040, 0x5a5: 0x0040, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,
- 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,
- 0x5b0: 0x0008, 0x5b1: 0x0008, 0x5b2: 0x0018, 0x5b3: 0x0018, 0x5b4: 0x0018, 0x5b5: 0x0018,
- 0x5b6: 0x0018, 0x5b7: 0x0018, 0x5b8: 0x0018, 0x5b9: 0x0018, 0x5ba: 0x0018, 0x5bb: 0x0018,
- 0x5bc: 0x0040, 0x5bd: 0x0040, 0x5be: 0x0040, 0x5bf: 0x0040,
- // Block 0x17, offset 0x5c0
- 0x5c0: 0x0040, 0x5c1: 0x1308, 0x5c2: 0x1308, 0x5c3: 0x1008, 0x5c4: 0x0040, 0x5c5: 0x0008,
- 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0040,
- 0x5cc: 0x0040, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,
- 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,
- 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,
- 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,
- 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,
- 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,
- 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0731, 0x5f4: 0x0040, 0x5f5: 0x0008,
- 0x5f6: 0x0769, 0x5f7: 0x0040, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,
- 0x5fc: 0x1308, 0x5fd: 0x0040, 0x5fe: 0x1008, 0x5ff: 0x1008,
- // Block 0x18, offset 0x600
- 0x600: 0x1008, 0x601: 0x1308, 0x602: 0x1308, 0x603: 0x0040, 0x604: 0x0040, 0x605: 0x0040,
- 0x606: 0x0040, 0x607: 0x1308, 0x608: 0x1308, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x1308,
- 0x60c: 0x1308, 0x60d: 0x1b08, 0x60e: 0x0040, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x1308,
- 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x0040,
- 0x618: 0x0040, 0x619: 0x07a1, 0x61a: 0x07d9, 0x61b: 0x0811, 0x61c: 0x0008, 0x61d: 0x0040,
- 0x61e: 0x0849, 0x61f: 0x0040, 0x620: 0x0040, 0x621: 0x0040, 0x622: 0x0040, 0x623: 0x0040,
- 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,
- 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,
- 0x630: 0x1308, 0x631: 0x1308, 0x632: 0x0008, 0x633: 0x0008, 0x634: 0x0008, 0x635: 0x1308,
- 0x636: 0x0040, 0x637: 0x0040, 0x638: 0x0040, 0x639: 0x0040, 0x63a: 0x0040, 0x63b: 0x0040,
- 0x63c: 0x0040, 0x63d: 0x0040, 0x63e: 0x0040, 0x63f: 0x0040,
- // Block 0x19, offset 0x640
- 0x640: 0x0040, 0x641: 0x1308, 0x642: 0x1308, 0x643: 0x1008, 0x644: 0x0040, 0x645: 0x0008,
- 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0008,
- 0x64c: 0x0008, 0x64d: 0x0008, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0008,
- 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,
- 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,
- 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,
- 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,
- 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,
- 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0008, 0x674: 0x0040, 0x675: 0x0008,
- 0x676: 0x0008, 0x677: 0x0008, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,
- 0x67c: 0x1308, 0x67d: 0x0008, 0x67e: 0x1008, 0x67f: 0x1008,
- // Block 0x1a, offset 0x680
- 0x680: 0x1008, 0x681: 0x1308, 0x682: 0x1308, 0x683: 0x1308, 0x684: 0x1308, 0x685: 0x1308,
- 0x686: 0x0040, 0x687: 0x1308, 0x688: 0x1308, 0x689: 0x1008, 0x68a: 0x0040, 0x68b: 0x1008,
- 0x68c: 0x1008, 0x68d: 0x1b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0008, 0x691: 0x0040,
- 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,
- 0x698: 0x0040, 0x699: 0x0040, 0x69a: 0x0040, 0x69b: 0x0040, 0x69c: 0x0040, 0x69d: 0x0040,
- 0x69e: 0x0040, 0x69f: 0x0040, 0x6a0: 0x0008, 0x6a1: 0x0008, 0x6a2: 0x1308, 0x6a3: 0x1308,
- 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,
- 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,
- 0x6b0: 0x0018, 0x6b1: 0x0018, 0x6b2: 0x0040, 0x6b3: 0x0040, 0x6b4: 0x0040, 0x6b5: 0x0040,
- 0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0008, 0x6ba: 0x0040, 0x6bb: 0x0040,
- 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,
- // Block 0x1b, offset 0x6c0
- 0x6c0: 0x0040, 0x6c1: 0x1308, 0x6c2: 0x1008, 0x6c3: 0x1008, 0x6c4: 0x0040, 0x6c5: 0x0008,
- 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,
- 0x6cc: 0x0008, 0x6cd: 0x0040, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0040,
- 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,
- 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,
- 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,
- 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,
- 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,
- 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,
- 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,
- 0x6fc: 0x1308, 0x6fd: 0x0008, 0x6fe: 0x1008, 0x6ff: 0x1308,
- // Block 0x1c, offset 0x700
- 0x700: 0x1008, 0x701: 0x1308, 0x702: 0x1308, 0x703: 0x1308, 0x704: 0x1308, 0x705: 0x0040,
- 0x706: 0x0040, 0x707: 0x1008, 0x708: 0x1008, 0x709: 0x0040, 0x70a: 0x0040, 0x70b: 0x1008,
- 0x70c: 0x1008, 0x70d: 0x1b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0040, 0x711: 0x0040,
- 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x1308, 0x717: 0x1008,
- 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0881, 0x71d: 0x08b9,
- 0x71e: 0x0040, 0x71f: 0x0008, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x1308, 0x723: 0x1308,
- 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,
- 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,
- 0x730: 0x0018, 0x731: 0x0008, 0x732: 0x0018, 0x733: 0x0018, 0x734: 0x0018, 0x735: 0x0018,
- 0x736: 0x0018, 0x737: 0x0018, 0x738: 0x0040, 0x739: 0x0040, 0x73a: 0x0040, 0x73b: 0x0040,
- 0x73c: 0x0040, 0x73d: 0x0040, 0x73e: 0x0040, 0x73f: 0x0040,
- // Block 0x1d, offset 0x740
- 0x740: 0x0040, 0x741: 0x0040, 0x742: 0x1308, 0x743: 0x0008, 0x744: 0x0040, 0x745: 0x0008,
- 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0040,
- 0x74c: 0x0040, 0x74d: 0x0040, 0x74e: 0x0008, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,
- 0x752: 0x0008, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0040, 0x757: 0x0040,
- 0x758: 0x0040, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0040, 0x75c: 0x0008, 0x75d: 0x0040,
- 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0040, 0x761: 0x0040, 0x762: 0x0040, 0x763: 0x0008,
- 0x764: 0x0008, 0x765: 0x0040, 0x766: 0x0040, 0x767: 0x0040, 0x768: 0x0008, 0x769: 0x0008,
- 0x76a: 0x0008, 0x76b: 0x0040, 0x76c: 0x0040, 0x76d: 0x0040, 0x76e: 0x0008, 0x76f: 0x0008,
- 0x770: 0x0008, 0x771: 0x0008, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0008, 0x775: 0x0008,
- 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,
- 0x77c: 0x0040, 0x77d: 0x0040, 0x77e: 0x1008, 0x77f: 0x1008,
- // Block 0x1e, offset 0x780
- 0x780: 0x1308, 0x781: 0x1008, 0x782: 0x1008, 0x783: 0x1008, 0x784: 0x1008, 0x785: 0x0040,
- 0x786: 0x1308, 0x787: 0x1308, 0x788: 0x1308, 0x789: 0x0040, 0x78a: 0x1308, 0x78b: 0x1308,
- 0x78c: 0x1308, 0x78d: 0x1b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,
- 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x1308, 0x796: 0x1308, 0x797: 0x0040,
- 0x798: 0x0008, 0x799: 0x0008, 0x79a: 0x0008, 0x79b: 0x0040, 0x79c: 0x0040, 0x79d: 0x0040,
- 0x79e: 0x0040, 0x79f: 0x0040, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x1308, 0x7a3: 0x1308,
- 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,
- 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,
- 0x7b0: 0x0040, 0x7b1: 0x0040, 0x7b2: 0x0040, 0x7b3: 0x0040, 0x7b4: 0x0040, 0x7b5: 0x0040,
- 0x7b6: 0x0040, 0x7b7: 0x0040, 0x7b8: 0x0018, 0x7b9: 0x0018, 0x7ba: 0x0018, 0x7bb: 0x0018,
- 0x7bc: 0x0018, 0x7bd: 0x0018, 0x7be: 0x0018, 0x7bf: 0x0018,
- // Block 0x1f, offset 0x7c0
- 0x7c0: 0x0008, 0x7c1: 0x1308, 0x7c2: 0x1008, 0x7c3: 0x1008, 0x7c4: 0x0040, 0x7c5: 0x0008,
- 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0008,
- 0x7cc: 0x0008, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,
- 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0008, 0x7d7: 0x0008,
- 0x7d8: 0x0008, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0008, 0x7dc: 0x0008, 0x7dd: 0x0008,
- 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0008, 0x7e1: 0x0008, 0x7e2: 0x0008, 0x7e3: 0x0008,
- 0x7e4: 0x0008, 0x7e5: 0x0008, 0x7e6: 0x0008, 0x7e7: 0x0008, 0x7e8: 0x0008, 0x7e9: 0x0040,
- 0x7ea: 0x0008, 0x7eb: 0x0008, 0x7ec: 0x0008, 0x7ed: 0x0008, 0x7ee: 0x0008, 0x7ef: 0x0008,
- 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0040, 0x7f5: 0x0008,
- 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,
- 0x7fc: 0x1308, 0x7fd: 0x0008, 0x7fe: 0x1008, 0x7ff: 0x1308,
- // Block 0x20, offset 0x800
- 0x800: 0x1008, 0x801: 0x1008, 0x802: 0x1008, 0x803: 0x1008, 0x804: 0x1008, 0x805: 0x0040,
- 0x806: 0x1308, 0x807: 0x1008, 0x808: 0x1008, 0x809: 0x0040, 0x80a: 0x1008, 0x80b: 0x1008,
- 0x80c: 0x1308, 0x80d: 0x1b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,
- 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x1008, 0x816: 0x1008, 0x817: 0x0040,
- 0x818: 0x0040, 0x819: 0x0040, 0x81a: 0x0040, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,
- 0x81e: 0x0008, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x1308, 0x823: 0x1308,
- 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,
- 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,
- 0x830: 0x0040, 0x831: 0x0008, 0x832: 0x0008, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,
- 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0040, 0x839: 0x0040, 0x83a: 0x0040, 0x83b: 0x0040,
- 0x83c: 0x0040, 0x83d: 0x0040, 0x83e: 0x0040, 0x83f: 0x0040,
- // Block 0x21, offset 0x840
- 0x840: 0x1008, 0x841: 0x1308, 0x842: 0x1308, 0x843: 0x1308, 0x844: 0x1308, 0x845: 0x0040,
- 0x846: 0x1008, 0x847: 0x1008, 0x848: 0x1008, 0x849: 0x0040, 0x84a: 0x1008, 0x84b: 0x1008,
- 0x84c: 0x1008, 0x84d: 0x1b08, 0x84e: 0x0008, 0x84f: 0x0018, 0x850: 0x0040, 0x851: 0x0040,
- 0x852: 0x0040, 0x853: 0x0040, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x1008,
- 0x858: 0x0018, 0x859: 0x0018, 0x85a: 0x0018, 0x85b: 0x0018, 0x85c: 0x0018, 0x85d: 0x0018,
- 0x85e: 0x0018, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x1308, 0x863: 0x1308,
- 0x864: 0x0040, 0x865: 0x0040, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0008,
- 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,
- 0x870: 0x0018, 0x871: 0x0018, 0x872: 0x0018, 0x873: 0x0018, 0x874: 0x0018, 0x875: 0x0018,
- 0x876: 0x0018, 0x877: 0x0018, 0x878: 0x0018, 0x879: 0x0018, 0x87a: 0x0008, 0x87b: 0x0008,
- 0x87c: 0x0008, 0x87d: 0x0008, 0x87e: 0x0008, 0x87f: 0x0008,
- // Block 0x22, offset 0x880
- 0x880: 0x0040, 0x881: 0x0008, 0x882: 0x0008, 0x883: 0x0040, 0x884: 0x0008, 0x885: 0x0040,
- 0x886: 0x0040, 0x887: 0x0008, 0x888: 0x0008, 0x889: 0x0040, 0x88a: 0x0008, 0x88b: 0x0040,
- 0x88c: 0x0040, 0x88d: 0x0008, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,
- 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0008, 0x895: 0x0008, 0x896: 0x0008, 0x897: 0x0008,
- 0x898: 0x0040, 0x899: 0x0008, 0x89a: 0x0008, 0x89b: 0x0008, 0x89c: 0x0008, 0x89d: 0x0008,
- 0x89e: 0x0008, 0x89f: 0x0008, 0x8a0: 0x0040, 0x8a1: 0x0008, 0x8a2: 0x0008, 0x8a3: 0x0008,
- 0x8a4: 0x0040, 0x8a5: 0x0008, 0x8a6: 0x0040, 0x8a7: 0x0008, 0x8a8: 0x0040, 0x8a9: 0x0040,
- 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0040, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,
- 0x8b0: 0x0008, 0x8b1: 0x1308, 0x8b2: 0x0008, 0x8b3: 0x0929, 0x8b4: 0x1308, 0x8b5: 0x1308,
- 0x8b6: 0x1308, 0x8b7: 0x1308, 0x8b8: 0x1308, 0x8b9: 0x1308, 0x8ba: 0x0040, 0x8bb: 0x1308,
- 0x8bc: 0x1308, 0x8bd: 0x0008, 0x8be: 0x0040, 0x8bf: 0x0040,
- // Block 0x23, offset 0x8c0
- 0x8c0: 0x0008, 0x8c1: 0x0008, 0x8c2: 0x0008, 0x8c3: 0x09d1, 0x8c4: 0x0008, 0x8c5: 0x0008,
- 0x8c6: 0x0008, 0x8c7: 0x0008, 0x8c8: 0x0040, 0x8c9: 0x0008, 0x8ca: 0x0008, 0x8cb: 0x0008,
- 0x8cc: 0x0008, 0x8cd: 0x0a09, 0x8ce: 0x0008, 0x8cf: 0x0008, 0x8d0: 0x0008, 0x8d1: 0x0008,
- 0x8d2: 0x0a41, 0x8d3: 0x0008, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x0a79,
- 0x8d8: 0x0008, 0x8d9: 0x0008, 0x8da: 0x0008, 0x8db: 0x0008, 0x8dc: 0x0ab1, 0x8dd: 0x0008,
- 0x8de: 0x0008, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x0008, 0x8e3: 0x0008,
- 0x8e4: 0x0008, 0x8e5: 0x0008, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0ae9,
- 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0040, 0x8ee: 0x0040, 0x8ef: 0x0040,
- 0x8f0: 0x0040, 0x8f1: 0x1308, 0x8f2: 0x1308, 0x8f3: 0x0b21, 0x8f4: 0x1308, 0x8f5: 0x0b59,
- 0x8f6: 0x0b91, 0x8f7: 0x0bc9, 0x8f8: 0x0c19, 0x8f9: 0x0c51, 0x8fa: 0x1308, 0x8fb: 0x1308,
- 0x8fc: 0x1308, 0x8fd: 0x1308, 0x8fe: 0x1308, 0x8ff: 0x1008,
- // Block 0x24, offset 0x900
- 0x900: 0x1308, 0x901: 0x0ca1, 0x902: 0x1308, 0x903: 0x1308, 0x904: 0x1b08, 0x905: 0x0018,
- 0x906: 0x1308, 0x907: 0x1308, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0008,
- 0x90c: 0x0008, 0x90d: 0x1308, 0x90e: 0x1308, 0x90f: 0x1308, 0x910: 0x1308, 0x911: 0x1308,
- 0x912: 0x1308, 0x913: 0x0cd9, 0x914: 0x1308, 0x915: 0x1308, 0x916: 0x1308, 0x917: 0x1308,
- 0x918: 0x0040, 0x919: 0x1308, 0x91a: 0x1308, 0x91b: 0x1308, 0x91c: 0x1308, 0x91d: 0x0d11,
- 0x91e: 0x1308, 0x91f: 0x1308, 0x920: 0x1308, 0x921: 0x1308, 0x922: 0x0d49, 0x923: 0x1308,
- 0x924: 0x1308, 0x925: 0x1308, 0x926: 0x1308, 0x927: 0x0d81, 0x928: 0x1308, 0x929: 0x1308,
- 0x92a: 0x1308, 0x92b: 0x1308, 0x92c: 0x0db9, 0x92d: 0x1308, 0x92e: 0x1308, 0x92f: 0x1308,
- 0x930: 0x1308, 0x931: 0x1308, 0x932: 0x1308, 0x933: 0x1308, 0x934: 0x1308, 0x935: 0x1308,
- 0x936: 0x1308, 0x937: 0x1308, 0x938: 0x1308, 0x939: 0x0df1, 0x93a: 0x1308, 0x93b: 0x1308,
- 0x93c: 0x1308, 0x93d: 0x0040, 0x93e: 0x0018, 0x93f: 0x0018,
- // Block 0x25, offset 0x940
- 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x0008, 0x944: 0x0008, 0x945: 0x0008,
- 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0008, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,
- 0x94c: 0x0008, 0x94d: 0x0008, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,
- 0x952: 0x0008, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0008,
- 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0008, 0x95d: 0x0008,
- 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,
- 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0008,
- 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0039, 0x96d: 0x0ed1, 0x96e: 0x0ee9, 0x96f: 0x0008,
- 0x970: 0x0ef9, 0x971: 0x0f09, 0x972: 0x0f19, 0x973: 0x0f31, 0x974: 0x0249, 0x975: 0x0f41,
- 0x976: 0x0259, 0x977: 0x0f51, 0x978: 0x0359, 0x979: 0x0f61, 0x97a: 0x0f71, 0x97b: 0x0008,
- 0x97c: 0x00d9, 0x97d: 0x0f81, 0x97e: 0x0f99, 0x97f: 0x0269,
- // Block 0x26, offset 0x980
- 0x980: 0x0fa9, 0x981: 0x0fb9, 0x982: 0x0279, 0x983: 0x0039, 0x984: 0x0fc9, 0x985: 0x0fe1,
- 0x986: 0x059d, 0x987: 0x0ee9, 0x988: 0x0ef9, 0x989: 0x0f09, 0x98a: 0x0ff9, 0x98b: 0x1011,
- 0x98c: 0x1029, 0x98d: 0x0f31, 0x98e: 0x0008, 0x98f: 0x0f51, 0x990: 0x0f61, 0x991: 0x1041,
- 0x992: 0x00d9, 0x993: 0x1059, 0x994: 0x05b5, 0x995: 0x05b5, 0x996: 0x0f99, 0x997: 0x0fa9,
- 0x998: 0x0fb9, 0x999: 0x059d, 0x99a: 0x1071, 0x99b: 0x1089, 0x99c: 0x05cd, 0x99d: 0x1099,
- 0x99e: 0x10b1, 0x99f: 0x10c9, 0x9a0: 0x10e1, 0x9a1: 0x10f9, 0x9a2: 0x0f41, 0x9a3: 0x0269,
- 0x9a4: 0x0fb9, 0x9a5: 0x1089, 0x9a6: 0x1099, 0x9a7: 0x10b1, 0x9a8: 0x1111, 0x9a9: 0x10e1,
- 0x9aa: 0x10f9, 0x9ab: 0x0008, 0x9ac: 0x0008, 0x9ad: 0x0008, 0x9ae: 0x0008, 0x9af: 0x0008,
- 0x9b0: 0x0008, 0x9b1: 0x0008, 0x9b2: 0x0008, 0x9b3: 0x0008, 0x9b4: 0x0008, 0x9b5: 0x0008,
- 0x9b6: 0x0008, 0x9b7: 0x0008, 0x9b8: 0x1129, 0x9b9: 0x0008, 0x9ba: 0x0008, 0x9bb: 0x0008,
- 0x9bc: 0x0008, 0x9bd: 0x0008, 0x9be: 0x0008, 0x9bf: 0x0008,
- // Block 0x27, offset 0x9c0
- 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,
- 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,
- 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,
- 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,
- 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x1141, 0x9dc: 0x1159, 0x9dd: 0x1169,
- 0x9de: 0x1181, 0x9df: 0x1029, 0x9e0: 0x1199, 0x9e1: 0x11a9, 0x9e2: 0x11c1, 0x9e3: 0x11d9,
- 0x9e4: 0x11f1, 0x9e5: 0x1209, 0x9e6: 0x1221, 0x9e7: 0x05e5, 0x9e8: 0x1239, 0x9e9: 0x1251,
- 0x9ea: 0xe17d, 0x9eb: 0x1269, 0x9ec: 0x1281, 0x9ed: 0x1299, 0x9ee: 0x12b1, 0x9ef: 0x12c9,
- 0x9f0: 0x12e1, 0x9f1: 0x12f9, 0x9f2: 0x1311, 0x9f3: 0x1329, 0x9f4: 0x1341, 0x9f5: 0x1359,
- 0x9f6: 0x1371, 0x9f7: 0x1389, 0x9f8: 0x05fd, 0x9f9: 0x13a1, 0x9fa: 0x13b9, 0x9fb: 0x13d1,
- 0x9fc: 0x13e1, 0x9fd: 0x13f9, 0x9fe: 0x1411, 0x9ff: 0x1429,
- // Block 0x28, offset 0xa00
- 0xa00: 0xe00d, 0xa01: 0x0008, 0xa02: 0xe00d, 0xa03: 0x0008, 0xa04: 0xe00d, 0xa05: 0x0008,
- 0xa06: 0xe00d, 0xa07: 0x0008, 0xa08: 0xe00d, 0xa09: 0x0008, 0xa0a: 0xe00d, 0xa0b: 0x0008,
- 0xa0c: 0xe00d, 0xa0d: 0x0008, 0xa0e: 0xe00d, 0xa0f: 0x0008, 0xa10: 0xe00d, 0xa11: 0x0008,
- 0xa12: 0xe00d, 0xa13: 0x0008, 0xa14: 0xe00d, 0xa15: 0x0008, 0xa16: 0xe00d, 0xa17: 0x0008,
- 0xa18: 0xe00d, 0xa19: 0x0008, 0xa1a: 0xe00d, 0xa1b: 0x0008, 0xa1c: 0xe00d, 0xa1d: 0x0008,
- 0xa1e: 0xe00d, 0xa1f: 0x0008, 0xa20: 0xe00d, 0xa21: 0x0008, 0xa22: 0xe00d, 0xa23: 0x0008,
- 0xa24: 0xe00d, 0xa25: 0x0008, 0xa26: 0xe00d, 0xa27: 0x0008, 0xa28: 0xe00d, 0xa29: 0x0008,
- 0xa2a: 0xe00d, 0xa2b: 0x0008, 0xa2c: 0xe00d, 0xa2d: 0x0008, 0xa2e: 0xe00d, 0xa2f: 0x0008,
- 0xa30: 0xe00d, 0xa31: 0x0008, 0xa32: 0xe00d, 0xa33: 0x0008, 0xa34: 0xe00d, 0xa35: 0x0008,
- 0xa36: 0xe00d, 0xa37: 0x0008, 0xa38: 0xe00d, 0xa39: 0x0008, 0xa3a: 0xe00d, 0xa3b: 0x0008,
- 0xa3c: 0xe00d, 0xa3d: 0x0008, 0xa3e: 0xe00d, 0xa3f: 0x0008,
- // Block 0x29, offset 0xa40
- 0xa40: 0xe00d, 0xa41: 0x0008, 0xa42: 0xe00d, 0xa43: 0x0008, 0xa44: 0xe00d, 0xa45: 0x0008,
- 0xa46: 0xe00d, 0xa47: 0x0008, 0xa48: 0xe00d, 0xa49: 0x0008, 0xa4a: 0xe00d, 0xa4b: 0x0008,
- 0xa4c: 0xe00d, 0xa4d: 0x0008, 0xa4e: 0xe00d, 0xa4f: 0x0008, 0xa50: 0xe00d, 0xa51: 0x0008,
- 0xa52: 0xe00d, 0xa53: 0x0008, 0xa54: 0xe00d, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,
- 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0615, 0xa5b: 0x0635, 0xa5c: 0x0008, 0xa5d: 0x0008,
- 0xa5e: 0x1441, 0xa5f: 0x0008, 0xa60: 0xe00d, 0xa61: 0x0008, 0xa62: 0xe00d, 0xa63: 0x0008,
- 0xa64: 0xe00d, 0xa65: 0x0008, 0xa66: 0xe00d, 0xa67: 0x0008, 0xa68: 0xe00d, 0xa69: 0x0008,
- 0xa6a: 0xe00d, 0xa6b: 0x0008, 0xa6c: 0xe00d, 0xa6d: 0x0008, 0xa6e: 0xe00d, 0xa6f: 0x0008,
- 0xa70: 0xe00d, 0xa71: 0x0008, 0xa72: 0xe00d, 0xa73: 0x0008, 0xa74: 0xe00d, 0xa75: 0x0008,
- 0xa76: 0xe00d, 0xa77: 0x0008, 0xa78: 0xe00d, 0xa79: 0x0008, 0xa7a: 0xe00d, 0xa7b: 0x0008,
- 0xa7c: 0xe00d, 0xa7d: 0x0008, 0xa7e: 0xe00d, 0xa7f: 0x0008,
- // Block 0x2a, offset 0xa80
- 0xa80: 0x0008, 0xa81: 0x0008, 0xa82: 0x0008, 0xa83: 0x0008, 0xa84: 0x0008, 0xa85: 0x0008,
- 0xa86: 0x0040, 0xa87: 0x0040, 0xa88: 0xe045, 0xa89: 0xe045, 0xa8a: 0xe045, 0xa8b: 0xe045,
- 0xa8c: 0xe045, 0xa8d: 0xe045, 0xa8e: 0x0040, 0xa8f: 0x0040, 0xa90: 0x0008, 0xa91: 0x0008,
- 0xa92: 0x0008, 0xa93: 0x0008, 0xa94: 0x0008, 0xa95: 0x0008, 0xa96: 0x0008, 0xa97: 0x0008,
- 0xa98: 0x0040, 0xa99: 0xe045, 0xa9a: 0x0040, 0xa9b: 0xe045, 0xa9c: 0x0040, 0xa9d: 0xe045,
- 0xa9e: 0x0040, 0xa9f: 0xe045, 0xaa0: 0x0008, 0xaa1: 0x0008, 0xaa2: 0x0008, 0xaa3: 0x0008,
- 0xaa4: 0x0008, 0xaa5: 0x0008, 0xaa6: 0x0008, 0xaa7: 0x0008, 0xaa8: 0xe045, 0xaa9: 0xe045,
- 0xaaa: 0xe045, 0xaab: 0xe045, 0xaac: 0xe045, 0xaad: 0xe045, 0xaae: 0xe045, 0xaaf: 0xe045,
- 0xab0: 0x0008, 0xab1: 0x1459, 0xab2: 0x0008, 0xab3: 0x1471, 0xab4: 0x0008, 0xab5: 0x1489,
- 0xab6: 0x0008, 0xab7: 0x14a1, 0xab8: 0x0008, 0xab9: 0x14b9, 0xaba: 0x0008, 0xabb: 0x14d1,
- 0xabc: 0x0008, 0xabd: 0x14e9, 0xabe: 0x0040, 0xabf: 0x0040,
- // Block 0x2b, offset 0xac0
- 0xac0: 0x1501, 0xac1: 0x1531, 0xac2: 0x1561, 0xac3: 0x1591, 0xac4: 0x15c1, 0xac5: 0x15f1,
- 0xac6: 0x1621, 0xac7: 0x1651, 0xac8: 0x1501, 0xac9: 0x1531, 0xaca: 0x1561, 0xacb: 0x1591,
- 0xacc: 0x15c1, 0xacd: 0x15f1, 0xace: 0x1621, 0xacf: 0x1651, 0xad0: 0x1681, 0xad1: 0x16b1,
- 0xad2: 0x16e1, 0xad3: 0x1711, 0xad4: 0x1741, 0xad5: 0x1771, 0xad6: 0x17a1, 0xad7: 0x17d1,
- 0xad8: 0x1681, 0xad9: 0x16b1, 0xada: 0x16e1, 0xadb: 0x1711, 0xadc: 0x1741, 0xadd: 0x1771,
- 0xade: 0x17a1, 0xadf: 0x17d1, 0xae0: 0x1801, 0xae1: 0x1831, 0xae2: 0x1861, 0xae3: 0x1891,
- 0xae4: 0x18c1, 0xae5: 0x18f1, 0xae6: 0x1921, 0xae7: 0x1951, 0xae8: 0x1801, 0xae9: 0x1831,
- 0xaea: 0x1861, 0xaeb: 0x1891, 0xaec: 0x18c1, 0xaed: 0x18f1, 0xaee: 0x1921, 0xaef: 0x1951,
- 0xaf0: 0x0008, 0xaf1: 0x0008, 0xaf2: 0x1981, 0xaf3: 0x19b1, 0xaf4: 0x19d9, 0xaf5: 0x0040,
- 0xaf6: 0x0008, 0xaf7: 0x1a01, 0xaf8: 0xe045, 0xaf9: 0xe045, 0xafa: 0x064d, 0xafb: 0x1459,
- 0xafc: 0x19b1, 0xafd: 0x0666, 0xafe: 0x1a31, 0xaff: 0x0686,
- // Block 0x2c, offset 0xb00
- 0xb00: 0x06a6, 0xb01: 0x1a4a, 0xb02: 0x1a79, 0xb03: 0x1aa9, 0xb04: 0x1ad1, 0xb05: 0x0040,
- 0xb06: 0x0008, 0xb07: 0x1af9, 0xb08: 0x06c5, 0xb09: 0x1471, 0xb0a: 0x06dd, 0xb0b: 0x1489,
- 0xb0c: 0x1aa9, 0xb0d: 0x1b2a, 0xb0e: 0x1b5a, 0xb0f: 0x1b8a, 0xb10: 0x0008, 0xb11: 0x0008,
- 0xb12: 0x0008, 0xb13: 0x1bb9, 0xb14: 0x0040, 0xb15: 0x0040, 0xb16: 0x0008, 0xb17: 0x0008,
- 0xb18: 0xe045, 0xb19: 0xe045, 0xb1a: 0x06f5, 0xb1b: 0x14a1, 0xb1c: 0x0040, 0xb1d: 0x1bd2,
- 0xb1e: 0x1c02, 0xb1f: 0x1c32, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x1c61,
- 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,
- 0xb2a: 0x070d, 0xb2b: 0x14d1, 0xb2c: 0xe04d, 0xb2d: 0x1c7a, 0xb2e: 0x03d2, 0xb2f: 0x1caa,
- 0xb30: 0x0040, 0xb31: 0x0040, 0xb32: 0x1cb9, 0xb33: 0x1ce9, 0xb34: 0x1d11, 0xb35: 0x0040,
- 0xb36: 0x0008, 0xb37: 0x1d39, 0xb38: 0x0725, 0xb39: 0x14b9, 0xb3a: 0x0515, 0xb3b: 0x14e9,
- 0xb3c: 0x1ce9, 0xb3d: 0x073e, 0xb3e: 0x075e, 0xb3f: 0x0040,
- // Block 0x2d, offset 0xb40
- 0xb40: 0x000a, 0xb41: 0x000a, 0xb42: 0x000a, 0xb43: 0x000a, 0xb44: 0x000a, 0xb45: 0x000a,
- 0xb46: 0x000a, 0xb47: 0x000a, 0xb48: 0x000a, 0xb49: 0x000a, 0xb4a: 0x000a, 0xb4b: 0x03c0,
- 0xb4c: 0x0003, 0xb4d: 0x0003, 0xb4e: 0x0340, 0xb4f: 0x0340, 0xb50: 0x0018, 0xb51: 0xe00d,
- 0xb52: 0x0018, 0xb53: 0x0018, 0xb54: 0x0018, 0xb55: 0x0018, 0xb56: 0x0018, 0xb57: 0x077e,
- 0xb58: 0x0018, 0xb59: 0x0018, 0xb5a: 0x0018, 0xb5b: 0x0018, 0xb5c: 0x0018, 0xb5d: 0x0018,
- 0xb5e: 0x0018, 0xb5f: 0x0018, 0xb60: 0x0018, 0xb61: 0x0018, 0xb62: 0x0018, 0xb63: 0x0018,
- 0xb64: 0x0040, 0xb65: 0x0040, 0xb66: 0x0040, 0xb67: 0x0018, 0xb68: 0x0040, 0xb69: 0x0040,
- 0xb6a: 0x0340, 0xb6b: 0x0340, 0xb6c: 0x0340, 0xb6d: 0x0340, 0xb6e: 0x0340, 0xb6f: 0x000a,
- 0xb70: 0x0018, 0xb71: 0x0018, 0xb72: 0x0018, 0xb73: 0x1d69, 0xb74: 0x1da1, 0xb75: 0x0018,
- 0xb76: 0x1df1, 0xb77: 0x1e29, 0xb78: 0x0018, 0xb79: 0x0018, 0xb7a: 0x0018, 0xb7b: 0x0018,
- 0xb7c: 0x1e7a, 0xb7d: 0x0018, 0xb7e: 0x079e, 0xb7f: 0x0018,
- // Block 0x2e, offset 0xb80
- 0xb80: 0x0018, 0xb81: 0x0018, 0xb82: 0x0018, 0xb83: 0x0018, 0xb84: 0x0018, 0xb85: 0x0018,
- 0xb86: 0x0018, 0xb87: 0x1e92, 0xb88: 0x1eaa, 0xb89: 0x1ec2, 0xb8a: 0x0018, 0xb8b: 0x0018,
- 0xb8c: 0x0018, 0xb8d: 0x0018, 0xb8e: 0x0018, 0xb8f: 0x0018, 0xb90: 0x0018, 0xb91: 0x0018,
- 0xb92: 0x0018, 0xb93: 0x0018, 0xb94: 0x0018, 0xb95: 0x0018, 0xb96: 0x0018, 0xb97: 0x1ed9,
- 0xb98: 0x0018, 0xb99: 0x0018, 0xb9a: 0x0018, 0xb9b: 0x0018, 0xb9c: 0x0018, 0xb9d: 0x0018,
- 0xb9e: 0x0018, 0xb9f: 0x000a, 0xba0: 0x03c0, 0xba1: 0x0340, 0xba2: 0x0340, 0xba3: 0x0340,
- 0xba4: 0x03c0, 0xba5: 0x0040, 0xba6: 0x0040, 0xba7: 0x0040, 0xba8: 0x0040, 0xba9: 0x0040,
- 0xbaa: 0x0340, 0xbab: 0x0340, 0xbac: 0x0340, 0xbad: 0x0340, 0xbae: 0x0340, 0xbaf: 0x0340,
- 0xbb0: 0x1f41, 0xbb1: 0x0f41, 0xbb2: 0x0040, 0xbb3: 0x0040, 0xbb4: 0x1f51, 0xbb5: 0x1f61,
- 0xbb6: 0x1f71, 0xbb7: 0x1f81, 0xbb8: 0x1f91, 0xbb9: 0x1fa1, 0xbba: 0x1fb2, 0xbbb: 0x07bd,
- 0xbbc: 0x1fc2, 0xbbd: 0x1fd2, 0xbbe: 0x1fe2, 0xbbf: 0x0f71,
- // Block 0x2f, offset 0xbc0
- 0xbc0: 0x1f41, 0xbc1: 0x00c9, 0xbc2: 0x0069, 0xbc3: 0x0079, 0xbc4: 0x1f51, 0xbc5: 0x1f61,
- 0xbc6: 0x1f71, 0xbc7: 0x1f81, 0xbc8: 0x1f91, 0xbc9: 0x1fa1, 0xbca: 0x1fb2, 0xbcb: 0x07d5,
- 0xbcc: 0x1fc2, 0xbcd: 0x1fd2, 0xbce: 0x1fe2, 0xbcf: 0x0040, 0xbd0: 0x0039, 0xbd1: 0x0f09,
- 0xbd2: 0x00d9, 0xbd3: 0x0369, 0xbd4: 0x0ff9, 0xbd5: 0x0249, 0xbd6: 0x0f51, 0xbd7: 0x0359,
- 0xbd8: 0x0f61, 0xbd9: 0x0f71, 0xbda: 0x0f99, 0xbdb: 0x01d9, 0xbdc: 0x0fa9, 0xbdd: 0x0040,
- 0xbde: 0x0040, 0xbdf: 0x0040, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,
- 0xbe4: 0x0018, 0xbe5: 0x0018, 0xbe6: 0x0018, 0xbe7: 0x0018, 0xbe8: 0x1ff1, 0xbe9: 0x0018,
- 0xbea: 0x0018, 0xbeb: 0x0018, 0xbec: 0x0018, 0xbed: 0x0018, 0xbee: 0x0018, 0xbef: 0x0018,
- 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x0018, 0xbf4: 0x0018, 0xbf5: 0x0018,
- 0xbf6: 0x0018, 0xbf7: 0x0018, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,
- 0xbfc: 0x0018, 0xbfd: 0x0018, 0xbfe: 0x0018, 0xbff: 0x0040,
- // Block 0x30, offset 0xc00
- 0xc00: 0x07ee, 0xc01: 0x080e, 0xc02: 0x1159, 0xc03: 0x082d, 0xc04: 0x0018, 0xc05: 0x084e,
- 0xc06: 0x086e, 0xc07: 0x1011, 0xc08: 0x0018, 0xc09: 0x088d, 0xc0a: 0x0f31, 0xc0b: 0x0249,
- 0xc0c: 0x0249, 0xc0d: 0x0249, 0xc0e: 0x0249, 0xc0f: 0x2009, 0xc10: 0x0f41, 0xc11: 0x0f41,
- 0xc12: 0x0359, 0xc13: 0x0359, 0xc14: 0x0018, 0xc15: 0x0f71, 0xc16: 0x2021, 0xc17: 0x0018,
- 0xc18: 0x0018, 0xc19: 0x0f99, 0xc1a: 0x2039, 0xc1b: 0x0269, 0xc1c: 0x0269, 0xc1d: 0x0269,
- 0xc1e: 0x0018, 0xc1f: 0x0018, 0xc20: 0x2049, 0xc21: 0x08ad, 0xc22: 0x2061, 0xc23: 0x0018,
- 0xc24: 0x13d1, 0xc25: 0x0018, 0xc26: 0x2079, 0xc27: 0x0018, 0xc28: 0x13d1, 0xc29: 0x0018,
- 0xc2a: 0x0f51, 0xc2b: 0x2091, 0xc2c: 0x0ee9, 0xc2d: 0x1159, 0xc2e: 0x0018, 0xc2f: 0x0f09,
- 0xc30: 0x0f09, 0xc31: 0x1199, 0xc32: 0x0040, 0xc33: 0x0f61, 0xc34: 0x00d9, 0xc35: 0x20a9,
- 0xc36: 0x20c1, 0xc37: 0x20d9, 0xc38: 0x20f1, 0xc39: 0x0f41, 0xc3a: 0x0018, 0xc3b: 0x08cd,
- 0xc3c: 0x2109, 0xc3d: 0x10b1, 0xc3e: 0x10b1, 0xc3f: 0x2109,
- // Block 0x31, offset 0xc40
- 0xc40: 0x08ed, 0xc41: 0x0018, 0xc42: 0x0018, 0xc43: 0x0018, 0xc44: 0x0018, 0xc45: 0x0ef9,
- 0xc46: 0x0ef9, 0xc47: 0x0f09, 0xc48: 0x0f41, 0xc49: 0x0259, 0xc4a: 0x0018, 0xc4b: 0x0018,
- 0xc4c: 0x0018, 0xc4d: 0x0018, 0xc4e: 0x0008, 0xc4f: 0x0018, 0xc50: 0x2121, 0xc51: 0x2151,
- 0xc52: 0x2181, 0xc53: 0x21b9, 0xc54: 0x21e9, 0xc55: 0x2219, 0xc56: 0x2249, 0xc57: 0x2279,
- 0xc58: 0x22a9, 0xc59: 0x22d9, 0xc5a: 0x2309, 0xc5b: 0x2339, 0xc5c: 0x2369, 0xc5d: 0x2399,
- 0xc5e: 0x23c9, 0xc5f: 0x23f9, 0xc60: 0x0f41, 0xc61: 0x2421, 0xc62: 0x0905, 0xc63: 0x2439,
- 0xc64: 0x1089, 0xc65: 0x2451, 0xc66: 0x0925, 0xc67: 0x2469, 0xc68: 0x2491, 0xc69: 0x0369,
- 0xc6a: 0x24a9, 0xc6b: 0x0945, 0xc6c: 0x0359, 0xc6d: 0x1159, 0xc6e: 0x0ef9, 0xc6f: 0x0f61,
- 0xc70: 0x0f41, 0xc71: 0x2421, 0xc72: 0x0965, 0xc73: 0x2439, 0xc74: 0x1089, 0xc75: 0x2451,
- 0xc76: 0x0985, 0xc77: 0x2469, 0xc78: 0x2491, 0xc79: 0x0369, 0xc7a: 0x24a9, 0xc7b: 0x09a5,
- 0xc7c: 0x0359, 0xc7d: 0x1159, 0xc7e: 0x0ef9, 0xc7f: 0x0f61,
- // Block 0x32, offset 0xc80
- 0xc80: 0x0018, 0xc81: 0x0018, 0xc82: 0x0018, 0xc83: 0x0018, 0xc84: 0x0018, 0xc85: 0x0018,
- 0xc86: 0x0018, 0xc87: 0x0018, 0xc88: 0x0018, 0xc89: 0x0018, 0xc8a: 0x0018, 0xc8b: 0x0040,
- 0xc8c: 0x0040, 0xc8d: 0x0040, 0xc8e: 0x0040, 0xc8f: 0x0040, 0xc90: 0x0040, 0xc91: 0x0040,
- 0xc92: 0x0040, 0xc93: 0x0040, 0xc94: 0x0040, 0xc95: 0x0040, 0xc96: 0x0040, 0xc97: 0x0040,
- 0xc98: 0x0040, 0xc99: 0x0040, 0xc9a: 0x0040, 0xc9b: 0x0040, 0xc9c: 0x0040, 0xc9d: 0x0040,
- 0xc9e: 0x0040, 0xc9f: 0x0040, 0xca0: 0x00c9, 0xca1: 0x0069, 0xca2: 0x0079, 0xca3: 0x1f51,
- 0xca4: 0x1f61, 0xca5: 0x1f71, 0xca6: 0x1f81, 0xca7: 0x1f91, 0xca8: 0x1fa1, 0xca9: 0x2601,
- 0xcaa: 0x2619, 0xcab: 0x2631, 0xcac: 0x2649, 0xcad: 0x2661, 0xcae: 0x2679, 0xcaf: 0x2691,
- 0xcb0: 0x26a9, 0xcb1: 0x26c1, 0xcb2: 0x26d9, 0xcb3: 0x26f1, 0xcb4: 0x0a06, 0xcb5: 0x0a26,
- 0xcb6: 0x0a46, 0xcb7: 0x0a66, 0xcb8: 0x0a86, 0xcb9: 0x0aa6, 0xcba: 0x0ac6, 0xcbb: 0x0ae6,
- 0xcbc: 0x0b06, 0xcbd: 0x270a, 0xcbe: 0x2732, 0xcbf: 0x275a,
- // Block 0x33, offset 0xcc0
- 0xcc0: 0x2782, 0xcc1: 0x27aa, 0xcc2: 0x27d2, 0xcc3: 0x27fa, 0xcc4: 0x2822, 0xcc5: 0x284a,
- 0xcc6: 0x2872, 0xcc7: 0x289a, 0xcc8: 0x0040, 0xcc9: 0x0040, 0xcca: 0x0040, 0xccb: 0x0040,
- 0xccc: 0x0040, 0xccd: 0x0040, 0xcce: 0x0040, 0xccf: 0x0040, 0xcd0: 0x0040, 0xcd1: 0x0040,
- 0xcd2: 0x0040, 0xcd3: 0x0040, 0xcd4: 0x0040, 0xcd5: 0x0040, 0xcd6: 0x0040, 0xcd7: 0x0040,
- 0xcd8: 0x0040, 0xcd9: 0x0040, 0xcda: 0x0040, 0xcdb: 0x0040, 0xcdc: 0x0b26, 0xcdd: 0x0b46,
- 0xcde: 0x0b66, 0xcdf: 0x0b86, 0xce0: 0x0ba6, 0xce1: 0x0bc6, 0xce2: 0x0be6, 0xce3: 0x0c06,
- 0xce4: 0x0c26, 0xce5: 0x0c46, 0xce6: 0x0c66, 0xce7: 0x0c86, 0xce8: 0x0ca6, 0xce9: 0x0cc6,
- 0xcea: 0x0ce6, 0xceb: 0x0d06, 0xcec: 0x0d26, 0xced: 0x0d46, 0xcee: 0x0d66, 0xcef: 0x0d86,
- 0xcf0: 0x0da6, 0xcf1: 0x0dc6, 0xcf2: 0x0de6, 0xcf3: 0x0e06, 0xcf4: 0x0e26, 0xcf5: 0x0e46,
- 0xcf6: 0x0039, 0xcf7: 0x0ee9, 0xcf8: 0x1159, 0xcf9: 0x0ef9, 0xcfa: 0x0f09, 0xcfb: 0x1199,
- 0xcfc: 0x0f31, 0xcfd: 0x0249, 0xcfe: 0x0f41, 0xcff: 0x0259,
- // Block 0x34, offset 0xd00
- 0xd00: 0x0f51, 0xd01: 0x0359, 0xd02: 0x0f61, 0xd03: 0x0f71, 0xd04: 0x00d9, 0xd05: 0x0f99,
- 0xd06: 0x2039, 0xd07: 0x0269, 0xd08: 0x01d9, 0xd09: 0x0fa9, 0xd0a: 0x0fb9, 0xd0b: 0x1089,
- 0xd0c: 0x0279, 0xd0d: 0x0369, 0xd0e: 0x0289, 0xd0f: 0x13d1, 0xd10: 0x0039, 0xd11: 0x0ee9,
- 0xd12: 0x1159, 0xd13: 0x0ef9, 0xd14: 0x0f09, 0xd15: 0x1199, 0xd16: 0x0f31, 0xd17: 0x0249,
- 0xd18: 0x0f41, 0xd19: 0x0259, 0xd1a: 0x0f51, 0xd1b: 0x0359, 0xd1c: 0x0f61, 0xd1d: 0x0f71,
- 0xd1e: 0x00d9, 0xd1f: 0x0f99, 0xd20: 0x2039, 0xd21: 0x0269, 0xd22: 0x01d9, 0xd23: 0x0fa9,
- 0xd24: 0x0fb9, 0xd25: 0x1089, 0xd26: 0x0279, 0xd27: 0x0369, 0xd28: 0x0289, 0xd29: 0x13d1,
- 0xd2a: 0x1f41, 0xd2b: 0x0018, 0xd2c: 0x0018, 0xd2d: 0x0018, 0xd2e: 0x0018, 0xd2f: 0x0018,
- 0xd30: 0x0018, 0xd31: 0x0018, 0xd32: 0x0018, 0xd33: 0x0018, 0xd34: 0x0018, 0xd35: 0x0018,
- 0xd36: 0x0018, 0xd37: 0x0018, 0xd38: 0x0018, 0xd39: 0x0018, 0xd3a: 0x0018, 0xd3b: 0x0018,
- 0xd3c: 0x0018, 0xd3d: 0x0018, 0xd3e: 0x0018, 0xd3f: 0x0018,
- // Block 0x35, offset 0xd40
- 0xd40: 0x0008, 0xd41: 0x0008, 0xd42: 0x0008, 0xd43: 0x0008, 0xd44: 0x0008, 0xd45: 0x0008,
- 0xd46: 0x0008, 0xd47: 0x0008, 0xd48: 0x0008, 0xd49: 0x0008, 0xd4a: 0x0008, 0xd4b: 0x0008,
- 0xd4c: 0x0008, 0xd4d: 0x0008, 0xd4e: 0x0008, 0xd4f: 0x0008, 0xd50: 0x0008, 0xd51: 0x0008,
- 0xd52: 0x0008, 0xd53: 0x0008, 0xd54: 0x0008, 0xd55: 0x0008, 0xd56: 0x0008, 0xd57: 0x0008,
- 0xd58: 0x0008, 0xd59: 0x0008, 0xd5a: 0x0008, 0xd5b: 0x0008, 0xd5c: 0x0008, 0xd5d: 0x0008,
- 0xd5e: 0x0008, 0xd5f: 0x0040, 0xd60: 0xe00d, 0xd61: 0x0008, 0xd62: 0x2971, 0xd63: 0x0ebd,
- 0xd64: 0x2989, 0xd65: 0x0008, 0xd66: 0x0008, 0xd67: 0xe07d, 0xd68: 0x0008, 0xd69: 0xe01d,
- 0xd6a: 0x0008, 0xd6b: 0xe03d, 0xd6c: 0x0008, 0xd6d: 0x0fe1, 0xd6e: 0x1281, 0xd6f: 0x0fc9,
- 0xd70: 0x1141, 0xd71: 0x0008, 0xd72: 0xe00d, 0xd73: 0x0008, 0xd74: 0x0008, 0xd75: 0xe01d,
- 0xd76: 0x0008, 0xd77: 0x0008, 0xd78: 0x0008, 0xd79: 0x0008, 0xd7a: 0x0008, 0xd7b: 0x0008,
- 0xd7c: 0x0259, 0xd7d: 0x1089, 0xd7e: 0x29a1, 0xd7f: 0x29b9,
- // Block 0x36, offset 0xd80
- 0xd80: 0xe00d, 0xd81: 0x0008, 0xd82: 0xe00d, 0xd83: 0x0008, 0xd84: 0xe00d, 0xd85: 0x0008,
- 0xd86: 0xe00d, 0xd87: 0x0008, 0xd88: 0xe00d, 0xd89: 0x0008, 0xd8a: 0xe00d, 0xd8b: 0x0008,
- 0xd8c: 0xe00d, 0xd8d: 0x0008, 0xd8e: 0xe00d, 0xd8f: 0x0008, 0xd90: 0xe00d, 0xd91: 0x0008,
- 0xd92: 0xe00d, 0xd93: 0x0008, 0xd94: 0xe00d, 0xd95: 0x0008, 0xd96: 0xe00d, 0xd97: 0x0008,
- 0xd98: 0xe00d, 0xd99: 0x0008, 0xd9a: 0xe00d, 0xd9b: 0x0008, 0xd9c: 0xe00d, 0xd9d: 0x0008,
- 0xd9e: 0xe00d, 0xd9f: 0x0008, 0xda0: 0xe00d, 0xda1: 0x0008, 0xda2: 0xe00d, 0xda3: 0x0008,
- 0xda4: 0x0008, 0xda5: 0x0018, 0xda6: 0x0018, 0xda7: 0x0018, 0xda8: 0x0018, 0xda9: 0x0018,
- 0xdaa: 0x0018, 0xdab: 0xe03d, 0xdac: 0x0008, 0xdad: 0xe01d, 0xdae: 0x0008, 0xdaf: 0x1308,
- 0xdb0: 0x1308, 0xdb1: 0x1308, 0xdb2: 0xe00d, 0xdb3: 0x0008, 0xdb4: 0x0040, 0xdb5: 0x0040,
- 0xdb6: 0x0040, 0xdb7: 0x0040, 0xdb8: 0x0040, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,
- 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,
- // Block 0x37, offset 0xdc0
- 0xdc0: 0x26fd, 0xdc1: 0x271d, 0xdc2: 0x273d, 0xdc3: 0x275d, 0xdc4: 0x277d, 0xdc5: 0x279d,
- 0xdc6: 0x27bd, 0xdc7: 0x27dd, 0xdc8: 0x27fd, 0xdc9: 0x281d, 0xdca: 0x283d, 0xdcb: 0x285d,
- 0xdcc: 0x287d, 0xdcd: 0x289d, 0xdce: 0x28bd, 0xdcf: 0x28dd, 0xdd0: 0x28fd, 0xdd1: 0x291d,
- 0xdd2: 0x293d, 0xdd3: 0x295d, 0xdd4: 0x297d, 0xdd5: 0x299d, 0xdd6: 0x0040, 0xdd7: 0x0040,
- 0xdd8: 0x0040, 0xdd9: 0x0040, 0xdda: 0x0040, 0xddb: 0x0040, 0xddc: 0x0040, 0xddd: 0x0040,
- 0xdde: 0x0040, 0xddf: 0x0040, 0xde0: 0x0040, 0xde1: 0x0040, 0xde2: 0x0040, 0xde3: 0x0040,
- 0xde4: 0x0040, 0xde5: 0x0040, 0xde6: 0x0040, 0xde7: 0x0040, 0xde8: 0x0040, 0xde9: 0x0040,
- 0xdea: 0x0040, 0xdeb: 0x0040, 0xdec: 0x0040, 0xded: 0x0040, 0xdee: 0x0040, 0xdef: 0x0040,
- 0xdf0: 0x0040, 0xdf1: 0x0040, 0xdf2: 0x0040, 0xdf3: 0x0040, 0xdf4: 0x0040, 0xdf5: 0x0040,
- 0xdf6: 0x0040, 0xdf7: 0x0040, 0xdf8: 0x0040, 0xdf9: 0x0040, 0xdfa: 0x0040, 0xdfb: 0x0040,
- 0xdfc: 0x0040, 0xdfd: 0x0040, 0xdfe: 0x0040, 0xdff: 0x0040,
- // Block 0x38, offset 0xe00
- 0xe00: 0x000a, 0xe01: 0x0018, 0xe02: 0x29d1, 0xe03: 0x0018, 0xe04: 0x0018, 0xe05: 0x0008,
- 0xe06: 0x0008, 0xe07: 0x0008, 0xe08: 0x0018, 0xe09: 0x0018, 0xe0a: 0x0018, 0xe0b: 0x0018,
- 0xe0c: 0x0018, 0xe0d: 0x0018, 0xe0e: 0x0018, 0xe0f: 0x0018, 0xe10: 0x0018, 0xe11: 0x0018,
- 0xe12: 0x0018, 0xe13: 0x0018, 0xe14: 0x0018, 0xe15: 0x0018, 0xe16: 0x0018, 0xe17: 0x0018,
- 0xe18: 0x0018, 0xe19: 0x0018, 0xe1a: 0x0018, 0xe1b: 0x0018, 0xe1c: 0x0018, 0xe1d: 0x0018,
- 0xe1e: 0x0018, 0xe1f: 0x0018, 0xe20: 0x0018, 0xe21: 0x0018, 0xe22: 0x0018, 0xe23: 0x0018,
- 0xe24: 0x0018, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,
- 0xe2a: 0x1308, 0xe2b: 0x1308, 0xe2c: 0x1308, 0xe2d: 0x1308, 0xe2e: 0x1018, 0xe2f: 0x1018,
- 0xe30: 0x0018, 0xe31: 0x0018, 0xe32: 0x0018, 0xe33: 0x0018, 0xe34: 0x0018, 0xe35: 0x0018,
- 0xe36: 0xe125, 0xe37: 0x0018, 0xe38: 0x29bd, 0xe39: 0x29dd, 0xe3a: 0x29fd, 0xe3b: 0x0018,
- 0xe3c: 0x0008, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,
- // Block 0x39, offset 0xe40
- 0xe40: 0x2b3d, 0xe41: 0x2b5d, 0xe42: 0x2b7d, 0xe43: 0x2b9d, 0xe44: 0x2bbd, 0xe45: 0x2bdd,
- 0xe46: 0x2bdd, 0xe47: 0x2bdd, 0xe48: 0x2bfd, 0xe49: 0x2bfd, 0xe4a: 0x2bfd, 0xe4b: 0x2bfd,
- 0xe4c: 0x2c1d, 0xe4d: 0x2c1d, 0xe4e: 0x2c1d, 0xe4f: 0x2c3d, 0xe50: 0x2c5d, 0xe51: 0x2c5d,
- 0xe52: 0x2a7d, 0xe53: 0x2a7d, 0xe54: 0x2c5d, 0xe55: 0x2c5d, 0xe56: 0x2c7d, 0xe57: 0x2c7d,
- 0xe58: 0x2c5d, 0xe59: 0x2c5d, 0xe5a: 0x2a7d, 0xe5b: 0x2a7d, 0xe5c: 0x2c5d, 0xe5d: 0x2c5d,
- 0xe5e: 0x2c3d, 0xe5f: 0x2c3d, 0xe60: 0x2c9d, 0xe61: 0x2c9d, 0xe62: 0x2cbd, 0xe63: 0x2cbd,
- 0xe64: 0x0040, 0xe65: 0x2cdd, 0xe66: 0x2cfd, 0xe67: 0x2d1d, 0xe68: 0x2d1d, 0xe69: 0x2d3d,
- 0xe6a: 0x2d5d, 0xe6b: 0x2d7d, 0xe6c: 0x2d9d, 0xe6d: 0x2dbd, 0xe6e: 0x2ddd, 0xe6f: 0x2dfd,
- 0xe70: 0x2e1d, 0xe71: 0x2e3d, 0xe72: 0x2e3d, 0xe73: 0x2e5d, 0xe74: 0x2e7d, 0xe75: 0x2e7d,
- 0xe76: 0x2e9d, 0xe77: 0x2ebd, 0xe78: 0x2e5d, 0xe79: 0x2edd, 0xe7a: 0x2efd, 0xe7b: 0x2edd,
- 0xe7c: 0x2e5d, 0xe7d: 0x2f1d, 0xe7e: 0x2f3d, 0xe7f: 0x2f5d,
- // Block 0x3a, offset 0xe80
- 0xe80: 0x2f7d, 0xe81: 0x2f9d, 0xe82: 0x2cfd, 0xe83: 0x2cdd, 0xe84: 0x2fbd, 0xe85: 0x2fdd,
- 0xe86: 0x2ffd, 0xe87: 0x301d, 0xe88: 0x303d, 0xe89: 0x305d, 0xe8a: 0x307d, 0xe8b: 0x309d,
- 0xe8c: 0x30bd, 0xe8d: 0x30dd, 0xe8e: 0x30fd, 0xe8f: 0x0040, 0xe90: 0x0018, 0xe91: 0x0018,
- 0xe92: 0x311d, 0xe93: 0x313d, 0xe94: 0x315d, 0xe95: 0x317d, 0xe96: 0x319d, 0xe97: 0x31bd,
- 0xe98: 0x31dd, 0xe99: 0x31fd, 0xe9a: 0x321d, 0xe9b: 0x323d, 0xe9c: 0x315d, 0xe9d: 0x325d,
- 0xe9e: 0x327d, 0xe9f: 0x329d, 0xea0: 0x0008, 0xea1: 0x0008, 0xea2: 0x0008, 0xea3: 0x0008,
- 0xea4: 0x0008, 0xea5: 0x0008, 0xea6: 0x0008, 0xea7: 0x0008, 0xea8: 0x0008, 0xea9: 0x0008,
- 0xeaa: 0x0008, 0xeab: 0x0008, 0xeac: 0x0008, 0xead: 0x0008, 0xeae: 0x0008, 0xeaf: 0x0008,
- 0xeb0: 0x0008, 0xeb1: 0x0008, 0xeb2: 0x0008, 0xeb3: 0x0008, 0xeb4: 0x0008, 0xeb5: 0x0008,
- 0xeb6: 0x0008, 0xeb7: 0x0008, 0xeb8: 0x0008, 0xeb9: 0x0008, 0xeba: 0x0008, 0xebb: 0x0040,
- 0xebc: 0x0040, 0xebd: 0x0040, 0xebe: 0x0040, 0xebf: 0x0040,
- // Block 0x3b, offset 0xec0
- 0xec0: 0x36a2, 0xec1: 0x36d2, 0xec2: 0x3702, 0xec3: 0x3732, 0xec4: 0x32bd, 0xec5: 0x32dd,
- 0xec6: 0x32fd, 0xec7: 0x331d, 0xec8: 0x0018, 0xec9: 0x0018, 0xeca: 0x0018, 0xecb: 0x0018,
- 0xecc: 0x0018, 0xecd: 0x0018, 0xece: 0x0018, 0xecf: 0x0018, 0xed0: 0x333d, 0xed1: 0x3761,
- 0xed2: 0x3779, 0xed3: 0x3791, 0xed4: 0x37a9, 0xed5: 0x37c1, 0xed6: 0x37d9, 0xed7: 0x37f1,
- 0xed8: 0x3809, 0xed9: 0x3821, 0xeda: 0x3839, 0xedb: 0x3851, 0xedc: 0x3869, 0xedd: 0x3881,
- 0xede: 0x3899, 0xedf: 0x38b1, 0xee0: 0x335d, 0xee1: 0x337d, 0xee2: 0x339d, 0xee3: 0x33bd,
- 0xee4: 0x33dd, 0xee5: 0x33dd, 0xee6: 0x33fd, 0xee7: 0x341d, 0xee8: 0x343d, 0xee9: 0x345d,
- 0xeea: 0x347d, 0xeeb: 0x349d, 0xeec: 0x34bd, 0xeed: 0x34dd, 0xeee: 0x34fd, 0xeef: 0x351d,
- 0xef0: 0x353d, 0xef1: 0x355d, 0xef2: 0x357d, 0xef3: 0x359d, 0xef4: 0x35bd, 0xef5: 0x35dd,
- 0xef6: 0x35fd, 0xef7: 0x361d, 0xef8: 0x363d, 0xef9: 0x365d, 0xefa: 0x367d, 0xefb: 0x369d,
- 0xefc: 0x38c9, 0xefd: 0x3901, 0xefe: 0x36bd, 0xeff: 0x0018,
- // Block 0x3c, offset 0xf00
- 0xf00: 0x36dd, 0xf01: 0x36fd, 0xf02: 0x371d, 0xf03: 0x373d, 0xf04: 0x375d, 0xf05: 0x377d,
- 0xf06: 0x379d, 0xf07: 0x37bd, 0xf08: 0x37dd, 0xf09: 0x37fd, 0xf0a: 0x381d, 0xf0b: 0x383d,
- 0xf0c: 0x385d, 0xf0d: 0x387d, 0xf0e: 0x389d, 0xf0f: 0x38bd, 0xf10: 0x38dd, 0xf11: 0x38fd,
- 0xf12: 0x391d, 0xf13: 0x393d, 0xf14: 0x395d, 0xf15: 0x397d, 0xf16: 0x399d, 0xf17: 0x39bd,
- 0xf18: 0x39dd, 0xf19: 0x39fd, 0xf1a: 0x3a1d, 0xf1b: 0x3a3d, 0xf1c: 0x3a5d, 0xf1d: 0x3a7d,
- 0xf1e: 0x3a9d, 0xf1f: 0x3abd, 0xf20: 0x3add, 0xf21: 0x3afd, 0xf22: 0x3b1d, 0xf23: 0x3b3d,
- 0xf24: 0x3b5d, 0xf25: 0x3b7d, 0xf26: 0x127d, 0xf27: 0x3b9d, 0xf28: 0x3bbd, 0xf29: 0x3bdd,
- 0xf2a: 0x3bfd, 0xf2b: 0x3c1d, 0xf2c: 0x3c3d, 0xf2d: 0x3c5d, 0xf2e: 0x239d, 0xf2f: 0x3c7d,
- 0xf30: 0x3c9d, 0xf31: 0x3939, 0xf32: 0x3951, 0xf33: 0x3969, 0xf34: 0x3981, 0xf35: 0x3999,
- 0xf36: 0x39b1, 0xf37: 0x39c9, 0xf38: 0x39e1, 0xf39: 0x39f9, 0xf3a: 0x3a11, 0xf3b: 0x3a29,
- 0xf3c: 0x3a41, 0xf3d: 0x3a59, 0xf3e: 0x3a71, 0xf3f: 0x3a89,
- // Block 0x3d, offset 0xf40
- 0xf40: 0x3aa1, 0xf41: 0x3ac9, 0xf42: 0x3af1, 0xf43: 0x3b19, 0xf44: 0x3b41, 0xf45: 0x3b69,
- 0xf46: 0x3b91, 0xf47: 0x3bb9, 0xf48: 0x3be1, 0xf49: 0x3c09, 0xf4a: 0x3c39, 0xf4b: 0x3c69,
- 0xf4c: 0x3c99, 0xf4d: 0x3cbd, 0xf4e: 0x3cb1, 0xf4f: 0x3cdd, 0xf50: 0x3cfd, 0xf51: 0x3d15,
- 0xf52: 0x3d2d, 0xf53: 0x3d45, 0xf54: 0x3d5d, 0xf55: 0x3d5d, 0xf56: 0x3d45, 0xf57: 0x3d75,
- 0xf58: 0x07bd, 0xf59: 0x3d8d, 0xf5a: 0x3da5, 0xf5b: 0x3dbd, 0xf5c: 0x3dd5, 0xf5d: 0x3ded,
- 0xf5e: 0x3e05, 0xf5f: 0x3e1d, 0xf60: 0x3e35, 0xf61: 0x3e4d, 0xf62: 0x3e65, 0xf63: 0x3e7d,
- 0xf64: 0x3e95, 0xf65: 0x3e95, 0xf66: 0x3ead, 0xf67: 0x3ead, 0xf68: 0x3ec5, 0xf69: 0x3ec5,
- 0xf6a: 0x3edd, 0xf6b: 0x3ef5, 0xf6c: 0x3f0d, 0xf6d: 0x3f25, 0xf6e: 0x3f3d, 0xf6f: 0x3f3d,
- 0xf70: 0x3f55, 0xf71: 0x3f55, 0xf72: 0x3f55, 0xf73: 0x3f6d, 0xf74: 0x3f85, 0xf75: 0x3f9d,
- 0xf76: 0x3fb5, 0xf77: 0x3f9d, 0xf78: 0x3fcd, 0xf79: 0x3fe5, 0xf7a: 0x3f6d, 0xf7b: 0x3ffd,
- 0xf7c: 0x4015, 0xf7d: 0x4015, 0xf7e: 0x4015, 0xf7f: 0x0040,
- // Block 0x3e, offset 0xf80
- 0xf80: 0x3cc9, 0xf81: 0x3d31, 0xf82: 0x3d99, 0xf83: 0x3e01, 0xf84: 0x3e51, 0xf85: 0x3eb9,
- 0xf86: 0x3f09, 0xf87: 0x3f59, 0xf88: 0x3fd9, 0xf89: 0x4041, 0xf8a: 0x4091, 0xf8b: 0x40e1,
- 0xf8c: 0x4131, 0xf8d: 0x4199, 0xf8e: 0x4201, 0xf8f: 0x4251, 0xf90: 0x42a1, 0xf91: 0x42d9,
- 0xf92: 0x4329, 0xf93: 0x4391, 0xf94: 0x43f9, 0xf95: 0x4431, 0xf96: 0x44b1, 0xf97: 0x4549,
- 0xf98: 0x45c9, 0xf99: 0x4619, 0xf9a: 0x4699, 0xf9b: 0x4719, 0xf9c: 0x4781, 0xf9d: 0x47d1,
- 0xf9e: 0x4821, 0xf9f: 0x4871, 0xfa0: 0x48d9, 0xfa1: 0x4959, 0xfa2: 0x49c1, 0xfa3: 0x4a11,
- 0xfa4: 0x4a61, 0xfa5: 0x4ab1, 0xfa6: 0x4ae9, 0xfa7: 0x4b21, 0xfa8: 0x4b59, 0xfa9: 0x4b91,
- 0xfaa: 0x4be1, 0xfab: 0x4c31, 0xfac: 0x4cb1, 0xfad: 0x4d01, 0xfae: 0x4d69, 0xfaf: 0x4de9,
- 0xfb0: 0x4e39, 0xfb1: 0x4e71, 0xfb2: 0x4ea9, 0xfb3: 0x4f29, 0xfb4: 0x4f91, 0xfb5: 0x5011,
- 0xfb6: 0x5061, 0xfb7: 0x50e1, 0xfb8: 0x5119, 0xfb9: 0x5169, 0xfba: 0x51b9, 0xfbb: 0x5209,
- 0xfbc: 0x5259, 0xfbd: 0x52a9, 0xfbe: 0x5311, 0xfbf: 0x5361,
- // Block 0x3f, offset 0xfc0
- 0xfc0: 0x5399, 0xfc1: 0x53e9, 0xfc2: 0x5439, 0xfc3: 0x5489, 0xfc4: 0x54f1, 0xfc5: 0x5541,
- 0xfc6: 0x5591, 0xfc7: 0x55e1, 0xfc8: 0x5661, 0xfc9: 0x56c9, 0xfca: 0x5701, 0xfcb: 0x5781,
- 0xfcc: 0x57b9, 0xfcd: 0x5821, 0xfce: 0x5889, 0xfcf: 0x58d9, 0xfd0: 0x5929, 0xfd1: 0x5979,
- 0xfd2: 0x59e1, 0xfd3: 0x5a19, 0xfd4: 0x5a69, 0xfd5: 0x5ad1, 0xfd6: 0x5b09, 0xfd7: 0x5b89,
- 0xfd8: 0x5bd9, 0xfd9: 0x5c01, 0xfda: 0x5c29, 0xfdb: 0x5c51, 0xfdc: 0x5c79, 0xfdd: 0x5ca1,
- 0xfde: 0x5cc9, 0xfdf: 0x5cf1, 0xfe0: 0x5d19, 0xfe1: 0x5d41, 0xfe2: 0x5d69, 0xfe3: 0x5d99,
- 0xfe4: 0x5dc9, 0xfe5: 0x5df9, 0xfe6: 0x5e29, 0xfe7: 0x5e59, 0xfe8: 0x5e89, 0xfe9: 0x5eb9,
- 0xfea: 0x5ee9, 0xfeb: 0x5f19, 0xfec: 0x5f49, 0xfed: 0x5f79, 0xfee: 0x5fa9, 0xfef: 0x5fd9,
- 0xff0: 0x6009, 0xff1: 0x402d, 0xff2: 0x6039, 0xff3: 0x6051, 0xff4: 0x404d, 0xff5: 0x6069,
- 0xff6: 0x6081, 0xff7: 0x6099, 0xff8: 0x406d, 0xff9: 0x406d, 0xffa: 0x60b1, 0xffb: 0x60c9,
- 0xffc: 0x6101, 0xffd: 0x6139, 0xffe: 0x6171, 0xfff: 0x61a9,
- // Block 0x40, offset 0x1000
- 0x1000: 0x6211, 0x1001: 0x6229, 0x1002: 0x408d, 0x1003: 0x6241, 0x1004: 0x6259, 0x1005: 0x6271,
- 0x1006: 0x6289, 0x1007: 0x62a1, 0x1008: 0x40ad, 0x1009: 0x62b9, 0x100a: 0x62e1, 0x100b: 0x62f9,
- 0x100c: 0x40cd, 0x100d: 0x40cd, 0x100e: 0x6311, 0x100f: 0x6329, 0x1010: 0x6341, 0x1011: 0x40ed,
- 0x1012: 0x410d, 0x1013: 0x412d, 0x1014: 0x414d, 0x1015: 0x416d, 0x1016: 0x6359, 0x1017: 0x6371,
- 0x1018: 0x6389, 0x1019: 0x63a1, 0x101a: 0x63b9, 0x101b: 0x418d, 0x101c: 0x63d1, 0x101d: 0x63e9,
- 0x101e: 0x6401, 0x101f: 0x41ad, 0x1020: 0x41cd, 0x1021: 0x6419, 0x1022: 0x41ed, 0x1023: 0x420d,
- 0x1024: 0x422d, 0x1025: 0x6431, 0x1026: 0x424d, 0x1027: 0x6449, 0x1028: 0x6479, 0x1029: 0x6211,
- 0x102a: 0x426d, 0x102b: 0x428d, 0x102c: 0x42ad, 0x102d: 0x42cd, 0x102e: 0x64b1, 0x102f: 0x64f1,
- 0x1030: 0x6539, 0x1031: 0x6551, 0x1032: 0x42ed, 0x1033: 0x6569, 0x1034: 0x6581, 0x1035: 0x6599,
- 0x1036: 0x430d, 0x1037: 0x65b1, 0x1038: 0x65c9, 0x1039: 0x65b1, 0x103a: 0x65e1, 0x103b: 0x65f9,
- 0x103c: 0x432d, 0x103d: 0x6611, 0x103e: 0x6629, 0x103f: 0x6611,
- // Block 0x41, offset 0x1040
- 0x1040: 0x434d, 0x1041: 0x436d, 0x1042: 0x0040, 0x1043: 0x6641, 0x1044: 0x6659, 0x1045: 0x6671,
- 0x1046: 0x6689, 0x1047: 0x0040, 0x1048: 0x66c1, 0x1049: 0x66d9, 0x104a: 0x66f1, 0x104b: 0x6709,
- 0x104c: 0x6721, 0x104d: 0x6739, 0x104e: 0x6401, 0x104f: 0x6751, 0x1050: 0x6769, 0x1051: 0x6781,
- 0x1052: 0x438d, 0x1053: 0x6799, 0x1054: 0x6289, 0x1055: 0x43ad, 0x1056: 0x43cd, 0x1057: 0x67b1,
- 0x1058: 0x0040, 0x1059: 0x43ed, 0x105a: 0x67c9, 0x105b: 0x67e1, 0x105c: 0x67f9, 0x105d: 0x6811,
- 0x105e: 0x6829, 0x105f: 0x6859, 0x1060: 0x6889, 0x1061: 0x68b1, 0x1062: 0x68d9, 0x1063: 0x6901,
- 0x1064: 0x6929, 0x1065: 0x6951, 0x1066: 0x6979, 0x1067: 0x69a1, 0x1068: 0x69c9, 0x1069: 0x69f1,
- 0x106a: 0x6a21, 0x106b: 0x6a51, 0x106c: 0x6a81, 0x106d: 0x6ab1, 0x106e: 0x6ae1, 0x106f: 0x6b11,
- 0x1070: 0x6b41, 0x1071: 0x6b71, 0x1072: 0x6ba1, 0x1073: 0x6bd1, 0x1074: 0x6c01, 0x1075: 0x6c31,
- 0x1076: 0x6c61, 0x1077: 0x6c91, 0x1078: 0x6cc1, 0x1079: 0x6cf1, 0x107a: 0x6d21, 0x107b: 0x6d51,
- 0x107c: 0x6d81, 0x107d: 0x6db1, 0x107e: 0x6de1, 0x107f: 0x440d,
- // Block 0x42, offset 0x1080
- 0x1080: 0xe00d, 0x1081: 0x0008, 0x1082: 0xe00d, 0x1083: 0x0008, 0x1084: 0xe00d, 0x1085: 0x0008,
- 0x1086: 0xe00d, 0x1087: 0x0008, 0x1088: 0xe00d, 0x1089: 0x0008, 0x108a: 0xe00d, 0x108b: 0x0008,
- 0x108c: 0xe00d, 0x108d: 0x0008, 0x108e: 0xe00d, 0x108f: 0x0008, 0x1090: 0xe00d, 0x1091: 0x0008,
- 0x1092: 0xe00d, 0x1093: 0x0008, 0x1094: 0xe00d, 0x1095: 0x0008, 0x1096: 0xe00d, 0x1097: 0x0008,
- 0x1098: 0xe00d, 0x1099: 0x0008, 0x109a: 0xe00d, 0x109b: 0x0008, 0x109c: 0xe00d, 0x109d: 0x0008,
- 0x109e: 0xe00d, 0x109f: 0x0008, 0x10a0: 0xe00d, 0x10a1: 0x0008, 0x10a2: 0xe00d, 0x10a3: 0x0008,
- 0x10a4: 0xe00d, 0x10a5: 0x0008, 0x10a6: 0xe00d, 0x10a7: 0x0008, 0x10a8: 0xe00d, 0x10a9: 0x0008,
- 0x10aa: 0xe00d, 0x10ab: 0x0008, 0x10ac: 0xe00d, 0x10ad: 0x0008, 0x10ae: 0x0008, 0x10af: 0x1308,
- 0x10b0: 0x1318, 0x10b1: 0x1318, 0x10b2: 0x1318, 0x10b3: 0x0018, 0x10b4: 0x1308, 0x10b5: 0x1308,
- 0x10b6: 0x1308, 0x10b7: 0x1308, 0x10b8: 0x1308, 0x10b9: 0x1308, 0x10ba: 0x1308, 0x10bb: 0x1308,
- 0x10bc: 0x1308, 0x10bd: 0x1308, 0x10be: 0x0018, 0x10bf: 0x0008,
- // Block 0x43, offset 0x10c0
- 0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008,
- 0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008,
- 0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008,
- 0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008,
- 0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0x0ea1, 0x10dd: 0x6e11,
- 0x10de: 0x1308, 0x10df: 0x1308, 0x10e0: 0x0008, 0x10e1: 0x0008, 0x10e2: 0x0008, 0x10e3: 0x0008,
- 0x10e4: 0x0008, 0x10e5: 0x0008, 0x10e6: 0x0008, 0x10e7: 0x0008, 0x10e8: 0x0008, 0x10e9: 0x0008,
- 0x10ea: 0x0008, 0x10eb: 0x0008, 0x10ec: 0x0008, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x0008,
- 0x10f0: 0x0008, 0x10f1: 0x0008, 0x10f2: 0x0008, 0x10f3: 0x0008, 0x10f4: 0x0008, 0x10f5: 0x0008,
- 0x10f6: 0x0008, 0x10f7: 0x0008, 0x10f8: 0x0008, 0x10f9: 0x0008, 0x10fa: 0x0008, 0x10fb: 0x0008,
- 0x10fc: 0x0008, 0x10fd: 0x0008, 0x10fe: 0x0008, 0x10ff: 0x0008,
- // Block 0x44, offset 0x1100
- 0x1100: 0x0018, 0x1101: 0x0018, 0x1102: 0x0018, 0x1103: 0x0018, 0x1104: 0x0018, 0x1105: 0x0018,
- 0x1106: 0x0018, 0x1107: 0x0018, 0x1108: 0x0018, 0x1109: 0x0018, 0x110a: 0x0018, 0x110b: 0x0018,
- 0x110c: 0x0018, 0x110d: 0x0018, 0x110e: 0x0018, 0x110f: 0x0018, 0x1110: 0x0018, 0x1111: 0x0018,
- 0x1112: 0x0018, 0x1113: 0x0018, 0x1114: 0x0018, 0x1115: 0x0018, 0x1116: 0x0018, 0x1117: 0x0008,
- 0x1118: 0x0008, 0x1119: 0x0008, 0x111a: 0x0008, 0x111b: 0x0008, 0x111c: 0x0008, 0x111d: 0x0008,
- 0x111e: 0x0008, 0x111f: 0x0008, 0x1120: 0x0018, 0x1121: 0x0018, 0x1122: 0xe00d, 0x1123: 0x0008,
- 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,
- 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0xe00d, 0x112f: 0x0008,
- 0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0xe00d, 0x1133: 0x0008, 0x1134: 0xe00d, 0x1135: 0x0008,
- 0x1136: 0xe00d, 0x1137: 0x0008, 0x1138: 0xe00d, 0x1139: 0x0008, 0x113a: 0xe00d, 0x113b: 0x0008,
- 0x113c: 0xe00d, 0x113d: 0x0008, 0x113e: 0xe00d, 0x113f: 0x0008,
- // Block 0x45, offset 0x1140
- 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,
- 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,
- 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,
- 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,
- 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0xe00d, 0x115d: 0x0008,
- 0x115e: 0xe00d, 0x115f: 0x0008, 0x1160: 0xe00d, 0x1161: 0x0008, 0x1162: 0xe00d, 0x1163: 0x0008,
- 0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008,
- 0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008,
- 0x1170: 0xe0fd, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,
- 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0xe01d, 0x117a: 0x0008, 0x117b: 0xe03d,
- 0x117c: 0x0008, 0x117d: 0x442d, 0x117e: 0xe00d, 0x117f: 0x0008,
- // Block 0x46, offset 0x1180
- 0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008,
- 0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0x0008, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0xe03d,
- 0x118c: 0x0008, 0x118d: 0x11d9, 0x118e: 0x0008, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008,
- 0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0x0008, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008,
- 0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008,
- 0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008,
- 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,
- 0x11aa: 0x6e29, 0x11ab: 0x1029, 0x11ac: 0x11c1, 0x11ad: 0x6e41, 0x11ae: 0x1221, 0x11af: 0x0040,
- 0x11b0: 0x6e59, 0x11b1: 0x6e71, 0x11b2: 0x1239, 0x11b3: 0x444d, 0x11b4: 0xe00d, 0x11b5: 0x0008,
- 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0x0040, 0x11b9: 0x0040, 0x11ba: 0x0040, 0x11bb: 0x0040,
- 0x11bc: 0x0040, 0x11bd: 0x0040, 0x11be: 0x0040, 0x11bf: 0x0040,
- // Block 0x47, offset 0x11c0
- 0x11c0: 0x64d5, 0x11c1: 0x64f5, 0x11c2: 0x6515, 0x11c3: 0x6535, 0x11c4: 0x6555, 0x11c5: 0x6575,
- 0x11c6: 0x6595, 0x11c7: 0x65b5, 0x11c8: 0x65d5, 0x11c9: 0x65f5, 0x11ca: 0x6615, 0x11cb: 0x6635,
- 0x11cc: 0x6655, 0x11cd: 0x6675, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0x6695, 0x11d1: 0x0008,
- 0x11d2: 0x66b5, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x66d5, 0x11d6: 0x66f5, 0x11d7: 0x6715,
- 0x11d8: 0x6735, 0x11d9: 0x6755, 0x11da: 0x6775, 0x11db: 0x6795, 0x11dc: 0x67b5, 0x11dd: 0x67d5,
- 0x11de: 0x67f5, 0x11df: 0x0008, 0x11e0: 0x6815, 0x11e1: 0x0008, 0x11e2: 0x6835, 0x11e3: 0x0008,
- 0x11e4: 0x0008, 0x11e5: 0x6855, 0x11e6: 0x6875, 0x11e7: 0x0008, 0x11e8: 0x0008, 0x11e9: 0x0008,
- 0x11ea: 0x6895, 0x11eb: 0x68b5, 0x11ec: 0x68d5, 0x11ed: 0x68f5, 0x11ee: 0x6915, 0x11ef: 0x6935,
- 0x11f0: 0x6955, 0x11f1: 0x6975, 0x11f2: 0x6995, 0x11f3: 0x69b5, 0x11f4: 0x69d5, 0x11f5: 0x69f5,
- 0x11f6: 0x6a15, 0x11f7: 0x6a35, 0x11f8: 0x6a55, 0x11f9: 0x6a75, 0x11fa: 0x6a95, 0x11fb: 0x6ab5,
- 0x11fc: 0x6ad5, 0x11fd: 0x6af5, 0x11fe: 0x6b15, 0x11ff: 0x6b35,
- // Block 0x48, offset 0x1200
- 0x1200: 0x7a95, 0x1201: 0x7ab5, 0x1202: 0x7ad5, 0x1203: 0x7af5, 0x1204: 0x7b15, 0x1205: 0x7b35,
- 0x1206: 0x7b55, 0x1207: 0x7b75, 0x1208: 0x7b95, 0x1209: 0x7bb5, 0x120a: 0x7bd5, 0x120b: 0x7bf5,
- 0x120c: 0x7c15, 0x120d: 0x7c35, 0x120e: 0x7c55, 0x120f: 0x6ec9, 0x1210: 0x6ef1, 0x1211: 0x6f19,
- 0x1212: 0x7c75, 0x1213: 0x7c95, 0x1214: 0x7cb5, 0x1215: 0x6f41, 0x1216: 0x6f69, 0x1217: 0x6f91,
- 0x1218: 0x7cd5, 0x1219: 0x7cf5, 0x121a: 0x0040, 0x121b: 0x0040, 0x121c: 0x0040, 0x121d: 0x0040,
- 0x121e: 0x0040, 0x121f: 0x0040, 0x1220: 0x0040, 0x1221: 0x0040, 0x1222: 0x0040, 0x1223: 0x0040,
- 0x1224: 0x0040, 0x1225: 0x0040, 0x1226: 0x0040, 0x1227: 0x0040, 0x1228: 0x0040, 0x1229: 0x0040,
- 0x122a: 0x0040, 0x122b: 0x0040, 0x122c: 0x0040, 0x122d: 0x0040, 0x122e: 0x0040, 0x122f: 0x0040,
- 0x1230: 0x0040, 0x1231: 0x0040, 0x1232: 0x0040, 0x1233: 0x0040, 0x1234: 0x0040, 0x1235: 0x0040,
- 0x1236: 0x0040, 0x1237: 0x0040, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040,
- 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040,
- // Block 0x49, offset 0x1240
- 0x1240: 0x6fb9, 0x1241: 0x6fd1, 0x1242: 0x6fe9, 0x1243: 0x7d15, 0x1244: 0x7d35, 0x1245: 0x7001,
- 0x1246: 0x7001, 0x1247: 0x0040, 0x1248: 0x0040, 0x1249: 0x0040, 0x124a: 0x0040, 0x124b: 0x0040,
- 0x124c: 0x0040, 0x124d: 0x0040, 0x124e: 0x0040, 0x124f: 0x0040, 0x1250: 0x0040, 0x1251: 0x0040,
- 0x1252: 0x0040, 0x1253: 0x7019, 0x1254: 0x7041, 0x1255: 0x7069, 0x1256: 0x7091, 0x1257: 0x70b9,
- 0x1258: 0x0040, 0x1259: 0x0040, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x70e1,
- 0x125e: 0x1308, 0x125f: 0x7109, 0x1260: 0x7131, 0x1261: 0x20a9, 0x1262: 0x20f1, 0x1263: 0x7149,
- 0x1264: 0x7161, 0x1265: 0x7179, 0x1266: 0x7191, 0x1267: 0x71a9, 0x1268: 0x71c1, 0x1269: 0x1fb2,
- 0x126a: 0x71d9, 0x126b: 0x7201, 0x126c: 0x7229, 0x126d: 0x7261, 0x126e: 0x7299, 0x126f: 0x72c1,
- 0x1270: 0x72e9, 0x1271: 0x7311, 0x1272: 0x7339, 0x1273: 0x7361, 0x1274: 0x7389, 0x1275: 0x73b1,
- 0x1276: 0x73d9, 0x1277: 0x0040, 0x1278: 0x7401, 0x1279: 0x7429, 0x127a: 0x7451, 0x127b: 0x7479,
- 0x127c: 0x74a1, 0x127d: 0x0040, 0x127e: 0x74c9, 0x127f: 0x0040,
- // Block 0x4a, offset 0x1280
- 0x1280: 0x74f1, 0x1281: 0x7519, 0x1282: 0x0040, 0x1283: 0x7541, 0x1284: 0x7569, 0x1285: 0x0040,
- 0x1286: 0x7591, 0x1287: 0x75b9, 0x1288: 0x75e1, 0x1289: 0x7609, 0x128a: 0x7631, 0x128b: 0x7659,
- 0x128c: 0x7681, 0x128d: 0x76a9, 0x128e: 0x76d1, 0x128f: 0x76f9, 0x1290: 0x7721, 0x1291: 0x7721,
- 0x1292: 0x7739, 0x1293: 0x7739, 0x1294: 0x7739, 0x1295: 0x7739, 0x1296: 0x7751, 0x1297: 0x7751,
- 0x1298: 0x7751, 0x1299: 0x7751, 0x129a: 0x7769, 0x129b: 0x7769, 0x129c: 0x7769, 0x129d: 0x7769,
- 0x129e: 0x7781, 0x129f: 0x7781, 0x12a0: 0x7781, 0x12a1: 0x7781, 0x12a2: 0x7799, 0x12a3: 0x7799,
- 0x12a4: 0x7799, 0x12a5: 0x7799, 0x12a6: 0x77b1, 0x12a7: 0x77b1, 0x12a8: 0x77b1, 0x12a9: 0x77b1,
- 0x12aa: 0x77c9, 0x12ab: 0x77c9, 0x12ac: 0x77c9, 0x12ad: 0x77c9, 0x12ae: 0x77e1, 0x12af: 0x77e1,
- 0x12b0: 0x77e1, 0x12b1: 0x77e1, 0x12b2: 0x77f9, 0x12b3: 0x77f9, 0x12b4: 0x77f9, 0x12b5: 0x77f9,
- 0x12b6: 0x7811, 0x12b7: 0x7811, 0x12b8: 0x7811, 0x12b9: 0x7811, 0x12ba: 0x7829, 0x12bb: 0x7829,
- 0x12bc: 0x7829, 0x12bd: 0x7829, 0x12be: 0x7841, 0x12bf: 0x7841,
- // Block 0x4b, offset 0x12c0
- 0x12c0: 0x7841, 0x12c1: 0x7841, 0x12c2: 0x7859, 0x12c3: 0x7859, 0x12c4: 0x7871, 0x12c5: 0x7871,
- 0x12c6: 0x7889, 0x12c7: 0x7889, 0x12c8: 0x78a1, 0x12c9: 0x78a1, 0x12ca: 0x78b9, 0x12cb: 0x78b9,
- 0x12cc: 0x78d1, 0x12cd: 0x78d1, 0x12ce: 0x78e9, 0x12cf: 0x78e9, 0x12d0: 0x78e9, 0x12d1: 0x78e9,
- 0x12d2: 0x7901, 0x12d3: 0x7901, 0x12d4: 0x7901, 0x12d5: 0x7901, 0x12d6: 0x7919, 0x12d7: 0x7919,
- 0x12d8: 0x7919, 0x12d9: 0x7919, 0x12da: 0x7931, 0x12db: 0x7931, 0x12dc: 0x7931, 0x12dd: 0x7931,
- 0x12de: 0x7949, 0x12df: 0x7949, 0x12e0: 0x7961, 0x12e1: 0x7961, 0x12e2: 0x7961, 0x12e3: 0x7961,
- 0x12e4: 0x7979, 0x12e5: 0x7979, 0x12e6: 0x7991, 0x12e7: 0x7991, 0x12e8: 0x7991, 0x12e9: 0x7991,
- 0x12ea: 0x79a9, 0x12eb: 0x79a9, 0x12ec: 0x79a9, 0x12ed: 0x79a9, 0x12ee: 0x79c1, 0x12ef: 0x79c1,
- 0x12f0: 0x79d9, 0x12f1: 0x79d9, 0x12f2: 0x0018, 0x12f3: 0x0018, 0x12f4: 0x0018, 0x12f5: 0x0018,
- 0x12f6: 0x0018, 0x12f7: 0x0018, 0x12f8: 0x0018, 0x12f9: 0x0018, 0x12fa: 0x0018, 0x12fb: 0x0018,
- 0x12fc: 0x0018, 0x12fd: 0x0018, 0x12fe: 0x0018, 0x12ff: 0x0018,
- // Block 0x4c, offset 0x1300
- 0x1300: 0x0018, 0x1301: 0x0018, 0x1302: 0x0040, 0x1303: 0x0040, 0x1304: 0x0040, 0x1305: 0x0040,
- 0x1306: 0x0040, 0x1307: 0x0040, 0x1308: 0x0040, 0x1309: 0x0040, 0x130a: 0x0040, 0x130b: 0x0040,
- 0x130c: 0x0040, 0x130d: 0x0040, 0x130e: 0x0040, 0x130f: 0x0040, 0x1310: 0x0040, 0x1311: 0x0040,
- 0x1312: 0x0040, 0x1313: 0x79f1, 0x1314: 0x79f1, 0x1315: 0x79f1, 0x1316: 0x79f1, 0x1317: 0x7a09,
- 0x1318: 0x7a09, 0x1319: 0x7a21, 0x131a: 0x7a21, 0x131b: 0x7a39, 0x131c: 0x7a39, 0x131d: 0x0479,
- 0x131e: 0x7a51, 0x131f: 0x7a51, 0x1320: 0x7a69, 0x1321: 0x7a69, 0x1322: 0x7a81, 0x1323: 0x7a81,
- 0x1324: 0x7a99, 0x1325: 0x7a99, 0x1326: 0x7a99, 0x1327: 0x7a99, 0x1328: 0x7ab1, 0x1329: 0x7ab1,
- 0x132a: 0x7ac9, 0x132b: 0x7ac9, 0x132c: 0x7af1, 0x132d: 0x7af1, 0x132e: 0x7b19, 0x132f: 0x7b19,
- 0x1330: 0x7b41, 0x1331: 0x7b41, 0x1332: 0x7b69, 0x1333: 0x7b69, 0x1334: 0x7b91, 0x1335: 0x7b91,
- 0x1336: 0x7bb9, 0x1337: 0x7bb9, 0x1338: 0x7bb9, 0x1339: 0x7be1, 0x133a: 0x7be1, 0x133b: 0x7be1,
- 0x133c: 0x7c09, 0x133d: 0x7c09, 0x133e: 0x7c09, 0x133f: 0x7c09,
- // Block 0x4d, offset 0x1340
- 0x1340: 0x85f9, 0x1341: 0x8621, 0x1342: 0x8649, 0x1343: 0x8671, 0x1344: 0x8699, 0x1345: 0x86c1,
- 0x1346: 0x86e9, 0x1347: 0x8711, 0x1348: 0x8739, 0x1349: 0x8761, 0x134a: 0x8789, 0x134b: 0x87b1,
- 0x134c: 0x87d9, 0x134d: 0x8801, 0x134e: 0x8829, 0x134f: 0x8851, 0x1350: 0x8879, 0x1351: 0x88a1,
- 0x1352: 0x88c9, 0x1353: 0x88f1, 0x1354: 0x8919, 0x1355: 0x8941, 0x1356: 0x8969, 0x1357: 0x8991,
- 0x1358: 0x89b9, 0x1359: 0x89e1, 0x135a: 0x8a09, 0x135b: 0x8a31, 0x135c: 0x8a59, 0x135d: 0x8a81,
- 0x135e: 0x8aaa, 0x135f: 0x8ada, 0x1360: 0x8b0a, 0x1361: 0x8b3a, 0x1362: 0x8b6a, 0x1363: 0x8b9a,
- 0x1364: 0x8bc9, 0x1365: 0x8bf1, 0x1366: 0x7c71, 0x1367: 0x8c19, 0x1368: 0x7be1, 0x1369: 0x7c99,
- 0x136a: 0x8c41, 0x136b: 0x8c69, 0x136c: 0x7d39, 0x136d: 0x8c91, 0x136e: 0x7d61, 0x136f: 0x7d89,
- 0x1370: 0x8cb9, 0x1371: 0x8ce1, 0x1372: 0x7e29, 0x1373: 0x8d09, 0x1374: 0x7e51, 0x1375: 0x7e79,
- 0x1376: 0x8d31, 0x1377: 0x8d59, 0x1378: 0x7ec9, 0x1379: 0x8d81, 0x137a: 0x7ef1, 0x137b: 0x7f19,
- 0x137c: 0x83a1, 0x137d: 0x83c9, 0x137e: 0x8441, 0x137f: 0x8469,
- // Block 0x4e, offset 0x1380
- 0x1380: 0x8491, 0x1381: 0x8531, 0x1382: 0x8559, 0x1383: 0x8581, 0x1384: 0x85a9, 0x1385: 0x8649,
- 0x1386: 0x8671, 0x1387: 0x8699, 0x1388: 0x8da9, 0x1389: 0x8739, 0x138a: 0x8dd1, 0x138b: 0x8df9,
- 0x138c: 0x8829, 0x138d: 0x8e21, 0x138e: 0x8851, 0x138f: 0x8879, 0x1390: 0x8a81, 0x1391: 0x8e49,
- 0x1392: 0x8e71, 0x1393: 0x89b9, 0x1394: 0x8e99, 0x1395: 0x89e1, 0x1396: 0x8a09, 0x1397: 0x7c21,
- 0x1398: 0x7c49, 0x1399: 0x8ec1, 0x139a: 0x7c71, 0x139b: 0x8ee9, 0x139c: 0x7cc1, 0x139d: 0x7ce9,
- 0x139e: 0x7d11, 0x139f: 0x7d39, 0x13a0: 0x8f11, 0x13a1: 0x7db1, 0x13a2: 0x7dd9, 0x13a3: 0x7e01,
- 0x13a4: 0x7e29, 0x13a5: 0x8f39, 0x13a6: 0x7ec9, 0x13a7: 0x7f41, 0x13a8: 0x7f69, 0x13a9: 0x7f91,
- 0x13aa: 0x7fb9, 0x13ab: 0x7fe1, 0x13ac: 0x8031, 0x13ad: 0x8059, 0x13ae: 0x8081, 0x13af: 0x80a9,
- 0x13b0: 0x80d1, 0x13b1: 0x80f9, 0x13b2: 0x8f61, 0x13b3: 0x8121, 0x13b4: 0x8149, 0x13b5: 0x8171,
- 0x13b6: 0x8199, 0x13b7: 0x81c1, 0x13b8: 0x81e9, 0x13b9: 0x8239, 0x13ba: 0x8261, 0x13bb: 0x8289,
- 0x13bc: 0x82b1, 0x13bd: 0x82d9, 0x13be: 0x8301, 0x13bf: 0x8329,
- // Block 0x4f, offset 0x13c0
- 0x13c0: 0x8351, 0x13c1: 0x8379, 0x13c2: 0x83f1, 0x13c3: 0x8419, 0x13c4: 0x84b9, 0x13c5: 0x84e1,
- 0x13c6: 0x8509, 0x13c7: 0x8531, 0x13c8: 0x8559, 0x13c9: 0x85d1, 0x13ca: 0x85f9, 0x13cb: 0x8621,
- 0x13cc: 0x8649, 0x13cd: 0x8f89, 0x13ce: 0x86c1, 0x13cf: 0x86e9, 0x13d0: 0x8711, 0x13d1: 0x8739,
- 0x13d2: 0x87b1, 0x13d3: 0x87d9, 0x13d4: 0x8801, 0x13d5: 0x8829, 0x13d6: 0x8fb1, 0x13d7: 0x88a1,
- 0x13d8: 0x88c9, 0x13d9: 0x8fd9, 0x13da: 0x8941, 0x13db: 0x8969, 0x13dc: 0x8991, 0x13dd: 0x89b9,
- 0x13de: 0x9001, 0x13df: 0x7c71, 0x13e0: 0x8ee9, 0x13e1: 0x7d39, 0x13e2: 0x8f11, 0x13e3: 0x7e29,
- 0x13e4: 0x8f39, 0x13e5: 0x7ec9, 0x13e6: 0x9029, 0x13e7: 0x80d1, 0x13e8: 0x9051, 0x13e9: 0x9079,
- 0x13ea: 0x90a1, 0x13eb: 0x8531, 0x13ec: 0x8559, 0x13ed: 0x8649, 0x13ee: 0x8829, 0x13ef: 0x8fb1,
- 0x13f0: 0x89b9, 0x13f1: 0x9001, 0x13f2: 0x90c9, 0x13f3: 0x9101, 0x13f4: 0x9139, 0x13f5: 0x9171,
- 0x13f6: 0x9199, 0x13f7: 0x91c1, 0x13f8: 0x91e9, 0x13f9: 0x9211, 0x13fa: 0x9239, 0x13fb: 0x9261,
- 0x13fc: 0x9289, 0x13fd: 0x92b1, 0x13fe: 0x92d9, 0x13ff: 0x9301,
- // Block 0x50, offset 0x1400
- 0x1400: 0x9329, 0x1401: 0x9351, 0x1402: 0x9379, 0x1403: 0x93a1, 0x1404: 0x93c9, 0x1405: 0x93f1,
- 0x1406: 0x9419, 0x1407: 0x9441, 0x1408: 0x9469, 0x1409: 0x9491, 0x140a: 0x94b9, 0x140b: 0x94e1,
- 0x140c: 0x9079, 0x140d: 0x9509, 0x140e: 0x9531, 0x140f: 0x9559, 0x1410: 0x9581, 0x1411: 0x9171,
- 0x1412: 0x9199, 0x1413: 0x91c1, 0x1414: 0x91e9, 0x1415: 0x9211, 0x1416: 0x9239, 0x1417: 0x9261,
- 0x1418: 0x9289, 0x1419: 0x92b1, 0x141a: 0x92d9, 0x141b: 0x9301, 0x141c: 0x9329, 0x141d: 0x9351,
- 0x141e: 0x9379, 0x141f: 0x93a1, 0x1420: 0x93c9, 0x1421: 0x93f1, 0x1422: 0x9419, 0x1423: 0x9441,
- 0x1424: 0x9469, 0x1425: 0x9491, 0x1426: 0x94b9, 0x1427: 0x94e1, 0x1428: 0x9079, 0x1429: 0x9509,
- 0x142a: 0x9531, 0x142b: 0x9559, 0x142c: 0x9581, 0x142d: 0x9491, 0x142e: 0x94b9, 0x142f: 0x94e1,
- 0x1430: 0x9079, 0x1431: 0x9051, 0x1432: 0x90a1, 0x1433: 0x8211, 0x1434: 0x8059, 0x1435: 0x8081,
- 0x1436: 0x80a9, 0x1437: 0x9491, 0x1438: 0x94b9, 0x1439: 0x94e1, 0x143a: 0x8211, 0x143b: 0x8239,
- 0x143c: 0x95a9, 0x143d: 0x95a9, 0x143e: 0x0018, 0x143f: 0x0018,
- // Block 0x51, offset 0x1440
- 0x1440: 0x0040, 0x1441: 0x0040, 0x1442: 0x0040, 0x1443: 0x0040, 0x1444: 0x0040, 0x1445: 0x0040,
- 0x1446: 0x0040, 0x1447: 0x0040, 0x1448: 0x0040, 0x1449: 0x0040, 0x144a: 0x0040, 0x144b: 0x0040,
- 0x144c: 0x0040, 0x144d: 0x0040, 0x144e: 0x0040, 0x144f: 0x0040, 0x1450: 0x95d1, 0x1451: 0x9609,
- 0x1452: 0x9609, 0x1453: 0x9641, 0x1454: 0x9679, 0x1455: 0x96b1, 0x1456: 0x96e9, 0x1457: 0x9721,
- 0x1458: 0x9759, 0x1459: 0x9759, 0x145a: 0x9791, 0x145b: 0x97c9, 0x145c: 0x9801, 0x145d: 0x9839,
- 0x145e: 0x9871, 0x145f: 0x98a9, 0x1460: 0x98a9, 0x1461: 0x98e1, 0x1462: 0x9919, 0x1463: 0x9919,
- 0x1464: 0x9951, 0x1465: 0x9951, 0x1466: 0x9989, 0x1467: 0x99c1, 0x1468: 0x99c1, 0x1469: 0x99f9,
- 0x146a: 0x9a31, 0x146b: 0x9a31, 0x146c: 0x9a69, 0x146d: 0x9a69, 0x146e: 0x9aa1, 0x146f: 0x9ad9,
- 0x1470: 0x9ad9, 0x1471: 0x9b11, 0x1472: 0x9b11, 0x1473: 0x9b49, 0x1474: 0x9b81, 0x1475: 0x9bb9,
- 0x1476: 0x9bf1, 0x1477: 0x9bf1, 0x1478: 0x9c29, 0x1479: 0x9c61, 0x147a: 0x9c99, 0x147b: 0x9cd1,
- 0x147c: 0x9d09, 0x147d: 0x9d09, 0x147e: 0x9d41, 0x147f: 0x9d79,
- // Block 0x52, offset 0x1480
- 0x1480: 0xa949, 0x1481: 0xa981, 0x1482: 0xa9b9, 0x1483: 0xa8a1, 0x1484: 0x9bb9, 0x1485: 0x9989,
- 0x1486: 0xa9f1, 0x1487: 0xaa29, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040,
- 0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x0040, 0x1491: 0x0040,
- 0x1492: 0x0040, 0x1493: 0x0040, 0x1494: 0x0040, 0x1495: 0x0040, 0x1496: 0x0040, 0x1497: 0x0040,
- 0x1498: 0x0040, 0x1499: 0x0040, 0x149a: 0x0040, 0x149b: 0x0040, 0x149c: 0x0040, 0x149d: 0x0040,
- 0x149e: 0x0040, 0x149f: 0x0040, 0x14a0: 0x0040, 0x14a1: 0x0040, 0x14a2: 0x0040, 0x14a3: 0x0040,
- 0x14a4: 0x0040, 0x14a5: 0x0040, 0x14a6: 0x0040, 0x14a7: 0x0040, 0x14a8: 0x0040, 0x14a9: 0x0040,
- 0x14aa: 0x0040, 0x14ab: 0x0040, 0x14ac: 0x0040, 0x14ad: 0x0040, 0x14ae: 0x0040, 0x14af: 0x0040,
- 0x14b0: 0xaa61, 0x14b1: 0xaa99, 0x14b2: 0xaad1, 0x14b3: 0xab19, 0x14b4: 0xab61, 0x14b5: 0xaba9,
- 0x14b6: 0xabf1, 0x14b7: 0xac39, 0x14b8: 0xac81, 0x14b9: 0xacc9, 0x14ba: 0xad02, 0x14bb: 0xae12,
- 0x14bc: 0xae91, 0x14bd: 0x0018, 0x14be: 0x0040, 0x14bf: 0x0040,
- // Block 0x53, offset 0x14c0
- 0x14c0: 0x13c0, 0x14c1: 0x13c0, 0x14c2: 0x13c0, 0x14c3: 0x13c0, 0x14c4: 0x13c0, 0x14c5: 0x13c0,
- 0x14c6: 0x13c0, 0x14c7: 0x13c0, 0x14c8: 0x13c0, 0x14c9: 0x13c0, 0x14ca: 0x13c0, 0x14cb: 0x13c0,
- 0x14cc: 0x13c0, 0x14cd: 0x13c0, 0x14ce: 0x13c0, 0x14cf: 0x13c0, 0x14d0: 0xaeda, 0x14d1: 0x7d55,
- 0x14d2: 0x0040, 0x14d3: 0xaeea, 0x14d4: 0x03c2, 0x14d5: 0xaefa, 0x14d6: 0xaf0a, 0x14d7: 0x7d75,
- 0x14d8: 0x7d95, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040,
- 0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x1308, 0x14e1: 0x1308, 0x14e2: 0x1308, 0x14e3: 0x1308,
- 0x14e4: 0x1308, 0x14e5: 0x1308, 0x14e6: 0x1308, 0x14e7: 0x1308, 0x14e8: 0x1308, 0x14e9: 0x1308,
- 0x14ea: 0x1308, 0x14eb: 0x1308, 0x14ec: 0x1308, 0x14ed: 0x1308, 0x14ee: 0x1308, 0x14ef: 0x1308,
- 0x14f0: 0x0040, 0x14f1: 0x7db5, 0x14f2: 0x7dd5, 0x14f3: 0xaf1a, 0x14f4: 0xaf1a, 0x14f5: 0x1fd2,
- 0x14f6: 0x1fe2, 0x14f7: 0xaf2a, 0x14f8: 0xaf3a, 0x14f9: 0x7df5, 0x14fa: 0x7e15, 0x14fb: 0x7e35,
- 0x14fc: 0x7df5, 0x14fd: 0x7e55, 0x14fe: 0x7e75, 0x14ff: 0x7e55,
- // Block 0x54, offset 0x1500
- 0x1500: 0x7e95, 0x1501: 0x7eb5, 0x1502: 0x7ed5, 0x1503: 0x7eb5, 0x1504: 0x7ef5, 0x1505: 0x0018,
- 0x1506: 0x0018, 0x1507: 0xaf4a, 0x1508: 0xaf5a, 0x1509: 0x7f16, 0x150a: 0x7f36, 0x150b: 0x7f56,
- 0x150c: 0x7f76, 0x150d: 0xaf1a, 0x150e: 0xaf1a, 0x150f: 0xaf1a, 0x1510: 0xaeda, 0x1511: 0x7f95,
- 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x03c2, 0x1515: 0xaeea, 0x1516: 0xaf0a, 0x1517: 0xaefa,
- 0x1518: 0x7fb5, 0x1519: 0x1fd2, 0x151a: 0x1fe2, 0x151b: 0xaf2a, 0x151c: 0xaf3a, 0x151d: 0x7e95,
- 0x151e: 0x7ef5, 0x151f: 0xaf6a, 0x1520: 0xaf7a, 0x1521: 0xaf8a, 0x1522: 0x1fb2, 0x1523: 0xaf99,
- 0x1524: 0xafaa, 0x1525: 0xafba, 0x1526: 0x1fc2, 0x1527: 0x0040, 0x1528: 0xafca, 0x1529: 0xafda,
- 0x152a: 0xafea, 0x152b: 0xaffa, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,
- 0x1530: 0x7fd6, 0x1531: 0xb009, 0x1532: 0x7ff6, 0x1533: 0x0008, 0x1534: 0x8016, 0x1535: 0x0040,
- 0x1536: 0x8036, 0x1537: 0xb031, 0x1538: 0x8056, 0x1539: 0xb059, 0x153a: 0x8076, 0x153b: 0xb081,
- 0x153c: 0x8096, 0x153d: 0xb0a9, 0x153e: 0x80b6, 0x153f: 0xb0d1,
- // Block 0x55, offset 0x1540
- 0x1540: 0xb0f9, 0x1541: 0xb111, 0x1542: 0xb111, 0x1543: 0xb129, 0x1544: 0xb129, 0x1545: 0xb141,
- 0x1546: 0xb141, 0x1547: 0xb159, 0x1548: 0xb159, 0x1549: 0xb171, 0x154a: 0xb171, 0x154b: 0xb171,
- 0x154c: 0xb171, 0x154d: 0xb189, 0x154e: 0xb189, 0x154f: 0xb1a1, 0x1550: 0xb1a1, 0x1551: 0xb1a1,
- 0x1552: 0xb1a1, 0x1553: 0xb1b9, 0x1554: 0xb1b9, 0x1555: 0xb1d1, 0x1556: 0xb1d1, 0x1557: 0xb1d1,
- 0x1558: 0xb1d1, 0x1559: 0xb1e9, 0x155a: 0xb1e9, 0x155b: 0xb1e9, 0x155c: 0xb1e9, 0x155d: 0xb201,
- 0x155e: 0xb201, 0x155f: 0xb201, 0x1560: 0xb201, 0x1561: 0xb219, 0x1562: 0xb219, 0x1563: 0xb219,
- 0x1564: 0xb219, 0x1565: 0xb231, 0x1566: 0xb231, 0x1567: 0xb231, 0x1568: 0xb231, 0x1569: 0xb249,
- 0x156a: 0xb249, 0x156b: 0xb261, 0x156c: 0xb261, 0x156d: 0xb279, 0x156e: 0xb279, 0x156f: 0xb291,
- 0x1570: 0xb291, 0x1571: 0xb2a9, 0x1572: 0xb2a9, 0x1573: 0xb2a9, 0x1574: 0xb2a9, 0x1575: 0xb2c1,
- 0x1576: 0xb2c1, 0x1577: 0xb2c1, 0x1578: 0xb2c1, 0x1579: 0xb2d9, 0x157a: 0xb2d9, 0x157b: 0xb2d9,
- 0x157c: 0xb2d9, 0x157d: 0xb2f1, 0x157e: 0xb2f1, 0x157f: 0xb2f1,
- // Block 0x56, offset 0x1580
- 0x1580: 0xb2f1, 0x1581: 0xb309, 0x1582: 0xb309, 0x1583: 0xb309, 0x1584: 0xb309, 0x1585: 0xb321,
- 0x1586: 0xb321, 0x1587: 0xb321, 0x1588: 0xb321, 0x1589: 0xb339, 0x158a: 0xb339, 0x158b: 0xb339,
- 0x158c: 0xb339, 0x158d: 0xb351, 0x158e: 0xb351, 0x158f: 0xb351, 0x1590: 0xb351, 0x1591: 0xb369,
- 0x1592: 0xb369, 0x1593: 0xb369, 0x1594: 0xb369, 0x1595: 0xb381, 0x1596: 0xb381, 0x1597: 0xb381,
- 0x1598: 0xb381, 0x1599: 0xb399, 0x159a: 0xb399, 0x159b: 0xb399, 0x159c: 0xb399, 0x159d: 0xb3b1,
- 0x159e: 0xb3b1, 0x159f: 0xb3b1, 0x15a0: 0xb3b1, 0x15a1: 0xb3c9, 0x15a2: 0xb3c9, 0x15a3: 0xb3c9,
- 0x15a4: 0xb3c9, 0x15a5: 0xb3e1, 0x15a6: 0xb3e1, 0x15a7: 0xb3e1, 0x15a8: 0xb3e1, 0x15a9: 0xb3f9,
- 0x15aa: 0xb3f9, 0x15ab: 0xb3f9, 0x15ac: 0xb3f9, 0x15ad: 0xb411, 0x15ae: 0xb411, 0x15af: 0x7ab1,
- 0x15b0: 0x7ab1, 0x15b1: 0xb429, 0x15b2: 0xb429, 0x15b3: 0xb429, 0x15b4: 0xb429, 0x15b5: 0xb441,
- 0x15b6: 0xb441, 0x15b7: 0xb469, 0x15b8: 0xb469, 0x15b9: 0xb491, 0x15ba: 0xb491, 0x15bb: 0xb4b9,
- 0x15bc: 0xb4b9, 0x15bd: 0x0040, 0x15be: 0x0040, 0x15bf: 0x03c0,
- // Block 0x57, offset 0x15c0
- 0x15c0: 0x0040, 0x15c1: 0xaefa, 0x15c2: 0xb4e2, 0x15c3: 0xaf6a, 0x15c4: 0xafda, 0x15c5: 0xafea,
- 0x15c6: 0xaf7a, 0x15c7: 0xb4f2, 0x15c8: 0x1fd2, 0x15c9: 0x1fe2, 0x15ca: 0xaf8a, 0x15cb: 0x1fb2,
- 0x15cc: 0xaeda, 0x15cd: 0xaf99, 0x15ce: 0x29d1, 0x15cf: 0xb502, 0x15d0: 0x1f41, 0x15d1: 0x00c9,
- 0x15d2: 0x0069, 0x15d3: 0x0079, 0x15d4: 0x1f51, 0x15d5: 0x1f61, 0x15d6: 0x1f71, 0x15d7: 0x1f81,
- 0x15d8: 0x1f91, 0x15d9: 0x1fa1, 0x15da: 0xaeea, 0x15db: 0x03c2, 0x15dc: 0xafaa, 0x15dd: 0x1fc2,
- 0x15de: 0xafba, 0x15df: 0xaf0a, 0x15e0: 0xaffa, 0x15e1: 0x0039, 0x15e2: 0x0ee9, 0x15e3: 0x1159,
- 0x15e4: 0x0ef9, 0x15e5: 0x0f09, 0x15e6: 0x1199, 0x15e7: 0x0f31, 0x15e8: 0x0249, 0x15e9: 0x0f41,
- 0x15ea: 0x0259, 0x15eb: 0x0f51, 0x15ec: 0x0359, 0x15ed: 0x0f61, 0x15ee: 0x0f71, 0x15ef: 0x00d9,
- 0x15f0: 0x0f99, 0x15f1: 0x2039, 0x15f2: 0x0269, 0x15f3: 0x01d9, 0x15f4: 0x0fa9, 0x15f5: 0x0fb9,
- 0x15f6: 0x1089, 0x15f7: 0x0279, 0x15f8: 0x0369, 0x15f9: 0x0289, 0x15fa: 0x13d1, 0x15fb: 0xaf4a,
- 0x15fc: 0xafca, 0x15fd: 0xaf5a, 0x15fe: 0xb512, 0x15ff: 0xaf1a,
- // Block 0x58, offset 0x1600
- 0x1600: 0x1caa, 0x1601: 0x0039, 0x1602: 0x0ee9, 0x1603: 0x1159, 0x1604: 0x0ef9, 0x1605: 0x0f09,
- 0x1606: 0x1199, 0x1607: 0x0f31, 0x1608: 0x0249, 0x1609: 0x0f41, 0x160a: 0x0259, 0x160b: 0x0f51,
- 0x160c: 0x0359, 0x160d: 0x0f61, 0x160e: 0x0f71, 0x160f: 0x00d9, 0x1610: 0x0f99, 0x1611: 0x2039,
- 0x1612: 0x0269, 0x1613: 0x01d9, 0x1614: 0x0fa9, 0x1615: 0x0fb9, 0x1616: 0x1089, 0x1617: 0x0279,
- 0x1618: 0x0369, 0x1619: 0x0289, 0x161a: 0x13d1, 0x161b: 0xaf2a, 0x161c: 0xb522, 0x161d: 0xaf3a,
- 0x161e: 0xb532, 0x161f: 0x80d5, 0x1620: 0x80f5, 0x1621: 0x29d1, 0x1622: 0x8115, 0x1623: 0x8115,
- 0x1624: 0x8135, 0x1625: 0x8155, 0x1626: 0x8175, 0x1627: 0x8195, 0x1628: 0x81b5, 0x1629: 0x81d5,
- 0x162a: 0x81f5, 0x162b: 0x8215, 0x162c: 0x8235, 0x162d: 0x8255, 0x162e: 0x8275, 0x162f: 0x8295,
- 0x1630: 0x82b5, 0x1631: 0x82d5, 0x1632: 0x82f5, 0x1633: 0x8315, 0x1634: 0x8335, 0x1635: 0x8355,
- 0x1636: 0x8375, 0x1637: 0x8395, 0x1638: 0x83b5, 0x1639: 0x83d5, 0x163a: 0x83f5, 0x163b: 0x8415,
- 0x163c: 0x81b5, 0x163d: 0x8435, 0x163e: 0x8455, 0x163f: 0x8215,
- // Block 0x59, offset 0x1640
- 0x1640: 0x8475, 0x1641: 0x8495, 0x1642: 0x84b5, 0x1643: 0x84d5, 0x1644: 0x84f5, 0x1645: 0x8515,
- 0x1646: 0x8535, 0x1647: 0x8555, 0x1648: 0x84d5, 0x1649: 0x8575, 0x164a: 0x84d5, 0x164b: 0x8595,
- 0x164c: 0x8595, 0x164d: 0x85b5, 0x164e: 0x85b5, 0x164f: 0x85d5, 0x1650: 0x8515, 0x1651: 0x85f5,
- 0x1652: 0x8615, 0x1653: 0x85f5, 0x1654: 0x8635, 0x1655: 0x8615, 0x1656: 0x8655, 0x1657: 0x8655,
- 0x1658: 0x8675, 0x1659: 0x8675, 0x165a: 0x8695, 0x165b: 0x8695, 0x165c: 0x8615, 0x165d: 0x8115,
- 0x165e: 0x86b5, 0x165f: 0x86d5, 0x1660: 0x0040, 0x1661: 0x86f5, 0x1662: 0x8715, 0x1663: 0x8735,
- 0x1664: 0x8755, 0x1665: 0x8735, 0x1666: 0x8775, 0x1667: 0x8795, 0x1668: 0x87b5, 0x1669: 0x87b5,
- 0x166a: 0x87d5, 0x166b: 0x87d5, 0x166c: 0x87f5, 0x166d: 0x87f5, 0x166e: 0x87d5, 0x166f: 0x87d5,
- 0x1670: 0x8815, 0x1671: 0x8835, 0x1672: 0x8855, 0x1673: 0x8875, 0x1674: 0x8895, 0x1675: 0x88b5,
- 0x1676: 0x88b5, 0x1677: 0x88b5, 0x1678: 0x88d5, 0x1679: 0x88d5, 0x167a: 0x88d5, 0x167b: 0x88d5,
- 0x167c: 0x87b5, 0x167d: 0x87b5, 0x167e: 0x87b5, 0x167f: 0x0040,
- // Block 0x5a, offset 0x1680
- 0x1680: 0x0040, 0x1681: 0x0040, 0x1682: 0x8715, 0x1683: 0x86f5, 0x1684: 0x88f5, 0x1685: 0x86f5,
- 0x1686: 0x8715, 0x1687: 0x86f5, 0x1688: 0x0040, 0x1689: 0x0040, 0x168a: 0x8915, 0x168b: 0x8715,
- 0x168c: 0x8935, 0x168d: 0x88f5, 0x168e: 0x8935, 0x168f: 0x8715, 0x1690: 0x0040, 0x1691: 0x0040,
- 0x1692: 0x8955, 0x1693: 0x8975, 0x1694: 0x8875, 0x1695: 0x8935, 0x1696: 0x88f5, 0x1697: 0x8935,
- 0x1698: 0x0040, 0x1699: 0x0040, 0x169a: 0x8995, 0x169b: 0x89b5, 0x169c: 0x8995, 0x169d: 0x0040,
- 0x169e: 0x0040, 0x169f: 0x0040, 0x16a0: 0xb541, 0x16a1: 0xb559, 0x16a2: 0xb571, 0x16a3: 0x89d6,
- 0x16a4: 0xb589, 0x16a5: 0xb5a1, 0x16a6: 0x89f5, 0x16a7: 0x0040, 0x16a8: 0x8a15, 0x16a9: 0x8a35,
- 0x16aa: 0x8a55, 0x16ab: 0x8a35, 0x16ac: 0x8a75, 0x16ad: 0x8a95, 0x16ae: 0x8ab5, 0x16af: 0x0040,
- 0x16b0: 0x0040, 0x16b1: 0x0040, 0x16b2: 0x0040, 0x16b3: 0x0040, 0x16b4: 0x0040, 0x16b5: 0x0040,
- 0x16b6: 0x0040, 0x16b7: 0x0040, 0x16b8: 0x0040, 0x16b9: 0x0340, 0x16ba: 0x0340, 0x16bb: 0x0340,
- 0x16bc: 0x0040, 0x16bd: 0x0040, 0x16be: 0x0040, 0x16bf: 0x0040,
- // Block 0x5b, offset 0x16c0
- 0x16c0: 0x0208, 0x16c1: 0x0208, 0x16c2: 0x0208, 0x16c3: 0x0208, 0x16c4: 0x0208, 0x16c5: 0x0408,
- 0x16c6: 0x0008, 0x16c7: 0x0408, 0x16c8: 0x0018, 0x16c9: 0x0408, 0x16ca: 0x0408, 0x16cb: 0x0008,
- 0x16cc: 0x0008, 0x16cd: 0x0108, 0x16ce: 0x0408, 0x16cf: 0x0408, 0x16d0: 0x0408, 0x16d1: 0x0408,
- 0x16d2: 0x0408, 0x16d3: 0x0208, 0x16d4: 0x0208, 0x16d5: 0x0208, 0x16d6: 0x0208, 0x16d7: 0x0108,
- 0x16d8: 0x0208, 0x16d9: 0x0208, 0x16da: 0x0208, 0x16db: 0x0208, 0x16dc: 0x0208, 0x16dd: 0x0408,
- 0x16de: 0x0208, 0x16df: 0x0208, 0x16e0: 0x0208, 0x16e1: 0x0408, 0x16e2: 0x0008, 0x16e3: 0x0008,
- 0x16e4: 0x0408, 0x16e5: 0x1308, 0x16e6: 0x1308, 0x16e7: 0x0040, 0x16e8: 0x0040, 0x16e9: 0x0040,
- 0x16ea: 0x0040, 0x16eb: 0x0218, 0x16ec: 0x0218, 0x16ed: 0x0218, 0x16ee: 0x0218, 0x16ef: 0x0418,
- 0x16f0: 0x0018, 0x16f1: 0x0018, 0x16f2: 0x0018, 0x16f3: 0x0018, 0x16f4: 0x0018, 0x16f5: 0x0018,
- 0x16f6: 0x0018, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0040, 0x16fa: 0x0040, 0x16fb: 0x0040,
- 0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040,
- // Block 0x5c, offset 0x1700
- 0x1700: 0x0208, 0x1701: 0x0408, 0x1702: 0x0208, 0x1703: 0x0408, 0x1704: 0x0408, 0x1705: 0x0408,
- 0x1706: 0x0208, 0x1707: 0x0208, 0x1708: 0x0208, 0x1709: 0x0408, 0x170a: 0x0208, 0x170b: 0x0208,
- 0x170c: 0x0408, 0x170d: 0x0208, 0x170e: 0x0408, 0x170f: 0x0408, 0x1710: 0x0208, 0x1711: 0x0408,
- 0x1712: 0x0040, 0x1713: 0x0040, 0x1714: 0x0040, 0x1715: 0x0040, 0x1716: 0x0040, 0x1717: 0x0040,
- 0x1718: 0x0040, 0x1719: 0x0018, 0x171a: 0x0018, 0x171b: 0x0018, 0x171c: 0x0018, 0x171d: 0x0040,
- 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0x0040, 0x1721: 0x0040, 0x1722: 0x0040, 0x1723: 0x0040,
- 0x1724: 0x0040, 0x1725: 0x0040, 0x1726: 0x0040, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0418,
- 0x172a: 0x0418, 0x172b: 0x0418, 0x172c: 0x0418, 0x172d: 0x0218, 0x172e: 0x0218, 0x172f: 0x0018,
- 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,
- 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040,
- 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,
- // Block 0x5d, offset 0x1740
- 0x1740: 0x1308, 0x1741: 0x1308, 0x1742: 0x1008, 0x1743: 0x1008, 0x1744: 0x0040, 0x1745: 0x0008,
- 0x1746: 0x0008, 0x1747: 0x0008, 0x1748: 0x0008, 0x1749: 0x0008, 0x174a: 0x0008, 0x174b: 0x0008,
- 0x174c: 0x0008, 0x174d: 0x0040, 0x174e: 0x0040, 0x174f: 0x0008, 0x1750: 0x0008, 0x1751: 0x0040,
- 0x1752: 0x0040, 0x1753: 0x0008, 0x1754: 0x0008, 0x1755: 0x0008, 0x1756: 0x0008, 0x1757: 0x0008,
- 0x1758: 0x0008, 0x1759: 0x0008, 0x175a: 0x0008, 0x175b: 0x0008, 0x175c: 0x0008, 0x175d: 0x0008,
- 0x175e: 0x0008, 0x175f: 0x0008, 0x1760: 0x0008, 0x1761: 0x0008, 0x1762: 0x0008, 0x1763: 0x0008,
- 0x1764: 0x0008, 0x1765: 0x0008, 0x1766: 0x0008, 0x1767: 0x0008, 0x1768: 0x0008, 0x1769: 0x0040,
- 0x176a: 0x0008, 0x176b: 0x0008, 0x176c: 0x0008, 0x176d: 0x0008, 0x176e: 0x0008, 0x176f: 0x0008,
- 0x1770: 0x0008, 0x1771: 0x0040, 0x1772: 0x0008, 0x1773: 0x0008, 0x1774: 0x0040, 0x1775: 0x0008,
- 0x1776: 0x0008, 0x1777: 0x0008, 0x1778: 0x0008, 0x1779: 0x0008, 0x177a: 0x0040, 0x177b: 0x0040,
- 0x177c: 0x1308, 0x177d: 0x0008, 0x177e: 0x1008, 0x177f: 0x1008,
- // Block 0x5e, offset 0x1780
- 0x1780: 0x1308, 0x1781: 0x1008, 0x1782: 0x1008, 0x1783: 0x1008, 0x1784: 0x1008, 0x1785: 0x0040,
- 0x1786: 0x0040, 0x1787: 0x1008, 0x1788: 0x1008, 0x1789: 0x0040, 0x178a: 0x0040, 0x178b: 0x1008,
- 0x178c: 0x1008, 0x178d: 0x1808, 0x178e: 0x0040, 0x178f: 0x0040, 0x1790: 0x0008, 0x1791: 0x0040,
- 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x1008,
- 0x1798: 0x0040, 0x1799: 0x0040, 0x179a: 0x0040, 0x179b: 0x0040, 0x179c: 0x0040, 0x179d: 0x0008,
- 0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x1008, 0x17a3: 0x1008,
- 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x1308, 0x17a7: 0x1308, 0x17a8: 0x1308, 0x17a9: 0x1308,
- 0x17aa: 0x1308, 0x17ab: 0x1308, 0x17ac: 0x1308, 0x17ad: 0x0040, 0x17ae: 0x0040, 0x17af: 0x0040,
- 0x17b0: 0x1308, 0x17b1: 0x1308, 0x17b2: 0x1308, 0x17b3: 0x1308, 0x17b4: 0x1308, 0x17b5: 0x0040,
- 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,
- 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,
- // Block 0x5f, offset 0x17c0
- 0x17c0: 0x0039, 0x17c1: 0x0ee9, 0x17c2: 0x1159, 0x17c3: 0x0ef9, 0x17c4: 0x0f09, 0x17c5: 0x1199,
- 0x17c6: 0x0f31, 0x17c7: 0x0249, 0x17c8: 0x0f41, 0x17c9: 0x0259, 0x17ca: 0x0f51, 0x17cb: 0x0359,
- 0x17cc: 0x0f61, 0x17cd: 0x0f71, 0x17ce: 0x00d9, 0x17cf: 0x0f99, 0x17d0: 0x2039, 0x17d1: 0x0269,
- 0x17d2: 0x01d9, 0x17d3: 0x0fa9, 0x17d4: 0x0fb9, 0x17d5: 0x1089, 0x17d6: 0x0279, 0x17d7: 0x0369,
- 0x17d8: 0x0289, 0x17d9: 0x13d1, 0x17da: 0x0039, 0x17db: 0x0ee9, 0x17dc: 0x1159, 0x17dd: 0x0ef9,
- 0x17de: 0x0f09, 0x17df: 0x1199, 0x17e0: 0x0f31, 0x17e1: 0x0249, 0x17e2: 0x0f41, 0x17e3: 0x0259,
- 0x17e4: 0x0f51, 0x17e5: 0x0359, 0x17e6: 0x0f61, 0x17e7: 0x0f71, 0x17e8: 0x00d9, 0x17e9: 0x0f99,
- 0x17ea: 0x2039, 0x17eb: 0x0269, 0x17ec: 0x01d9, 0x17ed: 0x0fa9, 0x17ee: 0x0fb9, 0x17ef: 0x1089,
- 0x17f0: 0x0279, 0x17f1: 0x0369, 0x17f2: 0x0289, 0x17f3: 0x13d1, 0x17f4: 0x0039, 0x17f5: 0x0ee9,
- 0x17f6: 0x1159, 0x17f7: 0x0ef9, 0x17f8: 0x0f09, 0x17f9: 0x1199, 0x17fa: 0x0f31, 0x17fb: 0x0249,
- 0x17fc: 0x0f41, 0x17fd: 0x0259, 0x17fe: 0x0f51, 0x17ff: 0x0359,
- // Block 0x60, offset 0x1800
- 0x1800: 0x0f61, 0x1801: 0x0f71, 0x1802: 0x00d9, 0x1803: 0x0f99, 0x1804: 0x2039, 0x1805: 0x0269,
- 0x1806: 0x01d9, 0x1807: 0x0fa9, 0x1808: 0x0fb9, 0x1809: 0x1089, 0x180a: 0x0279, 0x180b: 0x0369,
- 0x180c: 0x0289, 0x180d: 0x13d1, 0x180e: 0x0039, 0x180f: 0x0ee9, 0x1810: 0x1159, 0x1811: 0x0ef9,
- 0x1812: 0x0f09, 0x1813: 0x1199, 0x1814: 0x0f31, 0x1815: 0x0040, 0x1816: 0x0f41, 0x1817: 0x0259,
- 0x1818: 0x0f51, 0x1819: 0x0359, 0x181a: 0x0f61, 0x181b: 0x0f71, 0x181c: 0x00d9, 0x181d: 0x0f99,
- 0x181e: 0x2039, 0x181f: 0x0269, 0x1820: 0x01d9, 0x1821: 0x0fa9, 0x1822: 0x0fb9, 0x1823: 0x1089,
- 0x1824: 0x0279, 0x1825: 0x0369, 0x1826: 0x0289, 0x1827: 0x13d1, 0x1828: 0x0039, 0x1829: 0x0ee9,
- 0x182a: 0x1159, 0x182b: 0x0ef9, 0x182c: 0x0f09, 0x182d: 0x1199, 0x182e: 0x0f31, 0x182f: 0x0249,
- 0x1830: 0x0f41, 0x1831: 0x0259, 0x1832: 0x0f51, 0x1833: 0x0359, 0x1834: 0x0f61, 0x1835: 0x0f71,
- 0x1836: 0x00d9, 0x1837: 0x0f99, 0x1838: 0x2039, 0x1839: 0x0269, 0x183a: 0x01d9, 0x183b: 0x0fa9,
- 0x183c: 0x0fb9, 0x183d: 0x1089, 0x183e: 0x0279, 0x183f: 0x0369,
- // Block 0x61, offset 0x1840
- 0x1840: 0x0289, 0x1841: 0x13d1, 0x1842: 0x0039, 0x1843: 0x0ee9, 0x1844: 0x1159, 0x1845: 0x0ef9,
- 0x1846: 0x0f09, 0x1847: 0x1199, 0x1848: 0x0f31, 0x1849: 0x0249, 0x184a: 0x0f41, 0x184b: 0x0259,
- 0x184c: 0x0f51, 0x184d: 0x0359, 0x184e: 0x0f61, 0x184f: 0x0f71, 0x1850: 0x00d9, 0x1851: 0x0f99,
- 0x1852: 0x2039, 0x1853: 0x0269, 0x1854: 0x01d9, 0x1855: 0x0fa9, 0x1856: 0x0fb9, 0x1857: 0x1089,
- 0x1858: 0x0279, 0x1859: 0x0369, 0x185a: 0x0289, 0x185b: 0x13d1, 0x185c: 0x0039, 0x185d: 0x0040,
- 0x185e: 0x1159, 0x185f: 0x0ef9, 0x1860: 0x0040, 0x1861: 0x0040, 0x1862: 0x0f31, 0x1863: 0x0040,
- 0x1864: 0x0040, 0x1865: 0x0259, 0x1866: 0x0f51, 0x1867: 0x0040, 0x1868: 0x0040, 0x1869: 0x0f71,
- 0x186a: 0x00d9, 0x186b: 0x0f99, 0x186c: 0x2039, 0x186d: 0x0040, 0x186e: 0x01d9, 0x186f: 0x0fa9,
- 0x1870: 0x0fb9, 0x1871: 0x1089, 0x1872: 0x0279, 0x1873: 0x0369, 0x1874: 0x0289, 0x1875: 0x13d1,
- 0x1876: 0x0039, 0x1877: 0x0ee9, 0x1878: 0x1159, 0x1879: 0x0ef9, 0x187a: 0x0040, 0x187b: 0x1199,
- 0x187c: 0x0040, 0x187d: 0x0249, 0x187e: 0x0f41, 0x187f: 0x0259,
- // Block 0x62, offset 0x1880
- 0x1880: 0x0f51, 0x1881: 0x0359, 0x1882: 0x0f61, 0x1883: 0x0f71, 0x1884: 0x0040, 0x1885: 0x0f99,
- 0x1886: 0x2039, 0x1887: 0x0269, 0x1888: 0x01d9, 0x1889: 0x0fa9, 0x188a: 0x0fb9, 0x188b: 0x1089,
- 0x188c: 0x0279, 0x188d: 0x0369, 0x188e: 0x0289, 0x188f: 0x13d1, 0x1890: 0x0039, 0x1891: 0x0ee9,
- 0x1892: 0x1159, 0x1893: 0x0ef9, 0x1894: 0x0f09, 0x1895: 0x1199, 0x1896: 0x0f31, 0x1897: 0x0249,
- 0x1898: 0x0f41, 0x1899: 0x0259, 0x189a: 0x0f51, 0x189b: 0x0359, 0x189c: 0x0f61, 0x189d: 0x0f71,
- 0x189e: 0x00d9, 0x189f: 0x0f99, 0x18a0: 0x2039, 0x18a1: 0x0269, 0x18a2: 0x01d9, 0x18a3: 0x0fa9,
- 0x18a4: 0x0fb9, 0x18a5: 0x1089, 0x18a6: 0x0279, 0x18a7: 0x0369, 0x18a8: 0x0289, 0x18a9: 0x13d1,
- 0x18aa: 0x0039, 0x18ab: 0x0ee9, 0x18ac: 0x1159, 0x18ad: 0x0ef9, 0x18ae: 0x0f09, 0x18af: 0x1199,
- 0x18b0: 0x0f31, 0x18b1: 0x0249, 0x18b2: 0x0f41, 0x18b3: 0x0259, 0x18b4: 0x0f51, 0x18b5: 0x0359,
- 0x18b6: 0x0f61, 0x18b7: 0x0f71, 0x18b8: 0x00d9, 0x18b9: 0x0f99, 0x18ba: 0x2039, 0x18bb: 0x0269,
- 0x18bc: 0x01d9, 0x18bd: 0x0fa9, 0x18be: 0x0fb9, 0x18bf: 0x1089,
- // Block 0x63, offset 0x18c0
- 0x18c0: 0x0279, 0x18c1: 0x0369, 0x18c2: 0x0289, 0x18c3: 0x13d1, 0x18c4: 0x0039, 0x18c5: 0x0ee9,
- 0x18c6: 0x0040, 0x18c7: 0x0ef9, 0x18c8: 0x0f09, 0x18c9: 0x1199, 0x18ca: 0x0f31, 0x18cb: 0x0040,
- 0x18cc: 0x0040, 0x18cd: 0x0259, 0x18ce: 0x0f51, 0x18cf: 0x0359, 0x18d0: 0x0f61, 0x18d1: 0x0f71,
- 0x18d2: 0x00d9, 0x18d3: 0x0f99, 0x18d4: 0x2039, 0x18d5: 0x0040, 0x18d6: 0x01d9, 0x18d7: 0x0fa9,
- 0x18d8: 0x0fb9, 0x18d9: 0x1089, 0x18da: 0x0279, 0x18db: 0x0369, 0x18dc: 0x0289, 0x18dd: 0x0040,
- 0x18de: 0x0039, 0x18df: 0x0ee9, 0x18e0: 0x1159, 0x18e1: 0x0ef9, 0x18e2: 0x0f09, 0x18e3: 0x1199,
- 0x18e4: 0x0f31, 0x18e5: 0x0249, 0x18e6: 0x0f41, 0x18e7: 0x0259, 0x18e8: 0x0f51, 0x18e9: 0x0359,
- 0x18ea: 0x0f61, 0x18eb: 0x0f71, 0x18ec: 0x00d9, 0x18ed: 0x0f99, 0x18ee: 0x2039, 0x18ef: 0x0269,
- 0x18f0: 0x01d9, 0x18f1: 0x0fa9, 0x18f2: 0x0fb9, 0x18f3: 0x1089, 0x18f4: 0x0279, 0x18f5: 0x0369,
- 0x18f6: 0x0289, 0x18f7: 0x13d1, 0x18f8: 0x0039, 0x18f9: 0x0ee9, 0x18fa: 0x0040, 0x18fb: 0x0ef9,
- 0x18fc: 0x0f09, 0x18fd: 0x1199, 0x18fe: 0x0f31, 0x18ff: 0x0040,
- // Block 0x64, offset 0x1900
- 0x1900: 0x0f41, 0x1901: 0x0259, 0x1902: 0x0f51, 0x1903: 0x0359, 0x1904: 0x0f61, 0x1905: 0x0040,
- 0x1906: 0x00d9, 0x1907: 0x0040, 0x1908: 0x0040, 0x1909: 0x0040, 0x190a: 0x01d9, 0x190b: 0x0fa9,
- 0x190c: 0x0fb9, 0x190d: 0x1089, 0x190e: 0x0279, 0x190f: 0x0369, 0x1910: 0x0289, 0x1911: 0x0040,
- 0x1912: 0x0039, 0x1913: 0x0ee9, 0x1914: 0x1159, 0x1915: 0x0ef9, 0x1916: 0x0f09, 0x1917: 0x1199,
- 0x1918: 0x0f31, 0x1919: 0x0249, 0x191a: 0x0f41, 0x191b: 0x0259, 0x191c: 0x0f51, 0x191d: 0x0359,
- 0x191e: 0x0f61, 0x191f: 0x0f71, 0x1920: 0x00d9, 0x1921: 0x0f99, 0x1922: 0x2039, 0x1923: 0x0269,
- 0x1924: 0x01d9, 0x1925: 0x0fa9, 0x1926: 0x0fb9, 0x1927: 0x1089, 0x1928: 0x0279, 0x1929: 0x0369,
- 0x192a: 0x0289, 0x192b: 0x13d1, 0x192c: 0x0039, 0x192d: 0x0ee9, 0x192e: 0x1159, 0x192f: 0x0ef9,
- 0x1930: 0x0f09, 0x1931: 0x1199, 0x1932: 0x0f31, 0x1933: 0x0249, 0x1934: 0x0f41, 0x1935: 0x0259,
- 0x1936: 0x0f51, 0x1937: 0x0359, 0x1938: 0x0f61, 0x1939: 0x0f71, 0x193a: 0x00d9, 0x193b: 0x0f99,
- 0x193c: 0x2039, 0x193d: 0x0269, 0x193e: 0x01d9, 0x193f: 0x0fa9,
- // Block 0x65, offset 0x1940
- 0x1940: 0x0fb9, 0x1941: 0x1089, 0x1942: 0x0279, 0x1943: 0x0369, 0x1944: 0x0289, 0x1945: 0x13d1,
- 0x1946: 0x0039, 0x1947: 0x0ee9, 0x1948: 0x1159, 0x1949: 0x0ef9, 0x194a: 0x0f09, 0x194b: 0x1199,
- 0x194c: 0x0f31, 0x194d: 0x0249, 0x194e: 0x0f41, 0x194f: 0x0259, 0x1950: 0x0f51, 0x1951: 0x0359,
- 0x1952: 0x0f61, 0x1953: 0x0f71, 0x1954: 0x00d9, 0x1955: 0x0f99, 0x1956: 0x2039, 0x1957: 0x0269,
- 0x1958: 0x01d9, 0x1959: 0x0fa9, 0x195a: 0x0fb9, 0x195b: 0x1089, 0x195c: 0x0279, 0x195d: 0x0369,
- 0x195e: 0x0289, 0x195f: 0x13d1, 0x1960: 0x0039, 0x1961: 0x0ee9, 0x1962: 0x1159, 0x1963: 0x0ef9,
- 0x1964: 0x0f09, 0x1965: 0x1199, 0x1966: 0x0f31, 0x1967: 0x0249, 0x1968: 0x0f41, 0x1969: 0x0259,
- 0x196a: 0x0f51, 0x196b: 0x0359, 0x196c: 0x0f61, 0x196d: 0x0f71, 0x196e: 0x00d9, 0x196f: 0x0f99,
- 0x1970: 0x2039, 0x1971: 0x0269, 0x1972: 0x01d9, 0x1973: 0x0fa9, 0x1974: 0x0fb9, 0x1975: 0x1089,
- 0x1976: 0x0279, 0x1977: 0x0369, 0x1978: 0x0289, 0x1979: 0x13d1, 0x197a: 0x0039, 0x197b: 0x0ee9,
- 0x197c: 0x1159, 0x197d: 0x0ef9, 0x197e: 0x0f09, 0x197f: 0x1199,
- // Block 0x66, offset 0x1980
- 0x1980: 0x0f31, 0x1981: 0x0249, 0x1982: 0x0f41, 0x1983: 0x0259, 0x1984: 0x0f51, 0x1985: 0x0359,
- 0x1986: 0x0f61, 0x1987: 0x0f71, 0x1988: 0x00d9, 0x1989: 0x0f99, 0x198a: 0x2039, 0x198b: 0x0269,
- 0x198c: 0x01d9, 0x198d: 0x0fa9, 0x198e: 0x0fb9, 0x198f: 0x1089, 0x1990: 0x0279, 0x1991: 0x0369,
- 0x1992: 0x0289, 0x1993: 0x13d1, 0x1994: 0x0039, 0x1995: 0x0ee9, 0x1996: 0x1159, 0x1997: 0x0ef9,
- 0x1998: 0x0f09, 0x1999: 0x1199, 0x199a: 0x0f31, 0x199b: 0x0249, 0x199c: 0x0f41, 0x199d: 0x0259,
- 0x199e: 0x0f51, 0x199f: 0x0359, 0x19a0: 0x0f61, 0x19a1: 0x0f71, 0x19a2: 0x00d9, 0x19a3: 0x0f99,
- 0x19a4: 0x2039, 0x19a5: 0x0269, 0x19a6: 0x01d9, 0x19a7: 0x0fa9, 0x19a8: 0x0fb9, 0x19a9: 0x1089,
- 0x19aa: 0x0279, 0x19ab: 0x0369, 0x19ac: 0x0289, 0x19ad: 0x13d1, 0x19ae: 0x0039, 0x19af: 0x0ee9,
- 0x19b0: 0x1159, 0x19b1: 0x0ef9, 0x19b2: 0x0f09, 0x19b3: 0x1199, 0x19b4: 0x0f31, 0x19b5: 0x0249,
- 0x19b6: 0x0f41, 0x19b7: 0x0259, 0x19b8: 0x0f51, 0x19b9: 0x0359, 0x19ba: 0x0f61, 0x19bb: 0x0f71,
- 0x19bc: 0x00d9, 0x19bd: 0x0f99, 0x19be: 0x2039, 0x19bf: 0x0269,
- // Block 0x67, offset 0x19c0
- 0x19c0: 0x01d9, 0x19c1: 0x0fa9, 0x19c2: 0x0fb9, 0x19c3: 0x1089, 0x19c4: 0x0279, 0x19c5: 0x0369,
- 0x19c6: 0x0289, 0x19c7: 0x13d1, 0x19c8: 0x0039, 0x19c9: 0x0ee9, 0x19ca: 0x1159, 0x19cb: 0x0ef9,
- 0x19cc: 0x0f09, 0x19cd: 0x1199, 0x19ce: 0x0f31, 0x19cf: 0x0249, 0x19d0: 0x0f41, 0x19d1: 0x0259,
- 0x19d2: 0x0f51, 0x19d3: 0x0359, 0x19d4: 0x0f61, 0x19d5: 0x0f71, 0x19d6: 0x00d9, 0x19d7: 0x0f99,
- 0x19d8: 0x2039, 0x19d9: 0x0269, 0x19da: 0x01d9, 0x19db: 0x0fa9, 0x19dc: 0x0fb9, 0x19dd: 0x1089,
- 0x19de: 0x0279, 0x19df: 0x0369, 0x19e0: 0x0289, 0x19e1: 0x13d1, 0x19e2: 0x0039, 0x19e3: 0x0ee9,
- 0x19e4: 0x1159, 0x19e5: 0x0ef9, 0x19e6: 0x0f09, 0x19e7: 0x1199, 0x19e8: 0x0f31, 0x19e9: 0x0249,
- 0x19ea: 0x0f41, 0x19eb: 0x0259, 0x19ec: 0x0f51, 0x19ed: 0x0359, 0x19ee: 0x0f61, 0x19ef: 0x0f71,
- 0x19f0: 0x00d9, 0x19f1: 0x0f99, 0x19f2: 0x2039, 0x19f3: 0x0269, 0x19f4: 0x01d9, 0x19f5: 0x0fa9,
- 0x19f6: 0x0fb9, 0x19f7: 0x1089, 0x19f8: 0x0279, 0x19f9: 0x0369, 0x19fa: 0x0289, 0x19fb: 0x13d1,
- 0x19fc: 0x0039, 0x19fd: 0x0ee9, 0x19fe: 0x1159, 0x19ff: 0x0ef9,
- // Block 0x68, offset 0x1a00
- 0x1a00: 0x0f09, 0x1a01: 0x1199, 0x1a02: 0x0f31, 0x1a03: 0x0249, 0x1a04: 0x0f41, 0x1a05: 0x0259,
- 0x1a06: 0x0f51, 0x1a07: 0x0359, 0x1a08: 0x0f61, 0x1a09: 0x0f71, 0x1a0a: 0x00d9, 0x1a0b: 0x0f99,
- 0x1a0c: 0x2039, 0x1a0d: 0x0269, 0x1a0e: 0x01d9, 0x1a0f: 0x0fa9, 0x1a10: 0x0fb9, 0x1a11: 0x1089,
- 0x1a12: 0x0279, 0x1a13: 0x0369, 0x1a14: 0x0289, 0x1a15: 0x13d1, 0x1a16: 0x0039, 0x1a17: 0x0ee9,
- 0x1a18: 0x1159, 0x1a19: 0x0ef9, 0x1a1a: 0x0f09, 0x1a1b: 0x1199, 0x1a1c: 0x0f31, 0x1a1d: 0x0249,
- 0x1a1e: 0x0f41, 0x1a1f: 0x0259, 0x1a20: 0x0f51, 0x1a21: 0x0359, 0x1a22: 0x0f61, 0x1a23: 0x0f71,
- 0x1a24: 0x00d9, 0x1a25: 0x0f99, 0x1a26: 0x2039, 0x1a27: 0x0269, 0x1a28: 0x01d9, 0x1a29: 0x0fa9,
- 0x1a2a: 0x0fb9, 0x1a2b: 0x1089, 0x1a2c: 0x0279, 0x1a2d: 0x0369, 0x1a2e: 0x0289, 0x1a2f: 0x13d1,
- 0x1a30: 0x0039, 0x1a31: 0x0ee9, 0x1a32: 0x1159, 0x1a33: 0x0ef9, 0x1a34: 0x0f09, 0x1a35: 0x1199,
- 0x1a36: 0x0f31, 0x1a37: 0x0249, 0x1a38: 0x0f41, 0x1a39: 0x0259, 0x1a3a: 0x0f51, 0x1a3b: 0x0359,
- 0x1a3c: 0x0f61, 0x1a3d: 0x0f71, 0x1a3e: 0x00d9, 0x1a3f: 0x0f99,
- // Block 0x69, offset 0x1a40
- 0x1a40: 0x2039, 0x1a41: 0x0269, 0x1a42: 0x01d9, 0x1a43: 0x0fa9, 0x1a44: 0x0fb9, 0x1a45: 0x1089,
- 0x1a46: 0x0279, 0x1a47: 0x0369, 0x1a48: 0x0289, 0x1a49: 0x13d1, 0x1a4a: 0x0039, 0x1a4b: 0x0ee9,
- 0x1a4c: 0x1159, 0x1a4d: 0x0ef9, 0x1a4e: 0x0f09, 0x1a4f: 0x1199, 0x1a50: 0x0f31, 0x1a51: 0x0249,
- 0x1a52: 0x0f41, 0x1a53: 0x0259, 0x1a54: 0x0f51, 0x1a55: 0x0359, 0x1a56: 0x0f61, 0x1a57: 0x0f71,
- 0x1a58: 0x00d9, 0x1a59: 0x0f99, 0x1a5a: 0x2039, 0x1a5b: 0x0269, 0x1a5c: 0x01d9, 0x1a5d: 0x0fa9,
- 0x1a5e: 0x0fb9, 0x1a5f: 0x1089, 0x1a60: 0x0279, 0x1a61: 0x0369, 0x1a62: 0x0289, 0x1a63: 0x13d1,
- 0x1a64: 0xba81, 0x1a65: 0xba99, 0x1a66: 0x0040, 0x1a67: 0x0040, 0x1a68: 0xbab1, 0x1a69: 0x1099,
- 0x1a6a: 0x10b1, 0x1a6b: 0x10c9, 0x1a6c: 0xbac9, 0x1a6d: 0xbae1, 0x1a6e: 0xbaf9, 0x1a6f: 0x1429,
- 0x1a70: 0x1a31, 0x1a71: 0xbb11, 0x1a72: 0xbb29, 0x1a73: 0xbb41, 0x1a74: 0xbb59, 0x1a75: 0xbb71,
- 0x1a76: 0xbb89, 0x1a77: 0x2109, 0x1a78: 0x1111, 0x1a79: 0x1429, 0x1a7a: 0xbba1, 0x1a7b: 0xbbb9,
- 0x1a7c: 0xbbd1, 0x1a7d: 0x10e1, 0x1a7e: 0x10f9, 0x1a7f: 0xbbe9,
- // Block 0x6a, offset 0x1a80
- 0x1a80: 0x2079, 0x1a81: 0xbc01, 0x1a82: 0xbab1, 0x1a83: 0x1099, 0x1a84: 0x10b1, 0x1a85: 0x10c9,
- 0x1a86: 0xbac9, 0x1a87: 0xbae1, 0x1a88: 0xbaf9, 0x1a89: 0x1429, 0x1a8a: 0x1a31, 0x1a8b: 0xbb11,
- 0x1a8c: 0xbb29, 0x1a8d: 0xbb41, 0x1a8e: 0xbb59, 0x1a8f: 0xbb71, 0x1a90: 0xbb89, 0x1a91: 0x2109,
- 0x1a92: 0x1111, 0x1a93: 0xbba1, 0x1a94: 0xbba1, 0x1a95: 0xbbb9, 0x1a96: 0xbbd1, 0x1a97: 0x10e1,
- 0x1a98: 0x10f9, 0x1a99: 0xbbe9, 0x1a9a: 0x2079, 0x1a9b: 0xbc21, 0x1a9c: 0xbac9, 0x1a9d: 0x1429,
- 0x1a9e: 0xbb11, 0x1a9f: 0x10e1, 0x1aa0: 0x1111, 0x1aa1: 0x2109, 0x1aa2: 0xbab1, 0x1aa3: 0x1099,
- 0x1aa4: 0x10b1, 0x1aa5: 0x10c9, 0x1aa6: 0xbac9, 0x1aa7: 0xbae1, 0x1aa8: 0xbaf9, 0x1aa9: 0x1429,
- 0x1aaa: 0x1a31, 0x1aab: 0xbb11, 0x1aac: 0xbb29, 0x1aad: 0xbb41, 0x1aae: 0xbb59, 0x1aaf: 0xbb71,
- 0x1ab0: 0xbb89, 0x1ab1: 0x2109, 0x1ab2: 0x1111, 0x1ab3: 0x1429, 0x1ab4: 0xbba1, 0x1ab5: 0xbbb9,
- 0x1ab6: 0xbbd1, 0x1ab7: 0x10e1, 0x1ab8: 0x10f9, 0x1ab9: 0xbbe9, 0x1aba: 0x2079, 0x1abb: 0xbc01,
- 0x1abc: 0xbab1, 0x1abd: 0x1099, 0x1abe: 0x10b1, 0x1abf: 0x10c9,
- // Block 0x6b, offset 0x1ac0
- 0x1ac0: 0xbac9, 0x1ac1: 0xbae1, 0x1ac2: 0xbaf9, 0x1ac3: 0x1429, 0x1ac4: 0x1a31, 0x1ac5: 0xbb11,
- 0x1ac6: 0xbb29, 0x1ac7: 0xbb41, 0x1ac8: 0xbb59, 0x1ac9: 0xbb71, 0x1aca: 0xbb89, 0x1acb: 0x2109,
- 0x1acc: 0x1111, 0x1acd: 0xbba1, 0x1ace: 0xbba1, 0x1acf: 0xbbb9, 0x1ad0: 0xbbd1, 0x1ad1: 0x10e1,
- 0x1ad2: 0x10f9, 0x1ad3: 0xbbe9, 0x1ad4: 0x2079, 0x1ad5: 0xbc21, 0x1ad6: 0xbac9, 0x1ad7: 0x1429,
- 0x1ad8: 0xbb11, 0x1ad9: 0x10e1, 0x1ada: 0x1111, 0x1adb: 0x2109, 0x1adc: 0xbab1, 0x1add: 0x1099,
- 0x1ade: 0x10b1, 0x1adf: 0x10c9, 0x1ae0: 0xbac9, 0x1ae1: 0xbae1, 0x1ae2: 0xbaf9, 0x1ae3: 0x1429,
- 0x1ae4: 0x1a31, 0x1ae5: 0xbb11, 0x1ae6: 0xbb29, 0x1ae7: 0xbb41, 0x1ae8: 0xbb59, 0x1ae9: 0xbb71,
- 0x1aea: 0xbb89, 0x1aeb: 0x2109, 0x1aec: 0x1111, 0x1aed: 0x1429, 0x1aee: 0xbba1, 0x1aef: 0xbbb9,
- 0x1af0: 0xbbd1, 0x1af1: 0x10e1, 0x1af2: 0x10f9, 0x1af3: 0xbbe9, 0x1af4: 0x2079, 0x1af5: 0xbc01,
- 0x1af6: 0xbab1, 0x1af7: 0x1099, 0x1af8: 0x10b1, 0x1af9: 0x10c9, 0x1afa: 0xbac9, 0x1afb: 0xbae1,
- 0x1afc: 0xbaf9, 0x1afd: 0x1429, 0x1afe: 0x1a31, 0x1aff: 0xbb11,
- // Block 0x6c, offset 0x1b00
- 0x1b00: 0xbb29, 0x1b01: 0xbb41, 0x1b02: 0xbb59, 0x1b03: 0xbb71, 0x1b04: 0xbb89, 0x1b05: 0x2109,
- 0x1b06: 0x1111, 0x1b07: 0xbba1, 0x1b08: 0xbba1, 0x1b09: 0xbbb9, 0x1b0a: 0xbbd1, 0x1b0b: 0x10e1,
- 0x1b0c: 0x10f9, 0x1b0d: 0xbbe9, 0x1b0e: 0x2079, 0x1b0f: 0xbc21, 0x1b10: 0xbac9, 0x1b11: 0x1429,
- 0x1b12: 0xbb11, 0x1b13: 0x10e1, 0x1b14: 0x1111, 0x1b15: 0x2109, 0x1b16: 0xbab1, 0x1b17: 0x1099,
- 0x1b18: 0x10b1, 0x1b19: 0x10c9, 0x1b1a: 0xbac9, 0x1b1b: 0xbae1, 0x1b1c: 0xbaf9, 0x1b1d: 0x1429,
- 0x1b1e: 0x1a31, 0x1b1f: 0xbb11, 0x1b20: 0xbb29, 0x1b21: 0xbb41, 0x1b22: 0xbb59, 0x1b23: 0xbb71,
- 0x1b24: 0xbb89, 0x1b25: 0x2109, 0x1b26: 0x1111, 0x1b27: 0x1429, 0x1b28: 0xbba1, 0x1b29: 0xbbb9,
- 0x1b2a: 0xbbd1, 0x1b2b: 0x10e1, 0x1b2c: 0x10f9, 0x1b2d: 0xbbe9, 0x1b2e: 0x2079, 0x1b2f: 0xbc01,
- 0x1b30: 0xbab1, 0x1b31: 0x1099, 0x1b32: 0x10b1, 0x1b33: 0x10c9, 0x1b34: 0xbac9, 0x1b35: 0xbae1,
- 0x1b36: 0xbaf9, 0x1b37: 0x1429, 0x1b38: 0x1a31, 0x1b39: 0xbb11, 0x1b3a: 0xbb29, 0x1b3b: 0xbb41,
- 0x1b3c: 0xbb59, 0x1b3d: 0xbb71, 0x1b3e: 0xbb89, 0x1b3f: 0x2109,
- // Block 0x6d, offset 0x1b40
- 0x1b40: 0x1111, 0x1b41: 0xbba1, 0x1b42: 0xbba1, 0x1b43: 0xbbb9, 0x1b44: 0xbbd1, 0x1b45: 0x10e1,
- 0x1b46: 0x10f9, 0x1b47: 0xbbe9, 0x1b48: 0x2079, 0x1b49: 0xbc21, 0x1b4a: 0xbac9, 0x1b4b: 0x1429,
- 0x1b4c: 0xbb11, 0x1b4d: 0x10e1, 0x1b4e: 0x1111, 0x1b4f: 0x2109, 0x1b50: 0xbab1, 0x1b51: 0x1099,
- 0x1b52: 0x10b1, 0x1b53: 0x10c9, 0x1b54: 0xbac9, 0x1b55: 0xbae1, 0x1b56: 0xbaf9, 0x1b57: 0x1429,
- 0x1b58: 0x1a31, 0x1b59: 0xbb11, 0x1b5a: 0xbb29, 0x1b5b: 0xbb41, 0x1b5c: 0xbb59, 0x1b5d: 0xbb71,
- 0x1b5e: 0xbb89, 0x1b5f: 0x2109, 0x1b60: 0x1111, 0x1b61: 0x1429, 0x1b62: 0xbba1, 0x1b63: 0xbbb9,
- 0x1b64: 0xbbd1, 0x1b65: 0x10e1, 0x1b66: 0x10f9, 0x1b67: 0xbbe9, 0x1b68: 0x2079, 0x1b69: 0xbc01,
- 0x1b6a: 0xbab1, 0x1b6b: 0x1099, 0x1b6c: 0x10b1, 0x1b6d: 0x10c9, 0x1b6e: 0xbac9, 0x1b6f: 0xbae1,
- 0x1b70: 0xbaf9, 0x1b71: 0x1429, 0x1b72: 0x1a31, 0x1b73: 0xbb11, 0x1b74: 0xbb29, 0x1b75: 0xbb41,
- 0x1b76: 0xbb59, 0x1b77: 0xbb71, 0x1b78: 0xbb89, 0x1b79: 0x2109, 0x1b7a: 0x1111, 0x1b7b: 0xbba1,
- 0x1b7c: 0xbba1, 0x1b7d: 0xbbb9, 0x1b7e: 0xbbd1, 0x1b7f: 0x10e1,
- // Block 0x6e, offset 0x1b80
- 0x1b80: 0x10f9, 0x1b81: 0xbbe9, 0x1b82: 0x2079, 0x1b83: 0xbc21, 0x1b84: 0xbac9, 0x1b85: 0x1429,
- 0x1b86: 0xbb11, 0x1b87: 0x10e1, 0x1b88: 0x1111, 0x1b89: 0x2109, 0x1b8a: 0xbc41, 0x1b8b: 0xbc41,
- 0x1b8c: 0x0040, 0x1b8d: 0x0040, 0x1b8e: 0x1f41, 0x1b8f: 0x00c9, 0x1b90: 0x0069, 0x1b91: 0x0079,
- 0x1b92: 0x1f51, 0x1b93: 0x1f61, 0x1b94: 0x1f71, 0x1b95: 0x1f81, 0x1b96: 0x1f91, 0x1b97: 0x1fa1,
- 0x1b98: 0x1f41, 0x1b99: 0x00c9, 0x1b9a: 0x0069, 0x1b9b: 0x0079, 0x1b9c: 0x1f51, 0x1b9d: 0x1f61,
- 0x1b9e: 0x1f71, 0x1b9f: 0x1f81, 0x1ba0: 0x1f91, 0x1ba1: 0x1fa1, 0x1ba2: 0x1f41, 0x1ba3: 0x00c9,
- 0x1ba4: 0x0069, 0x1ba5: 0x0079, 0x1ba6: 0x1f51, 0x1ba7: 0x1f61, 0x1ba8: 0x1f71, 0x1ba9: 0x1f81,
- 0x1baa: 0x1f91, 0x1bab: 0x1fa1, 0x1bac: 0x1f41, 0x1bad: 0x00c9, 0x1bae: 0x0069, 0x1baf: 0x0079,
- 0x1bb0: 0x1f51, 0x1bb1: 0x1f61, 0x1bb2: 0x1f71, 0x1bb3: 0x1f81, 0x1bb4: 0x1f91, 0x1bb5: 0x1fa1,
- 0x1bb6: 0x1f41, 0x1bb7: 0x00c9, 0x1bb8: 0x0069, 0x1bb9: 0x0079, 0x1bba: 0x1f51, 0x1bbb: 0x1f61,
- 0x1bbc: 0x1f71, 0x1bbd: 0x1f81, 0x1bbe: 0x1f91, 0x1bbf: 0x1fa1,
- // Block 0x6f, offset 0x1bc0
- 0x1bc0: 0xe115, 0x1bc1: 0xe115, 0x1bc2: 0xe135, 0x1bc3: 0xe135, 0x1bc4: 0xe115, 0x1bc5: 0xe115,
- 0x1bc6: 0xe175, 0x1bc7: 0xe175, 0x1bc8: 0xe115, 0x1bc9: 0xe115, 0x1bca: 0xe135, 0x1bcb: 0xe135,
- 0x1bcc: 0xe115, 0x1bcd: 0xe115, 0x1bce: 0xe1f5, 0x1bcf: 0xe1f5, 0x1bd0: 0xe115, 0x1bd1: 0xe115,
- 0x1bd2: 0xe135, 0x1bd3: 0xe135, 0x1bd4: 0xe115, 0x1bd5: 0xe115, 0x1bd6: 0xe175, 0x1bd7: 0xe175,
- 0x1bd8: 0xe115, 0x1bd9: 0xe115, 0x1bda: 0xe135, 0x1bdb: 0xe135, 0x1bdc: 0xe115, 0x1bdd: 0xe115,
- 0x1bde: 0x8b05, 0x1bdf: 0x8b05, 0x1be0: 0x04b5, 0x1be1: 0x04b5, 0x1be2: 0x0208, 0x1be3: 0x0208,
- 0x1be4: 0x0208, 0x1be5: 0x0208, 0x1be6: 0x0208, 0x1be7: 0x0208, 0x1be8: 0x0208, 0x1be9: 0x0208,
- 0x1bea: 0x0208, 0x1beb: 0x0208, 0x1bec: 0x0208, 0x1bed: 0x0208, 0x1bee: 0x0208, 0x1bef: 0x0208,
- 0x1bf0: 0x0208, 0x1bf1: 0x0208, 0x1bf2: 0x0208, 0x1bf3: 0x0208, 0x1bf4: 0x0208, 0x1bf5: 0x0208,
- 0x1bf6: 0x0208, 0x1bf7: 0x0208, 0x1bf8: 0x0208, 0x1bf9: 0x0208, 0x1bfa: 0x0208, 0x1bfb: 0x0208,
- 0x1bfc: 0x0208, 0x1bfd: 0x0208, 0x1bfe: 0x0208, 0x1bff: 0x0208,
- // Block 0x70, offset 0x1c00
- 0x1c00: 0xb189, 0x1c01: 0xb1a1, 0x1c02: 0xb201, 0x1c03: 0xb249, 0x1c04: 0x0040, 0x1c05: 0xb411,
- 0x1c06: 0xb291, 0x1c07: 0xb219, 0x1c08: 0xb309, 0x1c09: 0xb429, 0x1c0a: 0xb399, 0x1c0b: 0xb3b1,
- 0x1c0c: 0xb3c9, 0x1c0d: 0xb3e1, 0x1c0e: 0xb2a9, 0x1c0f: 0xb339, 0x1c10: 0xb369, 0x1c11: 0xb2d9,
- 0x1c12: 0xb381, 0x1c13: 0xb279, 0x1c14: 0xb2c1, 0x1c15: 0xb1d1, 0x1c16: 0xb1e9, 0x1c17: 0xb231,
- 0x1c18: 0xb261, 0x1c19: 0xb2f1, 0x1c1a: 0xb321, 0x1c1b: 0xb351, 0x1c1c: 0xbc59, 0x1c1d: 0x7949,
- 0x1c1e: 0xbc71, 0x1c1f: 0xbc89, 0x1c20: 0x0040, 0x1c21: 0xb1a1, 0x1c22: 0xb201, 0x1c23: 0x0040,
- 0x1c24: 0xb3f9, 0x1c25: 0x0040, 0x1c26: 0x0040, 0x1c27: 0xb219, 0x1c28: 0x0040, 0x1c29: 0xb429,
- 0x1c2a: 0xb399, 0x1c2b: 0xb3b1, 0x1c2c: 0xb3c9, 0x1c2d: 0xb3e1, 0x1c2e: 0xb2a9, 0x1c2f: 0xb339,
- 0x1c30: 0xb369, 0x1c31: 0xb2d9, 0x1c32: 0xb381, 0x1c33: 0x0040, 0x1c34: 0xb2c1, 0x1c35: 0xb1d1,
- 0x1c36: 0xb1e9, 0x1c37: 0xb231, 0x1c38: 0x0040, 0x1c39: 0xb2f1, 0x1c3a: 0x0040, 0x1c3b: 0xb351,
- 0x1c3c: 0x0040, 0x1c3d: 0x0040, 0x1c3e: 0x0040, 0x1c3f: 0x0040,
- // Block 0x71, offset 0x1c40
- 0x1c40: 0x0040, 0x1c41: 0x0040, 0x1c42: 0xb201, 0x1c43: 0x0040, 0x1c44: 0x0040, 0x1c45: 0x0040,
- 0x1c46: 0x0040, 0x1c47: 0xb219, 0x1c48: 0x0040, 0x1c49: 0xb429, 0x1c4a: 0x0040, 0x1c4b: 0xb3b1,
- 0x1c4c: 0x0040, 0x1c4d: 0xb3e1, 0x1c4e: 0xb2a9, 0x1c4f: 0xb339, 0x1c50: 0x0040, 0x1c51: 0xb2d9,
- 0x1c52: 0xb381, 0x1c53: 0x0040, 0x1c54: 0xb2c1, 0x1c55: 0x0040, 0x1c56: 0x0040, 0x1c57: 0xb231,
- 0x1c58: 0x0040, 0x1c59: 0xb2f1, 0x1c5a: 0x0040, 0x1c5b: 0xb351, 0x1c5c: 0x0040, 0x1c5d: 0x7949,
- 0x1c5e: 0x0040, 0x1c5f: 0xbc89, 0x1c60: 0x0040, 0x1c61: 0xb1a1, 0x1c62: 0xb201, 0x1c63: 0x0040,
- 0x1c64: 0xb3f9, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0xb219, 0x1c68: 0xb309, 0x1c69: 0xb429,
- 0x1c6a: 0xb399, 0x1c6b: 0x0040, 0x1c6c: 0xb3c9, 0x1c6d: 0xb3e1, 0x1c6e: 0xb2a9, 0x1c6f: 0xb339,
- 0x1c70: 0xb369, 0x1c71: 0xb2d9, 0x1c72: 0xb381, 0x1c73: 0x0040, 0x1c74: 0xb2c1, 0x1c75: 0xb1d1,
- 0x1c76: 0xb1e9, 0x1c77: 0xb231, 0x1c78: 0x0040, 0x1c79: 0xb2f1, 0x1c7a: 0xb321, 0x1c7b: 0xb351,
- 0x1c7c: 0xbc59, 0x1c7d: 0x0040, 0x1c7e: 0xbc71, 0x1c7f: 0x0040,
- // Block 0x72, offset 0x1c80
- 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0xb3f9, 0x1c85: 0xb411,
- 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0x0040, 0x1c8b: 0xb3b1,
- 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9,
- 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231,
- 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0x0040, 0x1c9d: 0x0040,
- 0x1c9e: 0x0040, 0x1c9f: 0x0040, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0xb249,
- 0x1ca4: 0x0040, 0x1ca5: 0xb411, 0x1ca6: 0xb291, 0x1ca7: 0xb219, 0x1ca8: 0xb309, 0x1ca9: 0xb429,
- 0x1caa: 0x0040, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,
- 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0xb279, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,
- 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0xb261, 0x1cb9: 0xb2f1, 0x1cba: 0xb321, 0x1cbb: 0xb351,
- 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040,
- // Block 0x73, offset 0x1cc0
- 0x1cc0: 0x0040, 0x1cc1: 0xbca2, 0x1cc2: 0xbcba, 0x1cc3: 0xbcd2, 0x1cc4: 0xbcea, 0x1cc5: 0xbd02,
- 0x1cc6: 0xbd1a, 0x1cc7: 0xbd32, 0x1cc8: 0xbd4a, 0x1cc9: 0xbd62, 0x1cca: 0xbd7a, 0x1ccb: 0x0018,
- 0x1ccc: 0x0018, 0x1ccd: 0x0040, 0x1cce: 0x0040, 0x1ccf: 0x0040, 0x1cd0: 0xbd92, 0x1cd1: 0xbdb2,
- 0x1cd2: 0xbdd2, 0x1cd3: 0xbdf2, 0x1cd4: 0xbe12, 0x1cd5: 0xbe32, 0x1cd6: 0xbe52, 0x1cd7: 0xbe72,
- 0x1cd8: 0xbe92, 0x1cd9: 0xbeb2, 0x1cda: 0xbed2, 0x1cdb: 0xbef2, 0x1cdc: 0xbf12, 0x1cdd: 0xbf32,
- 0x1cde: 0xbf52, 0x1cdf: 0xbf72, 0x1ce0: 0xbf92, 0x1ce1: 0xbfb2, 0x1ce2: 0xbfd2, 0x1ce3: 0xbff2,
- 0x1ce4: 0xc012, 0x1ce5: 0xc032, 0x1ce6: 0xc052, 0x1ce7: 0xc072, 0x1ce8: 0xc092, 0x1ce9: 0xc0b2,
- 0x1cea: 0xc0d1, 0x1ceb: 0x1159, 0x1cec: 0x0269, 0x1ced: 0x6671, 0x1cee: 0xc111, 0x1cef: 0x0040,
- 0x1cf0: 0x0039, 0x1cf1: 0x0ee9, 0x1cf2: 0x1159, 0x1cf3: 0x0ef9, 0x1cf4: 0x0f09, 0x1cf5: 0x1199,
- 0x1cf6: 0x0f31, 0x1cf7: 0x0249, 0x1cf8: 0x0f41, 0x1cf9: 0x0259, 0x1cfa: 0x0f51, 0x1cfb: 0x0359,
- 0x1cfc: 0x0f61, 0x1cfd: 0x0f71, 0x1cfe: 0x00d9, 0x1cff: 0x0f99,
- // Block 0x74, offset 0x1d00
- 0x1d00: 0x2039, 0x1d01: 0x0269, 0x1d02: 0x01d9, 0x1d03: 0x0fa9, 0x1d04: 0x0fb9, 0x1d05: 0x1089,
- 0x1d06: 0x0279, 0x1d07: 0x0369, 0x1d08: 0x0289, 0x1d09: 0x13d1, 0x1d0a: 0xc129, 0x1d0b: 0x65b1,
- 0x1d0c: 0xc141, 0x1d0d: 0x1441, 0x1d0e: 0xc159, 0x1d0f: 0xc179, 0x1d10: 0x0018, 0x1d11: 0x0018,
- 0x1d12: 0x0018, 0x1d13: 0x0018, 0x1d14: 0x0018, 0x1d15: 0x0018, 0x1d16: 0x0018, 0x1d17: 0x0018,
- 0x1d18: 0x0018, 0x1d19: 0x0018, 0x1d1a: 0x0018, 0x1d1b: 0x0018, 0x1d1c: 0x0018, 0x1d1d: 0x0018,
- 0x1d1e: 0x0018, 0x1d1f: 0x0018, 0x1d20: 0x0018, 0x1d21: 0x0018, 0x1d22: 0x0018, 0x1d23: 0x0018,
- 0x1d24: 0x0018, 0x1d25: 0x0018, 0x1d26: 0x0018, 0x1d27: 0x0018, 0x1d28: 0x0018, 0x1d29: 0x0018,
- 0x1d2a: 0xc191, 0x1d2b: 0xc1a9, 0x1d2c: 0x0040, 0x1d2d: 0x0040, 0x1d2e: 0x0040, 0x1d2f: 0x0040,
- 0x1d30: 0x0018, 0x1d31: 0x0018, 0x1d32: 0x0018, 0x1d33: 0x0018, 0x1d34: 0x0018, 0x1d35: 0x0018,
- 0x1d36: 0x0018, 0x1d37: 0x0018, 0x1d38: 0x0018, 0x1d39: 0x0018, 0x1d3a: 0x0018, 0x1d3b: 0x0018,
- 0x1d3c: 0x0018, 0x1d3d: 0x0018, 0x1d3e: 0x0018, 0x1d3f: 0x0018,
- // Block 0x75, offset 0x1d40
- 0x1d40: 0xc1d9, 0x1d41: 0xc211, 0x1d42: 0xc249, 0x1d43: 0x0040, 0x1d44: 0x0040, 0x1d45: 0x0040,
- 0x1d46: 0x0040, 0x1d47: 0x0040, 0x1d48: 0x0040, 0x1d49: 0x0040, 0x1d4a: 0x0040, 0x1d4b: 0x0040,
- 0x1d4c: 0x0040, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xc269, 0x1d51: 0xc289,
- 0x1d52: 0xc2a9, 0x1d53: 0xc2c9, 0x1d54: 0xc2e9, 0x1d55: 0xc309, 0x1d56: 0xc329, 0x1d57: 0xc349,
- 0x1d58: 0xc369, 0x1d59: 0xc389, 0x1d5a: 0xc3a9, 0x1d5b: 0xc3c9, 0x1d5c: 0xc3e9, 0x1d5d: 0xc409,
- 0x1d5e: 0xc429, 0x1d5f: 0xc449, 0x1d60: 0xc469, 0x1d61: 0xc489, 0x1d62: 0xc4a9, 0x1d63: 0xc4c9,
- 0x1d64: 0xc4e9, 0x1d65: 0xc509, 0x1d66: 0xc529, 0x1d67: 0xc549, 0x1d68: 0xc569, 0x1d69: 0xc589,
- 0x1d6a: 0xc5a9, 0x1d6b: 0xc5c9, 0x1d6c: 0xc5e9, 0x1d6d: 0xc609, 0x1d6e: 0xc629, 0x1d6f: 0xc649,
- 0x1d70: 0xc669, 0x1d71: 0xc689, 0x1d72: 0xc6a9, 0x1d73: 0xc6c9, 0x1d74: 0xc6e9, 0x1d75: 0xc709,
- 0x1d76: 0xc729, 0x1d77: 0xc749, 0x1d78: 0xc769, 0x1d79: 0xc789, 0x1d7a: 0xc7a9, 0x1d7b: 0xc7c9,
- 0x1d7c: 0x0040, 0x1d7d: 0x0040, 0x1d7e: 0x0040, 0x1d7f: 0x0040,
- // Block 0x76, offset 0x1d80
- 0x1d80: 0xcaf9, 0x1d81: 0xcb19, 0x1d82: 0xcb39, 0x1d83: 0x8b1d, 0x1d84: 0xcb59, 0x1d85: 0xcb79,
- 0x1d86: 0xcb99, 0x1d87: 0xcbb9, 0x1d88: 0xcbd9, 0x1d89: 0xcbf9, 0x1d8a: 0xcc19, 0x1d8b: 0xcc39,
- 0x1d8c: 0xcc59, 0x1d8d: 0x8b3d, 0x1d8e: 0xcc79, 0x1d8f: 0xcc99, 0x1d90: 0xccb9, 0x1d91: 0xccd9,
- 0x1d92: 0x8b5d, 0x1d93: 0xccf9, 0x1d94: 0xcd19, 0x1d95: 0xc429, 0x1d96: 0x8b7d, 0x1d97: 0xcd39,
- 0x1d98: 0xcd59, 0x1d99: 0xcd79, 0x1d9a: 0xcd99, 0x1d9b: 0xcdb9, 0x1d9c: 0x8b9d, 0x1d9d: 0xcdd9,
- 0x1d9e: 0xcdf9, 0x1d9f: 0xce19, 0x1da0: 0xce39, 0x1da1: 0xce59, 0x1da2: 0xc789, 0x1da3: 0xce79,
- 0x1da4: 0xce99, 0x1da5: 0xceb9, 0x1da6: 0xced9, 0x1da7: 0xcef9, 0x1da8: 0xcf19, 0x1da9: 0xcf39,
- 0x1daa: 0xcf59, 0x1dab: 0xcf79, 0x1dac: 0xcf99, 0x1dad: 0xcfb9, 0x1dae: 0xcfd9, 0x1daf: 0xcff9,
- 0x1db0: 0xd019, 0x1db1: 0xd039, 0x1db2: 0xd039, 0x1db3: 0xd039, 0x1db4: 0x8bbd, 0x1db5: 0xd059,
- 0x1db6: 0xd079, 0x1db7: 0xd099, 0x1db8: 0x8bdd, 0x1db9: 0xd0b9, 0x1dba: 0xd0d9, 0x1dbb: 0xd0f9,
- 0x1dbc: 0xd119, 0x1dbd: 0xd139, 0x1dbe: 0xd159, 0x1dbf: 0xd179,
- // Block 0x77, offset 0x1dc0
- 0x1dc0: 0xd199, 0x1dc1: 0xd1b9, 0x1dc2: 0xd1d9, 0x1dc3: 0xd1f9, 0x1dc4: 0xd219, 0x1dc5: 0xd239,
- 0x1dc6: 0xd239, 0x1dc7: 0xd259, 0x1dc8: 0xd279, 0x1dc9: 0xd299, 0x1dca: 0xd2b9, 0x1dcb: 0xd2d9,
- 0x1dcc: 0xd2f9, 0x1dcd: 0xd319, 0x1dce: 0xd339, 0x1dcf: 0xd359, 0x1dd0: 0xd379, 0x1dd1: 0xd399,
- 0x1dd2: 0xd3b9, 0x1dd3: 0xd3d9, 0x1dd4: 0xd3f9, 0x1dd5: 0xd419, 0x1dd6: 0xd439, 0x1dd7: 0xd459,
- 0x1dd8: 0xd479, 0x1dd9: 0x8bfd, 0x1dda: 0xd499, 0x1ddb: 0xd4b9, 0x1ddc: 0xd4d9, 0x1ddd: 0xc309,
- 0x1dde: 0xd4f9, 0x1ddf: 0xd519, 0x1de0: 0x8c1d, 0x1de1: 0x8c3d, 0x1de2: 0xd539, 0x1de3: 0xd559,
- 0x1de4: 0xd579, 0x1de5: 0xd599, 0x1de6: 0xd5b9, 0x1de7: 0xd5d9, 0x1de8: 0x0040, 0x1de9: 0xd5f9,
- 0x1dea: 0xd619, 0x1deb: 0xd619, 0x1dec: 0x8c5d, 0x1ded: 0xd639, 0x1dee: 0xd659, 0x1def: 0xd679,
- 0x1df0: 0xd699, 0x1df1: 0x8c7d, 0x1df2: 0xd6b9, 0x1df3: 0xd6d9, 0x1df4: 0x0040, 0x1df5: 0xd6f9,
- 0x1df6: 0xd719, 0x1df7: 0xd739, 0x1df8: 0xd759, 0x1df9: 0xd779, 0x1dfa: 0xd799, 0x1dfb: 0x8c9d,
- 0x1dfc: 0xd7b9, 0x1dfd: 0x8cbd, 0x1dfe: 0xd7d9, 0x1dff: 0xd7f9,
- // Block 0x78, offset 0x1e00
- 0x1e00: 0xd819, 0x1e01: 0xd839, 0x1e02: 0xd859, 0x1e03: 0xd879, 0x1e04: 0xd899, 0x1e05: 0xd8b9,
- 0x1e06: 0xd8d9, 0x1e07: 0xd8f9, 0x1e08: 0xd919, 0x1e09: 0x8cdd, 0x1e0a: 0xd939, 0x1e0b: 0xd959,
- 0x1e0c: 0xd979, 0x1e0d: 0xd999, 0x1e0e: 0xd9b9, 0x1e0f: 0x8cfd, 0x1e10: 0xd9d9, 0x1e11: 0x8d1d,
- 0x1e12: 0x8d3d, 0x1e13: 0xd9f9, 0x1e14: 0xda19, 0x1e15: 0xda19, 0x1e16: 0xda39, 0x1e17: 0x8d5d,
- 0x1e18: 0x8d7d, 0x1e19: 0xda59, 0x1e1a: 0xda79, 0x1e1b: 0xda99, 0x1e1c: 0xdab9, 0x1e1d: 0xdad9,
- 0x1e1e: 0xdaf9, 0x1e1f: 0xdb19, 0x1e20: 0xdb39, 0x1e21: 0xdb59, 0x1e22: 0xdb79, 0x1e23: 0xdb99,
- 0x1e24: 0x8d9d, 0x1e25: 0xdbb9, 0x1e26: 0xdbd9, 0x1e27: 0xdbf9, 0x1e28: 0xdc19, 0x1e29: 0xdbf9,
- 0x1e2a: 0xdc39, 0x1e2b: 0xdc59, 0x1e2c: 0xdc79, 0x1e2d: 0xdc99, 0x1e2e: 0xdcb9, 0x1e2f: 0xdcd9,
- 0x1e30: 0xdcf9, 0x1e31: 0xdd19, 0x1e32: 0xdd39, 0x1e33: 0xdd59, 0x1e34: 0xdd79, 0x1e35: 0xdd99,
- 0x1e36: 0xddb9, 0x1e37: 0xddd9, 0x1e38: 0x8dbd, 0x1e39: 0xddf9, 0x1e3a: 0xde19, 0x1e3b: 0xde39,
- 0x1e3c: 0xde59, 0x1e3d: 0xde79, 0x1e3e: 0x8ddd, 0x1e3f: 0xde99,
- // Block 0x79, offset 0x1e40
- 0x1e40: 0xe599, 0x1e41: 0xe5b9, 0x1e42: 0xe5d9, 0x1e43: 0xe5f9, 0x1e44: 0xe619, 0x1e45: 0xe639,
- 0x1e46: 0x8efd, 0x1e47: 0xe659, 0x1e48: 0xe679, 0x1e49: 0xe699, 0x1e4a: 0xe6b9, 0x1e4b: 0xe6d9,
- 0x1e4c: 0xe6f9, 0x1e4d: 0x8f1d, 0x1e4e: 0xe719, 0x1e4f: 0xe739, 0x1e50: 0x8f3d, 0x1e51: 0x8f5d,
- 0x1e52: 0xe759, 0x1e53: 0xe779, 0x1e54: 0xe799, 0x1e55: 0xe7b9, 0x1e56: 0xe7d9, 0x1e57: 0xe7f9,
- 0x1e58: 0xe819, 0x1e59: 0xe839, 0x1e5a: 0xe859, 0x1e5b: 0x8f7d, 0x1e5c: 0xe879, 0x1e5d: 0x8f9d,
- 0x1e5e: 0xe899, 0x1e5f: 0x0040, 0x1e60: 0xe8b9, 0x1e61: 0xe8d9, 0x1e62: 0xe8f9, 0x1e63: 0x8fbd,
- 0x1e64: 0xe919, 0x1e65: 0xe939, 0x1e66: 0x8fdd, 0x1e67: 0x8ffd, 0x1e68: 0xe959, 0x1e69: 0xe979,
- 0x1e6a: 0xe999, 0x1e6b: 0xe9b9, 0x1e6c: 0xe9d9, 0x1e6d: 0xe9d9, 0x1e6e: 0xe9f9, 0x1e6f: 0xea19,
- 0x1e70: 0xea39, 0x1e71: 0xea59, 0x1e72: 0xea79, 0x1e73: 0xea99, 0x1e74: 0xeab9, 0x1e75: 0x901d,
- 0x1e76: 0xead9, 0x1e77: 0x903d, 0x1e78: 0xeaf9, 0x1e79: 0x905d, 0x1e7a: 0xeb19, 0x1e7b: 0x907d,
- 0x1e7c: 0x909d, 0x1e7d: 0x90bd, 0x1e7e: 0xeb39, 0x1e7f: 0xeb59,
- // Block 0x7a, offset 0x1e80
- 0x1e80: 0xeb79, 0x1e81: 0x90dd, 0x1e82: 0x90fd, 0x1e83: 0x911d, 0x1e84: 0x913d, 0x1e85: 0xeb99,
- 0x1e86: 0xebb9, 0x1e87: 0xebb9, 0x1e88: 0xebd9, 0x1e89: 0xebf9, 0x1e8a: 0xec19, 0x1e8b: 0xec39,
- 0x1e8c: 0xec59, 0x1e8d: 0x915d, 0x1e8e: 0xec79, 0x1e8f: 0xec99, 0x1e90: 0xecb9, 0x1e91: 0xecd9,
- 0x1e92: 0x917d, 0x1e93: 0xecf9, 0x1e94: 0x919d, 0x1e95: 0x91bd, 0x1e96: 0xed19, 0x1e97: 0xed39,
- 0x1e98: 0xed59, 0x1e99: 0xed79, 0x1e9a: 0xed99, 0x1e9b: 0xedb9, 0x1e9c: 0x91dd, 0x1e9d: 0x91fd,
- 0x1e9e: 0x921d, 0x1e9f: 0x0040, 0x1ea0: 0xedd9, 0x1ea1: 0x923d, 0x1ea2: 0xedf9, 0x1ea3: 0xee19,
- 0x1ea4: 0xee39, 0x1ea5: 0x925d, 0x1ea6: 0xee59, 0x1ea7: 0xee79, 0x1ea8: 0xee99, 0x1ea9: 0xeeb9,
- 0x1eaa: 0xeed9, 0x1eab: 0x927d, 0x1eac: 0xeef9, 0x1ead: 0xef19, 0x1eae: 0xef39, 0x1eaf: 0xef59,
- 0x1eb0: 0xef79, 0x1eb1: 0xef99, 0x1eb2: 0x929d, 0x1eb3: 0x92bd, 0x1eb4: 0xefb9, 0x1eb5: 0x92dd,
- 0x1eb6: 0xefd9, 0x1eb7: 0x92fd, 0x1eb8: 0xeff9, 0x1eb9: 0xf019, 0x1eba: 0xf039, 0x1ebb: 0x931d,
- 0x1ebc: 0x933d, 0x1ebd: 0xf059, 0x1ebe: 0x935d, 0x1ebf: 0xf079,
- // Block 0x7b, offset 0x1ec0
- 0x1ec0: 0xf6b9, 0x1ec1: 0xf6d9, 0x1ec2: 0xf6f9, 0x1ec3: 0xf719, 0x1ec4: 0xf739, 0x1ec5: 0x951d,
- 0x1ec6: 0xf759, 0x1ec7: 0xf779, 0x1ec8: 0xf799, 0x1ec9: 0xf7b9, 0x1eca: 0xf7d9, 0x1ecb: 0x953d,
- 0x1ecc: 0x955d, 0x1ecd: 0xf7f9, 0x1ece: 0xf819, 0x1ecf: 0xf839, 0x1ed0: 0xf859, 0x1ed1: 0xf879,
- 0x1ed2: 0xf899, 0x1ed3: 0x957d, 0x1ed4: 0xf8b9, 0x1ed5: 0xf8d9, 0x1ed6: 0xf8f9, 0x1ed7: 0xf919,
- 0x1ed8: 0x959d, 0x1ed9: 0x95bd, 0x1eda: 0xf939, 0x1edb: 0xf959, 0x1edc: 0xf979, 0x1edd: 0x95dd,
- 0x1ede: 0xf999, 0x1edf: 0xf9b9, 0x1ee0: 0x6815, 0x1ee1: 0x95fd, 0x1ee2: 0xf9d9, 0x1ee3: 0xf9f9,
- 0x1ee4: 0xfa19, 0x1ee5: 0x961d, 0x1ee6: 0xfa39, 0x1ee7: 0xfa59, 0x1ee8: 0xfa79, 0x1ee9: 0xfa99,
- 0x1eea: 0xfab9, 0x1eeb: 0xfad9, 0x1eec: 0xfaf9, 0x1eed: 0x963d, 0x1eee: 0xfb19, 0x1eef: 0xfb39,
- 0x1ef0: 0xfb59, 0x1ef1: 0x965d, 0x1ef2: 0xfb79, 0x1ef3: 0xfb99, 0x1ef4: 0xfbb9, 0x1ef5: 0xfbd9,
- 0x1ef6: 0x7b35, 0x1ef7: 0x967d, 0x1ef8: 0xfbf9, 0x1ef9: 0xfc19, 0x1efa: 0xfc39, 0x1efb: 0x969d,
- 0x1efc: 0xfc59, 0x1efd: 0x96bd, 0x1efe: 0xfc79, 0x1eff: 0xfc79,
- // Block 0x7c, offset 0x1f00
- 0x1f00: 0xfc99, 0x1f01: 0x96dd, 0x1f02: 0xfcb9, 0x1f03: 0xfcd9, 0x1f04: 0xfcf9, 0x1f05: 0xfd19,
- 0x1f06: 0xfd39, 0x1f07: 0xfd59, 0x1f08: 0xfd79, 0x1f09: 0x96fd, 0x1f0a: 0xfd99, 0x1f0b: 0xfdb9,
- 0x1f0c: 0xfdd9, 0x1f0d: 0xfdf9, 0x1f0e: 0xfe19, 0x1f0f: 0xfe39, 0x1f10: 0x971d, 0x1f11: 0xfe59,
- 0x1f12: 0x973d, 0x1f13: 0x975d, 0x1f14: 0x977d, 0x1f15: 0xfe79, 0x1f16: 0xfe99, 0x1f17: 0xfeb9,
- 0x1f18: 0xfed9, 0x1f19: 0xfef9, 0x1f1a: 0xff19, 0x1f1b: 0xff39, 0x1f1c: 0xff59, 0x1f1d: 0x979d,
- 0x1f1e: 0x0040, 0x1f1f: 0x0040, 0x1f20: 0x0040, 0x1f21: 0x0040, 0x1f22: 0x0040, 0x1f23: 0x0040,
- 0x1f24: 0x0040, 0x1f25: 0x0040, 0x1f26: 0x0040, 0x1f27: 0x0040, 0x1f28: 0x0040, 0x1f29: 0x0040,
- 0x1f2a: 0x0040, 0x1f2b: 0x0040, 0x1f2c: 0x0040, 0x1f2d: 0x0040, 0x1f2e: 0x0040, 0x1f2f: 0x0040,
- 0x1f30: 0x0040, 0x1f31: 0x0040, 0x1f32: 0x0040, 0x1f33: 0x0040, 0x1f34: 0x0040, 0x1f35: 0x0040,
- 0x1f36: 0x0040, 0x1f37: 0x0040, 0x1f38: 0x0040, 0x1f39: 0x0040, 0x1f3a: 0x0040, 0x1f3b: 0x0040,
- 0x1f3c: 0x0040, 0x1f3d: 0x0040, 0x1f3e: 0x0040, 0x1f3f: 0x0040,
-}
-
-// idnaIndex: 35 blocks, 2240 entries, 4480 bytes
-// Block 0 is the zero block.
-var idnaIndex = [2240]uint16{
- // Block 0x0, offset 0x0
- // Block 0x1, offset 0x40
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc2: 0x01, 0xc3: 0x7b, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,
- 0xc8: 0x06, 0xc9: 0x7c, 0xca: 0x7d, 0xcb: 0x07, 0xcc: 0x7e, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,
- 0xd0: 0x7f, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x80, 0xd6: 0x81, 0xd7: 0x82,
- 0xd8: 0x0f, 0xd9: 0x83, 0xda: 0x84, 0xdb: 0x10, 0xdc: 0x11, 0xdd: 0x85, 0xde: 0x86, 0xdf: 0x87,
- 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,
- 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,
- 0xf0: 0x1c, 0xf1: 0x1d, 0xf2: 0x1d, 0xf3: 0x1f, 0xf4: 0x20,
- // Block 0x4, offset 0x100
- 0x120: 0x88, 0x121: 0x89, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x12, 0x126: 0x13, 0x127: 0x14,
- 0x128: 0x15, 0x129: 0x16, 0x12a: 0x17, 0x12b: 0x18, 0x12c: 0x19, 0x12d: 0x1a, 0x12e: 0x1b, 0x12f: 0x8d,
- 0x130: 0x8e, 0x131: 0x1c, 0x132: 0x1d, 0x133: 0x1e, 0x134: 0x8f, 0x135: 0x1f, 0x136: 0x90, 0x137: 0x91,
- 0x138: 0x92, 0x139: 0x93, 0x13a: 0x20, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x21, 0x13e: 0x22, 0x13f: 0x96,
- // Block 0x5, offset 0x140
- 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9b, 0x147: 0x9b,
- 0x148: 0x9d, 0x149: 0x9e, 0x14a: 0x9f, 0x14b: 0xa0, 0x14c: 0xa1, 0x14d: 0xa2, 0x14e: 0xa3, 0x14f: 0xa4,
- 0x150: 0xa5, 0x151: 0x9d, 0x152: 0x9d, 0x153: 0x9d, 0x154: 0x9d, 0x155: 0x9d, 0x156: 0x9d, 0x157: 0x9d,
- 0x158: 0x9d, 0x159: 0xa6, 0x15a: 0xa7, 0x15b: 0xa8, 0x15c: 0xa9, 0x15d: 0xaa, 0x15e: 0xab, 0x15f: 0xac,
- 0x160: 0xad, 0x161: 0xae, 0x162: 0xaf, 0x163: 0xb0, 0x164: 0xb1, 0x165: 0xb2, 0x166: 0xb3, 0x167: 0xb4,
- 0x168: 0xb5, 0x169: 0xb6, 0x16a: 0xb7, 0x16b: 0xb8, 0x16c: 0xb9, 0x16d: 0xba, 0x16e: 0xbb, 0x16f: 0xbc,
- 0x170: 0xbd, 0x171: 0xbe, 0x172: 0xbf, 0x173: 0xc0, 0x174: 0x23, 0x175: 0x24, 0x176: 0x25, 0x177: 0xc1,
- 0x178: 0x26, 0x179: 0x26, 0x17a: 0x27, 0x17b: 0x26, 0x17c: 0xc2, 0x17d: 0x28, 0x17e: 0x29, 0x17f: 0x2a,
- // Block 0x6, offset 0x180
- 0x180: 0x2b, 0x181: 0x2c, 0x182: 0x2d, 0x183: 0xc3, 0x184: 0x2e, 0x185: 0x2f, 0x186: 0xc4, 0x187: 0x9b,
- 0x188: 0xc5, 0x189: 0xc6, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc7, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0xc8,
- 0x190: 0xc9, 0x191: 0x30, 0x192: 0x31, 0x193: 0x32, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,
- 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,
- 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,
- 0x1a8: 0xca, 0x1a9: 0xcb, 0x1aa: 0x9b, 0x1ab: 0xcc, 0x1ac: 0x9b, 0x1ad: 0xcd, 0x1ae: 0xce, 0x1af: 0xcf,
- 0x1b0: 0xd0, 0x1b1: 0x33, 0x1b2: 0x26, 0x1b3: 0x34, 0x1b4: 0xd1, 0x1b5: 0xd2, 0x1b6: 0xd3, 0x1b7: 0xd4,
- 0x1b8: 0xd5, 0x1b9: 0xd6, 0x1ba: 0xd7, 0x1bb: 0xd8, 0x1bc: 0xd9, 0x1bd: 0xda, 0x1be: 0xdb, 0x1bf: 0x35,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x36, 0x1c1: 0xdc, 0x1c2: 0xdd, 0x1c3: 0xde, 0x1c4: 0xdf, 0x1c5: 0x37, 0x1c6: 0x38, 0x1c7: 0xe0,
- 0x1c8: 0xe1, 0x1c9: 0x39, 0x1ca: 0x3a, 0x1cb: 0x3b, 0x1cc: 0x3c, 0x1cd: 0x3d, 0x1ce: 0x3e, 0x1cf: 0x3f,
- 0x1d0: 0x9d, 0x1d1: 0x9d, 0x1d2: 0x9d, 0x1d3: 0x9d, 0x1d4: 0x9d, 0x1d5: 0x9d, 0x1d6: 0x9d, 0x1d7: 0x9d,
- 0x1d8: 0x9d, 0x1d9: 0x9d, 0x1da: 0x9d, 0x1db: 0x9d, 0x1dc: 0x9d, 0x1dd: 0x9d, 0x1de: 0x9d, 0x1df: 0x9d,
- 0x1e0: 0x9d, 0x1e1: 0x9d, 0x1e2: 0x9d, 0x1e3: 0x9d, 0x1e4: 0x9d, 0x1e5: 0x9d, 0x1e6: 0x9d, 0x1e7: 0x9d,
- 0x1e8: 0x9d, 0x1e9: 0x9d, 0x1ea: 0x9d, 0x1eb: 0x9d, 0x1ec: 0x9d, 0x1ed: 0x9d, 0x1ee: 0x9d, 0x1ef: 0x9d,
- 0x1f0: 0x9d, 0x1f1: 0x9d, 0x1f2: 0x9d, 0x1f3: 0x9d, 0x1f4: 0x9d, 0x1f5: 0x9d, 0x1f6: 0x9d, 0x1f7: 0x9d,
- 0x1f8: 0x9d, 0x1f9: 0x9d, 0x1fa: 0x9d, 0x1fb: 0x9d, 0x1fc: 0x9d, 0x1fd: 0x9d, 0x1fe: 0x9d, 0x1ff: 0x9d,
- // Block 0x8, offset 0x200
- 0x200: 0x9d, 0x201: 0x9d, 0x202: 0x9d, 0x203: 0x9d, 0x204: 0x9d, 0x205: 0x9d, 0x206: 0x9d, 0x207: 0x9d,
- 0x208: 0x9d, 0x209: 0x9d, 0x20a: 0x9d, 0x20b: 0x9d, 0x20c: 0x9d, 0x20d: 0x9d, 0x20e: 0x9d, 0x20f: 0x9d,
- 0x210: 0x9d, 0x211: 0x9d, 0x212: 0x9d, 0x213: 0x9d, 0x214: 0x9d, 0x215: 0x9d, 0x216: 0x9d, 0x217: 0x9d,
- 0x218: 0x9d, 0x219: 0x9d, 0x21a: 0x9d, 0x21b: 0x9d, 0x21c: 0x9d, 0x21d: 0x9d, 0x21e: 0x9d, 0x21f: 0x9d,
- 0x220: 0x9d, 0x221: 0x9d, 0x222: 0x9d, 0x223: 0x9d, 0x224: 0x9d, 0x225: 0x9d, 0x226: 0x9d, 0x227: 0x9d,
- 0x228: 0x9d, 0x229: 0x9d, 0x22a: 0x9d, 0x22b: 0x9d, 0x22c: 0x9d, 0x22d: 0x9d, 0x22e: 0x9d, 0x22f: 0x9d,
- 0x230: 0x9d, 0x231: 0x9d, 0x232: 0x9d, 0x233: 0x9d, 0x234: 0x9d, 0x235: 0x9d, 0x236: 0xb0, 0x237: 0x9b,
- 0x238: 0x9d, 0x239: 0x9d, 0x23a: 0x9d, 0x23b: 0x9d, 0x23c: 0x9d, 0x23d: 0x9d, 0x23e: 0x9d, 0x23f: 0x9d,
- // Block 0x9, offset 0x240
- 0x240: 0x9d, 0x241: 0x9d, 0x242: 0x9d, 0x243: 0x9d, 0x244: 0x9d, 0x245: 0x9d, 0x246: 0x9d, 0x247: 0x9d,
- 0x248: 0x9d, 0x249: 0x9d, 0x24a: 0x9d, 0x24b: 0x9d, 0x24c: 0x9d, 0x24d: 0x9d, 0x24e: 0x9d, 0x24f: 0x9d,
- 0x250: 0x9d, 0x251: 0x9d, 0x252: 0x9d, 0x253: 0x9d, 0x254: 0x9d, 0x255: 0x9d, 0x256: 0x9d, 0x257: 0x9d,
- 0x258: 0x9d, 0x259: 0x9d, 0x25a: 0x9d, 0x25b: 0x9d, 0x25c: 0x9d, 0x25d: 0x9d, 0x25e: 0x9d, 0x25f: 0x9d,
- 0x260: 0x9d, 0x261: 0x9d, 0x262: 0x9d, 0x263: 0x9d, 0x264: 0x9d, 0x265: 0x9d, 0x266: 0x9d, 0x267: 0x9d,
- 0x268: 0x9d, 0x269: 0x9d, 0x26a: 0x9d, 0x26b: 0x9d, 0x26c: 0x9d, 0x26d: 0x9d, 0x26e: 0x9d, 0x26f: 0x9d,
- 0x270: 0x9d, 0x271: 0x9d, 0x272: 0x9d, 0x273: 0x9d, 0x274: 0x9d, 0x275: 0x9d, 0x276: 0x9d, 0x277: 0x9d,
- 0x278: 0x9d, 0x279: 0x9d, 0x27a: 0x9d, 0x27b: 0x9d, 0x27c: 0x9d, 0x27d: 0x9d, 0x27e: 0x9d, 0x27f: 0x9d,
- // Block 0xa, offset 0x280
- 0x280: 0x9d, 0x281: 0x9d, 0x282: 0x9d, 0x283: 0x9d, 0x284: 0x9d, 0x285: 0x9d, 0x286: 0x9d, 0x287: 0x9d,
- 0x288: 0x9d, 0x289: 0x9d, 0x28a: 0x9d, 0x28b: 0x9d, 0x28c: 0x9d, 0x28d: 0x9d, 0x28e: 0x9d, 0x28f: 0x9d,
- 0x290: 0x9d, 0x291: 0x9d, 0x292: 0x9d, 0x293: 0x9d, 0x294: 0x9d, 0x295: 0x9d, 0x296: 0x9d, 0x297: 0x9d,
- 0x298: 0x9d, 0x299: 0x9d, 0x29a: 0x9d, 0x29b: 0x9d, 0x29c: 0x9d, 0x29d: 0x9d, 0x29e: 0x9d, 0x29f: 0x9d,
- 0x2a0: 0x9d, 0x2a1: 0x9d, 0x2a2: 0x9d, 0x2a3: 0x9d, 0x2a4: 0x9d, 0x2a5: 0x9d, 0x2a6: 0x9d, 0x2a7: 0x9d,
- 0x2a8: 0x9d, 0x2a9: 0x9d, 0x2aa: 0x9d, 0x2ab: 0x9d, 0x2ac: 0x9d, 0x2ad: 0x9d, 0x2ae: 0x9d, 0x2af: 0x9d,
- 0x2b0: 0x9d, 0x2b1: 0x9d, 0x2b2: 0x9d, 0x2b3: 0x9d, 0x2b4: 0x9d, 0x2b5: 0x9d, 0x2b6: 0x9d, 0x2b7: 0x9d,
- 0x2b8: 0x9d, 0x2b9: 0x9d, 0x2ba: 0x9d, 0x2bb: 0x9d, 0x2bc: 0x9d, 0x2bd: 0x9d, 0x2be: 0x9d, 0x2bf: 0xe2,
- // Block 0xb, offset 0x2c0
- 0x2c0: 0x9d, 0x2c1: 0x9d, 0x2c2: 0x9d, 0x2c3: 0x9d, 0x2c4: 0x9d, 0x2c5: 0x9d, 0x2c6: 0x9d, 0x2c7: 0x9d,
- 0x2c8: 0x9d, 0x2c9: 0x9d, 0x2ca: 0x9d, 0x2cb: 0x9d, 0x2cc: 0x9d, 0x2cd: 0x9d, 0x2ce: 0x9d, 0x2cf: 0x9d,
- 0x2d0: 0x9d, 0x2d1: 0x9d, 0x2d2: 0xe3, 0x2d3: 0xe4, 0x2d4: 0x9d, 0x2d5: 0x9d, 0x2d6: 0x9d, 0x2d7: 0x9d,
- 0x2d8: 0xe5, 0x2d9: 0x40, 0x2da: 0x41, 0x2db: 0xe6, 0x2dc: 0x42, 0x2dd: 0x43, 0x2de: 0x44, 0x2df: 0xe7,
- 0x2e0: 0xe8, 0x2e1: 0xe9, 0x2e2: 0xea, 0x2e3: 0xeb, 0x2e4: 0xec, 0x2e5: 0xed, 0x2e6: 0xee, 0x2e7: 0xef,
- 0x2e8: 0xf0, 0x2e9: 0xf1, 0x2ea: 0xf2, 0x2eb: 0xf3, 0x2ec: 0xf4, 0x2ed: 0xf5, 0x2ee: 0xf6, 0x2ef: 0xf7,
- 0x2f0: 0x9d, 0x2f1: 0x9d, 0x2f2: 0x9d, 0x2f3: 0x9d, 0x2f4: 0x9d, 0x2f5: 0x9d, 0x2f6: 0x9d, 0x2f7: 0x9d,
- 0x2f8: 0x9d, 0x2f9: 0x9d, 0x2fa: 0x9d, 0x2fb: 0x9d, 0x2fc: 0x9d, 0x2fd: 0x9d, 0x2fe: 0x9d, 0x2ff: 0x9d,
- // Block 0xc, offset 0x300
- 0x300: 0x9d, 0x301: 0x9d, 0x302: 0x9d, 0x303: 0x9d, 0x304: 0x9d, 0x305: 0x9d, 0x306: 0x9d, 0x307: 0x9d,
- 0x308: 0x9d, 0x309: 0x9d, 0x30a: 0x9d, 0x30b: 0x9d, 0x30c: 0x9d, 0x30d: 0x9d, 0x30e: 0x9d, 0x30f: 0x9d,
- 0x310: 0x9d, 0x311: 0x9d, 0x312: 0x9d, 0x313: 0x9d, 0x314: 0x9d, 0x315: 0x9d, 0x316: 0x9d, 0x317: 0x9d,
- 0x318: 0x9d, 0x319: 0x9d, 0x31a: 0x9d, 0x31b: 0x9d, 0x31c: 0x9d, 0x31d: 0x9d, 0x31e: 0xf8, 0x31f: 0xf9,
- // Block 0xd, offset 0x340
- 0x340: 0xb8, 0x341: 0xb8, 0x342: 0xb8, 0x343: 0xb8, 0x344: 0xb8, 0x345: 0xb8, 0x346: 0xb8, 0x347: 0xb8,
- 0x348: 0xb8, 0x349: 0xb8, 0x34a: 0xb8, 0x34b: 0xb8, 0x34c: 0xb8, 0x34d: 0xb8, 0x34e: 0xb8, 0x34f: 0xb8,
- 0x350: 0xb8, 0x351: 0xb8, 0x352: 0xb8, 0x353: 0xb8, 0x354: 0xb8, 0x355: 0xb8, 0x356: 0xb8, 0x357: 0xb8,
- 0x358: 0xb8, 0x359: 0xb8, 0x35a: 0xb8, 0x35b: 0xb8, 0x35c: 0xb8, 0x35d: 0xb8, 0x35e: 0xb8, 0x35f: 0xb8,
- 0x360: 0xb8, 0x361: 0xb8, 0x362: 0xb8, 0x363: 0xb8, 0x364: 0xb8, 0x365: 0xb8, 0x366: 0xb8, 0x367: 0xb8,
- 0x368: 0xb8, 0x369: 0xb8, 0x36a: 0xb8, 0x36b: 0xb8, 0x36c: 0xb8, 0x36d: 0xb8, 0x36e: 0xb8, 0x36f: 0xb8,
- 0x370: 0xb8, 0x371: 0xb8, 0x372: 0xb8, 0x373: 0xb8, 0x374: 0xb8, 0x375: 0xb8, 0x376: 0xb8, 0x377: 0xb8,
- 0x378: 0xb8, 0x379: 0xb8, 0x37a: 0xb8, 0x37b: 0xb8, 0x37c: 0xb8, 0x37d: 0xb8, 0x37e: 0xb8, 0x37f: 0xb8,
- // Block 0xe, offset 0x380
- 0x380: 0xb8, 0x381: 0xb8, 0x382: 0xb8, 0x383: 0xb8, 0x384: 0xb8, 0x385: 0xb8, 0x386: 0xb8, 0x387: 0xb8,
- 0x388: 0xb8, 0x389: 0xb8, 0x38a: 0xb8, 0x38b: 0xb8, 0x38c: 0xb8, 0x38d: 0xb8, 0x38e: 0xb8, 0x38f: 0xb8,
- 0x390: 0xb8, 0x391: 0xb8, 0x392: 0xb8, 0x393: 0xb8, 0x394: 0xb8, 0x395: 0xb8, 0x396: 0xb8, 0x397: 0xb8,
- 0x398: 0xb8, 0x399: 0xb8, 0x39a: 0xb8, 0x39b: 0xb8, 0x39c: 0xb8, 0x39d: 0xb8, 0x39e: 0xb8, 0x39f: 0xb8,
- 0x3a0: 0xb8, 0x3a1: 0xb8, 0x3a2: 0xb8, 0x3a3: 0xb8, 0x3a4: 0xfa, 0x3a5: 0xfb, 0x3a6: 0xfc, 0x3a7: 0xfd,
- 0x3a8: 0x45, 0x3a9: 0xfe, 0x3aa: 0xff, 0x3ab: 0x46, 0x3ac: 0x47, 0x3ad: 0x48, 0x3ae: 0x49, 0x3af: 0x4a,
- 0x3b0: 0x100, 0x3b1: 0x4b, 0x3b2: 0x4c, 0x3b3: 0x4d, 0x3b4: 0x4e, 0x3b5: 0x4f, 0x3b6: 0x101, 0x3b7: 0x50,
- 0x3b8: 0x51, 0x3b9: 0x52, 0x3ba: 0x53, 0x3bb: 0x54, 0x3bc: 0x55, 0x3bd: 0x56, 0x3be: 0x57, 0x3bf: 0x58,
- // Block 0xf, offset 0x3c0
- 0x3c0: 0x102, 0x3c1: 0x103, 0x3c2: 0x9d, 0x3c3: 0x104, 0x3c4: 0x105, 0x3c5: 0x9b, 0x3c6: 0x106, 0x3c7: 0x107,
- 0x3c8: 0xb8, 0x3c9: 0xb8, 0x3ca: 0x108, 0x3cb: 0x109, 0x3cc: 0x10a, 0x3cd: 0x10b, 0x3ce: 0x10c, 0x3cf: 0x10d,
- 0x3d0: 0x10e, 0x3d1: 0x9d, 0x3d2: 0x10f, 0x3d3: 0x110, 0x3d4: 0x111, 0x3d5: 0x112, 0x3d6: 0xb8, 0x3d7: 0xb8,
- 0x3d8: 0x9d, 0x3d9: 0x9d, 0x3da: 0x9d, 0x3db: 0x9d, 0x3dc: 0x113, 0x3dd: 0x114, 0x3de: 0xb8, 0x3df: 0xb8,
- 0x3e0: 0x115, 0x3e1: 0x116, 0x3e2: 0x117, 0x3e3: 0x118, 0x3e4: 0x119, 0x3e5: 0xb8, 0x3e6: 0x11a, 0x3e7: 0x11b,
- 0x3e8: 0x11c, 0x3e9: 0x11d, 0x3ea: 0x11e, 0x3eb: 0x59, 0x3ec: 0x11f, 0x3ed: 0x120, 0x3ee: 0x5a, 0x3ef: 0xb8,
- 0x3f0: 0x9d, 0x3f1: 0x121, 0x3f2: 0x122, 0x3f3: 0x123, 0x3f4: 0xb8, 0x3f5: 0xb8, 0x3f6: 0xb8, 0x3f7: 0xb8,
- 0x3f8: 0xb8, 0x3f9: 0x124, 0x3fa: 0xb8, 0x3fb: 0xb8, 0x3fc: 0xb8, 0x3fd: 0xb8, 0x3fe: 0xb8, 0x3ff: 0xb8,
- // Block 0x10, offset 0x400
- 0x400: 0x125, 0x401: 0x126, 0x402: 0x127, 0x403: 0x128, 0x404: 0x129, 0x405: 0x12a, 0x406: 0x12b, 0x407: 0x12c,
- 0x408: 0x12d, 0x409: 0xb8, 0x40a: 0x12e, 0x40b: 0x12f, 0x40c: 0x5b, 0x40d: 0x5c, 0x40e: 0xb8, 0x40f: 0xb8,
- 0x410: 0x130, 0x411: 0x131, 0x412: 0x132, 0x413: 0x133, 0x414: 0xb8, 0x415: 0xb8, 0x416: 0x134, 0x417: 0x135,
- 0x418: 0x136, 0x419: 0x137, 0x41a: 0x138, 0x41b: 0x139, 0x41c: 0x13a, 0x41d: 0xb8, 0x41e: 0xb8, 0x41f: 0xb8,
- 0x420: 0xb8, 0x421: 0xb8, 0x422: 0x13b, 0x423: 0x13c, 0x424: 0xb8, 0x425: 0xb8, 0x426: 0xb8, 0x427: 0xb8,
- 0x428: 0xb8, 0x429: 0xb8, 0x42a: 0xb8, 0x42b: 0x13d, 0x42c: 0xb8, 0x42d: 0xb8, 0x42e: 0xb8, 0x42f: 0xb8,
- 0x430: 0x13e, 0x431: 0x13f, 0x432: 0x140, 0x433: 0xb8, 0x434: 0xb8, 0x435: 0xb8, 0x436: 0xb8, 0x437: 0xb8,
- 0x438: 0xb8, 0x439: 0xb8, 0x43a: 0xb8, 0x43b: 0xb8, 0x43c: 0xb8, 0x43d: 0xb8, 0x43e: 0xb8, 0x43f: 0xb8,
- // Block 0x11, offset 0x440
- 0x440: 0x9d, 0x441: 0x9d, 0x442: 0x9d, 0x443: 0x9d, 0x444: 0x9d, 0x445: 0x9d, 0x446: 0x9d, 0x447: 0x9d,
- 0x448: 0x9d, 0x449: 0x9d, 0x44a: 0x9d, 0x44b: 0x9d, 0x44c: 0x9d, 0x44d: 0x9d, 0x44e: 0x141, 0x44f: 0xb8,
- 0x450: 0x9b, 0x451: 0x142, 0x452: 0x9d, 0x453: 0x9d, 0x454: 0x9d, 0x455: 0x143, 0x456: 0xb8, 0x457: 0xb8,
- 0x458: 0xb8, 0x459: 0xb8, 0x45a: 0xb8, 0x45b: 0xb8, 0x45c: 0xb8, 0x45d: 0xb8, 0x45e: 0xb8, 0x45f: 0xb8,
- 0x460: 0xb8, 0x461: 0xb8, 0x462: 0xb8, 0x463: 0xb8, 0x464: 0xb8, 0x465: 0xb8, 0x466: 0xb8, 0x467: 0xb8,
- 0x468: 0xb8, 0x469: 0xb8, 0x46a: 0xb8, 0x46b: 0xb8, 0x46c: 0xb8, 0x46d: 0xb8, 0x46e: 0xb8, 0x46f: 0xb8,
- 0x470: 0xb8, 0x471: 0xb8, 0x472: 0xb8, 0x473: 0xb8, 0x474: 0xb8, 0x475: 0xb8, 0x476: 0xb8, 0x477: 0xb8,
- 0x478: 0xb8, 0x479: 0xb8, 0x47a: 0xb8, 0x47b: 0xb8, 0x47c: 0xb8, 0x47d: 0xb8, 0x47e: 0xb8, 0x47f: 0xb8,
- // Block 0x12, offset 0x480
- 0x480: 0x9d, 0x481: 0x9d, 0x482: 0x9d, 0x483: 0x9d, 0x484: 0x9d, 0x485: 0x9d, 0x486: 0x9d, 0x487: 0x9d,
- 0x488: 0x9d, 0x489: 0x9d, 0x48a: 0x9d, 0x48b: 0x9d, 0x48c: 0x9d, 0x48d: 0x9d, 0x48e: 0x9d, 0x48f: 0x9d,
- 0x490: 0x144, 0x491: 0xb8, 0x492: 0xb8, 0x493: 0xb8, 0x494: 0xb8, 0x495: 0xb8, 0x496: 0xb8, 0x497: 0xb8,
- 0x498: 0xb8, 0x499: 0xb8, 0x49a: 0xb8, 0x49b: 0xb8, 0x49c: 0xb8, 0x49d: 0xb8, 0x49e: 0xb8, 0x49f: 0xb8,
- 0x4a0: 0xb8, 0x4a1: 0xb8, 0x4a2: 0xb8, 0x4a3: 0xb8, 0x4a4: 0xb8, 0x4a5: 0xb8, 0x4a6: 0xb8, 0x4a7: 0xb8,
- 0x4a8: 0xb8, 0x4a9: 0xb8, 0x4aa: 0xb8, 0x4ab: 0xb8, 0x4ac: 0xb8, 0x4ad: 0xb8, 0x4ae: 0xb8, 0x4af: 0xb8,
- 0x4b0: 0xb8, 0x4b1: 0xb8, 0x4b2: 0xb8, 0x4b3: 0xb8, 0x4b4: 0xb8, 0x4b5: 0xb8, 0x4b6: 0xb8, 0x4b7: 0xb8,
- 0x4b8: 0xb8, 0x4b9: 0xb8, 0x4ba: 0xb8, 0x4bb: 0xb8, 0x4bc: 0xb8, 0x4bd: 0xb8, 0x4be: 0xb8, 0x4bf: 0xb8,
- // Block 0x13, offset 0x4c0
- 0x4c0: 0xb8, 0x4c1: 0xb8, 0x4c2: 0xb8, 0x4c3: 0xb8, 0x4c4: 0xb8, 0x4c5: 0xb8, 0x4c6: 0xb8, 0x4c7: 0xb8,
- 0x4c8: 0xb8, 0x4c9: 0xb8, 0x4ca: 0xb8, 0x4cb: 0xb8, 0x4cc: 0xb8, 0x4cd: 0xb8, 0x4ce: 0xb8, 0x4cf: 0xb8,
- 0x4d0: 0x9d, 0x4d1: 0x9d, 0x4d2: 0x9d, 0x4d3: 0x9d, 0x4d4: 0x9d, 0x4d5: 0x9d, 0x4d6: 0x9d, 0x4d7: 0x9d,
- 0x4d8: 0x9d, 0x4d9: 0x145, 0x4da: 0xb8, 0x4db: 0xb8, 0x4dc: 0xb8, 0x4dd: 0xb8, 0x4de: 0xb8, 0x4df: 0xb8,
- 0x4e0: 0xb8, 0x4e1: 0xb8, 0x4e2: 0xb8, 0x4e3: 0xb8, 0x4e4: 0xb8, 0x4e5: 0xb8, 0x4e6: 0xb8, 0x4e7: 0xb8,
- 0x4e8: 0xb8, 0x4e9: 0xb8, 0x4ea: 0xb8, 0x4eb: 0xb8, 0x4ec: 0xb8, 0x4ed: 0xb8, 0x4ee: 0xb8, 0x4ef: 0xb8,
- 0x4f0: 0xb8, 0x4f1: 0xb8, 0x4f2: 0xb8, 0x4f3: 0xb8, 0x4f4: 0xb8, 0x4f5: 0xb8, 0x4f6: 0xb8, 0x4f7: 0xb8,
- 0x4f8: 0xb8, 0x4f9: 0xb8, 0x4fa: 0xb8, 0x4fb: 0xb8, 0x4fc: 0xb8, 0x4fd: 0xb8, 0x4fe: 0xb8, 0x4ff: 0xb8,
- // Block 0x14, offset 0x500
- 0x500: 0xb8, 0x501: 0xb8, 0x502: 0xb8, 0x503: 0xb8, 0x504: 0xb8, 0x505: 0xb8, 0x506: 0xb8, 0x507: 0xb8,
- 0x508: 0xb8, 0x509: 0xb8, 0x50a: 0xb8, 0x50b: 0xb8, 0x50c: 0xb8, 0x50d: 0xb8, 0x50e: 0xb8, 0x50f: 0xb8,
- 0x510: 0xb8, 0x511: 0xb8, 0x512: 0xb8, 0x513: 0xb8, 0x514: 0xb8, 0x515: 0xb8, 0x516: 0xb8, 0x517: 0xb8,
- 0x518: 0xb8, 0x519: 0xb8, 0x51a: 0xb8, 0x51b: 0xb8, 0x51c: 0xb8, 0x51d: 0xb8, 0x51e: 0xb8, 0x51f: 0xb8,
- 0x520: 0x9d, 0x521: 0x9d, 0x522: 0x9d, 0x523: 0x9d, 0x524: 0x9d, 0x525: 0x9d, 0x526: 0x9d, 0x527: 0x9d,
- 0x528: 0x13d, 0x529: 0x146, 0x52a: 0xb8, 0x52b: 0x147, 0x52c: 0x148, 0x52d: 0x149, 0x52e: 0x14a, 0x52f: 0xb8,
- 0x530: 0xb8, 0x531: 0xb8, 0x532: 0xb8, 0x533: 0xb8, 0x534: 0xb8, 0x535: 0xb8, 0x536: 0xb8, 0x537: 0xb8,
- 0x538: 0xb8, 0x539: 0xb8, 0x53a: 0xb8, 0x53b: 0xb8, 0x53c: 0x9d, 0x53d: 0x14b, 0x53e: 0x14c, 0x53f: 0x14d,
- // Block 0x15, offset 0x540
- 0x540: 0x9d, 0x541: 0x9d, 0x542: 0x9d, 0x543: 0x9d, 0x544: 0x9d, 0x545: 0x9d, 0x546: 0x9d, 0x547: 0x9d,
- 0x548: 0x9d, 0x549: 0x9d, 0x54a: 0x9d, 0x54b: 0x9d, 0x54c: 0x9d, 0x54d: 0x9d, 0x54e: 0x9d, 0x54f: 0x9d,
- 0x550: 0x9d, 0x551: 0x9d, 0x552: 0x9d, 0x553: 0x9d, 0x554: 0x9d, 0x555: 0x9d, 0x556: 0x9d, 0x557: 0x9d,
- 0x558: 0x9d, 0x559: 0x9d, 0x55a: 0x9d, 0x55b: 0x9d, 0x55c: 0x9d, 0x55d: 0x9d, 0x55e: 0x9d, 0x55f: 0x14e,
- 0x560: 0x9d, 0x561: 0x9d, 0x562: 0x9d, 0x563: 0x9d, 0x564: 0x9d, 0x565: 0x9d, 0x566: 0x9d, 0x567: 0x9d,
- 0x568: 0x9d, 0x569: 0x9d, 0x56a: 0x9d, 0x56b: 0x14f, 0x56c: 0xb8, 0x56d: 0xb8, 0x56e: 0xb8, 0x56f: 0xb8,
- 0x570: 0xb8, 0x571: 0xb8, 0x572: 0xb8, 0x573: 0xb8, 0x574: 0xb8, 0x575: 0xb8, 0x576: 0xb8, 0x577: 0xb8,
- 0x578: 0xb8, 0x579: 0xb8, 0x57a: 0xb8, 0x57b: 0xb8, 0x57c: 0xb8, 0x57d: 0xb8, 0x57e: 0xb8, 0x57f: 0xb8,
- // Block 0x16, offset 0x580
- 0x580: 0x150, 0x581: 0xb8, 0x582: 0xb8, 0x583: 0xb8, 0x584: 0xb8, 0x585: 0xb8, 0x586: 0xb8, 0x587: 0xb8,
- 0x588: 0xb8, 0x589: 0xb8, 0x58a: 0xb8, 0x58b: 0xb8, 0x58c: 0xb8, 0x58d: 0xb8, 0x58e: 0xb8, 0x58f: 0xb8,
- 0x590: 0xb8, 0x591: 0xb8, 0x592: 0xb8, 0x593: 0xb8, 0x594: 0xb8, 0x595: 0xb8, 0x596: 0xb8, 0x597: 0xb8,
- 0x598: 0xb8, 0x599: 0xb8, 0x59a: 0xb8, 0x59b: 0xb8, 0x59c: 0xb8, 0x59d: 0xb8, 0x59e: 0xb8, 0x59f: 0xb8,
- 0x5a0: 0xb8, 0x5a1: 0xb8, 0x5a2: 0xb8, 0x5a3: 0xb8, 0x5a4: 0xb8, 0x5a5: 0xb8, 0x5a6: 0xb8, 0x5a7: 0xb8,
- 0x5a8: 0xb8, 0x5a9: 0xb8, 0x5aa: 0xb8, 0x5ab: 0xb8, 0x5ac: 0xb8, 0x5ad: 0xb8, 0x5ae: 0xb8, 0x5af: 0xb8,
- 0x5b0: 0x9d, 0x5b1: 0x151, 0x5b2: 0x152, 0x5b3: 0xb8, 0x5b4: 0xb8, 0x5b5: 0xb8, 0x5b6: 0xb8, 0x5b7: 0xb8,
- 0x5b8: 0xb8, 0x5b9: 0xb8, 0x5ba: 0xb8, 0x5bb: 0xb8, 0x5bc: 0xb8, 0x5bd: 0xb8, 0x5be: 0xb8, 0x5bf: 0xb8,
- // Block 0x17, offset 0x5c0
- 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x153, 0x5c4: 0x154, 0x5c5: 0x155, 0x5c6: 0x156, 0x5c7: 0x157,
- 0x5c8: 0x9b, 0x5c9: 0x158, 0x5ca: 0xb8, 0x5cb: 0xb8, 0x5cc: 0x9b, 0x5cd: 0x159, 0x5ce: 0xb8, 0x5cf: 0xb8,
- 0x5d0: 0x5d, 0x5d1: 0x5e, 0x5d2: 0x5f, 0x5d3: 0x60, 0x5d4: 0x61, 0x5d5: 0x62, 0x5d6: 0x63, 0x5d7: 0x64,
- 0x5d8: 0x65, 0x5d9: 0x66, 0x5da: 0x67, 0x5db: 0x68, 0x5dc: 0x69, 0x5dd: 0x6a, 0x5de: 0x6b, 0x5df: 0x6c,
- 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,
- 0x5e8: 0x15a, 0x5e9: 0x15b, 0x5ea: 0x15c, 0x5eb: 0xb8, 0x5ec: 0xb8, 0x5ed: 0xb8, 0x5ee: 0xb8, 0x5ef: 0xb8,
- 0x5f0: 0xb8, 0x5f1: 0xb8, 0x5f2: 0xb8, 0x5f3: 0xb8, 0x5f4: 0xb8, 0x5f5: 0xb8, 0x5f6: 0xb8, 0x5f7: 0xb8,
- 0x5f8: 0xb8, 0x5f9: 0xb8, 0x5fa: 0xb8, 0x5fb: 0xb8, 0x5fc: 0xb8, 0x5fd: 0xb8, 0x5fe: 0xb8, 0x5ff: 0xb8,
- // Block 0x18, offset 0x600
- 0x600: 0x15d, 0x601: 0xb8, 0x602: 0xb8, 0x603: 0xb8, 0x604: 0xb8, 0x605: 0xb8, 0x606: 0xb8, 0x607: 0xb8,
- 0x608: 0xb8, 0x609: 0xb8, 0x60a: 0xb8, 0x60b: 0xb8, 0x60c: 0xb8, 0x60d: 0xb8, 0x60e: 0xb8, 0x60f: 0xb8,
- 0x610: 0xb8, 0x611: 0xb8, 0x612: 0xb8, 0x613: 0xb8, 0x614: 0xb8, 0x615: 0xb8, 0x616: 0xb8, 0x617: 0xb8,
- 0x618: 0xb8, 0x619: 0xb8, 0x61a: 0xb8, 0x61b: 0xb8, 0x61c: 0xb8, 0x61d: 0xb8, 0x61e: 0xb8, 0x61f: 0xb8,
- 0x620: 0x9d, 0x621: 0x9d, 0x622: 0x9d, 0x623: 0x15e, 0x624: 0x6d, 0x625: 0x15f, 0x626: 0xb8, 0x627: 0xb8,
- 0x628: 0xb8, 0x629: 0xb8, 0x62a: 0xb8, 0x62b: 0xb8, 0x62c: 0xb8, 0x62d: 0xb8, 0x62e: 0xb8, 0x62f: 0xb8,
- 0x630: 0xb8, 0x631: 0xb8, 0x632: 0xb8, 0x633: 0xb8, 0x634: 0xb8, 0x635: 0xb8, 0x636: 0xb8, 0x637: 0xb8,
- 0x638: 0x6e, 0x639: 0x6f, 0x63a: 0x70, 0x63b: 0x160, 0x63c: 0xb8, 0x63d: 0xb8, 0x63e: 0xb8, 0x63f: 0xb8,
- // Block 0x19, offset 0x640
- 0x640: 0x161, 0x641: 0x9b, 0x642: 0x162, 0x643: 0x163, 0x644: 0x71, 0x645: 0x72, 0x646: 0x164, 0x647: 0x165,
- 0x648: 0x73, 0x649: 0x166, 0x64a: 0xb8, 0x64b: 0xb8, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,
- 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,
- 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x167, 0x65c: 0x9b, 0x65d: 0x168, 0x65e: 0x9b, 0x65f: 0x169,
- 0x660: 0x16a, 0x661: 0x16b, 0x662: 0x16c, 0x663: 0xb8, 0x664: 0x16d, 0x665: 0x16e, 0x666: 0x16f, 0x667: 0x170,
- 0x668: 0xb8, 0x669: 0xb8, 0x66a: 0xb8, 0x66b: 0xb8, 0x66c: 0xb8, 0x66d: 0xb8, 0x66e: 0xb8, 0x66f: 0xb8,
- 0x670: 0xb8, 0x671: 0xb8, 0x672: 0xb8, 0x673: 0xb8, 0x674: 0xb8, 0x675: 0xb8, 0x676: 0xb8, 0x677: 0xb8,
- 0x678: 0xb8, 0x679: 0xb8, 0x67a: 0xb8, 0x67b: 0xb8, 0x67c: 0xb8, 0x67d: 0xb8, 0x67e: 0xb8, 0x67f: 0xb8,
- // Block 0x1a, offset 0x680
- 0x680: 0x9d, 0x681: 0x9d, 0x682: 0x9d, 0x683: 0x9d, 0x684: 0x9d, 0x685: 0x9d, 0x686: 0x9d, 0x687: 0x9d,
- 0x688: 0x9d, 0x689: 0x9d, 0x68a: 0x9d, 0x68b: 0x9d, 0x68c: 0x9d, 0x68d: 0x9d, 0x68e: 0x9d, 0x68f: 0x9d,
- 0x690: 0x9d, 0x691: 0x9d, 0x692: 0x9d, 0x693: 0x9d, 0x694: 0x9d, 0x695: 0x9d, 0x696: 0x9d, 0x697: 0x9d,
- 0x698: 0x9d, 0x699: 0x9d, 0x69a: 0x9d, 0x69b: 0x171, 0x69c: 0x9d, 0x69d: 0x9d, 0x69e: 0x9d, 0x69f: 0x9d,
- 0x6a0: 0x9d, 0x6a1: 0x9d, 0x6a2: 0x9d, 0x6a3: 0x9d, 0x6a4: 0x9d, 0x6a5: 0x9d, 0x6a6: 0x9d, 0x6a7: 0x9d,
- 0x6a8: 0x9d, 0x6a9: 0x9d, 0x6aa: 0x9d, 0x6ab: 0x9d, 0x6ac: 0x9d, 0x6ad: 0x9d, 0x6ae: 0x9d, 0x6af: 0x9d,
- 0x6b0: 0x9d, 0x6b1: 0x9d, 0x6b2: 0x9d, 0x6b3: 0x9d, 0x6b4: 0x9d, 0x6b5: 0x9d, 0x6b6: 0x9d, 0x6b7: 0x9d,
- 0x6b8: 0x9d, 0x6b9: 0x9d, 0x6ba: 0x9d, 0x6bb: 0x9d, 0x6bc: 0x9d, 0x6bd: 0x9d, 0x6be: 0x9d, 0x6bf: 0x9d,
- // Block 0x1b, offset 0x6c0
- 0x6c0: 0x9d, 0x6c1: 0x9d, 0x6c2: 0x9d, 0x6c3: 0x9d, 0x6c4: 0x9d, 0x6c5: 0x9d, 0x6c6: 0x9d, 0x6c7: 0x9d,
- 0x6c8: 0x9d, 0x6c9: 0x9d, 0x6ca: 0x9d, 0x6cb: 0x9d, 0x6cc: 0x9d, 0x6cd: 0x9d, 0x6ce: 0x9d, 0x6cf: 0x9d,
- 0x6d0: 0x9d, 0x6d1: 0x9d, 0x6d2: 0x9d, 0x6d3: 0x9d, 0x6d4: 0x9d, 0x6d5: 0x9d, 0x6d6: 0x9d, 0x6d7: 0x9d,
- 0x6d8: 0x9d, 0x6d9: 0x9d, 0x6da: 0x9d, 0x6db: 0x9d, 0x6dc: 0x172, 0x6dd: 0x9d, 0x6de: 0x9d, 0x6df: 0x9d,
- 0x6e0: 0x173, 0x6e1: 0x9d, 0x6e2: 0x9d, 0x6e3: 0x9d, 0x6e4: 0x9d, 0x6e5: 0x9d, 0x6e6: 0x9d, 0x6e7: 0x9d,
- 0x6e8: 0x9d, 0x6e9: 0x9d, 0x6ea: 0x9d, 0x6eb: 0x9d, 0x6ec: 0x9d, 0x6ed: 0x9d, 0x6ee: 0x9d, 0x6ef: 0x9d,
- 0x6f0: 0x9d, 0x6f1: 0x9d, 0x6f2: 0x9d, 0x6f3: 0x9d, 0x6f4: 0x9d, 0x6f5: 0x9d, 0x6f6: 0x9d, 0x6f7: 0x9d,
- 0x6f8: 0x9d, 0x6f9: 0x9d, 0x6fa: 0x9d, 0x6fb: 0x9d, 0x6fc: 0x9d, 0x6fd: 0x9d, 0x6fe: 0x9d, 0x6ff: 0x9d,
- // Block 0x1c, offset 0x700
- 0x700: 0x9d, 0x701: 0x9d, 0x702: 0x9d, 0x703: 0x9d, 0x704: 0x9d, 0x705: 0x9d, 0x706: 0x9d, 0x707: 0x9d,
- 0x708: 0x9d, 0x709: 0x9d, 0x70a: 0x9d, 0x70b: 0x9d, 0x70c: 0x9d, 0x70d: 0x9d, 0x70e: 0x9d, 0x70f: 0x9d,
- 0x710: 0x9d, 0x711: 0x9d, 0x712: 0x9d, 0x713: 0x9d, 0x714: 0x9d, 0x715: 0x9d, 0x716: 0x9d, 0x717: 0x9d,
- 0x718: 0x9d, 0x719: 0x9d, 0x71a: 0x9d, 0x71b: 0x9d, 0x71c: 0x9d, 0x71d: 0x9d, 0x71e: 0x9d, 0x71f: 0x9d,
- 0x720: 0x9d, 0x721: 0x9d, 0x722: 0x9d, 0x723: 0x9d, 0x724: 0x9d, 0x725: 0x9d, 0x726: 0x9d, 0x727: 0x9d,
- 0x728: 0x9d, 0x729: 0x9d, 0x72a: 0x9d, 0x72b: 0x9d, 0x72c: 0x9d, 0x72d: 0x9d, 0x72e: 0x9d, 0x72f: 0x9d,
- 0x730: 0x9d, 0x731: 0x9d, 0x732: 0x9d, 0x733: 0x9d, 0x734: 0x9d, 0x735: 0x9d, 0x736: 0x9d, 0x737: 0x9d,
- 0x738: 0x9d, 0x739: 0x9d, 0x73a: 0x174, 0x73b: 0xb8, 0x73c: 0xb8, 0x73d: 0xb8, 0x73e: 0xb8, 0x73f: 0xb8,
- // Block 0x1d, offset 0x740
- 0x740: 0xb8, 0x741: 0xb8, 0x742: 0xb8, 0x743: 0xb8, 0x744: 0xb8, 0x745: 0xb8, 0x746: 0xb8, 0x747: 0xb8,
- 0x748: 0xb8, 0x749: 0xb8, 0x74a: 0xb8, 0x74b: 0xb8, 0x74c: 0xb8, 0x74d: 0xb8, 0x74e: 0xb8, 0x74f: 0xb8,
- 0x750: 0xb8, 0x751: 0xb8, 0x752: 0xb8, 0x753: 0xb8, 0x754: 0xb8, 0x755: 0xb8, 0x756: 0xb8, 0x757: 0xb8,
- 0x758: 0xb8, 0x759: 0xb8, 0x75a: 0xb8, 0x75b: 0xb8, 0x75c: 0xb8, 0x75d: 0xb8, 0x75e: 0xb8, 0x75f: 0xb8,
- 0x760: 0x74, 0x761: 0x75, 0x762: 0x76, 0x763: 0x175, 0x764: 0x77, 0x765: 0x78, 0x766: 0x176, 0x767: 0x79,
- 0x768: 0x7a, 0x769: 0xb8, 0x76a: 0xb8, 0x76b: 0xb8, 0x76c: 0xb8, 0x76d: 0xb8, 0x76e: 0xb8, 0x76f: 0xb8,
- 0x770: 0xb8, 0x771: 0xb8, 0x772: 0xb8, 0x773: 0xb8, 0x774: 0xb8, 0x775: 0xb8, 0x776: 0xb8, 0x777: 0xb8,
- 0x778: 0xb8, 0x779: 0xb8, 0x77a: 0xb8, 0x77b: 0xb8, 0x77c: 0xb8, 0x77d: 0xb8, 0x77e: 0xb8, 0x77f: 0xb8,
- // Block 0x1e, offset 0x780
- 0x790: 0x0d, 0x791: 0x0e, 0x792: 0x0f, 0x793: 0x10, 0x794: 0x11, 0x795: 0x0b, 0x796: 0x12, 0x797: 0x07,
- 0x798: 0x13, 0x799: 0x0b, 0x79a: 0x0b, 0x79b: 0x14, 0x79c: 0x0b, 0x79d: 0x15, 0x79e: 0x16, 0x79f: 0x17,
- 0x7a0: 0x07, 0x7a1: 0x07, 0x7a2: 0x07, 0x7a3: 0x07, 0x7a4: 0x07, 0x7a5: 0x07, 0x7a6: 0x07, 0x7a7: 0x07,
- 0x7a8: 0x07, 0x7a9: 0x07, 0x7aa: 0x18, 0x7ab: 0x19, 0x7ac: 0x1a, 0x7ad: 0x0b, 0x7ae: 0x0b, 0x7af: 0x1b,
- 0x7b0: 0x0b, 0x7b1: 0x0b, 0x7b2: 0x0b, 0x7b3: 0x0b, 0x7b4: 0x0b, 0x7b5: 0x0b, 0x7b6: 0x0b, 0x7b7: 0x0b,
- 0x7b8: 0x0b, 0x7b9: 0x0b, 0x7ba: 0x0b, 0x7bb: 0x0b, 0x7bc: 0x0b, 0x7bd: 0x0b, 0x7be: 0x0b, 0x7bf: 0x0b,
- // Block 0x1f, offset 0x7c0
- 0x7c0: 0x0b, 0x7c1: 0x0b, 0x7c2: 0x0b, 0x7c3: 0x0b, 0x7c4: 0x0b, 0x7c5: 0x0b, 0x7c6: 0x0b, 0x7c7: 0x0b,
- 0x7c8: 0x0b, 0x7c9: 0x0b, 0x7ca: 0x0b, 0x7cb: 0x0b, 0x7cc: 0x0b, 0x7cd: 0x0b, 0x7ce: 0x0b, 0x7cf: 0x0b,
- 0x7d0: 0x0b, 0x7d1: 0x0b, 0x7d2: 0x0b, 0x7d3: 0x0b, 0x7d4: 0x0b, 0x7d5: 0x0b, 0x7d6: 0x0b, 0x7d7: 0x0b,
- 0x7d8: 0x0b, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x0b, 0x7dc: 0x0b, 0x7dd: 0x0b, 0x7de: 0x0b, 0x7df: 0x0b,
- 0x7e0: 0x0b, 0x7e1: 0x0b, 0x7e2: 0x0b, 0x7e3: 0x0b, 0x7e4: 0x0b, 0x7e5: 0x0b, 0x7e6: 0x0b, 0x7e7: 0x0b,
- 0x7e8: 0x0b, 0x7e9: 0x0b, 0x7ea: 0x0b, 0x7eb: 0x0b, 0x7ec: 0x0b, 0x7ed: 0x0b, 0x7ee: 0x0b, 0x7ef: 0x0b,
- 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,
- 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,
- // Block 0x20, offset 0x800
- 0x800: 0x177, 0x801: 0x178, 0x802: 0xb8, 0x803: 0xb8, 0x804: 0x179, 0x805: 0x179, 0x806: 0x179, 0x807: 0x17a,
- 0x808: 0xb8, 0x809: 0xb8, 0x80a: 0xb8, 0x80b: 0xb8, 0x80c: 0xb8, 0x80d: 0xb8, 0x80e: 0xb8, 0x80f: 0xb8,
- 0x810: 0xb8, 0x811: 0xb8, 0x812: 0xb8, 0x813: 0xb8, 0x814: 0xb8, 0x815: 0xb8, 0x816: 0xb8, 0x817: 0xb8,
- 0x818: 0xb8, 0x819: 0xb8, 0x81a: 0xb8, 0x81b: 0xb8, 0x81c: 0xb8, 0x81d: 0xb8, 0x81e: 0xb8, 0x81f: 0xb8,
- 0x820: 0xb8, 0x821: 0xb8, 0x822: 0xb8, 0x823: 0xb8, 0x824: 0xb8, 0x825: 0xb8, 0x826: 0xb8, 0x827: 0xb8,
- 0x828: 0xb8, 0x829: 0xb8, 0x82a: 0xb8, 0x82b: 0xb8, 0x82c: 0xb8, 0x82d: 0xb8, 0x82e: 0xb8, 0x82f: 0xb8,
- 0x830: 0xb8, 0x831: 0xb8, 0x832: 0xb8, 0x833: 0xb8, 0x834: 0xb8, 0x835: 0xb8, 0x836: 0xb8, 0x837: 0xb8,
- 0x838: 0xb8, 0x839: 0xb8, 0x83a: 0xb8, 0x83b: 0xb8, 0x83c: 0xb8, 0x83d: 0xb8, 0x83e: 0xb8, 0x83f: 0xb8,
- // Block 0x21, offset 0x840
- 0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b,
- 0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b,
- 0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b,
- 0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b,
- 0x860: 0x1e, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b,
- 0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b,
- 0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b,
- 0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b,
- // Block 0x22, offset 0x880
- 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,
- 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,
-}
-
-// idnaSparseOffset: 256 entries, 512 bytes
-var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x5c, 0x60, 0x6f, 0x74, 0x7b, 0x87, 0x95, 0xa3, 0xa8, 0xb1, 0xc1, 0xcf, 0xdc, 0xe8, 0xf9, 0x103, 0x10a, 0x117, 0x128, 0x12f, 0x13a, 0x149, 0x157, 0x161, 0x163, 0x167, 0x169, 0x175, 0x180, 0x188, 0x18e, 0x194, 0x199, 0x19e, 0x1a1, 0x1a5, 0x1ab, 0x1b0, 0x1bc, 0x1c6, 0x1cc, 0x1dd, 0x1e7, 0x1ea, 0x1f2, 0x1f5, 0x202, 0x20a, 0x20e, 0x215, 0x21d, 0x22d, 0x239, 0x23b, 0x245, 0x251, 0x25d, 0x269, 0x271, 0x276, 0x280, 0x291, 0x295, 0x2a0, 0x2a4, 0x2ad, 0x2b5, 0x2bb, 0x2c0, 0x2c3, 0x2c6, 0x2ca, 0x2d0, 0x2d4, 0x2d8, 0x2de, 0x2e5, 0x2eb, 0x2f3, 0x2fa, 0x305, 0x30f, 0x313, 0x316, 0x31c, 0x320, 0x322, 0x325, 0x327, 0x32a, 0x334, 0x337, 0x346, 0x34a, 0x34f, 0x352, 0x356, 0x35b, 0x360, 0x366, 0x36c, 0x37b, 0x381, 0x385, 0x394, 0x399, 0x3a1, 0x3ab, 0x3b6, 0x3be, 0x3cf, 0x3d8, 0x3e8, 0x3f5, 0x3ff, 0x404, 0x411, 0x415, 0x41a, 0x41c, 0x420, 0x422, 0x426, 0x42f, 0x435, 0x439, 0x449, 0x453, 0x458, 0x45b, 0x461, 0x468, 0x46d, 0x471, 0x477, 0x47c, 0x485, 0x48a, 0x490, 0x497, 0x49e, 0x4a5, 0x4a9, 0x4ae, 0x4b1, 0x4b6, 0x4c2, 0x4c8, 0x4cd, 0x4d4, 0x4dc, 0x4e1, 0x4e5, 0x4f5, 0x4fc, 0x500, 0x504, 0x50b, 0x50e, 0x511, 0x515, 0x519, 0x51f, 0x528, 0x534, 0x53b, 0x544, 0x54c, 0x553, 0x561, 0x56e, 0x57b, 0x584, 0x588, 0x596, 0x59e, 0x5a9, 0x5b2, 0x5b8, 0x5c0, 0x5c9, 0x5d3, 0x5d6, 0x5e2, 0x5e5, 0x5ea, 0x5ed, 0x5f7, 0x600, 0x60c, 0x60f, 0x614, 0x617, 0x61a, 0x61d, 0x624, 0x62b, 0x62f, 0x63a, 0x63d, 0x643, 0x648, 0x64c, 0x64f, 0x652, 0x655, 0x65a, 0x664, 0x667, 0x66b, 0x67a, 0x686, 0x68a, 0x68f, 0x694, 0x698, 0x69d, 0x6a6, 0x6b1, 0x6b7, 0x6bf, 0x6c3, 0x6c7, 0x6cd, 0x6d3, 0x6d8, 0x6db, 0x6e9, 0x6f0, 0x6f3, 0x6f6, 0x6fa, 0x700, 0x705, 0x70f, 0x714, 0x717, 0x71a, 0x71d, 0x720, 0x724, 0x727, 0x737, 0x748, 0x74d, 0x74f, 0x751}
-
-// idnaSparseValues: 1876 entries, 7504 bytes
-var idnaSparseValues = [1876]valueRange{
- // Block 0x0, offset 0x0
- {value: 0x0000, lo: 0x07},
- {value: 0xe105, lo: 0x80, hi: 0x96},
- {value: 0x0018, lo: 0x97, hi: 0x97},
- {value: 0xe105, lo: 0x98, hi: 0x9e},
- {value: 0x001f, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xb7},
- {value: 0x0008, lo: 0xb8, hi: 0xbf},
- // Block 0x1, offset 0x8
- {value: 0x0000, lo: 0x10},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0xe01d, lo: 0x81, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0x82},
- {value: 0x0335, lo: 0x83, hi: 0x83},
- {value: 0x034d, lo: 0x84, hi: 0x84},
- {value: 0x0365, lo: 0x85, hi: 0x85},
- {value: 0xe00d, lo: 0x86, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x87},
- {value: 0xe00d, lo: 0x88, hi: 0x88},
- {value: 0x0008, lo: 0x89, hi: 0x89},
- {value: 0xe00d, lo: 0x8a, hi: 0x8a},
- {value: 0x0008, lo: 0x8b, hi: 0x8b},
- {value: 0xe00d, lo: 0x8c, hi: 0x8c},
- {value: 0x0008, lo: 0x8d, hi: 0x8d},
- {value: 0xe00d, lo: 0x8e, hi: 0x8e},
- {value: 0x0008, lo: 0x8f, hi: 0xbf},
- // Block 0x2, offset 0x19
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x0249, lo: 0xb0, hi: 0xb0},
- {value: 0x037d, lo: 0xb1, hi: 0xb1},
- {value: 0x0259, lo: 0xb2, hi: 0xb2},
- {value: 0x0269, lo: 0xb3, hi: 0xb3},
- {value: 0x034d, lo: 0xb4, hi: 0xb4},
- {value: 0x0395, lo: 0xb5, hi: 0xb5},
- {value: 0xe1bd, lo: 0xb6, hi: 0xb6},
- {value: 0x0279, lo: 0xb7, hi: 0xb7},
- {value: 0x0289, lo: 0xb8, hi: 0xb8},
- {value: 0x0008, lo: 0xb9, hi: 0xbf},
- // Block 0x3, offset 0x25
- {value: 0x0000, lo: 0x01},
- {value: 0x1308, lo: 0x80, hi: 0xbf},
- // Block 0x4, offset 0x27
- {value: 0x0000, lo: 0x04},
- {value: 0x03f5, lo: 0x80, hi: 0x8f},
- {value: 0xe105, lo: 0x90, hi: 0x9f},
- {value: 0x049d, lo: 0xa0, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x5, offset 0x2c
- {value: 0x0000, lo: 0x07},
- {value: 0xe185, lo: 0x80, hi: 0x8f},
- {value: 0x0545, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x98},
- {value: 0x0008, lo: 0x99, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xa0},
- {value: 0x0008, lo: 0xa1, hi: 0xbf},
- // Block 0x6, offset 0x34
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0401, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x88},
- {value: 0x0018, lo: 0x89, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x90},
- {value: 0x1308, lo: 0x91, hi: 0xbd},
- {value: 0x0018, lo: 0xbe, hi: 0xbe},
- {value: 0x1308, lo: 0xbf, hi: 0xbf},
- // Block 0x7, offset 0x3f
- {value: 0x0000, lo: 0x0b},
- {value: 0x0018, lo: 0x80, hi: 0x80},
- {value: 0x1308, lo: 0x81, hi: 0x82},
- {value: 0x0018, lo: 0x83, hi: 0x83},
- {value: 0x1308, lo: 0x84, hi: 0x85},
- {value: 0x0018, lo: 0x86, hi: 0x86},
- {value: 0x1308, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0x8, offset 0x4b
- {value: 0x0000, lo: 0x10},
- {value: 0x0018, lo: 0x80, hi: 0x80},
- {value: 0x0208, lo: 0x81, hi: 0x87},
- {value: 0x0408, lo: 0x88, hi: 0x88},
- {value: 0x0208, lo: 0x89, hi: 0x8a},
- {value: 0x1308, lo: 0x8b, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0018, lo: 0xaa, hi: 0xad},
- {value: 0x0208, lo: 0xae, hi: 0xaf},
- {value: 0x1308, lo: 0xb0, hi: 0xb0},
- {value: 0x0408, lo: 0xb1, hi: 0xb3},
- {value: 0x0008, lo: 0xb4, hi: 0xb4},
- {value: 0x0429, lo: 0xb5, hi: 0xb5},
- {value: 0x0451, lo: 0xb6, hi: 0xb6},
- {value: 0x0479, lo: 0xb7, hi: 0xb7},
- {value: 0x04a1, lo: 0xb8, hi: 0xb8},
- {value: 0x0208, lo: 0xb9, hi: 0xbf},
- // Block 0x9, offset 0x5c
- {value: 0x0000, lo: 0x03},
- {value: 0x0208, lo: 0x80, hi: 0x87},
- {value: 0x0408, lo: 0x88, hi: 0x99},
- {value: 0x0208, lo: 0x9a, hi: 0xbf},
- // Block 0xa, offset 0x60
- {value: 0x0000, lo: 0x0e},
- {value: 0x1308, lo: 0x80, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8c},
- {value: 0x0408, lo: 0x8d, hi: 0x8d},
- {value: 0x0208, lo: 0x8e, hi: 0x98},
- {value: 0x0408, lo: 0x99, hi: 0x9b},
- {value: 0x0208, lo: 0x9c, hi: 0xaa},
- {value: 0x0408, lo: 0xab, hi: 0xac},
- {value: 0x0208, lo: 0xad, hi: 0xb0},
- {value: 0x0408, lo: 0xb1, hi: 0xb1},
- {value: 0x0208, lo: 0xb2, hi: 0xb2},
- {value: 0x0408, lo: 0xb3, hi: 0xb4},
- {value: 0x0208, lo: 0xb5, hi: 0xb7},
- {value: 0x0408, lo: 0xb8, hi: 0xb9},
- {value: 0x0208, lo: 0xba, hi: 0xbf},
- // Block 0xb, offset 0x6f
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x1308, lo: 0xa6, hi: 0xb0},
- {value: 0x0008, lo: 0xb1, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbf},
- // Block 0xc, offset 0x74
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0208, lo: 0x8a, hi: 0xaa},
- {value: 0x1308, lo: 0xab, hi: 0xb3},
- {value: 0x0008, lo: 0xb4, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0xd, offset 0x7b
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x95},
- {value: 0x1308, lo: 0x96, hi: 0x99},
- {value: 0x0008, lo: 0x9a, hi: 0x9a},
- {value: 0x1308, lo: 0x9b, hi: 0xa3},
- {value: 0x0008, lo: 0xa4, hi: 0xa4},
- {value: 0x1308, lo: 0xa5, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xa8},
- {value: 0x1308, lo: 0xa9, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xe, offset 0x87
- {value: 0x0000, lo: 0x0d},
- {value: 0x0408, lo: 0x80, hi: 0x80},
- {value: 0x0208, lo: 0x81, hi: 0x85},
- {value: 0x0408, lo: 0x86, hi: 0x87},
- {value: 0x0208, lo: 0x88, hi: 0x88},
- {value: 0x0408, lo: 0x89, hi: 0x89},
- {value: 0x0208, lo: 0x8a, hi: 0x93},
- {value: 0x0408, lo: 0x94, hi: 0x94},
- {value: 0x0208, lo: 0x95, hi: 0x95},
- {value: 0x0008, lo: 0x96, hi: 0x98},
- {value: 0x1308, lo: 0x99, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0xbf},
- // Block 0xf, offset 0x95
- {value: 0x0000, lo: 0x0d},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0208, lo: 0xa0, hi: 0xa9},
- {value: 0x0408, lo: 0xaa, hi: 0xac},
- {value: 0x0008, lo: 0xad, hi: 0xad},
- {value: 0x0408, lo: 0xae, hi: 0xae},
- {value: 0x0208, lo: 0xaf, hi: 0xb0},
- {value: 0x0408, lo: 0xb1, hi: 0xb2},
- {value: 0x0208, lo: 0xb3, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xb5},
- {value: 0x0208, lo: 0xb6, hi: 0xb8},
- {value: 0x0408, lo: 0xb9, hi: 0xb9},
- {value: 0x0208, lo: 0xba, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x10, offset 0xa3
- {value: 0x0000, lo: 0x04},
- {value: 0x0040, lo: 0x80, hi: 0x93},
- {value: 0x1308, lo: 0x94, hi: 0xa1},
- {value: 0x0040, lo: 0xa2, hi: 0xa2},
- {value: 0x1308, lo: 0xa3, hi: 0xbf},
- // Block 0x11, offset 0xa8
- {value: 0x0000, lo: 0x08},
- {value: 0x1308, lo: 0x80, hi: 0x82},
- {value: 0x1008, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0xb9},
- {value: 0x1308, lo: 0xba, hi: 0xba},
- {value: 0x1008, lo: 0xbb, hi: 0xbb},
- {value: 0x1308, lo: 0xbc, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x1008, lo: 0xbe, hi: 0xbf},
- // Block 0x12, offset 0xb1
- {value: 0x0000, lo: 0x0f},
- {value: 0x1308, lo: 0x80, hi: 0x80},
- {value: 0x1008, lo: 0x81, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x85},
- {value: 0x1008, lo: 0x86, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x1008, lo: 0x8a, hi: 0x8c},
- {value: 0x1b08, lo: 0x8d, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x96},
- {value: 0x1008, lo: 0x97, hi: 0x97},
- {value: 0x0040, lo: 0x98, hi: 0xa5},
- {value: 0x0008, lo: 0xa6, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0x13, offset 0xc1
- {value: 0x0000, lo: 0x0d},
- {value: 0x1308, lo: 0x80, hi: 0x80},
- {value: 0x1008, lo: 0x81, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x91},
- {value: 0x0008, lo: 0x92, hi: 0xa8},
- {value: 0x0040, lo: 0xa9, hi: 0xa9},
- {value: 0x0008, lo: 0xaa, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x1308, lo: 0xbe, hi: 0xbf},
- // Block 0x14, offset 0xcf
- {value: 0x0000, lo: 0x0c},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x1308, lo: 0x81, hi: 0x81},
- {value: 0x1008, lo: 0x82, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x91},
- {value: 0x0008, lo: 0x92, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x1008, lo: 0xbe, hi: 0xbf},
- // Block 0x15, offset 0xdc
- {value: 0x0000, lo: 0x0b},
- {value: 0x0040, lo: 0x80, hi: 0x81},
- {value: 0x1008, lo: 0x82, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x99},
- {value: 0x0008, lo: 0x9a, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xb2},
- {value: 0x0008, lo: 0xb3, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x16, offset 0xe8
- {value: 0x0000, lo: 0x10},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x89},
- {value: 0x1b08, lo: 0x8a, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8e},
- {value: 0x1008, lo: 0x8f, hi: 0x91},
- {value: 0x1308, lo: 0x92, hi: 0x94},
- {value: 0x0040, lo: 0x95, hi: 0x95},
- {value: 0x1308, lo: 0x96, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x97},
- {value: 0x1008, lo: 0x98, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xa5},
- {value: 0x0008, lo: 0xa6, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xb1},
- {value: 0x1008, lo: 0xb2, hi: 0xb3},
- {value: 0x0018, lo: 0xb4, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0x17, offset 0xf9
- {value: 0x0000, lo: 0x09},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0xb0},
- {value: 0x1308, lo: 0xb1, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xb2},
- {value: 0x08f1, lo: 0xb3, hi: 0xb3},
- {value: 0x1308, lo: 0xb4, hi: 0xb9},
- {value: 0x1b08, lo: 0xba, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbe},
- {value: 0x0018, lo: 0xbf, hi: 0xbf},
- // Block 0x18, offset 0x103
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x1308, lo: 0x87, hi: 0x8e},
- {value: 0x0018, lo: 0x8f, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0xbf},
- // Block 0x19, offset 0x10a
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x84},
- {value: 0x0040, lo: 0x85, hi: 0x85},
- {value: 0x0008, lo: 0x86, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x1308, lo: 0x88, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9b},
- {value: 0x0961, lo: 0x9c, hi: 0x9c},
- {value: 0x0999, lo: 0x9d, hi: 0x9d},
- {value: 0x0008, lo: 0x9e, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0x1a, offset 0x117
- {value: 0x0000, lo: 0x10},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x8a},
- {value: 0x0008, lo: 0x8b, hi: 0x8b},
- {value: 0xe03d, lo: 0x8c, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0x97},
- {value: 0x1308, lo: 0x98, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0018, lo: 0xaa, hi: 0xb4},
- {value: 0x1308, lo: 0xb5, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xb6},
- {value: 0x1308, lo: 0xb7, hi: 0xb7},
- {value: 0x0018, lo: 0xb8, hi: 0xb8},
- {value: 0x1308, lo: 0xb9, hi: 0xb9},
- {value: 0x0018, lo: 0xba, hi: 0xbd},
- {value: 0x1008, lo: 0xbe, hi: 0xbf},
- // Block 0x1b, offset 0x128
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x85},
- {value: 0x1308, lo: 0x86, hi: 0x86},
- {value: 0x0018, lo: 0x87, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8d},
- {value: 0x0018, lo: 0x8e, hi: 0x9a},
- {value: 0x0040, lo: 0x9b, hi: 0xbf},
- // Block 0x1c, offset 0x12f
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0xaa},
- {value: 0x1008, lo: 0xab, hi: 0xac},
- {value: 0x1308, lo: 0xad, hi: 0xb0},
- {value: 0x1008, lo: 0xb1, hi: 0xb1},
- {value: 0x1308, lo: 0xb2, hi: 0xb7},
- {value: 0x1008, lo: 0xb8, hi: 0xb8},
- {value: 0x1b08, lo: 0xb9, hi: 0xba},
- {value: 0x1008, lo: 0xbb, hi: 0xbc},
- {value: 0x1308, lo: 0xbd, hi: 0xbe},
- {value: 0x0008, lo: 0xbf, hi: 0xbf},
- // Block 0x1d, offset 0x13a
- {value: 0x0000, lo: 0x0e},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0018, lo: 0x8a, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x95},
- {value: 0x1008, lo: 0x96, hi: 0x97},
- {value: 0x1308, lo: 0x98, hi: 0x99},
- {value: 0x0008, lo: 0x9a, hi: 0x9d},
- {value: 0x1308, lo: 0x9e, hi: 0xa0},
- {value: 0x0008, lo: 0xa1, hi: 0xa1},
- {value: 0x1008, lo: 0xa2, hi: 0xa4},
- {value: 0x0008, lo: 0xa5, hi: 0xa6},
- {value: 0x1008, lo: 0xa7, hi: 0xad},
- {value: 0x0008, lo: 0xae, hi: 0xb0},
- {value: 0x1308, lo: 0xb1, hi: 0xb4},
- {value: 0x0008, lo: 0xb5, hi: 0xbf},
- // Block 0x1e, offset 0x149
- {value: 0x0000, lo: 0x0d},
- {value: 0x0008, lo: 0x80, hi: 0x81},
- {value: 0x1308, lo: 0x82, hi: 0x82},
- {value: 0x1008, lo: 0x83, hi: 0x84},
- {value: 0x1308, lo: 0x85, hi: 0x86},
- {value: 0x1008, lo: 0x87, hi: 0x8c},
- {value: 0x1308, lo: 0x8d, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x8e},
- {value: 0x1008, lo: 0x8f, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x1008, lo: 0x9a, hi: 0x9c},
- {value: 0x1308, lo: 0x9d, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0x1f, offset 0x157
- {value: 0x0000, lo: 0x09},
- {value: 0x0040, lo: 0x80, hi: 0x86},
- {value: 0x055d, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8c},
- {value: 0x055d, lo: 0x8d, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xba},
- {value: 0x0018, lo: 0xbb, hi: 0xbb},
- {value: 0xe105, lo: 0xbc, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbf},
- // Block 0x20, offset 0x161
- {value: 0x0000, lo: 0x01},
- {value: 0x0018, lo: 0x80, hi: 0xbf},
- // Block 0x21, offset 0x163
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0xa0},
- {value: 0x0018, lo: 0xa1, hi: 0xbf},
- // Block 0x22, offset 0x167
- {value: 0x0000, lo: 0x01},
- {value: 0x0008, lo: 0x80, hi: 0xbf},
- // Block 0x23, offset 0x169
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0x98},
- {value: 0x0040, lo: 0x99, hi: 0x99},
- {value: 0x0008, lo: 0x9a, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x24, offset 0x175
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb7},
- {value: 0x0008, lo: 0xb8, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0x25, offset 0x180
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x0040, lo: 0x81, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0xbf},
- // Block 0x26, offset 0x188
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x91},
- {value: 0x0008, lo: 0x92, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0xbf},
- // Block 0x27, offset 0x18e
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x9a},
- {value: 0x0040, lo: 0x9b, hi: 0x9c},
- {value: 0x1308, lo: 0x9d, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0x28, offset 0x194
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x29, offset 0x199
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb7},
- {value: 0xe045, lo: 0xb8, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x2a, offset 0x19e
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0xbf},
- // Block 0x2b, offset 0x1a1
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xac},
- {value: 0x0018, lo: 0xad, hi: 0xae},
- {value: 0x0008, lo: 0xaf, hi: 0xbf},
- // Block 0x2c, offset 0x1a5
- {value: 0x0000, lo: 0x05},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9c},
- {value: 0x0040, lo: 0x9d, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x2d, offset 0x1ab
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xaa},
- {value: 0x0018, lo: 0xab, hi: 0xb0},
- {value: 0x0008, lo: 0xb1, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0x2e, offset 0x1b0
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x91},
- {value: 0x1308, lo: 0x92, hi: 0x93},
- {value: 0x1b08, lo: 0x94, hi: 0x94},
- {value: 0x0040, lo: 0x95, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb1},
- {value: 0x1308, lo: 0xb2, hi: 0xb3},
- {value: 0x1b08, lo: 0xb4, hi: 0xb4},
- {value: 0x0018, lo: 0xb5, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x2f, offset 0x1bc
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x91},
- {value: 0x1308, lo: 0x92, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xad},
- {value: 0x0008, lo: 0xae, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xb1},
- {value: 0x1308, lo: 0xb2, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbf},
- // Block 0x30, offset 0x1c6
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0xb3},
- {value: 0x1340, lo: 0xb4, hi: 0xb5},
- {value: 0x1008, lo: 0xb6, hi: 0xb6},
- {value: 0x1308, lo: 0xb7, hi: 0xbd},
- {value: 0x1008, lo: 0xbe, hi: 0xbf},
- // Block 0x31, offset 0x1cc
- {value: 0x0000, lo: 0x10},
- {value: 0x1008, lo: 0x80, hi: 0x85},
- {value: 0x1308, lo: 0x86, hi: 0x86},
- {value: 0x1008, lo: 0x87, hi: 0x88},
- {value: 0x1308, lo: 0x89, hi: 0x91},
- {value: 0x1b08, lo: 0x92, hi: 0x92},
- {value: 0x1308, lo: 0x93, hi: 0x93},
- {value: 0x0018, lo: 0x94, hi: 0x96},
- {value: 0x0008, lo: 0x97, hi: 0x97},
- {value: 0x0018, lo: 0x98, hi: 0x9b},
- {value: 0x0008, lo: 0x9c, hi: 0x9c},
- {value: 0x1308, lo: 0x9d, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0x32, offset 0x1dd
- {value: 0x0000, lo: 0x09},
- {value: 0x0018, lo: 0x80, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x86},
- {value: 0x0218, lo: 0x87, hi: 0x87},
- {value: 0x0018, lo: 0x88, hi: 0x8a},
- {value: 0x13c0, lo: 0x8b, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0208, lo: 0xa0, hi: 0xbf},
- // Block 0x33, offset 0x1e7
- {value: 0x0000, lo: 0x02},
- {value: 0x0208, lo: 0x80, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbf},
- // Block 0x34, offset 0x1ea
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x84},
- {value: 0x1308, lo: 0x85, hi: 0x86},
- {value: 0x0208, lo: 0x87, hi: 0xa8},
- {value: 0x1308, lo: 0xa9, hi: 0xa9},
- {value: 0x0208, lo: 0xaa, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x35, offset 0x1f2
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xbf},
- // Block 0x36, offset 0x1f5
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x1308, lo: 0xa0, hi: 0xa2},
- {value: 0x1008, lo: 0xa3, hi: 0xa6},
- {value: 0x1308, lo: 0xa7, hi: 0xa8},
- {value: 0x1008, lo: 0xa9, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x1008, lo: 0xb0, hi: 0xb1},
- {value: 0x1308, lo: 0xb2, hi: 0xb2},
- {value: 0x1008, lo: 0xb3, hi: 0xb8},
- {value: 0x1308, lo: 0xb9, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0x37, offset 0x202
- {value: 0x0000, lo: 0x07},
- {value: 0x0018, lo: 0x80, hi: 0x80},
- {value: 0x0040, lo: 0x81, hi: 0x83},
- {value: 0x0018, lo: 0x84, hi: 0x85},
- {value: 0x0008, lo: 0x86, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0x38, offset 0x20a
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x39, offset 0x20e
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0028, lo: 0x9a, hi: 0x9a},
- {value: 0x0040, lo: 0x9b, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0xbf},
- // Block 0x3a, offset 0x215
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x96},
- {value: 0x1308, lo: 0x97, hi: 0x98},
- {value: 0x1008, lo: 0x99, hi: 0x9a},
- {value: 0x1308, lo: 0x9b, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x3b, offset 0x21d
- {value: 0x0000, lo: 0x0f},
- {value: 0x0008, lo: 0x80, hi: 0x94},
- {value: 0x1008, lo: 0x95, hi: 0x95},
- {value: 0x1308, lo: 0x96, hi: 0x96},
- {value: 0x1008, lo: 0x97, hi: 0x97},
- {value: 0x1308, lo: 0x98, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x1b08, lo: 0xa0, hi: 0xa0},
- {value: 0x1008, lo: 0xa1, hi: 0xa1},
- {value: 0x1308, lo: 0xa2, hi: 0xa2},
- {value: 0x1008, lo: 0xa3, hi: 0xa4},
- {value: 0x1308, lo: 0xa5, hi: 0xac},
- {value: 0x1008, lo: 0xad, hi: 0xb2},
- {value: 0x1308, lo: 0xb3, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbe},
- {value: 0x1308, lo: 0xbf, hi: 0xbf},
- // Block 0x3c, offset 0x22d
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa6},
- {value: 0x0008, lo: 0xa7, hi: 0xa7},
- {value: 0x0018, lo: 0xa8, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x1308, lo: 0xb0, hi: 0xbd},
- {value: 0x1318, lo: 0xbe, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0x3d, offset 0x239
- {value: 0x0000, lo: 0x01},
- {value: 0x0040, lo: 0x80, hi: 0xbf},
- // Block 0x3e, offset 0x23b
- {value: 0x0000, lo: 0x09},
- {value: 0x1308, lo: 0x80, hi: 0x83},
- {value: 0x1008, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0xb3},
- {value: 0x1308, lo: 0xb4, hi: 0xb4},
- {value: 0x1008, lo: 0xb5, hi: 0xb5},
- {value: 0x1308, lo: 0xb6, hi: 0xba},
- {value: 0x1008, lo: 0xbb, hi: 0xbb},
- {value: 0x1308, lo: 0xbc, hi: 0xbc},
- {value: 0x1008, lo: 0xbd, hi: 0xbf},
- // Block 0x3f, offset 0x245
- {value: 0x0000, lo: 0x0b},
- {value: 0x1008, lo: 0x80, hi: 0x81},
- {value: 0x1308, lo: 0x82, hi: 0x82},
- {value: 0x1008, lo: 0x83, hi: 0x83},
- {value: 0x1808, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0xaa},
- {value: 0x1308, lo: 0xab, hi: 0xb3},
- {value: 0x0018, lo: 0xb4, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0x40, offset 0x251
- {value: 0x0000, lo: 0x0b},
- {value: 0x1308, lo: 0x80, hi: 0x81},
- {value: 0x1008, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xa0},
- {value: 0x1008, lo: 0xa1, hi: 0xa1},
- {value: 0x1308, lo: 0xa2, hi: 0xa5},
- {value: 0x1008, lo: 0xa6, hi: 0xa7},
- {value: 0x1308, lo: 0xa8, hi: 0xa9},
- {value: 0x1808, lo: 0xaa, hi: 0xaa},
- {value: 0x1b08, lo: 0xab, hi: 0xab},
- {value: 0x1308, lo: 0xac, hi: 0xad},
- {value: 0x0008, lo: 0xae, hi: 0xbf},
- // Block 0x41, offset 0x25d
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x1308, lo: 0xa6, hi: 0xa6},
- {value: 0x1008, lo: 0xa7, hi: 0xa7},
- {value: 0x1308, lo: 0xa8, hi: 0xa9},
- {value: 0x1008, lo: 0xaa, hi: 0xac},
- {value: 0x1308, lo: 0xad, hi: 0xad},
- {value: 0x1008, lo: 0xae, hi: 0xae},
- {value: 0x1308, lo: 0xaf, hi: 0xb1},
- {value: 0x1808, lo: 0xb2, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbb},
- {value: 0x0018, lo: 0xbc, hi: 0xbf},
- // Block 0x42, offset 0x269
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xa3},
- {value: 0x1008, lo: 0xa4, hi: 0xab},
- {value: 0x1308, lo: 0xac, hi: 0xb3},
- {value: 0x1008, lo: 0xb4, hi: 0xb5},
- {value: 0x1308, lo: 0xb6, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xba},
- {value: 0x0018, lo: 0xbb, hi: 0xbf},
- // Block 0x43, offset 0x271
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0x8c},
- {value: 0x0008, lo: 0x8d, hi: 0xbd},
- {value: 0x0018, lo: 0xbe, hi: 0xbf},
- // Block 0x44, offset 0x276
- {value: 0x0000, lo: 0x09},
- {value: 0x0e29, lo: 0x80, hi: 0x80},
- {value: 0x0e41, lo: 0x81, hi: 0x81},
- {value: 0x0e59, lo: 0x82, hi: 0x82},
- {value: 0x0e71, lo: 0x83, hi: 0x83},
- {value: 0x0e89, lo: 0x84, hi: 0x85},
- {value: 0x0ea1, lo: 0x86, hi: 0x86},
- {value: 0x0eb9, lo: 0x87, hi: 0x87},
- {value: 0x057d, lo: 0x88, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0xbf},
- // Block 0x45, offset 0x280
- {value: 0x0000, lo: 0x10},
- {value: 0x0018, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x1308, lo: 0x90, hi: 0x92},
- {value: 0x0018, lo: 0x93, hi: 0x93},
- {value: 0x1308, lo: 0x94, hi: 0xa0},
- {value: 0x1008, lo: 0xa1, hi: 0xa1},
- {value: 0x1308, lo: 0xa2, hi: 0xa8},
- {value: 0x0008, lo: 0xa9, hi: 0xac},
- {value: 0x1308, lo: 0xad, hi: 0xad},
- {value: 0x0008, lo: 0xae, hi: 0xb1},
- {value: 0x1008, lo: 0xb2, hi: 0xb3},
- {value: 0x1308, lo: 0xb4, hi: 0xb4},
- {value: 0x0008, lo: 0xb5, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xb7},
- {value: 0x1308, lo: 0xb8, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0x46, offset 0x291
- {value: 0x0000, lo: 0x03},
- {value: 0x1308, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xba},
- {value: 0x1308, lo: 0xbb, hi: 0xbf},
- // Block 0x47, offset 0x295
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x87},
- {value: 0xe045, lo: 0x88, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x97},
- {value: 0xe045, lo: 0x98, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa7},
- {value: 0xe045, lo: 0xa8, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb7},
- {value: 0xe045, lo: 0xb8, hi: 0xbf},
- // Block 0x48, offset 0x2a0
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0x8f},
- {value: 0x1318, lo: 0x90, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xbf},
- // Block 0x49, offset 0x2a4
- {value: 0x0000, lo: 0x08},
- {value: 0x0018, lo: 0x80, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x84},
- {value: 0x0018, lo: 0x85, hi: 0x88},
- {value: 0x24c1, lo: 0x89, hi: 0x89},
- {value: 0x0018, lo: 0x8a, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xbf},
- // Block 0x4a, offset 0x2ad
- {value: 0x0000, lo: 0x07},
- {value: 0x0018, lo: 0x80, hi: 0xab},
- {value: 0x24f1, lo: 0xac, hi: 0xac},
- {value: 0x2529, lo: 0xad, hi: 0xad},
- {value: 0x0018, lo: 0xae, hi: 0xae},
- {value: 0x2579, lo: 0xaf, hi: 0xaf},
- {value: 0x25b1, lo: 0xb0, hi: 0xb0},
- {value: 0x0018, lo: 0xb1, hi: 0xbf},
- // Block 0x4b, offset 0x2b5
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x9f},
- {value: 0x0080, lo: 0xa0, hi: 0xa0},
- {value: 0x0018, lo: 0xa1, hi: 0xad},
- {value: 0x0080, lo: 0xae, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbf},
- // Block 0x4c, offset 0x2bb
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0xa8},
- {value: 0x09c5, lo: 0xa9, hi: 0xa9},
- {value: 0x09e5, lo: 0xaa, hi: 0xaa},
- {value: 0x0018, lo: 0xab, hi: 0xbf},
- // Block 0x4d, offset 0x2c0
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0x4e, offset 0x2c3
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xbf},
- // Block 0x4f, offset 0x2c6
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x8b},
- {value: 0x28c1, lo: 0x8c, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0xbf},
- // Block 0x50, offset 0x2ca
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0xb3},
- {value: 0x0e66, lo: 0xb4, hi: 0xb4},
- {value: 0x292a, lo: 0xb5, hi: 0xb5},
- {value: 0x0e86, lo: 0xb6, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xbf},
- // Block 0x51, offset 0x2d0
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x9b},
- {value: 0x2941, lo: 0x9c, hi: 0x9c},
- {value: 0x0018, lo: 0x9d, hi: 0xbf},
- // Block 0x52, offset 0x2d4
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xbf},
- // Block 0x53, offset 0x2d8
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x97},
- {value: 0x0018, lo: 0x98, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbc},
- {value: 0x0018, lo: 0xbd, hi: 0xbf},
- // Block 0x54, offset 0x2de
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0018, lo: 0x8a, hi: 0x91},
- {value: 0x0040, lo: 0x92, hi: 0xab},
- {value: 0x0018, lo: 0xac, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0x55, offset 0x2e5
- {value: 0x0000, lo: 0x05},
- {value: 0xe185, lo: 0x80, hi: 0x8f},
- {value: 0x03f5, lo: 0x90, hi: 0x9f},
- {value: 0x0ea5, lo: 0xa0, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x56, offset 0x2eb
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x0040, lo: 0xa6, hi: 0xa6},
- {value: 0x0008, lo: 0xa7, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xac},
- {value: 0x0008, lo: 0xad, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x57, offset 0x2f3
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xae},
- {value: 0xe075, lo: 0xaf, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xbe},
- {value: 0x1b08, lo: 0xbf, hi: 0xbf},
- // Block 0x58, offset 0x2fa
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xb7},
- {value: 0x0008, lo: 0xb8, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0x59, offset 0x305
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x8e},
- {value: 0x0040, lo: 0x8f, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x1308, lo: 0xa0, hi: 0xbf},
- // Block 0x5a, offset 0x30f
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xae},
- {value: 0x0008, lo: 0xaf, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbf},
- // Block 0x5b, offset 0x313
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0x84},
- {value: 0x0040, lo: 0x85, hi: 0xbf},
- // Block 0x5c, offset 0x316
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9e},
- {value: 0x0edd, lo: 0x9f, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xbf},
- // Block 0x5d, offset 0x31c
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xb2},
- {value: 0x0efd, lo: 0xb3, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbf},
- // Block 0x5e, offset 0x320
- {value: 0x0020, lo: 0x01},
- {value: 0x0f1d, lo: 0x80, hi: 0xbf},
- // Block 0x5f, offset 0x322
- {value: 0x0020, lo: 0x02},
- {value: 0x171d, lo: 0x80, hi: 0x8f},
- {value: 0x18fd, lo: 0x90, hi: 0xbf},
- // Block 0x60, offset 0x325
- {value: 0x0020, lo: 0x01},
- {value: 0x1efd, lo: 0x80, hi: 0xbf},
- // Block 0x61, offset 0x327
- {value: 0x0000, lo: 0x02},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0xbf},
- // Block 0x62, offset 0x32a
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x98},
- {value: 0x1308, lo: 0x99, hi: 0x9a},
- {value: 0x29e2, lo: 0x9b, hi: 0x9b},
- {value: 0x2a0a, lo: 0x9c, hi: 0x9c},
- {value: 0x0008, lo: 0x9d, hi: 0x9e},
- {value: 0x2a31, lo: 0x9f, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa0},
- {value: 0x0008, lo: 0xa1, hi: 0xbf},
- // Block 0x63, offset 0x334
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xbe},
- {value: 0x2a69, lo: 0xbf, hi: 0xbf},
- // Block 0x64, offset 0x337
- {value: 0x0000, lo: 0x0e},
- {value: 0x0040, lo: 0x80, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xb0},
- {value: 0x2a1d, lo: 0xb1, hi: 0xb1},
- {value: 0x2a3d, lo: 0xb2, hi: 0xb2},
- {value: 0x2a5d, lo: 0xb3, hi: 0xb3},
- {value: 0x2a7d, lo: 0xb4, hi: 0xb4},
- {value: 0x2a5d, lo: 0xb5, hi: 0xb5},
- {value: 0x2a9d, lo: 0xb6, hi: 0xb6},
- {value: 0x2abd, lo: 0xb7, hi: 0xb7},
- {value: 0x2add, lo: 0xb8, hi: 0xb9},
- {value: 0x2afd, lo: 0xba, hi: 0xbb},
- {value: 0x2b1d, lo: 0xbc, hi: 0xbd},
- {value: 0x2afd, lo: 0xbe, hi: 0xbf},
- // Block 0x65, offset 0x346
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x66, offset 0x34a
- {value: 0x0030, lo: 0x04},
- {value: 0x2aa2, lo: 0x80, hi: 0x9d},
- {value: 0x305a, lo: 0x9e, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x30a2, lo: 0xa0, hi: 0xbf},
- // Block 0x67, offset 0x34f
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0xbf},
- // Block 0x68, offset 0x352
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xbf},
- // Block 0x69, offset 0x356
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xbd},
- {value: 0x0018, lo: 0xbe, hi: 0xbf},
- // Block 0x6a, offset 0x35b
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xbf},
- // Block 0x6b, offset 0x360
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x0018, lo: 0xa6, hi: 0xaf},
- {value: 0x1308, lo: 0xb0, hi: 0xb1},
- {value: 0x0018, lo: 0xb2, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbf},
- // Block 0x6c, offset 0x366
- {value: 0x0000, lo: 0x05},
- {value: 0x0040, lo: 0x80, hi: 0xb6},
- {value: 0x0008, lo: 0xb7, hi: 0xb7},
- {value: 0x2009, lo: 0xb8, hi: 0xb8},
- {value: 0x6e89, lo: 0xb9, hi: 0xb9},
- {value: 0x0008, lo: 0xba, hi: 0xbf},
- // Block 0x6d, offset 0x36c
- {value: 0x0000, lo: 0x0e},
- {value: 0x0008, lo: 0x80, hi: 0x81},
- {value: 0x1308, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0x85},
- {value: 0x1b08, lo: 0x86, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x8a},
- {value: 0x1308, lo: 0x8b, hi: 0x8b},
- {value: 0x0008, lo: 0x8c, hi: 0xa2},
- {value: 0x1008, lo: 0xa3, hi: 0xa4},
- {value: 0x1308, lo: 0xa5, hi: 0xa6},
- {value: 0x1008, lo: 0xa7, hi: 0xa7},
- {value: 0x0018, lo: 0xa8, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0x6e, offset 0x37b
- {value: 0x0000, lo: 0x05},
- {value: 0x0208, lo: 0x80, hi: 0xb1},
- {value: 0x0108, lo: 0xb2, hi: 0xb2},
- {value: 0x0008, lo: 0xb3, hi: 0xb3},
- {value: 0x0018, lo: 0xb4, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbf},
- // Block 0x6f, offset 0x381
- {value: 0x0000, lo: 0x03},
- {value: 0x1008, lo: 0x80, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0xb3},
- {value: 0x1008, lo: 0xb4, hi: 0xbf},
- // Block 0x70, offset 0x385
- {value: 0x0000, lo: 0x0e},
- {value: 0x1008, lo: 0x80, hi: 0x83},
- {value: 0x1b08, lo: 0x84, hi: 0x84},
- {value: 0x1308, lo: 0x85, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x8d},
- {value: 0x0018, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x1308, lo: 0xa0, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xb7},
- {value: 0x0018, lo: 0xb8, hi: 0xba},
- {value: 0x0008, lo: 0xbb, hi: 0xbb},
- {value: 0x0018, lo: 0xbc, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x71, offset 0x394
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x1308, lo: 0xa6, hi: 0xad},
- {value: 0x0018, lo: 0xae, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x72, offset 0x399
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x1308, lo: 0x87, hi: 0x91},
- {value: 0x1008, lo: 0x92, hi: 0x92},
- {value: 0x1808, lo: 0x93, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x9e},
- {value: 0x0018, lo: 0x9f, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0x73, offset 0x3a1
- {value: 0x0000, lo: 0x09},
- {value: 0x1308, lo: 0x80, hi: 0x82},
- {value: 0x1008, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0xb2},
- {value: 0x1308, lo: 0xb3, hi: 0xb3},
- {value: 0x1008, lo: 0xb4, hi: 0xb5},
- {value: 0x1308, lo: 0xb6, hi: 0xb9},
- {value: 0x1008, lo: 0xba, hi: 0xbb},
- {value: 0x1308, lo: 0xbc, hi: 0xbc},
- {value: 0x1008, lo: 0xbd, hi: 0xbf},
- // Block 0x74, offset 0x3ab
- {value: 0x0000, lo: 0x0a},
- {value: 0x1808, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8e},
- {value: 0x0008, lo: 0x8f, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa4},
- {value: 0x1308, lo: 0xa5, hi: 0xa5},
- {value: 0x0008, lo: 0xa6, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0x75, offset 0x3b6
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xa8},
- {value: 0x1308, lo: 0xa9, hi: 0xae},
- {value: 0x1008, lo: 0xaf, hi: 0xb0},
- {value: 0x1308, lo: 0xb1, hi: 0xb2},
- {value: 0x1008, lo: 0xb3, hi: 0xb4},
- {value: 0x1308, lo: 0xb5, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x76, offset 0x3be
- {value: 0x0000, lo: 0x10},
- {value: 0x0008, lo: 0x80, hi: 0x82},
- {value: 0x1308, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x8b},
- {value: 0x1308, lo: 0x8c, hi: 0x8c},
- {value: 0x1008, lo: 0x8d, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9b},
- {value: 0x0018, lo: 0x9c, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xb9},
- {value: 0x0008, lo: 0xba, hi: 0xba},
- {value: 0x1008, lo: 0xbb, hi: 0xbb},
- {value: 0x1308, lo: 0xbc, hi: 0xbc},
- {value: 0x1008, lo: 0xbd, hi: 0xbd},
- {value: 0x0008, lo: 0xbe, hi: 0xbf},
- // Block 0x77, offset 0x3cf
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x1308, lo: 0xb0, hi: 0xb0},
- {value: 0x0008, lo: 0xb1, hi: 0xb1},
- {value: 0x1308, lo: 0xb2, hi: 0xb4},
- {value: 0x0008, lo: 0xb5, hi: 0xb6},
- {value: 0x1308, lo: 0xb7, hi: 0xb8},
- {value: 0x0008, lo: 0xb9, hi: 0xbd},
- {value: 0x1308, lo: 0xbe, hi: 0xbf},
- // Block 0x78, offset 0x3d8
- {value: 0x0000, lo: 0x0f},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x1308, lo: 0x81, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x9a},
- {value: 0x0008, lo: 0x9b, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xaa},
- {value: 0x1008, lo: 0xab, hi: 0xab},
- {value: 0x1308, lo: 0xac, hi: 0xad},
- {value: 0x1008, lo: 0xae, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xb4},
- {value: 0x1008, lo: 0xb5, hi: 0xb5},
- {value: 0x1b08, lo: 0xb6, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x79, offset 0x3e8
- {value: 0x0000, lo: 0x0c},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x88},
- {value: 0x0008, lo: 0x89, hi: 0x8e},
- {value: 0x0040, lo: 0x8f, hi: 0x90},
- {value: 0x0008, lo: 0x91, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x7a, offset 0x3f5
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9b},
- {value: 0x4465, lo: 0x9c, hi: 0x9c},
- {value: 0x447d, lo: 0x9d, hi: 0x9d},
- {value: 0x2971, lo: 0x9e, hi: 0x9e},
- {value: 0xe06d, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa5},
- {value: 0x0040, lo: 0xa6, hi: 0xaf},
- {value: 0x4495, lo: 0xb0, hi: 0xbf},
- // Block 0x7b, offset 0x3ff
- {value: 0x0000, lo: 0x04},
- {value: 0x44b5, lo: 0x80, hi: 0x8f},
- {value: 0x44d5, lo: 0x90, hi: 0x9f},
- {value: 0x44f5, lo: 0xa0, hi: 0xaf},
- {value: 0x44d5, lo: 0xb0, hi: 0xbf},
- // Block 0x7c, offset 0x404
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0xa2},
- {value: 0x1008, lo: 0xa3, hi: 0xa4},
- {value: 0x1308, lo: 0xa5, hi: 0xa5},
- {value: 0x1008, lo: 0xa6, hi: 0xa7},
- {value: 0x1308, lo: 0xa8, hi: 0xa8},
- {value: 0x1008, lo: 0xa9, hi: 0xaa},
- {value: 0x0018, lo: 0xab, hi: 0xab},
- {value: 0x1008, lo: 0xac, hi: 0xac},
- {value: 0x1b08, lo: 0xad, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0x7d, offset 0x411
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbf},
- // Block 0x7e, offset 0x415
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x8a},
- {value: 0x0018, lo: 0x8b, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0x7f, offset 0x41a
- {value: 0x0020, lo: 0x01},
- {value: 0x4515, lo: 0x80, hi: 0xbf},
- // Block 0x80, offset 0x41c
- {value: 0x0020, lo: 0x03},
- {value: 0x4d15, lo: 0x80, hi: 0x94},
- {value: 0x4ad5, lo: 0x95, hi: 0x95},
- {value: 0x4fb5, lo: 0x96, hi: 0xbf},
- // Block 0x81, offset 0x420
- {value: 0x0020, lo: 0x01},
- {value: 0x54f5, lo: 0x80, hi: 0xbf},
- // Block 0x82, offset 0x422
- {value: 0x0020, lo: 0x03},
- {value: 0x5cf5, lo: 0x80, hi: 0x84},
- {value: 0x5655, lo: 0x85, hi: 0x85},
- {value: 0x5d95, lo: 0x86, hi: 0xbf},
- // Block 0x83, offset 0x426
- {value: 0x0020, lo: 0x08},
- {value: 0x6b55, lo: 0x80, hi: 0x8f},
- {value: 0x6d15, lo: 0x90, hi: 0x90},
- {value: 0x6d55, lo: 0x91, hi: 0xab},
- {value: 0x6ea1, lo: 0xac, hi: 0xac},
- {value: 0x70b5, lo: 0xad, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x70d5, lo: 0xb0, hi: 0xbf},
- // Block 0x84, offset 0x42f
- {value: 0x0020, lo: 0x05},
- {value: 0x72d5, lo: 0x80, hi: 0xad},
- {value: 0x6535, lo: 0xae, hi: 0xae},
- {value: 0x7895, lo: 0xaf, hi: 0xb5},
- {value: 0x6f55, lo: 0xb6, hi: 0xb6},
- {value: 0x7975, lo: 0xb7, hi: 0xbf},
- // Block 0x85, offset 0x435
- {value: 0x0028, lo: 0x03},
- {value: 0x7c21, lo: 0x80, hi: 0x82},
- {value: 0x7be1, lo: 0x83, hi: 0x83},
- {value: 0x7c99, lo: 0x84, hi: 0xbf},
- // Block 0x86, offset 0x439
- {value: 0x0038, lo: 0x0f},
- {value: 0x9db1, lo: 0x80, hi: 0x83},
- {value: 0x9e59, lo: 0x84, hi: 0x85},
- {value: 0x9e91, lo: 0x86, hi: 0x87},
- {value: 0x9ec9, lo: 0x88, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x91},
- {value: 0xa089, lo: 0x92, hi: 0x97},
- {value: 0xa1a1, lo: 0x98, hi: 0x9c},
- {value: 0xa281, lo: 0x9d, hi: 0xb3},
- {value: 0x9d41, lo: 0xb4, hi: 0xb4},
- {value: 0x9db1, lo: 0xb5, hi: 0xb5},
- {value: 0xa789, lo: 0xb6, hi: 0xbb},
- {value: 0xa869, lo: 0xbc, hi: 0xbc},
- {value: 0xa7f9, lo: 0xbd, hi: 0xbd},
- {value: 0xa8d9, lo: 0xbe, hi: 0xbf},
- // Block 0x87, offset 0x449
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8c},
- {value: 0x0008, lo: 0x8d, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbb},
- {value: 0x0008, lo: 0xbc, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbe},
- {value: 0x0008, lo: 0xbf, hi: 0xbf},
- // Block 0x88, offset 0x453
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0xbf},
- // Block 0x89, offset 0x458
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0x8a, offset 0x45b
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x86},
- {value: 0x0018, lo: 0x87, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xbf},
- // Block 0x8b, offset 0x461
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x8e},
- {value: 0x0040, lo: 0x8f, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa0},
- {value: 0x0040, lo: 0xa1, hi: 0xbf},
- // Block 0x8c, offset 0x468
- {value: 0x0000, lo: 0x04},
- {value: 0x0040, lo: 0x80, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xbc},
- {value: 0x1308, lo: 0xbd, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x8d, offset 0x46d
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0x9c},
- {value: 0x0040, lo: 0x9d, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x8e, offset 0x471
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x9f},
- {value: 0x1308, lo: 0xa0, hi: 0xa0},
- {value: 0x0018, lo: 0xa1, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0x8f, offset 0x477
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x90, offset 0x47c
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0x89},
- {value: 0x0018, lo: 0x8a, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xb5},
- {value: 0x1308, lo: 0xb6, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0x91, offset 0x485
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9e},
- {value: 0x0018, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x92, offset 0x48a
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0xbf},
- // Block 0x93, offset 0x490
- {value: 0x0000, lo: 0x06},
- {value: 0xe145, lo: 0x80, hi: 0x87},
- {value: 0xe1c5, lo: 0x88, hi: 0x8f},
- {value: 0xe145, lo: 0x90, hi: 0x97},
- {value: 0x8ad5, lo: 0x98, hi: 0x9f},
- {value: 0x8aed, lo: 0xa0, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xbf},
- // Block 0x94, offset 0x497
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xaf},
- {value: 0x8aed, lo: 0xb0, hi: 0xb7},
- {value: 0x8ad5, lo: 0xb8, hi: 0xbf},
- // Block 0x95, offset 0x49e
- {value: 0x0000, lo: 0x06},
- {value: 0xe145, lo: 0x80, hi: 0x87},
- {value: 0xe1c5, lo: 0x88, hi: 0x8f},
- {value: 0xe145, lo: 0x90, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0x96, offset 0x4a5
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x97, offset 0x4a9
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xae},
- {value: 0x0018, lo: 0xaf, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0x98, offset 0x4ae
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x99, offset 0x4b1
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xbf},
- // Block 0x9a, offset 0x4b6
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb6},
- {value: 0x0008, lo: 0xb7, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbb},
- {value: 0x0008, lo: 0xbc, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbe},
- {value: 0x0008, lo: 0xbf, hi: 0xbf},
- // Block 0x9b, offset 0x4c2
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x96},
- {value: 0x0018, lo: 0x97, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xbf},
- // Block 0x9c, offset 0x4c8
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0xa6},
- {value: 0x0018, lo: 0xa7, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0x9d, offset 0x4cd
- {value: 0x0000, lo: 0x06},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xb3},
- {value: 0x0008, lo: 0xb4, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xba},
- {value: 0x0018, lo: 0xbb, hi: 0xbf},
- // Block 0x9e, offset 0x4d4
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x95},
- {value: 0x0018, lo: 0x96, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0x9e},
- {value: 0x0018, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbe},
- {value: 0x0018, lo: 0xbf, hi: 0xbf},
- // Block 0x9f, offset 0x4dc
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbb},
- {value: 0x0018, lo: 0xbc, hi: 0xbd},
- {value: 0x0008, lo: 0xbe, hi: 0xbf},
- // Block 0xa0, offset 0x4e1
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x91},
- {value: 0x0018, lo: 0x92, hi: 0xbf},
- // Block 0xa1, offset 0x4e5
- {value: 0x0000, lo: 0x0f},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x1308, lo: 0x81, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x84},
- {value: 0x1308, lo: 0x85, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x8b},
- {value: 0x1308, lo: 0x8c, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x94},
- {value: 0x0008, lo: 0x95, hi: 0x97},
- {value: 0x0040, lo: 0x98, hi: 0x98},
- {value: 0x0008, lo: 0x99, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xb7},
- {value: 0x1308, lo: 0xb8, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbe},
- {value: 0x1b08, lo: 0xbf, hi: 0xbf},
- // Block 0xa2, offset 0x4f5
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x98},
- {value: 0x0040, lo: 0x99, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbc},
- {value: 0x0018, lo: 0xbd, hi: 0xbf},
- // Block 0xa3, offset 0x4fc
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0x9c},
- {value: 0x0018, lo: 0x9d, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0xa4, offset 0x500
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb8},
- {value: 0x0018, lo: 0xb9, hi: 0xbf},
- // Block 0xa5, offset 0x504
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x97},
- {value: 0x0018, lo: 0x98, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xb7},
- {value: 0x0018, lo: 0xb8, hi: 0xbf},
- // Block 0xa6, offset 0x50b
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0xbf},
- // Block 0xa7, offset 0x50e
- {value: 0x0000, lo: 0x02},
- {value: 0x03dd, lo: 0x80, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xbf},
- // Block 0xa8, offset 0x511
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xb9},
- {value: 0x0018, lo: 0xba, hi: 0xbf},
- // Block 0xa9, offset 0x515
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xaa, offset 0x519
- {value: 0x0000, lo: 0x05},
- {value: 0x1008, lo: 0x80, hi: 0x80},
- {value: 0x1308, lo: 0x81, hi: 0x81},
- {value: 0x1008, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xb7},
- {value: 0x1308, lo: 0xb8, hi: 0xbf},
- // Block 0xab, offset 0x51f
- {value: 0x0000, lo: 0x08},
- {value: 0x1308, lo: 0x80, hi: 0x85},
- {value: 0x1b08, lo: 0x86, hi: 0x86},
- {value: 0x0018, lo: 0x87, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x91},
- {value: 0x0018, lo: 0x92, hi: 0xa5},
- {value: 0x0008, lo: 0xa6, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbe},
- {value: 0x1b08, lo: 0xbf, hi: 0xbf},
- // Block 0xac, offset 0x528
- {value: 0x0000, lo: 0x0b},
- {value: 0x1308, lo: 0x80, hi: 0x81},
- {value: 0x1008, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xaf},
- {value: 0x1008, lo: 0xb0, hi: 0xb2},
- {value: 0x1308, lo: 0xb3, hi: 0xb6},
- {value: 0x1008, lo: 0xb7, hi: 0xb8},
- {value: 0x1b08, lo: 0xb9, hi: 0xb9},
- {value: 0x1308, lo: 0xba, hi: 0xba},
- {value: 0x0018, lo: 0xbb, hi: 0xbc},
- {value: 0x0340, lo: 0xbd, hi: 0xbd},
- {value: 0x0018, lo: 0xbe, hi: 0xbf},
- // Block 0xad, offset 0x534
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x81},
- {value: 0x0040, lo: 0x82, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xa8},
- {value: 0x0040, lo: 0xa9, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0xae, offset 0x53b
- {value: 0x0000, lo: 0x08},
- {value: 0x1308, lo: 0x80, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xa6},
- {value: 0x1308, lo: 0xa7, hi: 0xab},
- {value: 0x1008, lo: 0xac, hi: 0xac},
- {value: 0x1308, lo: 0xad, hi: 0xb2},
- {value: 0x1b08, lo: 0xb3, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xb5},
- {value: 0x0008, lo: 0xb6, hi: 0xbf},
- // Block 0xaf, offset 0x544
- {value: 0x0000, lo: 0x07},
- {value: 0x0018, lo: 0x80, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xb2},
- {value: 0x1308, lo: 0xb3, hi: 0xb3},
- {value: 0x0018, lo: 0xb4, hi: 0xb5},
- {value: 0x0008, lo: 0xb6, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0xb0, offset 0x54c
- {value: 0x0000, lo: 0x06},
- {value: 0x1308, lo: 0x80, hi: 0x81},
- {value: 0x1008, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xb2},
- {value: 0x1008, lo: 0xb3, hi: 0xb5},
- {value: 0x1308, lo: 0xb6, hi: 0xbe},
- {value: 0x1008, lo: 0xbf, hi: 0xbf},
- // Block 0xb1, offset 0x553
- {value: 0x0000, lo: 0x0d},
- {value: 0x1808, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0x84},
- {value: 0x0018, lo: 0x85, hi: 0x89},
- {value: 0x1308, lo: 0x8a, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9b},
- {value: 0x0008, lo: 0x9c, hi: 0x9c},
- {value: 0x0018, lo: 0x9d, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xa0},
- {value: 0x0018, lo: 0xa1, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0xb2, offset 0x561
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x91},
- {value: 0x0040, lo: 0x92, hi: 0x92},
- {value: 0x0008, lo: 0x93, hi: 0xab},
- {value: 0x1008, lo: 0xac, hi: 0xae},
- {value: 0x1308, lo: 0xaf, hi: 0xb1},
- {value: 0x1008, lo: 0xb2, hi: 0xb3},
- {value: 0x1308, lo: 0xb4, hi: 0xb4},
- {value: 0x1808, lo: 0xb5, hi: 0xb5},
- {value: 0x1308, lo: 0xb6, hi: 0xb7},
- {value: 0x0018, lo: 0xb8, hi: 0xbd},
- {value: 0x1308, lo: 0xbe, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xb3, offset 0x56e
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8e},
- {value: 0x0008, lo: 0x8f, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9e},
- {value: 0x0008, lo: 0x9f, hi: 0xa8},
- {value: 0x0018, lo: 0xa9, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0xb4, offset 0x57b
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0x9e},
- {value: 0x1308, lo: 0x9f, hi: 0x9f},
- {value: 0x1008, lo: 0xa0, hi: 0xa2},
- {value: 0x1308, lo: 0xa3, hi: 0xa9},
- {value: 0x1b08, lo: 0xaa, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0xb5, offset 0x584
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xb4},
- {value: 0x1008, lo: 0xb5, hi: 0xb7},
- {value: 0x1308, lo: 0xb8, hi: 0xbf},
- // Block 0xb6, offset 0x588
- {value: 0x0000, lo: 0x0d},
- {value: 0x1008, lo: 0x80, hi: 0x81},
- {value: 0x1b08, lo: 0x82, hi: 0x82},
- {value: 0x1308, lo: 0x83, hi: 0x84},
- {value: 0x1008, lo: 0x85, hi: 0x85},
- {value: 0x1308, lo: 0x86, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x8a},
- {value: 0x0018, lo: 0x8b, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0x9c},
- {value: 0x0018, lo: 0x9d, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0xbf},
- // Block 0xb7, offset 0x596
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x1008, lo: 0xb0, hi: 0xb2},
- {value: 0x1308, lo: 0xb3, hi: 0xb8},
- {value: 0x1008, lo: 0xb9, hi: 0xb9},
- {value: 0x1308, lo: 0xba, hi: 0xba},
- {value: 0x1008, lo: 0xbb, hi: 0xbe},
- {value: 0x1308, lo: 0xbf, hi: 0xbf},
- // Block 0xb8, offset 0x59e
- {value: 0x0000, lo: 0x0a},
- {value: 0x1308, lo: 0x80, hi: 0x80},
- {value: 0x1008, lo: 0x81, hi: 0x81},
- {value: 0x1b08, lo: 0x82, hi: 0x82},
- {value: 0x1308, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x85},
- {value: 0x0018, lo: 0x86, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0xbf},
- // Block 0xb9, offset 0x5a9
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0xae},
- {value: 0x1008, lo: 0xaf, hi: 0xb1},
- {value: 0x1308, lo: 0xb2, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb7},
- {value: 0x1008, lo: 0xb8, hi: 0xbb},
- {value: 0x1308, lo: 0xbc, hi: 0xbd},
- {value: 0x1008, lo: 0xbe, hi: 0xbe},
- {value: 0x1b08, lo: 0xbf, hi: 0xbf},
- // Block 0xba, offset 0x5b2
- {value: 0x0000, lo: 0x05},
- {value: 0x1308, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0x9b},
- {value: 0x1308, lo: 0x9c, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0xbf},
- // Block 0xbb, offset 0x5b8
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x1008, lo: 0xb0, hi: 0xb2},
- {value: 0x1308, lo: 0xb3, hi: 0xba},
- {value: 0x1008, lo: 0xbb, hi: 0xbc},
- {value: 0x1308, lo: 0xbd, hi: 0xbd},
- {value: 0x1008, lo: 0xbe, hi: 0xbe},
- {value: 0x1b08, lo: 0xbf, hi: 0xbf},
- // Block 0xbc, offset 0x5c0
- {value: 0x0000, lo: 0x08},
- {value: 0x1308, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x84},
- {value: 0x0040, lo: 0x85, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xbf},
- // Block 0xbd, offset 0x5c9
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0xaa},
- {value: 0x1308, lo: 0xab, hi: 0xab},
- {value: 0x1008, lo: 0xac, hi: 0xac},
- {value: 0x1308, lo: 0xad, hi: 0xad},
- {value: 0x1008, lo: 0xae, hi: 0xaf},
- {value: 0x1308, lo: 0xb0, hi: 0xb5},
- {value: 0x1808, lo: 0xb6, hi: 0xb6},
- {value: 0x1308, lo: 0xb7, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbf},
- // Block 0xbe, offset 0x5d3
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0xbf},
- // Block 0xbf, offset 0x5d6
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9c},
- {value: 0x1308, lo: 0x9d, hi: 0x9f},
- {value: 0x1008, lo: 0xa0, hi: 0xa1},
- {value: 0x1308, lo: 0xa2, hi: 0xa5},
- {value: 0x1008, lo: 0xa6, hi: 0xa6},
- {value: 0x1308, lo: 0xa7, hi: 0xaa},
- {value: 0x1b08, lo: 0xab, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0018, lo: 0xba, hi: 0xbf},
- // Block 0xc0, offset 0x5e2
- {value: 0x0000, lo: 0x02},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x049d, lo: 0xa0, hi: 0xbf},
- // Block 0xc1, offset 0x5e5
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xa9},
- {value: 0x0018, lo: 0xaa, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xbe},
- {value: 0x0008, lo: 0xbf, hi: 0xbf},
- // Block 0xc2, offset 0x5ea
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0xc3, offset 0x5ed
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0xae},
- {value: 0x1008, lo: 0xaf, hi: 0xaf},
- {value: 0x1308, lo: 0xb0, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xb7},
- {value: 0x1308, lo: 0xb8, hi: 0xbd},
- {value: 0x1008, lo: 0xbe, hi: 0xbe},
- {value: 0x1b08, lo: 0xbf, hi: 0xbf},
- // Block 0xc4, offset 0x5f7
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xbf},
- // Block 0xc5, offset 0x600
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x91},
- {value: 0x1308, lo: 0x92, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xa8},
- {value: 0x1008, lo: 0xa9, hi: 0xa9},
- {value: 0x1308, lo: 0xaa, hi: 0xb0},
- {value: 0x1008, lo: 0xb1, hi: 0xb1},
- {value: 0x1308, lo: 0xb2, hi: 0xb3},
- {value: 0x1008, lo: 0xb4, hi: 0xb4},
- {value: 0x1308, lo: 0xb5, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0xc6, offset 0x60c
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0xbf},
- // Block 0xc7, offset 0x60f
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0xc8, offset 0x614
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0xbf},
- // Block 0xc9, offset 0x617
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xbf},
- // Block 0xca, offset 0x61a
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0xbf},
- // Block 0xcb, offset 0x61d
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xad},
- {value: 0x0018, lo: 0xae, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0xcc, offset 0x624
- {value: 0x0000, lo: 0x06},
- {value: 0x0040, lo: 0x80, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x1308, lo: 0xb0, hi: 0xb4},
- {value: 0x0018, lo: 0xb5, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xbf},
- // Block 0xcd, offset 0x62b
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x1308, lo: 0xb0, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xbf},
- // Block 0xce, offset 0x62f
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x83},
- {value: 0x0018, lo: 0x84, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0xa1},
- {value: 0x0040, lo: 0xa2, hi: 0xa2},
- {value: 0x0008, lo: 0xa3, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbf},
- // Block 0xcf, offset 0x63a
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0xbf},
- // Block 0xd0, offset 0x63d
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x84},
- {value: 0x0040, lo: 0x85, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x90},
- {value: 0x1008, lo: 0x91, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xd1, offset 0x643
- {value: 0x0000, lo: 0x04},
- {value: 0x0040, lo: 0x80, hi: 0x8e},
- {value: 0x1308, lo: 0x8f, hi: 0x92},
- {value: 0x0008, lo: 0x93, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0xd2, offset 0x648
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa0},
- {value: 0x0040, lo: 0xa1, hi: 0xbf},
- // Block 0xd3, offset 0x64c
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xbf},
- // Block 0xd4, offset 0x64f
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xbf},
- // Block 0xd5, offset 0x652
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x81},
- {value: 0x0040, lo: 0x82, hi: 0xbf},
- // Block 0xd6, offset 0x655
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0xd7, offset 0x65a
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9b},
- {value: 0x0018, lo: 0x9c, hi: 0x9c},
- {value: 0x1308, lo: 0x9d, hi: 0x9e},
- {value: 0x0018, lo: 0x9f, hi: 0x9f},
- {value: 0x03c0, lo: 0xa0, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xbf},
- // Block 0xd8, offset 0x664
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xbf},
- // Block 0xd9, offset 0x667
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xa8},
- {value: 0x0018, lo: 0xa9, hi: 0xbf},
- // Block 0xda, offset 0x66b
- {value: 0x0000, lo: 0x0e},
- {value: 0x0018, lo: 0x80, hi: 0x9d},
- {value: 0xb5b9, lo: 0x9e, hi: 0x9e},
- {value: 0xb601, lo: 0x9f, hi: 0x9f},
- {value: 0xb649, lo: 0xa0, hi: 0xa0},
- {value: 0xb6b1, lo: 0xa1, hi: 0xa1},
- {value: 0xb719, lo: 0xa2, hi: 0xa2},
- {value: 0xb781, lo: 0xa3, hi: 0xa3},
- {value: 0xb7e9, lo: 0xa4, hi: 0xa4},
- {value: 0x1018, lo: 0xa5, hi: 0xa6},
- {value: 0x1318, lo: 0xa7, hi: 0xa9},
- {value: 0x0018, lo: 0xaa, hi: 0xac},
- {value: 0x1018, lo: 0xad, hi: 0xb2},
- {value: 0x0340, lo: 0xb3, hi: 0xba},
- {value: 0x1318, lo: 0xbb, hi: 0xbf},
- // Block 0xdb, offset 0x67a
- {value: 0x0000, lo: 0x0b},
- {value: 0x1318, lo: 0x80, hi: 0x82},
- {value: 0x0018, lo: 0x83, hi: 0x84},
- {value: 0x1318, lo: 0x85, hi: 0x8b},
- {value: 0x0018, lo: 0x8c, hi: 0xa9},
- {value: 0x1318, lo: 0xaa, hi: 0xad},
- {value: 0x0018, lo: 0xae, hi: 0xba},
- {value: 0xb851, lo: 0xbb, hi: 0xbb},
- {value: 0xb899, lo: 0xbc, hi: 0xbc},
- {value: 0xb8e1, lo: 0xbd, hi: 0xbd},
- {value: 0xb949, lo: 0xbe, hi: 0xbe},
- {value: 0xb9b1, lo: 0xbf, hi: 0xbf},
- // Block 0xdc, offset 0x686
- {value: 0x0000, lo: 0x03},
- {value: 0xba19, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0xa8},
- {value: 0x0040, lo: 0xa9, hi: 0xbf},
- // Block 0xdd, offset 0x68a
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x81},
- {value: 0x1318, lo: 0x82, hi: 0x84},
- {value: 0x0018, lo: 0x85, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0xbf},
- // Block 0xde, offset 0x68f
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbf},
- // Block 0xdf, offset 0x694
- {value: 0x0000, lo: 0x03},
- {value: 0x1308, lo: 0x80, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xba},
- {value: 0x1308, lo: 0xbb, hi: 0xbf},
- // Block 0xe0, offset 0x698
- {value: 0x0000, lo: 0x04},
- {value: 0x1308, lo: 0x80, hi: 0xac},
- {value: 0x0018, lo: 0xad, hi: 0xb4},
- {value: 0x1308, lo: 0xb5, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xbf},
- // Block 0xe1, offset 0x69d
- {value: 0x0000, lo: 0x08},
- {value: 0x0018, lo: 0x80, hi: 0x83},
- {value: 0x1308, lo: 0x84, hi: 0x84},
- {value: 0x0018, lo: 0x85, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x9a},
- {value: 0x1308, lo: 0x9b, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xa0},
- {value: 0x1308, lo: 0xa1, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0xe2, offset 0x6a6
- {value: 0x0000, lo: 0x0a},
- {value: 0x1308, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x1308, lo: 0x88, hi: 0x98},
- {value: 0x0040, lo: 0x99, hi: 0x9a},
- {value: 0x1308, lo: 0x9b, hi: 0xa1},
- {value: 0x0040, lo: 0xa2, hi: 0xa2},
- {value: 0x1308, lo: 0xa3, hi: 0xa4},
- {value: 0x0040, lo: 0xa5, hi: 0xa5},
- {value: 0x1308, lo: 0xa6, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xbf},
- // Block 0xe3, offset 0x6b1
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x84},
- {value: 0x0040, lo: 0x85, hi: 0x86},
- {value: 0x0018, lo: 0x87, hi: 0x8f},
- {value: 0x1308, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0xbf},
- // Block 0xe4, offset 0x6b7
- {value: 0x0000, lo: 0x07},
- {value: 0x0208, lo: 0x80, hi: 0x83},
- {value: 0x1308, lo: 0x84, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0xe5, offset 0x6bf
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbf},
- // Block 0xe6, offset 0x6c3
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbf},
- // Block 0xe7, offset 0x6c7
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xb0},
- {value: 0x0018, lo: 0xb1, hi: 0xbf},
- // Block 0xe8, offset 0x6cd
- {value: 0x0000, lo: 0x05},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x90},
- {value: 0x0018, lo: 0x91, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xbf},
- // Block 0xe9, offset 0x6d3
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x8f},
- {value: 0xc1c1, lo: 0x90, hi: 0x90},
- {value: 0x0018, lo: 0x91, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xbf},
- // Block 0xea, offset 0x6d8
- {value: 0x0000, lo: 0x02},
- {value: 0x0040, lo: 0x80, hi: 0xa5},
- {value: 0x0018, lo: 0xa6, hi: 0xbf},
- // Block 0xeb, offset 0x6db
- {value: 0x0000, lo: 0x0d},
- {value: 0xc7e9, lo: 0x80, hi: 0x80},
- {value: 0xc839, lo: 0x81, hi: 0x81},
- {value: 0xc889, lo: 0x82, hi: 0x82},
- {value: 0xc8d9, lo: 0x83, hi: 0x83},
- {value: 0xc929, lo: 0x84, hi: 0x84},
- {value: 0xc979, lo: 0x85, hi: 0x85},
- {value: 0xc9c9, lo: 0x86, hi: 0x86},
- {value: 0xca19, lo: 0x87, hi: 0x87},
- {value: 0xca69, lo: 0x88, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x8f},
- {value: 0xcab9, lo: 0x90, hi: 0x90},
- {value: 0xcad9, lo: 0x91, hi: 0x91},
- {value: 0x0040, lo: 0x92, hi: 0xbf},
- // Block 0xec, offset 0x6e9
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x92},
- {value: 0x0040, lo: 0x93, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0xed, offset 0x6f0
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbf},
- // Block 0xee, offset 0x6f3
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0x94},
- {value: 0x0040, lo: 0x95, hi: 0xbf},
- // Block 0xef, offset 0x6f6
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xbf},
- // Block 0xf0, offset 0x6fa
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xbf},
- // Block 0xf1, offset 0x700
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xbf},
- // Block 0xf2, offset 0x705
- {value: 0x0000, lo: 0x09},
- {value: 0x0040, lo: 0x80, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xb2},
- {value: 0x0018, lo: 0xb3, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xf3, offset 0x70f
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0xbf},
- // Block 0xf4, offset 0x714
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0x91},
- {value: 0x0040, lo: 0x92, hi: 0xbf},
- // Block 0xf5, offset 0x717
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0x80},
- {value: 0x0040, lo: 0x81, hi: 0xbf},
- // Block 0xf6, offset 0x71a
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0xbf},
- // Block 0xf7, offset 0x71d
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0xf8, offset 0x720
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0xf9, offset 0x724
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xa1},
- {value: 0x0040, lo: 0xa2, hi: 0xbf},
- // Block 0xfa, offset 0x727
- {value: 0x0020, lo: 0x0f},
- {value: 0xdeb9, lo: 0x80, hi: 0x89},
- {value: 0x8dfd, lo: 0x8a, hi: 0x8a},
- {value: 0xdff9, lo: 0x8b, hi: 0x9c},
- {value: 0x8e1d, lo: 0x9d, hi: 0x9d},
- {value: 0xe239, lo: 0x9e, hi: 0xa2},
- {value: 0x8e3d, lo: 0xa3, hi: 0xa3},
- {value: 0xe2d9, lo: 0xa4, hi: 0xab},
- {value: 0x7ed5, lo: 0xac, hi: 0xac},
- {value: 0xe3d9, lo: 0xad, hi: 0xaf},
- {value: 0x8e5d, lo: 0xb0, hi: 0xb0},
- {value: 0xe439, lo: 0xb1, hi: 0xb6},
- {value: 0x8e7d, lo: 0xb7, hi: 0xb9},
- {value: 0xe4f9, lo: 0xba, hi: 0xba},
- {value: 0x8edd, lo: 0xbb, hi: 0xbb},
- {value: 0xe519, lo: 0xbc, hi: 0xbf},
- // Block 0xfb, offset 0x737
- {value: 0x0020, lo: 0x10},
- {value: 0x937d, lo: 0x80, hi: 0x80},
- {value: 0xf099, lo: 0x81, hi: 0x86},
- {value: 0x939d, lo: 0x87, hi: 0x8a},
- {value: 0xd9f9, lo: 0x8b, hi: 0x8b},
- {value: 0xf159, lo: 0x8c, hi: 0x96},
- {value: 0x941d, lo: 0x97, hi: 0x97},
- {value: 0xf2b9, lo: 0x98, hi: 0xa3},
- {value: 0x943d, lo: 0xa4, hi: 0xa6},
- {value: 0xf439, lo: 0xa7, hi: 0xaa},
- {value: 0x949d, lo: 0xab, hi: 0xab},
- {value: 0xf4b9, lo: 0xac, hi: 0xac},
- {value: 0x94bd, lo: 0xad, hi: 0xad},
- {value: 0xf4d9, lo: 0xae, hi: 0xaf},
- {value: 0x94dd, lo: 0xb0, hi: 0xb1},
- {value: 0xf519, lo: 0xb2, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xfc, offset 0x748
- {value: 0x0000, lo: 0x04},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0340, lo: 0x81, hi: 0x81},
- {value: 0x0040, lo: 0x82, hi: 0x9f},
- {value: 0x0340, lo: 0xa0, hi: 0xbf},
- // Block 0xfd, offset 0x74d
- {value: 0x0000, lo: 0x01},
- {value: 0x0340, lo: 0x80, hi: 0xbf},
- // Block 0xfe, offset 0x74f
- {value: 0x0000, lo: 0x01},
- {value: 0x13c0, lo: 0x80, hi: 0xbf},
- // Block 0xff, offset 0x751
- {value: 0x0000, lo: 0x02},
- {value: 0x13c0, lo: 0x80, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
-}
-
-// Total table size 41559 bytes (40KiB); checksum: F4A1FA4E
diff --git a/vendor/golang.org/x/net/idna/trie.go b/vendor/golang.org/x/net/idna/trie.go
deleted file mode 100644
index c4ef847e7..000000000
--- a/vendor/golang.org/x/net/idna/trie.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package idna
-
-// appendMapping appends the mapping for the respective rune. isMapped must be
-// true. A mapping is a categorization of a rune as defined in UTS #46.
-func (c info) appendMapping(b []byte, s string) []byte {
- index := int(c >> indexShift)
- if c&xorBit == 0 {
- s := mappings[index:]
- return append(b, s[1:s[0]+1]...)
- }
- b = append(b, s...)
- if c&inlineXOR == inlineXOR {
- // TODO: support and handle two-byte inline masks
- b[len(b)-1] ^= byte(index)
- } else {
- for p := len(b) - int(xorData[index]); p < len(b); p++ {
- index++
- b[p] ^= xorData[index]
- }
- }
- return b
-}
-
-// Sparse block handling code.
-
-type valueRange struct {
- value uint16 // header: value:stride
- lo, hi byte // header: lo:n
-}
-
-type sparseBlocks struct {
- values []valueRange
- offset []uint16
-}
-
-var idnaSparse = sparseBlocks{
- values: idnaSparseValues[:],
- offset: idnaSparseOffset[:],
-}
-
-// Don't use newIdnaTrie to avoid unconditional linking in of the table.
-var trie = &idnaTrie{}
-
-// lookup determines the type of block n and looks up the value for b.
-// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
-// is a list of ranges with an accompanying value. Given a matching range r,
-// the value for b is by r.value + (b - r.lo) * stride.
-func (t *sparseBlocks) lookup(n uint32, b byte) uint16 {
- offset := t.offset[n]
- header := t.values[offset]
- lo := offset + 1
- hi := lo + uint16(header.lo)
- for lo < hi {
- m := lo + (hi-lo)/2
- r := t.values[m]
- if r.lo <= b && b <= r.hi {
- return r.value + uint16(b-r.lo)*header.value
- }
- if b < r.lo {
- hi = m
- } else {
- lo = m + 1
- }
- }
- return 0
-}
diff --git a/vendor/golang.org/x/net/idna/trieval.go b/vendor/golang.org/x/net/idna/trieval.go
deleted file mode 100644
index 63cb03b59..000000000
--- a/vendor/golang.org/x/net/idna/trieval.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-package idna
-
-// This file contains definitions for interpreting the trie value of the idna
-// trie generated by "go run gen*.go". It is shared by both the generator
-// program and the resultant package. Sharing is achieved by the generator
-// copying gen_trieval.go to trieval.go and changing what's above this comment.
-
-// info holds information from the IDNA mapping table for a single rune. It is
-// the value returned by a trie lookup. In most cases, all information fits in
-// a 16-bit value. For mappings, this value may contain an index into a slice
-// with the mapped string. Such mappings can consist of the actual mapped value
-// or an XOR pattern to be applied to the bytes of the UTF8 encoding of the
-// input rune. This technique is used by the cases packages and reduces the
-// table size significantly.
-//
-// The per-rune values have the following format:
-//
-// if mapped {
-// if inlinedXOR {
-// 15..13 inline XOR marker
-// 12..11 unused
-// 10..3 inline XOR mask
-// } else {
-// 15..3 index into xor or mapping table
-// }
-// } else {
-// 15..13 unused
-// 12 modifier (including virama)
-// 11 virama modifier
-// 10..8 joining type
-// 7..3 category type
-// }
-// 2 use xor pattern
-// 1..0 mapped category
-//
-// See the definitions below for a more detailed description of the various
-// bits.
-type info uint16
-
-const (
- catSmallMask = 0x3
- catBigMask = 0xF8
- indexShift = 3
- xorBit = 0x4 // interpret the index as an xor pattern
- inlineXOR = 0xE000 // These bits are set if the XOR pattern is inlined.
-
- joinShift = 8
- joinMask = 0x07
-
- viramaModifier = 0x0800
- modifier = 0x1000
-)
-
-// A category corresponds to a category defined in the IDNA mapping table.
-type category uint16
-
-const (
- unknown category = 0 // not defined currently in unicode.
- mapped category = 1
- disallowedSTD3Mapped category = 2
- deviation category = 3
-)
-
-const (
- valid category = 0x08
- validNV8 category = 0x18
- validXV8 category = 0x28
- disallowed category = 0x40
- disallowedSTD3Valid category = 0x80
- ignored category = 0xC0
-)
-
-// join types and additional rune information
-const (
- joiningL = (iota + 1)
- joiningD
- joiningT
- joiningR
-
- //the following types are derived during processing
- joinZWJ
- joinZWNJ
- joinVirama
- numJoinTypes
-)
-
-func (c info) isMapped() bool {
- return c&0x3 != 0
-}
-
-func (c info) category() category {
- small := c & catSmallMask
- if small != 0 {
- return category(small)
- }
- return category(c & catBigMask)
-}
-
-func (c info) joinType() info {
- if c.isMapped() {
- return 0
- }
- return (c >> joinShift) & joinMask
-}
-
-func (c info) isModifier() bool {
- return c&(modifier|catSmallMask) == modifier
-}
-
-func (c info) isViramaModifier() bool {
- return c&(viramaModifier|catSmallMask) == viramaModifier
-}
diff --git a/vendor/golang.org/x/net/internal/timeseries/timeseries.go b/vendor/golang.org/x/net/internal/timeseries/timeseries.go
deleted file mode 100644
index 685f0e7ea..000000000
--- a/vendor/golang.org/x/net/internal/timeseries/timeseries.go
+++ /dev/null
@@ -1,525 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package timeseries implements a time series structure for stats collection.
-package timeseries // import "golang.org/x/net/internal/timeseries"
-
-import (
- "fmt"
- "log"
- "time"
-)
-
-const (
- timeSeriesNumBuckets = 64
- minuteHourSeriesNumBuckets = 60
-)
-
-var timeSeriesResolutions = []time.Duration{
- 1 * time.Second,
- 10 * time.Second,
- 1 * time.Minute,
- 10 * time.Minute,
- 1 * time.Hour,
- 6 * time.Hour,
- 24 * time.Hour, // 1 day
- 7 * 24 * time.Hour, // 1 week
- 4 * 7 * 24 * time.Hour, // 4 weeks
- 16 * 7 * 24 * time.Hour, // 16 weeks
-}
-
-var minuteHourSeriesResolutions = []time.Duration{
- 1 * time.Second,
- 1 * time.Minute,
-}
-
-// An Observable is a kind of data that can be aggregated in a time series.
-type Observable interface {
- Multiply(ratio float64) // Multiplies the data in self by a given ratio
- Add(other Observable) // Adds the data from a different observation to self
- Clear() // Clears the observation so it can be reused.
- CopyFrom(other Observable) // Copies the contents of a given observation to self
-}
-
-// Float attaches the methods of Observable to a float64.
-type Float float64
-
-// NewFloat returns a Float.
-func NewFloat() Observable {
- f := Float(0)
- return &f
-}
-
-// String returns the float as a string.
-func (f *Float) String() string { return fmt.Sprintf("%g", f.Value()) }
-
-// Value returns the float's value.
-func (f *Float) Value() float64 { return float64(*f) }
-
-func (f *Float) Multiply(ratio float64) { *f *= Float(ratio) }
-
-func (f *Float) Add(other Observable) {
- o := other.(*Float)
- *f += *o
-}
-
-func (f *Float) Clear() { *f = 0 }
-
-func (f *Float) CopyFrom(other Observable) {
- o := other.(*Float)
- *f = *o
-}
-
-// A Clock tells the current time.
-type Clock interface {
- Time() time.Time
-}
-
-type defaultClock int
-
-var defaultClockInstance defaultClock
-
-func (defaultClock) Time() time.Time { return time.Now() }
-
-// Information kept per level. Each level consists of a circular list of
-// observations. The start of the level may be derived from end and the
-// len(buckets) * sizeInMillis.
-type tsLevel struct {
- oldest int // index to oldest bucketed Observable
- newest int // index to newest bucketed Observable
- end time.Time // end timestamp for this level
- size time.Duration // duration of the bucketed Observable
- buckets []Observable // collections of observations
- provider func() Observable // used for creating new Observable
-}
-
-func (l *tsLevel) Clear() {
- l.oldest = 0
- l.newest = len(l.buckets) - 1
- l.end = time.Time{}
- for i := range l.buckets {
- if l.buckets[i] != nil {
- l.buckets[i].Clear()
- l.buckets[i] = nil
- }
- }
-}
-
-func (l *tsLevel) InitLevel(size time.Duration, numBuckets int, f func() Observable) {
- l.size = size
- l.provider = f
- l.buckets = make([]Observable, numBuckets)
-}
-
-// Keeps a sequence of levels. Each level is responsible for storing data at
-// a given resolution. For example, the first level stores data at a one
-// minute resolution while the second level stores data at a one hour
-// resolution.
-
-// Each level is represented by a sequence of buckets. Each bucket spans an
-// interval equal to the resolution of the level. New observations are added
-// to the last bucket.
-type timeSeries struct {
- provider func() Observable // make more Observable
- numBuckets int // number of buckets in each level
- levels []*tsLevel // levels of bucketed Observable
- lastAdd time.Time // time of last Observable tracked
- total Observable // convenient aggregation of all Observable
- clock Clock // Clock for getting current time
- pending Observable // observations not yet bucketed
- pendingTime time.Time // what time are we keeping in pending
- dirty bool // if there are pending observations
-}
-
-// init initializes a level according to the supplied criteria.
-func (ts *timeSeries) init(resolutions []time.Duration, f func() Observable, numBuckets int, clock Clock) {
- ts.provider = f
- ts.numBuckets = numBuckets
- ts.clock = clock
- ts.levels = make([]*tsLevel, len(resolutions))
-
- for i := range resolutions {
- if i > 0 && resolutions[i-1] >= resolutions[i] {
- log.Print("timeseries: resolutions must be monotonically increasing")
- break
- }
- newLevel := new(tsLevel)
- newLevel.InitLevel(resolutions[i], ts.numBuckets, ts.provider)
- ts.levels[i] = newLevel
- }
-
- ts.Clear()
-}
-
-// Clear removes all observations from the time series.
-func (ts *timeSeries) Clear() {
- ts.lastAdd = time.Time{}
- ts.total = ts.resetObservation(ts.total)
- ts.pending = ts.resetObservation(ts.pending)
- ts.pendingTime = time.Time{}
- ts.dirty = false
-
- for i := range ts.levels {
- ts.levels[i].Clear()
- }
-}
-
-// Add records an observation at the current time.
-func (ts *timeSeries) Add(observation Observable) {
- ts.AddWithTime(observation, ts.clock.Time())
-}
-
-// AddWithTime records an observation at the specified time.
-func (ts *timeSeries) AddWithTime(observation Observable, t time.Time) {
-
- smallBucketDuration := ts.levels[0].size
-
- if t.After(ts.lastAdd) {
- ts.lastAdd = t
- }
-
- if t.After(ts.pendingTime) {
- ts.advance(t)
- ts.mergePendingUpdates()
- ts.pendingTime = ts.levels[0].end
- ts.pending.CopyFrom(observation)
- ts.dirty = true
- } else if t.After(ts.pendingTime.Add(-1 * smallBucketDuration)) {
- // The observation is close enough to go into the pending bucket.
- // This compensates for clock skewing and small scheduling delays
- // by letting the update stay in the fast path.
- ts.pending.Add(observation)
- ts.dirty = true
- } else {
- ts.mergeValue(observation, t)
- }
-}
-
-// mergeValue inserts the observation at the specified time in the past into all levels.
-func (ts *timeSeries) mergeValue(observation Observable, t time.Time) {
- for _, level := range ts.levels {
- index := (ts.numBuckets - 1) - int(level.end.Sub(t)/level.size)
- if 0 <= index && index < ts.numBuckets {
- bucketNumber := (level.oldest + index) % ts.numBuckets
- if level.buckets[bucketNumber] == nil {
- level.buckets[bucketNumber] = level.provider()
- }
- level.buckets[bucketNumber].Add(observation)
- }
- }
- ts.total.Add(observation)
-}
-
-// mergePendingUpdates applies the pending updates into all levels.
-func (ts *timeSeries) mergePendingUpdates() {
- if ts.dirty {
- ts.mergeValue(ts.pending, ts.pendingTime)
- ts.pending = ts.resetObservation(ts.pending)
- ts.dirty = false
- }
-}
-
-// advance cycles the buckets at each level until the latest bucket in
-// each level can hold the time specified.
-func (ts *timeSeries) advance(t time.Time) {
- if !t.After(ts.levels[0].end) {
- return
- }
- for i := 0; i < len(ts.levels); i++ {
- level := ts.levels[i]
- if !level.end.Before(t) {
- break
- }
-
- // If the time is sufficiently far, just clear the level and advance
- // directly.
- if !t.Before(level.end.Add(level.size * time.Duration(ts.numBuckets))) {
- for _, b := range level.buckets {
- ts.resetObservation(b)
- }
- level.end = time.Unix(0, (t.UnixNano()/level.size.Nanoseconds())*level.size.Nanoseconds())
- }
-
- for t.After(level.end) {
- level.end = level.end.Add(level.size)
- level.newest = level.oldest
- level.oldest = (level.oldest + 1) % ts.numBuckets
- ts.resetObservation(level.buckets[level.newest])
- }
-
- t = level.end
- }
-}
-
-// Latest returns the sum of the num latest buckets from the level.
-func (ts *timeSeries) Latest(level, num int) Observable {
- now := ts.clock.Time()
- if ts.levels[0].end.Before(now) {
- ts.advance(now)
- }
-
- ts.mergePendingUpdates()
-
- result := ts.provider()
- l := ts.levels[level]
- index := l.newest
-
- for i := 0; i < num; i++ {
- if l.buckets[index] != nil {
- result.Add(l.buckets[index])
- }
- if index == 0 {
- index = ts.numBuckets
- }
- index--
- }
-
- return result
-}
-
-// LatestBuckets returns a copy of the num latest buckets from level.
-func (ts *timeSeries) LatestBuckets(level, num int) []Observable {
- if level < 0 || level > len(ts.levels) {
- log.Print("timeseries: bad level argument: ", level)
- return nil
- }
- if num < 0 || num >= ts.numBuckets {
- log.Print("timeseries: bad num argument: ", num)
- return nil
- }
-
- results := make([]Observable, num)
- now := ts.clock.Time()
- if ts.levels[0].end.Before(now) {
- ts.advance(now)
- }
-
- ts.mergePendingUpdates()
-
- l := ts.levels[level]
- index := l.newest
-
- for i := 0; i < num; i++ {
- result := ts.provider()
- results[i] = result
- if l.buckets[index] != nil {
- result.CopyFrom(l.buckets[index])
- }
-
- if index == 0 {
- index = ts.numBuckets
- }
- index -= 1
- }
- return results
-}
-
-// ScaleBy updates observations by scaling by factor.
-func (ts *timeSeries) ScaleBy(factor float64) {
- for _, l := range ts.levels {
- for i := 0; i < ts.numBuckets; i++ {
- l.buckets[i].Multiply(factor)
- }
- }
-
- ts.total.Multiply(factor)
- ts.pending.Multiply(factor)
-}
-
-// Range returns the sum of observations added over the specified time range.
-// If start or finish times don't fall on bucket boundaries of the same
-// level, then return values are approximate answers.
-func (ts *timeSeries) Range(start, finish time.Time) Observable {
- return ts.ComputeRange(start, finish, 1)[0]
-}
-
-// Recent returns the sum of observations from the last delta.
-func (ts *timeSeries) Recent(delta time.Duration) Observable {
- now := ts.clock.Time()
- return ts.Range(now.Add(-delta), now)
-}
-
-// Total returns the total of all observations.
-func (ts *timeSeries) Total() Observable {
- ts.mergePendingUpdates()
- return ts.total
-}
-
-// ComputeRange computes a specified number of values into a slice using
-// the observations recorded over the specified time period. The return
-// values are approximate if the start or finish times don't fall on the
-// bucket boundaries at the same level or if the number of buckets spanning
-// the range is not an integral multiple of num.
-func (ts *timeSeries) ComputeRange(start, finish time.Time, num int) []Observable {
- if start.After(finish) {
- log.Printf("timeseries: start > finish, %v>%v", start, finish)
- return nil
- }
-
- if num < 0 {
- log.Printf("timeseries: num < 0, %v", num)
- return nil
- }
-
- results := make([]Observable, num)
-
- for _, l := range ts.levels {
- if !start.Before(l.end.Add(-l.size * time.Duration(ts.numBuckets))) {
- ts.extract(l, start, finish, num, results)
- return results
- }
- }
-
- // Failed to find a level that covers the desired range. So just
- // extract from the last level, even if it doesn't cover the entire
- // desired range.
- ts.extract(ts.levels[len(ts.levels)-1], start, finish, num, results)
-
- return results
-}
-
-// RecentList returns the specified number of values in slice over the most
-// recent time period of the specified range.
-func (ts *timeSeries) RecentList(delta time.Duration, num int) []Observable {
- if delta < 0 {
- return nil
- }
- now := ts.clock.Time()
- return ts.ComputeRange(now.Add(-delta), now, num)
-}
-
-// extract returns a slice of specified number of observations from a given
-// level over a given range.
-func (ts *timeSeries) extract(l *tsLevel, start, finish time.Time, num int, results []Observable) {
- ts.mergePendingUpdates()
-
- srcInterval := l.size
- dstInterval := finish.Sub(start) / time.Duration(num)
- dstStart := start
- srcStart := l.end.Add(-srcInterval * time.Duration(ts.numBuckets))
-
- srcIndex := 0
-
- // Where should scanning start?
- if dstStart.After(srcStart) {
- advance := dstStart.Sub(srcStart) / srcInterval
- srcIndex += int(advance)
- srcStart = srcStart.Add(advance * srcInterval)
- }
-
- // The i'th value is computed as show below.
- // interval = (finish/start)/num
- // i'th value = sum of observation in range
- // [ start + i * interval,
- // start + (i + 1) * interval )
- for i := 0; i < num; i++ {
- results[i] = ts.resetObservation(results[i])
- dstEnd := dstStart.Add(dstInterval)
- for srcIndex < ts.numBuckets && srcStart.Before(dstEnd) {
- srcEnd := srcStart.Add(srcInterval)
- if srcEnd.After(ts.lastAdd) {
- srcEnd = ts.lastAdd
- }
-
- if !srcEnd.Before(dstStart) {
- srcValue := l.buckets[(srcIndex+l.oldest)%ts.numBuckets]
- if !srcStart.Before(dstStart) && !srcEnd.After(dstEnd) {
- // dst completely contains src.
- if srcValue != nil {
- results[i].Add(srcValue)
- }
- } else {
- // dst partially overlaps src.
- overlapStart := maxTime(srcStart, dstStart)
- overlapEnd := minTime(srcEnd, dstEnd)
- base := srcEnd.Sub(srcStart)
- fraction := overlapEnd.Sub(overlapStart).Seconds() / base.Seconds()
-
- used := ts.provider()
- if srcValue != nil {
- used.CopyFrom(srcValue)
- }
- used.Multiply(fraction)
- results[i].Add(used)
- }
-
- if srcEnd.After(dstEnd) {
- break
- }
- }
- srcIndex++
- srcStart = srcStart.Add(srcInterval)
- }
- dstStart = dstStart.Add(dstInterval)
- }
-}
-
-// resetObservation clears the content so the struct may be reused.
-func (ts *timeSeries) resetObservation(observation Observable) Observable {
- if observation == nil {
- observation = ts.provider()
- } else {
- observation.Clear()
- }
- return observation
-}
-
-// TimeSeries tracks data at granularities from 1 second to 16 weeks.
-type TimeSeries struct {
- timeSeries
-}
-
-// NewTimeSeries creates a new TimeSeries using the function provided for creating new Observable.
-func NewTimeSeries(f func() Observable) *TimeSeries {
- return NewTimeSeriesWithClock(f, defaultClockInstance)
-}
-
-// NewTimeSeriesWithClock creates a new TimeSeries using the function provided for creating new Observable and the clock for
-// assigning timestamps.
-func NewTimeSeriesWithClock(f func() Observable, clock Clock) *TimeSeries {
- ts := new(TimeSeries)
- ts.timeSeries.init(timeSeriesResolutions, f, timeSeriesNumBuckets, clock)
- return ts
-}
-
-// MinuteHourSeries tracks data at granularities of 1 minute and 1 hour.
-type MinuteHourSeries struct {
- timeSeries
-}
-
-// NewMinuteHourSeries creates a new MinuteHourSeries using the function provided for creating new Observable.
-func NewMinuteHourSeries(f func() Observable) *MinuteHourSeries {
- return NewMinuteHourSeriesWithClock(f, defaultClockInstance)
-}
-
-// NewMinuteHourSeriesWithClock creates a new MinuteHourSeries using the function provided for creating new Observable and the clock for
-// assigning timestamps.
-func NewMinuteHourSeriesWithClock(f func() Observable, clock Clock) *MinuteHourSeries {
- ts := new(MinuteHourSeries)
- ts.timeSeries.init(minuteHourSeriesResolutions, f,
- minuteHourSeriesNumBuckets, clock)
- return ts
-}
-
-func (ts *MinuteHourSeries) Minute() Observable {
- return ts.timeSeries.Latest(0, 60)
-}
-
-func (ts *MinuteHourSeries) Hour() Observable {
- return ts.timeSeries.Latest(1, 60)
-}
-
-func minTime(a, b time.Time) time.Time {
- if a.Before(b) {
- return a
- }
- return b
-}
-
-func maxTime(a, b time.Time) time.Time {
- if a.After(b) {
- return a
- }
- return b
-}
diff --git a/vendor/golang.org/x/net/internal/timeseries/timeseries_test.go b/vendor/golang.org/x/net/internal/timeseries/timeseries_test.go
deleted file mode 100644
index 66325a912..000000000
--- a/vendor/golang.org/x/net/internal/timeseries/timeseries_test.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package timeseries
-
-import (
- "math"
- "testing"
- "time"
-)
-
-func isNear(x *Float, y float64, tolerance float64) bool {
- return math.Abs(x.Value()-y) < tolerance
-}
-
-func isApproximate(x *Float, y float64) bool {
- return isNear(x, y, 1e-2)
-}
-
-func checkApproximate(t *testing.T, o Observable, y float64) {
- x := o.(*Float)
- if !isApproximate(x, y) {
- t.Errorf("Wanted %g, got %g", y, x.Value())
- }
-}
-
-func checkNear(t *testing.T, o Observable, y, tolerance float64) {
- x := o.(*Float)
- if !isNear(x, y, tolerance) {
- t.Errorf("Wanted %g +- %g, got %g", y, tolerance, x.Value())
- }
-}
-
-var baseTime = time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC)
-
-func tu(s int64) time.Time {
- return baseTime.Add(time.Duration(s) * time.Second)
-}
-
-func tu2(s int64, ns int64) time.Time {
- return baseTime.Add(time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond)
-}
-
-func TestBasicTimeSeries(t *testing.T) {
- ts := NewTimeSeries(NewFloat)
- fo := new(Float)
- *fo = Float(10)
- ts.AddWithTime(fo, tu(1))
- ts.AddWithTime(fo, tu(1))
- ts.AddWithTime(fo, tu(1))
- ts.AddWithTime(fo, tu(1))
- checkApproximate(t, ts.Range(tu(0), tu(1)), 40)
- checkApproximate(t, ts.Total(), 40)
- ts.AddWithTime(fo, tu(3))
- ts.AddWithTime(fo, tu(3))
- ts.AddWithTime(fo, tu(3))
- checkApproximate(t, ts.Range(tu(0), tu(2)), 40)
- checkApproximate(t, ts.Range(tu(2), tu(4)), 30)
- checkApproximate(t, ts.Total(), 70)
- ts.AddWithTime(fo, tu(1))
- ts.AddWithTime(fo, tu(1))
- checkApproximate(t, ts.Range(tu(0), tu(2)), 60)
- checkApproximate(t, ts.Range(tu(2), tu(4)), 30)
- checkApproximate(t, ts.Total(), 90)
- *fo = Float(100)
- ts.AddWithTime(fo, tu(100))
- checkApproximate(t, ts.Range(tu(99), tu(100)), 100)
- checkApproximate(t, ts.Range(tu(0), tu(4)), 36)
- checkApproximate(t, ts.Total(), 190)
- *fo = Float(10)
- ts.AddWithTime(fo, tu(1))
- ts.AddWithTime(fo, tu(1))
- checkApproximate(t, ts.Range(tu(0), tu(4)), 44)
- checkApproximate(t, ts.Range(tu(37), tu2(100, 100e6)), 100)
- checkApproximate(t, ts.Range(tu(50), tu2(100, 100e6)), 100)
- checkApproximate(t, ts.Range(tu(99), tu2(100, 100e6)), 100)
- checkApproximate(t, ts.Total(), 210)
-
- for i, l := range ts.ComputeRange(tu(36), tu(100), 64) {
- if i == 63 {
- checkApproximate(t, l, 100)
- } else {
- checkApproximate(t, l, 0)
- }
- }
-
- checkApproximate(t, ts.Range(tu(0), tu(100)), 210)
- checkApproximate(t, ts.Range(tu(10), tu(100)), 100)
-
- for i, l := range ts.ComputeRange(tu(0), tu(100), 100) {
- if i < 10 {
- checkApproximate(t, l, 11)
- } else if i >= 90 {
- checkApproximate(t, l, 10)
- } else {
- checkApproximate(t, l, 0)
- }
- }
-}
-
-func TestFloat(t *testing.T) {
- f := Float(1)
- if g, w := f.String(), "1"; g != w {
- t.Errorf("Float(1).String = %q; want %q", g, w)
- }
- f2 := Float(2)
- var o Observable = &f2
- f.Add(o)
- if g, w := f.Value(), 3.0; g != w {
- t.Errorf("Float post-add = %v; want %v", g, w)
- }
- f.Multiply(2)
- if g, w := f.Value(), 6.0; g != w {
- t.Errorf("Float post-multiply = %v; want %v", g, w)
- }
- f.Clear()
- if g, w := f.Value(), 0.0; g != w {
- t.Errorf("Float post-clear = %v; want %v", g, w)
- }
- f.CopyFrom(&f2)
- if g, w := f.Value(), 2.0; g != w {
- t.Errorf("Float post-CopyFrom = %v; want %v", g, w)
- }
-}
-
-type mockClock struct {
- time time.Time
-}
-
-func (m *mockClock) Time() time.Time { return m.time }
-func (m *mockClock) Set(t time.Time) { m.time = t }
-
-const buckets = 6
-
-var testResolutions = []time.Duration{
- 10 * time.Second, // level holds one minute of observations
- 100 * time.Second, // level holds ten minutes of observations
- 10 * time.Minute, // level holds one hour of observations
-}
-
-// TestTimeSeries uses a small number of buckets to force a higher
-// error rate on approximations from the timeseries.
-type TestTimeSeries struct {
- timeSeries
-}
-
-func TestExpectedErrorRate(t *testing.T) {
- ts := new(TestTimeSeries)
- fake := new(mockClock)
- fake.Set(time.Now())
- ts.timeSeries.init(testResolutions, NewFloat, buckets, fake)
- for i := 1; i <= 61*61; i++ {
- fake.Set(fake.Time().Add(1 * time.Second))
- ob := Float(1)
- ts.AddWithTime(&ob, fake.Time())
-
- // The results should be accurate within one missing bucket (1/6) of the observations recorded.
- checkNear(t, ts.Latest(0, buckets), min(float64(i), 60), 10)
- checkNear(t, ts.Latest(1, buckets), min(float64(i), 600), 100)
- checkNear(t, ts.Latest(2, buckets), min(float64(i), 3600), 600)
- }
-}
-
-func min(a, b float64) float64 {
- if a < b {
- return a
- }
- return b
-}
diff --git a/vendor/golang.org/x/net/lex/httplex/httplex.go b/vendor/golang.org/x/net/lex/httplex/httplex.go
deleted file mode 100644
index 20f2b8940..000000000
--- a/vendor/golang.org/x/net/lex/httplex/httplex.go
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package httplex contains rules around lexical matters of various
-// HTTP-related specifications.
-//
-// This package is shared by the standard library (which vendors it)
-// and x/net/http2. It comes with no API stability promise.
-package httplex
-
-import (
- "net"
- "strings"
- "unicode/utf8"
-
- "golang.org/x/net/idna"
-)
-
-var isTokenTable = [127]bool{
- '!': true,
- '#': true,
- '$': true,
- '%': true,
- '&': true,
- '\'': true,
- '*': true,
- '+': true,
- '-': true,
- '.': true,
- '0': true,
- '1': true,
- '2': true,
- '3': true,
- '4': true,
- '5': true,
- '6': true,
- '7': true,
- '8': true,
- '9': true,
- 'A': true,
- 'B': true,
- 'C': true,
- 'D': true,
- 'E': true,
- 'F': true,
- 'G': true,
- 'H': true,
- 'I': true,
- 'J': true,
- 'K': true,
- 'L': true,
- 'M': true,
- 'N': true,
- 'O': true,
- 'P': true,
- 'Q': true,
- 'R': true,
- 'S': true,
- 'T': true,
- 'U': true,
- 'W': true,
- 'V': true,
- 'X': true,
- 'Y': true,
- 'Z': true,
- '^': true,
- '_': true,
- '`': true,
- 'a': true,
- 'b': true,
- 'c': true,
- 'd': true,
- 'e': true,
- 'f': true,
- 'g': true,
- 'h': true,
- 'i': true,
- 'j': true,
- 'k': true,
- 'l': true,
- 'm': true,
- 'n': true,
- 'o': true,
- 'p': true,
- 'q': true,
- 'r': true,
- 's': true,
- 't': true,
- 'u': true,
- 'v': true,
- 'w': true,
- 'x': true,
- 'y': true,
- 'z': true,
- '|': true,
- '~': true,
-}
-
-func IsTokenRune(r rune) bool {
- i := int(r)
- return i < len(isTokenTable) && isTokenTable[i]
-}
-
-func isNotToken(r rune) bool {
- return !IsTokenRune(r)
-}
-
-// HeaderValuesContainsToken reports whether any string in values
-// contains the provided token, ASCII case-insensitively.
-func HeaderValuesContainsToken(values []string, token string) bool {
- for _, v := range values {
- if headerValueContainsToken(v, token) {
- return true
- }
- }
- return false
-}
-
-// isOWS reports whether b is an optional whitespace byte, as defined
-// by RFC 7230 section 3.2.3.
-func isOWS(b byte) bool { return b == ' ' || b == '\t' }
-
-// trimOWS returns x with all optional whitespace removes from the
-// beginning and end.
-func trimOWS(x string) string {
- // TODO: consider using strings.Trim(x, " \t") instead,
- // if and when it's fast enough. See issue 10292.
- // But this ASCII-only code will probably always beat UTF-8
- // aware code.
- for len(x) > 0 && isOWS(x[0]) {
- x = x[1:]
- }
- for len(x) > 0 && isOWS(x[len(x)-1]) {
- x = x[:len(x)-1]
- }
- return x
-}
-
-// headerValueContainsToken reports whether v (assumed to be a
-// 0#element, in the ABNF extension described in RFC 7230 section 7)
-// contains token amongst its comma-separated tokens, ASCII
-// case-insensitively.
-func headerValueContainsToken(v string, token string) bool {
- v = trimOWS(v)
- if comma := strings.IndexByte(v, ','); comma != -1 {
- return tokenEqual(trimOWS(v[:comma]), token) || headerValueContainsToken(v[comma+1:], token)
- }
- return tokenEqual(v, token)
-}
-
-// lowerASCII returns the ASCII lowercase version of b.
-func lowerASCII(b byte) byte {
- if 'A' <= b && b <= 'Z' {
- return b + ('a' - 'A')
- }
- return b
-}
-
-// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.
-func tokenEqual(t1, t2 string) bool {
- if len(t1) != len(t2) {
- return false
- }
- for i, b := range t1 {
- if b >= utf8.RuneSelf {
- // No UTF-8 or non-ASCII allowed in tokens.
- return false
- }
- if lowerASCII(byte(b)) != lowerASCII(t2[i]) {
- return false
- }
- }
- return true
-}
-
-// isLWS reports whether b is linear white space, according
-// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
-// LWS = [CRLF] 1*( SP | HT )
-func isLWS(b byte) bool { return b == ' ' || b == '\t' }
-
-// isCTL reports whether b is a control byte, according
-// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
-// CTL = <any US-ASCII control character
-// (octets 0 - 31) and DEL (127)>
-func isCTL(b byte) bool {
- const del = 0x7f // a CTL
- return b < ' ' || b == del
-}
-
-// ValidHeaderFieldName reports whether v is a valid HTTP/1.x header name.
-// HTTP/2 imposes the additional restriction that uppercase ASCII
-// letters are not allowed.
-//
-// RFC 7230 says:
-// header-field = field-name ":" OWS field-value OWS
-// field-name = token
-// token = 1*tchar
-// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
-// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
-func ValidHeaderFieldName(v string) bool {
- if len(v) == 0 {
- return false
- }
- for _, r := range v {
- if !IsTokenRune(r) {
- return false
- }
- }
- return true
-}
-
-// ValidHostHeader reports whether h is a valid host header.
-func ValidHostHeader(h string) bool {
- // The latest spec is actually this:
- //
- // http://tools.ietf.org/html/rfc7230#section-5.4
- // Host = uri-host [ ":" port ]
- //
- // Where uri-host is:
- // http://tools.ietf.org/html/rfc3986#section-3.2.2
- //
- // But we're going to be much more lenient for now and just
- // search for any byte that's not a valid byte in any of those
- // expressions.
- for i := 0; i < len(h); i++ {
- if !validHostByte[h[i]] {
- return false
- }
- }
- return true
-}
-
-// See the validHostHeader comment.
-var validHostByte = [256]bool{
- '0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true,
- '8': true, '9': true,
-
- 'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true,
- 'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true,
- 'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true,
- 'y': true, 'z': true,
-
- 'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true,
- 'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true,
- 'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true,
- 'Y': true, 'Z': true,
-
- '!': true, // sub-delims
- '$': true, // sub-delims
- '%': true, // pct-encoded (and used in IPv6 zones)
- '&': true, // sub-delims
- '(': true, // sub-delims
- ')': true, // sub-delims
- '*': true, // sub-delims
- '+': true, // sub-delims
- ',': true, // sub-delims
- '-': true, // unreserved
- '.': true, // unreserved
- ':': true, // IPv6address + Host expression's optional port
- ';': true, // sub-delims
- '=': true, // sub-delims
- '[': true,
- '\'': true, // sub-delims
- ']': true,
- '_': true, // unreserved
- '~': true, // unreserved
-}
-
-// ValidHeaderFieldValue reports whether v is a valid "field-value" according to
-// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
-//
-// message-header = field-name ":" [ field-value ]
-// field-value = *( field-content | LWS )
-// field-content = <the OCTETs making up the field-value
-// and consisting of either *TEXT or combinations
-// of token, separators, and quoted-string>
-//
-// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
-//
-// TEXT = <any OCTET except CTLs,
-// but including LWS>
-// LWS = [CRLF] 1*( SP | HT )
-// CTL = <any US-ASCII control character
-// (octets 0 - 31) and DEL (127)>
-//
-// RFC 7230 says:
-// field-value = *( field-content / obs-fold )
-// obj-fold = N/A to http2, and deprecated
-// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
-// field-vchar = VCHAR / obs-text
-// obs-text = %x80-FF
-// VCHAR = "any visible [USASCII] character"
-//
-// http2 further says: "Similarly, HTTP/2 allows header field values
-// that are not valid. While most of the values that can be encoded
-// will not alter header field parsing, carriage return (CR, ASCII
-// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
-// 0x0) might be exploited by an attacker if they are translated
-// verbatim. Any request or response that contains a character not
-// permitted in a header field value MUST be treated as malformed
-// (Section 8.1.2.6). Valid characters are defined by the
-// field-content ABNF rule in Section 3.2 of [RFC7230]."
-//
-// This function does not (yet?) properly handle the rejection of
-// strings that begin or end with SP or HTAB.
-func ValidHeaderFieldValue(v string) bool {
- for i := 0; i < len(v); i++ {
- b := v[i]
- if isCTL(b) && !isLWS(b) {
- return false
- }
- }
- return true
-}
-
-func isASCII(s string) bool {
- for i := 0; i < len(s); i++ {
- if s[i] >= utf8.RuneSelf {
- return false
- }
- }
- return true
-}
-
-// PunycodeHostPort returns the IDNA Punycode version
-// of the provided "host" or "host:port" string.
-func PunycodeHostPort(v string) (string, error) {
- if isASCII(v) {
- return v, nil
- }
-
- host, port, err := net.SplitHostPort(v)
- if err != nil {
- // The input 'v' argument was just a "host" argument,
- // without a port. This error should not be returned
- // to the caller.
- host = v
- port = ""
- }
- host, err = idna.ToASCII(host)
- if err != nil {
- // Non-UTF-8? Not representable in Punycode, in any
- // case.
- return "", err
- }
- if port == "" {
- return host, nil
- }
- return net.JoinHostPort(host, port), nil
-}
diff --git a/vendor/golang.org/x/net/lex/httplex/httplex_test.go b/vendor/golang.org/x/net/lex/httplex/httplex_test.go
deleted file mode 100644
index f47adc939..000000000
--- a/vendor/golang.org/x/net/lex/httplex/httplex_test.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package httplex
-
-import (
- "testing"
-)
-
-func isChar(c rune) bool { return c <= 127 }
-
-func isCtl(c rune) bool { return c <= 31 || c == 127 }
-
-func isSeparator(c rune) bool {
- switch c {
- case '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t':
- return true
- }
- return false
-}
-
-func TestIsToken(t *testing.T) {
- for i := 0; i <= 130; i++ {
- r := rune(i)
- expected := isChar(r) && !isCtl(r) && !isSeparator(r)
- if IsTokenRune(r) != expected {
- t.Errorf("isToken(0x%x) = %v", r, !expected)
- }
- }
-}
-
-func TestHeaderValuesContainsToken(t *testing.T) {
- tests := []struct {
- vals []string
- token string
- want bool
- }{
- {
- vals: []string{"foo"},
- token: "foo",
- want: true,
- },
- {
- vals: []string{"bar", "foo"},
- token: "foo",
- want: true,
- },
- {
- vals: []string{"foo"},
- token: "FOO",
- want: true,
- },
- {
- vals: []string{"foo"},
- token: "bar",
- want: false,
- },
- {
- vals: []string{" foo "},
- token: "FOO",
- want: true,
- },
- {
- vals: []string{"foo,bar"},
- token: "FOO",
- want: true,
- },
- {
- vals: []string{"bar,foo,bar"},
- token: "FOO",
- want: true,
- },
- {
- vals: []string{"bar , foo"},
- token: "FOO",
- want: true,
- },
- {
- vals: []string{"foo ,bar "},
- token: "FOO",
- want: true,
- },
- {
- vals: []string{"bar, foo ,bar"},
- token: "FOO",
- want: true,
- },
- {
- vals: []string{"bar , foo"},
- token: "FOO",
- want: true,
- },
- }
- for _, tt := range tests {
- got := HeaderValuesContainsToken(tt.vals, tt.token)
- if got != tt.want {
- t.Errorf("headerValuesContainsToken(%q, %q) = %v; want %v", tt.vals, tt.token, got, tt.want)
- }
- }
-}
-
-func TestPunycodeHostPort(t *testing.T) {
- tests := []struct {
- in, want string
- }{
- {"www.google.com", "www.google.com"},
- {"гофер.рф", "xn--c1ae0ajs.xn--p1ai"},
- {"bücher.de", "xn--bcher-kva.de"},
- {"bücher.de:8080", "xn--bcher-kva.de:8080"},
- {"[1::6]:8080", "[1::6]:8080"},
- }
- for _, tt := range tests {
- got, err := PunycodeHostPort(tt.in)
- if tt.want != got || err != nil {
- t.Errorf("PunycodeHostPort(%q) = %q, %v, want %q, nil", tt.in, got, err, tt.want)
- }
- }
-}
diff --git a/vendor/golang.org/x/net/trace/events.go b/vendor/golang.org/x/net/trace/events.go
deleted file mode 100644
index d8daec1a7..000000000
--- a/vendor/golang.org/x/net/trace/events.go
+++ /dev/null
@@ -1,532 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package trace
-
-import (
- "bytes"
- "fmt"
- "html/template"
- "io"
- "log"
- "net/http"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "text/tabwriter"
- "time"
-)
-
-const maxEventsPerLog = 100
-
-type bucket struct {
- MaxErrAge time.Duration
- String string
-}
-
-var buckets = []bucket{
- {0, "total"},
- {10 * time.Second, "errs<10s"},
- {1 * time.Minute, "errs<1m"},
- {10 * time.Minute, "errs<10m"},
- {1 * time.Hour, "errs<1h"},
- {10 * time.Hour, "errs<10h"},
- {24000 * time.Hour, "errors"},
-}
-
-// RenderEvents renders the HTML page typically served at /debug/events.
-// It does not do any auth checking; see AuthRequest for the default auth check
-// used by the handler registered on http.DefaultServeMux.
-// req may be nil.
-func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) {
- now := time.Now()
- data := &struct {
- Families []string // family names
- Buckets []bucket
- Counts [][]int // eventLog count per family/bucket
-
- // Set when a bucket has been selected.
- Family string
- Bucket int
- EventLogs eventLogs
- Expanded bool
- }{
- Buckets: buckets,
- }
-
- data.Families = make([]string, 0, len(families))
- famMu.RLock()
- for name := range families {
- data.Families = append(data.Families, name)
- }
- famMu.RUnlock()
- sort.Strings(data.Families)
-
- // Count the number of eventLogs in each family for each error age.
- data.Counts = make([][]int, len(data.Families))
- for i, name := range data.Families {
- // TODO(sameer): move this loop under the family lock.
- f := getEventFamily(name)
- data.Counts[i] = make([]int, len(data.Buckets))
- for j, b := range data.Buckets {
- data.Counts[i][j] = f.Count(now, b.MaxErrAge)
- }
- }
-
- if req != nil {
- var ok bool
- data.Family, data.Bucket, ok = parseEventsArgs(req)
- if !ok {
- // No-op
- } else {
- data.EventLogs = getEventFamily(data.Family).Copy(now, buckets[data.Bucket].MaxErrAge)
- }
- if data.EventLogs != nil {
- defer data.EventLogs.Free()
- sort.Sort(data.EventLogs)
- }
- if exp, err := strconv.ParseBool(req.FormValue("exp")); err == nil {
- data.Expanded = exp
- }
- }
-
- famMu.RLock()
- defer famMu.RUnlock()
- if err := eventsTmpl().Execute(w, data); err != nil {
- log.Printf("net/trace: Failed executing template: %v", err)
- }
-}
-
-func parseEventsArgs(req *http.Request) (fam string, b int, ok bool) {
- fam, bStr := req.FormValue("fam"), req.FormValue("b")
- if fam == "" || bStr == "" {
- return "", 0, false
- }
- b, err := strconv.Atoi(bStr)
- if err != nil || b < 0 || b >= len(buckets) {
- return "", 0, false
- }
- return fam, b, true
-}
-
-// An EventLog provides a log of events associated with a specific object.
-type EventLog interface {
- // Printf formats its arguments with fmt.Sprintf and adds the
- // result to the event log.
- Printf(format string, a ...interface{})
-
- // Errorf is like Printf, but it marks this event as an error.
- Errorf(format string, a ...interface{})
-
- // Finish declares that this event log is complete.
- // The event log should not be used after calling this method.
- Finish()
-}
-
-// NewEventLog returns a new EventLog with the specified family name
-// and title.
-func NewEventLog(family, title string) EventLog {
- el := newEventLog()
- el.ref()
- el.Family, el.Title = family, title
- el.Start = time.Now()
- el.events = make([]logEntry, 0, maxEventsPerLog)
- el.stack = make([]uintptr, 32)
- n := runtime.Callers(2, el.stack)
- el.stack = el.stack[:n]
-
- getEventFamily(family).add(el)
- return el
-}
-
-func (el *eventLog) Finish() {
- getEventFamily(el.Family).remove(el)
- el.unref() // matches ref in New
-}
-
-var (
- famMu sync.RWMutex
- families = make(map[string]*eventFamily) // family name => family
-)
-
-func getEventFamily(fam string) *eventFamily {
- famMu.Lock()
- defer famMu.Unlock()
- f := families[fam]
- if f == nil {
- f = &eventFamily{}
- families[fam] = f
- }
- return f
-}
-
-type eventFamily struct {
- mu sync.RWMutex
- eventLogs eventLogs
-}
-
-func (f *eventFamily) add(el *eventLog) {
- f.mu.Lock()
- f.eventLogs = append(f.eventLogs, el)
- f.mu.Unlock()
-}
-
-func (f *eventFamily) remove(el *eventLog) {
- f.mu.Lock()
- defer f.mu.Unlock()
- for i, el0 := range f.eventLogs {
- if el == el0 {
- copy(f.eventLogs[i:], f.eventLogs[i+1:])
- f.eventLogs = f.eventLogs[:len(f.eventLogs)-1]
- return
- }
- }
-}
-
-func (f *eventFamily) Count(now time.Time, maxErrAge time.Duration) (n int) {
- f.mu.RLock()
- defer f.mu.RUnlock()
- for _, el := range f.eventLogs {
- if el.hasRecentError(now, maxErrAge) {
- n++
- }
- }
- return
-}
-
-func (f *eventFamily) Copy(now time.Time, maxErrAge time.Duration) (els eventLogs) {
- f.mu.RLock()
- defer f.mu.RUnlock()
- els = make(eventLogs, 0, len(f.eventLogs))
- for _, el := range f.eventLogs {
- if el.hasRecentError(now, maxErrAge) {
- el.ref()
- els = append(els, el)
- }
- }
- return
-}
-
-type eventLogs []*eventLog
-
-// Free calls unref on each element of the list.
-func (els eventLogs) Free() {
- for _, el := range els {
- el.unref()
- }
-}
-
-// eventLogs may be sorted in reverse chronological order.
-func (els eventLogs) Len() int { return len(els) }
-func (els eventLogs) Less(i, j int) bool { return els[i].Start.After(els[j].Start) }
-func (els eventLogs) Swap(i, j int) { els[i], els[j] = els[j], els[i] }
-
-// A logEntry is a timestamped log entry in an event log.
-type logEntry struct {
- When time.Time
- Elapsed time.Duration // since previous event in log
- NewDay bool // whether this event is on a different day to the previous event
- What string
- IsErr bool
-}
-
-// WhenString returns a string representation of the elapsed time of the event.
-// It will include the date if midnight was crossed.
-func (e logEntry) WhenString() string {
- if e.NewDay {
- return e.When.Format("2006/01/02 15:04:05.000000")
- }
- return e.When.Format("15:04:05.000000")
-}
-
-// An eventLog represents an active event log.
-type eventLog struct {
- // Family is the top-level grouping of event logs to which this belongs.
- Family string
-
- // Title is the title of this event log.
- Title string
-
- // Timing information.
- Start time.Time
-
- // Call stack where this event log was created.
- stack []uintptr
-
- // Append-only sequence of events.
- //
- // TODO(sameer): change this to a ring buffer to avoid the array copy
- // when we hit maxEventsPerLog.
- mu sync.RWMutex
- events []logEntry
- LastErrorTime time.Time
- discarded int
-
- refs int32 // how many buckets this is in
-}
-
-func (el *eventLog) reset() {
- // Clear all but the mutex. Mutexes may not be copied, even when unlocked.
- el.Family = ""
- el.Title = ""
- el.Start = time.Time{}
- el.stack = nil
- el.events = nil
- el.LastErrorTime = time.Time{}
- el.discarded = 0
- el.refs = 0
-}
-
-func (el *eventLog) hasRecentError(now time.Time, maxErrAge time.Duration) bool {
- if maxErrAge == 0 {
- return true
- }
- el.mu.RLock()
- defer el.mu.RUnlock()
- return now.Sub(el.LastErrorTime) < maxErrAge
-}
-
-// delta returns the elapsed time since the last event or the log start,
-// and whether it spans midnight.
-// L >= el.mu
-func (el *eventLog) delta(t time.Time) (time.Duration, bool) {
- if len(el.events) == 0 {
- return t.Sub(el.Start), false
- }
- prev := el.events[len(el.events)-1].When
- return t.Sub(prev), prev.Day() != t.Day()
-
-}
-
-func (el *eventLog) Printf(format string, a ...interface{}) {
- el.printf(false, format, a...)
-}
-
-func (el *eventLog) Errorf(format string, a ...interface{}) {
- el.printf(true, format, a...)
-}
-
-func (el *eventLog) printf(isErr bool, format string, a ...interface{}) {
- e := logEntry{When: time.Now(), IsErr: isErr, What: fmt.Sprintf(format, a...)}
- el.mu.Lock()
- e.Elapsed, e.NewDay = el.delta(e.When)
- if len(el.events) < maxEventsPerLog {
- el.events = append(el.events, e)
- } else {
- // Discard the oldest event.
- if el.discarded == 0 {
- // el.discarded starts at two to count for the event it
- // is replacing, plus the next one that we are about to
- // drop.
- el.discarded = 2
- } else {
- el.discarded++
- }
- // TODO(sameer): if this causes allocations on a critical path,
- // change eventLog.What to be a fmt.Stringer, as in trace.go.
- el.events[0].What = fmt.Sprintf("(%d events discarded)", el.discarded)
- // The timestamp of the discarded meta-event should be
- // the time of the last event it is representing.
- el.events[0].When = el.events[1].When
- copy(el.events[1:], el.events[2:])
- el.events[maxEventsPerLog-1] = e
- }
- if e.IsErr {
- el.LastErrorTime = e.When
- }
- el.mu.Unlock()
-}
-
-func (el *eventLog) ref() {
- atomic.AddInt32(&el.refs, 1)
-}
-
-func (el *eventLog) unref() {
- if atomic.AddInt32(&el.refs, -1) == 0 {
- freeEventLog(el)
- }
-}
-
-func (el *eventLog) When() string {
- return el.Start.Format("2006/01/02 15:04:05.000000")
-}
-
-func (el *eventLog) ElapsedTime() string {
- elapsed := time.Since(el.Start)
- return fmt.Sprintf("%.6f", elapsed.Seconds())
-}
-
-func (el *eventLog) Stack() string {
- buf := new(bytes.Buffer)
- tw := tabwriter.NewWriter(buf, 1, 8, 1, '\t', 0)
- printStackRecord(tw, el.stack)
- tw.Flush()
- return buf.String()
-}
-
-// printStackRecord prints the function + source line information
-// for a single stack trace.
-// Adapted from runtime/pprof/pprof.go.
-func printStackRecord(w io.Writer, stk []uintptr) {
- for _, pc := range stk {
- f := runtime.FuncForPC(pc)
- if f == nil {
- continue
- }
- file, line := f.FileLine(pc)
- name := f.Name()
- // Hide runtime.goexit and any runtime functions at the beginning.
- if strings.HasPrefix(name, "runtime.") {
- continue
- }
- fmt.Fprintf(w, "# %s\t%s:%d\n", name, file, line)
- }
-}
-
-func (el *eventLog) Events() []logEntry {
- el.mu.RLock()
- defer el.mu.RUnlock()
- return el.events
-}
-
-// freeEventLogs is a freelist of *eventLog
-var freeEventLogs = make(chan *eventLog, 1000)
-
-// newEventLog returns a event log ready to use.
-func newEventLog() *eventLog {
- select {
- case el := <-freeEventLogs:
- return el
- default:
- return new(eventLog)
- }
-}
-
-// freeEventLog adds el to freeEventLogs if there's room.
-// This is non-blocking.
-func freeEventLog(el *eventLog) {
- el.reset()
- select {
- case freeEventLogs <- el:
- default:
- }
-}
-
-var eventsTmplCache *template.Template
-var eventsTmplOnce sync.Once
-
-func eventsTmpl() *template.Template {
- eventsTmplOnce.Do(func() {
- eventsTmplCache = template.Must(template.New("events").Funcs(template.FuncMap{
- "elapsed": elapsed,
- "trimSpace": strings.TrimSpace,
- }).Parse(eventsHTML))
- })
- return eventsTmplCache
-}
-
-const eventsHTML = `
-<html>
- <head>
- <title>events</title>
- </head>
- <style type="text/css">
- body {
- font-family: sans-serif;
- }
- table#req-status td.family {
- padding-right: 2em;
- }
- table#req-status td.active {
- padding-right: 1em;
- }
- table#req-status td.empty {
- color: #aaa;
- }
- table#reqs {
- margin-top: 1em;
- }
- table#reqs tr.first {
- {{if $.Expanded}}font-weight: bold;{{end}}
- }
- table#reqs td {
- font-family: monospace;
- }
- table#reqs td.when {
- text-align: right;
- white-space: nowrap;
- }
- table#reqs td.elapsed {
- padding: 0 0.5em;
- text-align: right;
- white-space: pre;
- width: 10em;
- }
- address {
- font-size: smaller;
- margin-top: 5em;
- }
- </style>
- <body>
-
-<h1>/debug/events</h1>
-
-<table id="req-status">
- {{range $i, $fam := .Families}}
- <tr>
- <td class="family">{{$fam}}</td>
-
- {{range $j, $bucket := $.Buckets}}
- {{$n := index $.Counts $i $j}}
- <td class="{{if not $bucket.MaxErrAge}}active{{end}}{{if not $n}}empty{{end}}">
- {{if $n}}<a href="?fam={{$fam}}&b={{$j}}{{if $.Expanded}}&exp=1{{end}}">{{end}}
- [{{$n}} {{$bucket.String}}]
- {{if $n}}</a>{{end}}
- </td>
- {{end}}
-
- </tr>{{end}}
-</table>
-
-{{if $.EventLogs}}
-<hr />
-<h3>Family: {{$.Family}}</h3>
-
-{{if $.Expanded}}<a href="?fam={{$.Family}}&b={{$.Bucket}}">{{end}}
-[Summary]{{if $.Expanded}}</a>{{end}}
-
-{{if not $.Expanded}}<a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1">{{end}}
-[Expanded]{{if not $.Expanded}}</a>{{end}}
-
-<table id="reqs">
- <tr><th>When</th><th>Elapsed</th></tr>
- {{range $el := $.EventLogs}}
- <tr class="first">
- <td class="when">{{$el.When}}</td>
- <td class="elapsed">{{$el.ElapsedTime}}</td>
- <td>{{$el.Title}}
- </tr>
- {{if $.Expanded}}
- <tr>
- <td class="when"></td>
- <td class="elapsed"></td>
- <td><pre>{{$el.Stack|trimSpace}}</pre></td>
- </tr>
- {{range $el.Events}}
- <tr>
- <td class="when">{{.WhenString}}</td>
- <td class="elapsed">{{elapsed .Elapsed}}</td>
- <td>.{{if .IsErr}}E{{else}}.{{end}}. {{.What}}</td>
- </tr>
- {{end}}
- {{end}}
- {{end}}
-</table>
-{{end}}
- </body>
-</html>
-`
diff --git a/vendor/golang.org/x/net/trace/histogram.go b/vendor/golang.org/x/net/trace/histogram.go
deleted file mode 100644
index 9bf4286c7..000000000
--- a/vendor/golang.org/x/net/trace/histogram.go
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package trace
-
-// This file implements histogramming for RPC statistics collection.
-
-import (
- "bytes"
- "fmt"
- "html/template"
- "log"
- "math"
- "sync"
-
- "golang.org/x/net/internal/timeseries"
-)
-
-const (
- bucketCount = 38
-)
-
-// histogram keeps counts of values in buckets that are spaced
-// out in powers of 2: 0-1, 2-3, 4-7...
-// histogram implements timeseries.Observable
-type histogram struct {
- sum int64 // running total of measurements
- sumOfSquares float64 // square of running total
- buckets []int64 // bucketed values for histogram
- value int // holds a single value as an optimization
- valueCount int64 // number of values recorded for single value
-}
-
-// AddMeasurement records a value measurement observation to the histogram.
-func (h *histogram) addMeasurement(value int64) {
- // TODO: assert invariant
- h.sum += value
- h.sumOfSquares += float64(value) * float64(value)
-
- bucketIndex := getBucket(value)
-
- if h.valueCount == 0 || (h.valueCount > 0 && h.value == bucketIndex) {
- h.value = bucketIndex
- h.valueCount++
- } else {
- h.allocateBuckets()
- h.buckets[bucketIndex]++
- }
-}
-
-func (h *histogram) allocateBuckets() {
- if h.buckets == nil {
- h.buckets = make([]int64, bucketCount)
- h.buckets[h.value] = h.valueCount
- h.value = 0
- h.valueCount = -1
- }
-}
-
-func log2(i int64) int {
- n := 0
- for ; i >= 0x100; i >>= 8 {
- n += 8
- }
- for ; i > 0; i >>= 1 {
- n += 1
- }
- return n
-}
-
-func getBucket(i int64) (index int) {
- index = log2(i) - 1
- if index < 0 {
- index = 0
- }
- if index >= bucketCount {
- index = bucketCount - 1
- }
- return
-}
-
-// Total returns the number of recorded observations.
-func (h *histogram) total() (total int64) {
- if h.valueCount >= 0 {
- total = h.valueCount
- }
- for _, val := range h.buckets {
- total += int64(val)
- }
- return
-}
-
-// Average returns the average value of recorded observations.
-func (h *histogram) average() float64 {
- t := h.total()
- if t == 0 {
- return 0
- }
- return float64(h.sum) / float64(t)
-}
-
-// Variance returns the variance of recorded observations.
-func (h *histogram) variance() float64 {
- t := float64(h.total())
- if t == 0 {
- return 0
- }
- s := float64(h.sum) / t
- return h.sumOfSquares/t - s*s
-}
-
-// StandardDeviation returns the standard deviation of recorded observations.
-func (h *histogram) standardDeviation() float64 {
- return math.Sqrt(h.variance())
-}
-
-// PercentileBoundary estimates the value that the given fraction of recorded
-// observations are less than.
-func (h *histogram) percentileBoundary(percentile float64) int64 {
- total := h.total()
-
- // Corner cases (make sure result is strictly less than Total())
- if total == 0 {
- return 0
- } else if total == 1 {
- return int64(h.average())
- }
-
- percentOfTotal := round(float64(total) * percentile)
- var runningTotal int64
-
- for i := range h.buckets {
- value := h.buckets[i]
- runningTotal += value
- if runningTotal == percentOfTotal {
- // We hit an exact bucket boundary. If the next bucket has data, it is a
- // good estimate of the value. If the bucket is empty, we interpolate the
- // midpoint between the next bucket's boundary and the next non-zero
- // bucket. If the remaining buckets are all empty, then we use the
- // boundary for the next bucket as the estimate.
- j := uint8(i + 1)
- min := bucketBoundary(j)
- if runningTotal < total {
- for h.buckets[j] == 0 {
- j++
- }
- }
- max := bucketBoundary(j)
- return min + round(float64(max-min)/2)
- } else if runningTotal > percentOfTotal {
- // The value is in this bucket. Interpolate the value.
- delta := runningTotal - percentOfTotal
- percentBucket := float64(value-delta) / float64(value)
- bucketMin := bucketBoundary(uint8(i))
- nextBucketMin := bucketBoundary(uint8(i + 1))
- bucketSize := nextBucketMin - bucketMin
- return bucketMin + round(percentBucket*float64(bucketSize))
- }
- }
- return bucketBoundary(bucketCount - 1)
-}
-
-// Median returns the estimated median of the observed values.
-func (h *histogram) median() int64 {
- return h.percentileBoundary(0.5)
-}
-
-// Add adds other to h.
-func (h *histogram) Add(other timeseries.Observable) {
- o := other.(*histogram)
- if o.valueCount == 0 {
- // Other histogram is empty
- } else if h.valueCount >= 0 && o.valueCount > 0 && h.value == o.value {
- // Both have a single bucketed value, aggregate them
- h.valueCount += o.valueCount
- } else {
- // Two different values necessitate buckets in this histogram
- h.allocateBuckets()
- if o.valueCount >= 0 {
- h.buckets[o.value] += o.valueCount
- } else {
- for i := range h.buckets {
- h.buckets[i] += o.buckets[i]
- }
- }
- }
- h.sumOfSquares += o.sumOfSquares
- h.sum += o.sum
-}
-
-// Clear resets the histogram to an empty state, removing all observed values.
-func (h *histogram) Clear() {
- h.buckets = nil
- h.value = 0
- h.valueCount = 0
- h.sum = 0
- h.sumOfSquares = 0
-}
-
-// CopyFrom copies from other, which must be a *histogram, into h.
-func (h *histogram) CopyFrom(other timeseries.Observable) {
- o := other.(*histogram)
- if o.valueCount == -1 {
- h.allocateBuckets()
- copy(h.buckets, o.buckets)
- }
- h.sum = o.sum
- h.sumOfSquares = o.sumOfSquares
- h.value = o.value
- h.valueCount = o.valueCount
-}
-
-// Multiply scales the histogram by the specified ratio.
-func (h *histogram) Multiply(ratio float64) {
- if h.valueCount == -1 {
- for i := range h.buckets {
- h.buckets[i] = int64(float64(h.buckets[i]) * ratio)
- }
- } else {
- h.valueCount = int64(float64(h.valueCount) * ratio)
- }
- h.sum = int64(float64(h.sum) * ratio)
- h.sumOfSquares = h.sumOfSquares * ratio
-}
-
-// New creates a new histogram.
-func (h *histogram) New() timeseries.Observable {
- r := new(histogram)
- r.Clear()
- return r
-}
-
-func (h *histogram) String() string {
- return fmt.Sprintf("%d, %f, %d, %d, %v",
- h.sum, h.sumOfSquares, h.value, h.valueCount, h.buckets)
-}
-
-// round returns the closest int64 to the argument
-func round(in float64) int64 {
- return int64(math.Floor(in + 0.5))
-}
-
-// bucketBoundary returns the first value in the bucket.
-func bucketBoundary(bucket uint8) int64 {
- if bucket == 0 {
- return 0
- }
- return 1 << bucket
-}
-
-// bucketData holds data about a specific bucket for use in distTmpl.
-type bucketData struct {
- Lower, Upper int64
- N int64
- Pct, CumulativePct float64
- GraphWidth int
-}
-
-// data holds data about a Distribution for use in distTmpl.
-type data struct {
- Buckets []*bucketData
- Count, Median int64
- Mean, StandardDeviation float64
-}
-
-// maxHTMLBarWidth is the maximum width of the HTML bar for visualizing buckets.
-const maxHTMLBarWidth = 350.0
-
-// newData returns data representing h for use in distTmpl.
-func (h *histogram) newData() *data {
- // Force the allocation of buckets to simplify the rendering implementation
- h.allocateBuckets()
- // We scale the bars on the right so that the largest bar is
- // maxHTMLBarWidth pixels in width.
- maxBucket := int64(0)
- for _, n := range h.buckets {
- if n > maxBucket {
- maxBucket = n
- }
- }
- total := h.total()
- barsizeMult := maxHTMLBarWidth / float64(maxBucket)
- var pctMult float64
- if total == 0 {
- pctMult = 1.0
- } else {
- pctMult = 100.0 / float64(total)
- }
-
- buckets := make([]*bucketData, len(h.buckets))
- runningTotal := int64(0)
- for i, n := range h.buckets {
- if n == 0 {
- continue
- }
- runningTotal += n
- var upperBound int64
- if i < bucketCount-1 {
- upperBound = bucketBoundary(uint8(i + 1))
- } else {
- upperBound = math.MaxInt64
- }
- buckets[i] = &bucketData{
- Lower: bucketBoundary(uint8(i)),
- Upper: upperBound,
- N: n,
- Pct: float64(n) * pctMult,
- CumulativePct: float64(runningTotal) * pctMult,
- GraphWidth: int(float64(n) * barsizeMult),
- }
- }
- return &data{
- Buckets: buckets,
- Count: total,
- Median: h.median(),
- Mean: h.average(),
- StandardDeviation: h.standardDeviation(),
- }
-}
-
-func (h *histogram) html() template.HTML {
- buf := new(bytes.Buffer)
- if err := distTmpl().Execute(buf, h.newData()); err != nil {
- buf.Reset()
- log.Printf("net/trace: couldn't execute template: %v", err)
- }
- return template.HTML(buf.String())
-}
-
-var distTmplCache *template.Template
-var distTmplOnce sync.Once
-
-func distTmpl() *template.Template {
- distTmplOnce.Do(func() {
- // Input: data
- distTmplCache = template.Must(template.New("distTmpl").Parse(`
-<table>
-<tr>
- <td style="padding:0.25em">Count: {{.Count}}</td>
- <td style="padding:0.25em">Mean: {{printf "%.0f" .Mean}}</td>
- <td style="padding:0.25em">StdDev: {{printf "%.0f" .StandardDeviation}}</td>
- <td style="padding:0.25em">Median: {{.Median}}</td>
-</tr>
-</table>
-<hr>
-<table>
-{{range $b := .Buckets}}
-{{if $b}}
- <tr>
- <td style="padding:0 0 0 0.25em">[</td>
- <td style="text-align:right;padding:0 0.25em">{{.Lower}},</td>
- <td style="text-align:right;padding:0 0.25em">{{.Upper}})</td>
- <td style="text-align:right;padding:0 0.25em">{{.N}}</td>
- <td style="text-align:right;padding:0 0.25em">{{printf "%#.3f" .Pct}}%</td>
- <td style="text-align:right;padding:0 0.25em">{{printf "%#.3f" .CumulativePct}}%</td>
- <td><div style="background-color: blue; height: 1em; width: {{.GraphWidth}};"></div></td>
- </tr>
-{{end}}
-{{end}}
-</table>
-`))
- })
- return distTmplCache
-}
diff --git a/vendor/golang.org/x/net/trace/histogram_test.go b/vendor/golang.org/x/net/trace/histogram_test.go
deleted file mode 100644
index d384b9332..000000000
--- a/vendor/golang.org/x/net/trace/histogram_test.go
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package trace
-
-import (
- "math"
- "testing"
-)
-
-type sumTest struct {
- value int64
- sum int64
- sumOfSquares float64
- total int64
-}
-
-var sumTests = []sumTest{
- {100, 100, 10000, 1},
- {50, 150, 12500, 2},
- {50, 200, 15000, 3},
- {50, 250, 17500, 4},
-}
-
-type bucketingTest struct {
- in int64
- log int
- bucket int
-}
-
-var bucketingTests = []bucketingTest{
- {0, 0, 0},
- {1, 1, 0},
- {2, 2, 1},
- {3, 2, 1},
- {4, 3, 2},
- {1000, 10, 9},
- {1023, 10, 9},
- {1024, 11, 10},
- {1000000, 20, 19},
-}
-
-type multiplyTest struct {
- in int64
- ratio float64
- expectedSum int64
- expectedTotal int64
- expectedSumOfSquares float64
-}
-
-var multiplyTests = []multiplyTest{
- {15, 2.5, 37, 2, 562.5},
- {128, 4.6, 758, 13, 77953.9},
-}
-
-type percentileTest struct {
- fraction float64
- expected int64
-}
-
-var percentileTests = []percentileTest{
- {0.25, 48},
- {0.5, 96},
- {0.6, 109},
- {0.75, 128},
- {0.90, 205},
- {0.95, 230},
- {0.99, 256},
-}
-
-func TestSum(t *testing.T) {
- var h histogram
-
- for _, test := range sumTests {
- h.addMeasurement(test.value)
- sum := h.sum
- if sum != test.sum {
- t.Errorf("h.Sum = %v WANT: %v", sum, test.sum)
- }
-
- sumOfSquares := h.sumOfSquares
- if sumOfSquares != test.sumOfSquares {
- t.Errorf("h.SumOfSquares = %v WANT: %v", sumOfSquares, test.sumOfSquares)
- }
-
- total := h.total()
- if total != test.total {
- t.Errorf("h.Total = %v WANT: %v", total, test.total)
- }
- }
-}
-
-func TestMultiply(t *testing.T) {
- var h histogram
- for i, test := range multiplyTests {
- h.addMeasurement(test.in)
- h.Multiply(test.ratio)
- if h.sum != test.expectedSum {
- t.Errorf("#%v: h.sum = %v WANT: %v", i, h.sum, test.expectedSum)
- }
- if h.total() != test.expectedTotal {
- t.Errorf("#%v: h.total = %v WANT: %v", i, h.total(), test.expectedTotal)
- }
- if h.sumOfSquares != test.expectedSumOfSquares {
- t.Errorf("#%v: h.SumOfSquares = %v WANT: %v", i, test.expectedSumOfSquares, h.sumOfSquares)
- }
- }
-}
-
-func TestBucketingFunctions(t *testing.T) {
- for _, test := range bucketingTests {
- log := log2(test.in)
- if log != test.log {
- t.Errorf("log2 = %v WANT: %v", log, test.log)
- }
-
- bucket := getBucket(test.in)
- if bucket != test.bucket {
- t.Errorf("getBucket = %v WANT: %v", bucket, test.bucket)
- }
- }
-}
-
-func TestAverage(t *testing.T) {
- a := new(histogram)
- average := a.average()
- if average != 0 {
- t.Errorf("Average of empty histogram was %v WANT: 0", average)
- }
-
- a.addMeasurement(1)
- a.addMeasurement(1)
- a.addMeasurement(3)
- const expected = float64(5) / float64(3)
- average = a.average()
-
- if !isApproximate(average, expected) {
- t.Errorf("Average = %g WANT: %v", average, expected)
- }
-}
-
-func TestStandardDeviation(t *testing.T) {
- a := new(histogram)
- add(a, 10, 1<<4)
- add(a, 10, 1<<5)
- add(a, 10, 1<<6)
- stdDev := a.standardDeviation()
- const expected = 19.95
-
- if !isApproximate(stdDev, expected) {
- t.Errorf("StandardDeviation = %v WANT: %v", stdDev, expected)
- }
-
- // No values
- a = new(histogram)
- stdDev = a.standardDeviation()
-
- if !isApproximate(stdDev, 0) {
- t.Errorf("StandardDeviation = %v WANT: 0", stdDev)
- }
-
- add(a, 1, 1<<4)
- if !isApproximate(stdDev, 0) {
- t.Errorf("StandardDeviation = %v WANT: 0", stdDev)
- }
-
- add(a, 10, 1<<4)
- if !isApproximate(stdDev, 0) {
- t.Errorf("StandardDeviation = %v WANT: 0", stdDev)
- }
-}
-
-func TestPercentileBoundary(t *testing.T) {
- a := new(histogram)
- add(a, 5, 1<<4)
- add(a, 10, 1<<6)
- add(a, 5, 1<<7)
-
- for _, test := range percentileTests {
- percentile := a.percentileBoundary(test.fraction)
- if percentile != test.expected {
- t.Errorf("h.PercentileBoundary (fraction=%v) = %v WANT: %v", test.fraction, percentile, test.expected)
- }
- }
-}
-
-func TestCopyFrom(t *testing.T) {
- a := histogram{5, 25, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38}, 4, -1}
- b := histogram{6, 36, []int64{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39}, 5, -1}
-
- a.CopyFrom(&b)
-
- if a.String() != b.String() {
- t.Errorf("a.String = %s WANT: %s", a.String(), b.String())
- }
-}
-
-func TestClear(t *testing.T) {
- a := histogram{5, 25, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38}, 4, -1}
-
- a.Clear()
-
- expected := "0, 0.000000, 0, 0, []"
- if a.String() != expected {
- t.Errorf("a.String = %s WANT %s", a.String(), expected)
- }
-}
-
-func TestNew(t *testing.T) {
- a := histogram{5, 25, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38}, 4, -1}
- b := a.New()
-
- expected := "0, 0.000000, 0, 0, []"
- if b.(*histogram).String() != expected {
- t.Errorf("b.(*histogram).String = %s WANT: %s", b.(*histogram).String(), expected)
- }
-}
-
-func TestAdd(t *testing.T) {
- // The tests here depend on the associativity of addMeasurement and Add.
- // Add empty observation
- a := histogram{5, 25, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38}, 4, -1}
- b := a.New()
-
- expected := a.String()
- a.Add(b)
- if a.String() != expected {
- t.Errorf("a.String = %s WANT: %s", a.String(), expected)
- }
-
- // Add same bucketed value, no new buckets
- c := new(histogram)
- d := new(histogram)
- e := new(histogram)
- c.addMeasurement(12)
- d.addMeasurement(11)
- e.addMeasurement(12)
- e.addMeasurement(11)
- c.Add(d)
- if c.String() != e.String() {
- t.Errorf("c.String = %s WANT: %s", c.String(), e.String())
- }
-
- // Add bucketed values
- f := new(histogram)
- g := new(histogram)
- h := new(histogram)
- f.addMeasurement(4)
- f.addMeasurement(12)
- f.addMeasurement(100)
- g.addMeasurement(18)
- g.addMeasurement(36)
- g.addMeasurement(255)
- h.addMeasurement(4)
- h.addMeasurement(12)
- h.addMeasurement(100)
- h.addMeasurement(18)
- h.addMeasurement(36)
- h.addMeasurement(255)
- f.Add(g)
- if f.String() != h.String() {
- t.Errorf("f.String = %q WANT: %q", f.String(), h.String())
- }
-
- // add buckets to no buckets
- i := new(histogram)
- j := new(histogram)
- k := new(histogram)
- j.addMeasurement(18)
- j.addMeasurement(36)
- j.addMeasurement(255)
- k.addMeasurement(18)
- k.addMeasurement(36)
- k.addMeasurement(255)
- i.Add(j)
- if i.String() != k.String() {
- t.Errorf("i.String = %q WANT: %q", i.String(), k.String())
- }
-
- // add buckets to single value (no overlap)
- l := new(histogram)
- m := new(histogram)
- n := new(histogram)
- l.addMeasurement(0)
- m.addMeasurement(18)
- m.addMeasurement(36)
- m.addMeasurement(255)
- n.addMeasurement(0)
- n.addMeasurement(18)
- n.addMeasurement(36)
- n.addMeasurement(255)
- l.Add(m)
- if l.String() != n.String() {
- t.Errorf("l.String = %q WANT: %q", l.String(), n.String())
- }
-
- // mixed order
- o := new(histogram)
- p := new(histogram)
- o.addMeasurement(0)
- o.addMeasurement(2)
- o.addMeasurement(0)
- p.addMeasurement(0)
- p.addMeasurement(0)
- p.addMeasurement(2)
- if o.String() != p.String() {
- t.Errorf("o.String = %q WANT: %q", o.String(), p.String())
- }
-}
-
-func add(h *histogram, times int, val int64) {
- for i := 0; i < times; i++ {
- h.addMeasurement(val)
- }
-}
-
-func isApproximate(x, y float64) bool {
- return math.Abs(x-y) < 1e-2
-}
diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go
deleted file mode 100644
index 3d9b64611..000000000
--- a/vendor/golang.org/x/net/trace/trace.go
+++ /dev/null
@@ -1,1066 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package trace implements tracing of requests and long-lived objects.
-It exports HTTP interfaces on /debug/requests and /debug/events.
-
-A trace.Trace provides tracing for short-lived objects, usually requests.
-A request handler might be implemented like this:
-
- func fooHandler(w http.ResponseWriter, req *http.Request) {
- tr := trace.New("mypkg.Foo", req.URL.Path)
- defer tr.Finish()
- ...
- tr.LazyPrintf("some event %q happened", str)
- ...
- if err := somethingImportant(); err != nil {
- tr.LazyPrintf("somethingImportant failed: %v", err)
- tr.SetError()
- }
- }
-
-The /debug/requests HTTP endpoint organizes the traces by family,
-errors, and duration. It also provides histogram of request duration
-for each family.
-
-A trace.EventLog provides tracing for long-lived objects, such as RPC
-connections.
-
- // A Fetcher fetches URL paths for a single domain.
- type Fetcher struct {
- domain string
- events trace.EventLog
- }
-
- func NewFetcher(domain string) *Fetcher {
- return &Fetcher{
- domain,
- trace.NewEventLog("mypkg.Fetcher", domain),
- }
- }
-
- func (f *Fetcher) Fetch(path string) (string, error) {
- resp, err := http.Get("http://" + f.domain + "/" + path)
- if err != nil {
- f.events.Errorf("Get(%q) = %v", path, err)
- return "", err
- }
- f.events.Printf("Get(%q) = %s", path, resp.Status)
- ...
- }
-
- func (f *Fetcher) Close() error {
- f.events.Finish()
- return nil
- }
-
-The /debug/events HTTP endpoint organizes the event logs by family and
-by time since the last error. The expanded view displays recent log
-entries and the log's call stack.
-*/
-package trace // import "golang.org/x/net/trace"
-
-import (
- "bytes"
- "fmt"
- "html/template"
- "io"
- "log"
- "net"
- "net/http"
- "runtime"
- "sort"
- "strconv"
- "sync"
- "sync/atomic"
- "time"
-
- "golang.org/x/net/internal/timeseries"
-)
-
-// DebugUseAfterFinish controls whether to debug uses of Trace values after finishing.
-// FOR DEBUGGING ONLY. This will slow down the program.
-var DebugUseAfterFinish = false
-
-// AuthRequest determines whether a specific request is permitted to load the
-// /debug/requests or /debug/events pages.
-//
-// It returns two bools; the first indicates whether the page may be viewed at all,
-// and the second indicates whether sensitive events will be shown.
-//
-// AuthRequest may be replaced by a program to customize its authorization requirements.
-//
-// The default AuthRequest function returns (true, true) if and only if the request
-// comes from localhost/127.0.0.1/[::1].
-var AuthRequest = func(req *http.Request) (any, sensitive bool) {
- // RemoteAddr is commonly in the form "IP" or "IP:port".
- // If it is in the form "IP:port", split off the port.
- host, _, err := net.SplitHostPort(req.RemoteAddr)
- if err != nil {
- host = req.RemoteAddr
- }
- switch host {
- case "localhost", "127.0.0.1", "::1":
- return true, true
- default:
- return false, false
- }
-}
-
-func init() {
- http.HandleFunc("/debug/requests", func(w http.ResponseWriter, req *http.Request) {
- any, sensitive := AuthRequest(req)
- if !any {
- http.Error(w, "not allowed", http.StatusUnauthorized)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- Render(w, req, sensitive)
- })
- http.HandleFunc("/debug/events", func(w http.ResponseWriter, req *http.Request) {
- any, sensitive := AuthRequest(req)
- if !any {
- http.Error(w, "not allowed", http.StatusUnauthorized)
- return
- }
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- RenderEvents(w, req, sensitive)
- })
-}
-
-// Render renders the HTML page typically served at /debug/requests.
-// It does not do any auth checking; see AuthRequest for the default auth check
-// used by the handler registered on http.DefaultServeMux.
-// req may be nil.
-func Render(w io.Writer, req *http.Request, sensitive bool) {
- data := &struct {
- Families []string
- ActiveTraceCount map[string]int
- CompletedTraces map[string]*family
-
- // Set when a bucket has been selected.
- Traces traceList
- Family string
- Bucket int
- Expanded bool
- Traced bool
- Active bool
- ShowSensitive bool // whether to show sensitive events
-
- Histogram template.HTML
- HistogramWindow string // e.g. "last minute", "last hour", "all time"
-
- // If non-zero, the set of traces is a partial set,
- // and this is the total number.
- Total int
- }{
- CompletedTraces: completedTraces,
- }
-
- data.ShowSensitive = sensitive
- if req != nil {
- // Allow show_sensitive=0 to force hiding of sensitive data for testing.
- // This only goes one way; you can't use show_sensitive=1 to see things.
- if req.FormValue("show_sensitive") == "0" {
- data.ShowSensitive = false
- }
-
- if exp, err := strconv.ParseBool(req.FormValue("exp")); err == nil {
- data.Expanded = exp
- }
- if exp, err := strconv.ParseBool(req.FormValue("rtraced")); err == nil {
- data.Traced = exp
- }
- }
-
- completedMu.RLock()
- data.Families = make([]string, 0, len(completedTraces))
- for fam := range completedTraces {
- data.Families = append(data.Families, fam)
- }
- completedMu.RUnlock()
- sort.Strings(data.Families)
-
- // We are careful here to minimize the time spent locking activeMu,
- // since that lock is required every time an RPC starts and finishes.
- data.ActiveTraceCount = make(map[string]int, len(data.Families))
- activeMu.RLock()
- for fam, s := range activeTraces {
- data.ActiveTraceCount[fam] = s.Len()
- }
- activeMu.RUnlock()
-
- var ok bool
- data.Family, data.Bucket, ok = parseArgs(req)
- switch {
- case !ok:
- // No-op
- case data.Bucket == -1:
- data.Active = true
- n := data.ActiveTraceCount[data.Family]
- data.Traces = getActiveTraces(data.Family)
- if len(data.Traces) < n {
- data.Total = n
- }
- case data.Bucket < bucketsPerFamily:
- if b := lookupBucket(data.Family, data.Bucket); b != nil {
- data.Traces = b.Copy(data.Traced)
- }
- default:
- if f := getFamily(data.Family, false); f != nil {
- var obs timeseries.Observable
- f.LatencyMu.RLock()
- switch o := data.Bucket - bucketsPerFamily; o {
- case 0:
- obs = f.Latency.Minute()
- data.HistogramWindow = "last minute"
- case 1:
- obs = f.Latency.Hour()
- data.HistogramWindow = "last hour"
- case 2:
- obs = f.Latency.Total()
- data.HistogramWindow = "all time"
- }
- f.LatencyMu.RUnlock()
- if obs != nil {
- data.Histogram = obs.(*histogram).html()
- }
- }
- }
-
- if data.Traces != nil {
- defer data.Traces.Free()
- sort.Sort(data.Traces)
- }
-
- completedMu.RLock()
- defer completedMu.RUnlock()
- if err := pageTmpl().ExecuteTemplate(w, "Page", data); err != nil {
- log.Printf("net/trace: Failed executing template: %v", err)
- }
-}
-
-func parseArgs(req *http.Request) (fam string, b int, ok bool) {
- if req == nil {
- return "", 0, false
- }
- fam, bStr := req.FormValue("fam"), req.FormValue("b")
- if fam == "" || bStr == "" {
- return "", 0, false
- }
- b, err := strconv.Atoi(bStr)
- if err != nil || b < -1 {
- return "", 0, false
- }
-
- return fam, b, true
-}
-
-func lookupBucket(fam string, b int) *traceBucket {
- f := getFamily(fam, false)
- if f == nil || b < 0 || b >= len(f.Buckets) {
- return nil
- }
- return f.Buckets[b]
-}
-
-type contextKeyT string
-
-var contextKey = contextKeyT("golang.org/x/net/trace.Trace")
-
-// Trace represents an active request.
-type Trace interface {
- // LazyLog adds x to the event log. It will be evaluated each time the
- // /debug/requests page is rendered. Any memory referenced by x will be
- // pinned until the trace is finished and later discarded.
- LazyLog(x fmt.Stringer, sensitive bool)
-
- // LazyPrintf evaluates its arguments with fmt.Sprintf each time the
- // /debug/requests page is rendered. Any memory referenced by a will be
- // pinned until the trace is finished and later discarded.
- LazyPrintf(format string, a ...interface{})
-
- // SetError declares that this trace resulted in an error.
- SetError()
-
- // SetRecycler sets a recycler for the trace.
- // f will be called for each event passed to LazyLog at a time when
- // it is no longer required, whether while the trace is still active
- // and the event is discarded, or when a completed trace is discarded.
- SetRecycler(f func(interface{}))
-
- // SetTraceInfo sets the trace info for the trace.
- // This is currently unused.
- SetTraceInfo(traceID, spanID uint64)
-
- // SetMaxEvents sets the maximum number of events that will be stored
- // in the trace. This has no effect if any events have already been
- // added to the trace.
- SetMaxEvents(m int)
-
- // Finish declares that this trace is complete.
- // The trace should not be used after calling this method.
- Finish()
-}
-
-type lazySprintf struct {
- format string
- a []interface{}
-}
-
-func (l *lazySprintf) String() string {
- return fmt.Sprintf(l.format, l.a...)
-}
-
-// New returns a new Trace with the specified family and title.
-func New(family, title string) Trace {
- tr := newTrace()
- tr.ref()
- tr.Family, tr.Title = family, title
- tr.Start = time.Now()
- tr.maxEvents = maxEventsPerTrace
- tr.events = tr.eventsBuf[:0]
-
- activeMu.RLock()
- s := activeTraces[tr.Family]
- activeMu.RUnlock()
- if s == nil {
- activeMu.Lock()
- s = activeTraces[tr.Family] // check again
- if s == nil {
- s = new(traceSet)
- activeTraces[tr.Family] = s
- }
- activeMu.Unlock()
- }
- s.Add(tr)
-
- // Trigger allocation of the completed trace structure for this family.
- // This will cause the family to be present in the request page during
- // the first trace of this family. We don't care about the return value,
- // nor is there any need for this to run inline, so we execute it in its
- // own goroutine, but only if the family isn't allocated yet.
- completedMu.RLock()
- if _, ok := completedTraces[tr.Family]; !ok {
- go allocFamily(tr.Family)
- }
- completedMu.RUnlock()
-
- return tr
-}
-
-func (tr *trace) Finish() {
- tr.Elapsed = time.Now().Sub(tr.Start)
- if DebugUseAfterFinish {
- buf := make([]byte, 4<<10) // 4 KB should be enough
- n := runtime.Stack(buf, false)
- tr.finishStack = buf[:n]
- }
-
- activeMu.RLock()
- m := activeTraces[tr.Family]
- activeMu.RUnlock()
- m.Remove(tr)
-
- f := getFamily(tr.Family, true)
- for _, b := range f.Buckets {
- if b.Cond.match(tr) {
- b.Add(tr)
- }
- }
- // Add a sample of elapsed time as microseconds to the family's timeseries
- h := new(histogram)
- h.addMeasurement(tr.Elapsed.Nanoseconds() / 1e3)
- f.LatencyMu.Lock()
- f.Latency.Add(h)
- f.LatencyMu.Unlock()
-
- tr.unref() // matches ref in New
-}
-
-const (
- bucketsPerFamily = 9
- tracesPerBucket = 10
- maxActiveTraces = 20 // Maximum number of active traces to show.
- maxEventsPerTrace = 10
- numHistogramBuckets = 38
-)
-
-var (
- // The active traces.
- activeMu sync.RWMutex
- activeTraces = make(map[string]*traceSet) // family -> traces
-
- // Families of completed traces.
- completedMu sync.RWMutex
- completedTraces = make(map[string]*family) // family -> traces
-)
-
-type traceSet struct {
- mu sync.RWMutex
- m map[*trace]bool
-
- // We could avoid the entire map scan in FirstN by having a slice of all the traces
- // ordered by start time, and an index into that from the trace struct, with a periodic
- // repack of the slice after enough traces finish; we could also use a skip list or similar.
- // However, that would shift some of the expense from /debug/requests time to RPC time,
- // which is probably the wrong trade-off.
-}
-
-func (ts *traceSet) Len() int {
- ts.mu.RLock()
- defer ts.mu.RUnlock()
- return len(ts.m)
-}
-
-func (ts *traceSet) Add(tr *trace) {
- ts.mu.Lock()
- if ts.m == nil {
- ts.m = make(map[*trace]bool)
- }
- ts.m[tr] = true
- ts.mu.Unlock()
-}
-
-func (ts *traceSet) Remove(tr *trace) {
- ts.mu.Lock()
- delete(ts.m, tr)
- ts.mu.Unlock()
-}
-
-// FirstN returns the first n traces ordered by time.
-func (ts *traceSet) FirstN(n int) traceList {
- ts.mu.RLock()
- defer ts.mu.RUnlock()
-
- if n > len(ts.m) {
- n = len(ts.m)
- }
- trl := make(traceList, 0, n)
-
- // Fast path for when no selectivity is needed.
- if n == len(ts.m) {
- for tr := range ts.m {
- tr.ref()
- trl = append(trl, tr)
- }
- sort.Sort(trl)
- return trl
- }
-
- // Pick the oldest n traces.
- // This is inefficient. See the comment in the traceSet struct.
- for tr := range ts.m {
- // Put the first n traces into trl in the order they occur.
- // When we have n, sort trl, and thereafter maintain its order.
- if len(trl) < n {
- tr.ref()
- trl = append(trl, tr)
- if len(trl) == n {
- // This is guaranteed to happen exactly once during this loop.
- sort.Sort(trl)
- }
- continue
- }
- if tr.Start.After(trl[n-1].Start) {
- continue
- }
-
- // Find where to insert this one.
- tr.ref()
- i := sort.Search(n, func(i int) bool { return trl[i].Start.After(tr.Start) })
- trl[n-1].unref()
- copy(trl[i+1:], trl[i:])
- trl[i] = tr
- }
-
- return trl
-}
-
-func getActiveTraces(fam string) traceList {
- activeMu.RLock()
- s := activeTraces[fam]
- activeMu.RUnlock()
- if s == nil {
- return nil
- }
- return s.FirstN(maxActiveTraces)
-}
-
-func getFamily(fam string, allocNew bool) *family {
- completedMu.RLock()
- f := completedTraces[fam]
- completedMu.RUnlock()
- if f == nil && allocNew {
- f = allocFamily(fam)
- }
- return f
-}
-
-func allocFamily(fam string) *family {
- completedMu.Lock()
- defer completedMu.Unlock()
- f := completedTraces[fam]
- if f == nil {
- f = newFamily()
- completedTraces[fam] = f
- }
- return f
-}
-
-// family represents a set of trace buckets and associated latency information.
-type family struct {
- // traces may occur in multiple buckets.
- Buckets [bucketsPerFamily]*traceBucket
-
- // latency time series
- LatencyMu sync.RWMutex
- Latency *timeseries.MinuteHourSeries
-}
-
-func newFamily() *family {
- return &family{
- Buckets: [bucketsPerFamily]*traceBucket{
- {Cond: minCond(0)},
- {Cond: minCond(50 * time.Millisecond)},
- {Cond: minCond(100 * time.Millisecond)},
- {Cond: minCond(200 * time.Millisecond)},
- {Cond: minCond(500 * time.Millisecond)},
- {Cond: minCond(1 * time.Second)},
- {Cond: minCond(10 * time.Second)},
- {Cond: minCond(100 * time.Second)},
- {Cond: errorCond{}},
- },
- Latency: timeseries.NewMinuteHourSeries(func() timeseries.Observable { return new(histogram) }),
- }
-}
-
-// traceBucket represents a size-capped bucket of historic traces,
-// along with a condition for a trace to belong to the bucket.
-type traceBucket struct {
- Cond cond
-
- // Ring buffer implementation of a fixed-size FIFO queue.
- mu sync.RWMutex
- buf [tracesPerBucket]*trace
- start int // < tracesPerBucket
- length int // <= tracesPerBucket
-}
-
-func (b *traceBucket) Add(tr *trace) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- i := b.start + b.length
- if i >= tracesPerBucket {
- i -= tracesPerBucket
- }
- if b.length == tracesPerBucket {
- // "Remove" an element from the bucket.
- b.buf[i].unref()
- b.start++
- if b.start == tracesPerBucket {
- b.start = 0
- }
- }
- b.buf[i] = tr
- if b.length < tracesPerBucket {
- b.length++
- }
- tr.ref()
-}
-
-// Copy returns a copy of the traces in the bucket.
-// If tracedOnly is true, only the traces with trace information will be returned.
-// The logs will be ref'd before returning; the caller should call
-// the Free method when it is done with them.
-// TODO(dsymonds): keep track of traced requests in separate buckets.
-func (b *traceBucket) Copy(tracedOnly bool) traceList {
- b.mu.RLock()
- defer b.mu.RUnlock()
-
- trl := make(traceList, 0, b.length)
- for i, x := 0, b.start; i < b.length; i++ {
- tr := b.buf[x]
- if !tracedOnly || tr.spanID != 0 {
- tr.ref()
- trl = append(trl, tr)
- }
- x++
- if x == b.length {
- x = 0
- }
- }
- return trl
-}
-
-func (b *traceBucket) Empty() bool {
- b.mu.RLock()
- defer b.mu.RUnlock()
- return b.length == 0
-}
-
-// cond represents a condition on a trace.
-type cond interface {
- match(t *trace) bool
- String() string
-}
-
-type minCond time.Duration
-
-func (m minCond) match(t *trace) bool { return t.Elapsed >= time.Duration(m) }
-func (m minCond) String() string { return fmt.Sprintf("≥%gs", time.Duration(m).Seconds()) }
-
-type errorCond struct{}
-
-func (e errorCond) match(t *trace) bool { return t.IsError }
-func (e errorCond) String() string { return "errors" }
-
-type traceList []*trace
-
-// Free calls unref on each element of the list.
-func (trl traceList) Free() {
- for _, t := range trl {
- t.unref()
- }
-}
-
-// traceList may be sorted in reverse chronological order.
-func (trl traceList) Len() int { return len(trl) }
-func (trl traceList) Less(i, j int) bool { return trl[i].Start.After(trl[j].Start) }
-func (trl traceList) Swap(i, j int) { trl[i], trl[j] = trl[j], trl[i] }
-
-// An event is a timestamped log entry in a trace.
-type event struct {
- When time.Time
- Elapsed time.Duration // since previous event in trace
- NewDay bool // whether this event is on a different day to the previous event
- Recyclable bool // whether this event was passed via LazyLog
- Sensitive bool // whether this event contains sensitive information
- What interface{} // string or fmt.Stringer
-}
-
-// WhenString returns a string representation of the elapsed time of the event.
-// It will include the date if midnight was crossed.
-func (e event) WhenString() string {
- if e.NewDay {
- return e.When.Format("2006/01/02 15:04:05.000000")
- }
- return e.When.Format("15:04:05.000000")
-}
-
-// discarded represents a number of discarded events.
-// It is stored as *discarded to make it easier to update in-place.
-type discarded int
-
-func (d *discarded) String() string {
- return fmt.Sprintf("(%d events discarded)", int(*d))
-}
-
-// trace represents an active or complete request,
-// either sent or received by this program.
-type trace struct {
- // Family is the top-level grouping of traces to which this belongs.
- Family string
-
- // Title is the title of this trace.
- Title string
-
- // Timing information.
- Start time.Time
- Elapsed time.Duration // zero while active
-
- // Trace information if non-zero.
- traceID uint64
- spanID uint64
-
- // Whether this trace resulted in an error.
- IsError bool
-
- // Append-only sequence of events (modulo discards).
- mu sync.RWMutex
- events []event
- maxEvents int
-
- refs int32 // how many buckets this is in
- recycler func(interface{})
- disc discarded // scratch space to avoid allocation
-
- finishStack []byte // where finish was called, if DebugUseAfterFinish is set
-
- eventsBuf [4]event // preallocated buffer in case we only log a few events
-}
-
-func (tr *trace) reset() {
- // Clear all but the mutex. Mutexes may not be copied, even when unlocked.
- tr.Family = ""
- tr.Title = ""
- tr.Start = time.Time{}
- tr.Elapsed = 0
- tr.traceID = 0
- tr.spanID = 0
- tr.IsError = false
- tr.maxEvents = 0
- tr.events = nil
- tr.refs = 0
- tr.recycler = nil
- tr.disc = 0
- tr.finishStack = nil
- for i := range tr.eventsBuf {
- tr.eventsBuf[i] = event{}
- }
-}
-
-// delta returns the elapsed time since the last event or the trace start,
-// and whether it spans midnight.
-// L >= tr.mu
-func (tr *trace) delta(t time.Time) (time.Duration, bool) {
- if len(tr.events) == 0 {
- return t.Sub(tr.Start), false
- }
- prev := tr.events[len(tr.events)-1].When
- return t.Sub(prev), prev.Day() != t.Day()
-}
-
-func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) {
- if DebugUseAfterFinish && tr.finishStack != nil {
- buf := make([]byte, 4<<10) // 4 KB should be enough
- n := runtime.Stack(buf, false)
- log.Printf("net/trace: trace used after finish:\nFinished at:\n%s\nUsed at:\n%s", tr.finishStack, buf[:n])
- }
-
- /*
- NOTE TO DEBUGGERS
-
- If you are here because your program panicked in this code,
- it is almost definitely the fault of code using this package,
- and very unlikely to be the fault of this code.
-
- The most likely scenario is that some code elsewhere is using
- a trace.Trace after its Finish method is called.
- You can temporarily set the DebugUseAfterFinish var
- to help discover where that is; do not leave that var set,
- since it makes this package much less efficient.
- */
-
- e := event{When: time.Now(), What: x, Recyclable: recyclable, Sensitive: sensitive}
- tr.mu.Lock()
- e.Elapsed, e.NewDay = tr.delta(e.When)
- if len(tr.events) < tr.maxEvents {
- tr.events = append(tr.events, e)
- } else {
- // Discard the middle events.
- di := int((tr.maxEvents - 1) / 2)
- if d, ok := tr.events[di].What.(*discarded); ok {
- (*d)++
- } else {
- // disc starts at two to count for the event it is replacing,
- // plus the next one that we are about to drop.
- tr.disc = 2
- if tr.recycler != nil && tr.events[di].Recyclable {
- go tr.recycler(tr.events[di].What)
- }
- tr.events[di].What = &tr.disc
- }
- // The timestamp of the discarded meta-event should be
- // the time of the last event it is representing.
- tr.events[di].When = tr.events[di+1].When
-
- if tr.recycler != nil && tr.events[di+1].Recyclable {
- go tr.recycler(tr.events[di+1].What)
- }
- copy(tr.events[di+1:], tr.events[di+2:])
- tr.events[tr.maxEvents-1] = e
- }
- tr.mu.Unlock()
-}
-
-func (tr *trace) LazyLog(x fmt.Stringer, sensitive bool) {
- tr.addEvent(x, true, sensitive)
-}
-
-func (tr *trace) LazyPrintf(format string, a ...interface{}) {
- tr.addEvent(&lazySprintf{format, a}, false, false)
-}
-
-func (tr *trace) SetError() { tr.IsError = true }
-
-func (tr *trace) SetRecycler(f func(interface{})) {
- tr.recycler = f
-}
-
-func (tr *trace) SetTraceInfo(traceID, spanID uint64) {
- tr.traceID, tr.spanID = traceID, spanID
-}
-
-func (tr *trace) SetMaxEvents(m int) {
- // Always keep at least three events: first, discarded count, last.
- if len(tr.events) == 0 && m > 3 {
- tr.maxEvents = m
- }
-}
-
-func (tr *trace) ref() {
- atomic.AddInt32(&tr.refs, 1)
-}
-
-func (tr *trace) unref() {
- if atomic.AddInt32(&tr.refs, -1) == 0 {
- if tr.recycler != nil {
- // freeTrace clears tr, so we hold tr.recycler and tr.events here.
- go func(f func(interface{}), es []event) {
- for _, e := range es {
- if e.Recyclable {
- f(e.What)
- }
- }
- }(tr.recycler, tr.events)
- }
-
- freeTrace(tr)
- }
-}
-
-func (tr *trace) When() string {
- return tr.Start.Format("2006/01/02 15:04:05.000000")
-}
-
-func (tr *trace) ElapsedTime() string {
- t := tr.Elapsed
- if t == 0 {
- // Active trace.
- t = time.Since(tr.Start)
- }
- return fmt.Sprintf("%.6f", t.Seconds())
-}
-
-func (tr *trace) Events() []event {
- tr.mu.RLock()
- defer tr.mu.RUnlock()
- return tr.events
-}
-
-var traceFreeList = make(chan *trace, 1000) // TODO(dsymonds): Use sync.Pool?
-
-// newTrace returns a trace ready to use.
-func newTrace() *trace {
- select {
- case tr := <-traceFreeList:
- return tr
- default:
- return new(trace)
- }
-}
-
-// freeTrace adds tr to traceFreeList if there's room.
-// This is non-blocking.
-func freeTrace(tr *trace) {
- if DebugUseAfterFinish {
- return // never reuse
- }
- tr.reset()
- select {
- case traceFreeList <- tr:
- default:
- }
-}
-
-func elapsed(d time.Duration) string {
- b := []byte(fmt.Sprintf("%.6f", d.Seconds()))
-
- // For subsecond durations, blank all zeros before decimal point,
- // and all zeros between the decimal point and the first non-zero digit.
- if d < time.Second {
- dot := bytes.IndexByte(b, '.')
- for i := 0; i < dot; i++ {
- b[i] = ' '
- }
- for i := dot + 1; i < len(b); i++ {
- if b[i] == '0' {
- b[i] = ' '
- } else {
- break
- }
- }
- }
-
- return string(b)
-}
-
-var pageTmplCache *template.Template
-var pageTmplOnce sync.Once
-
-func pageTmpl() *template.Template {
- pageTmplOnce.Do(func() {
- pageTmplCache = template.Must(template.New("Page").Funcs(template.FuncMap{
- "elapsed": elapsed,
- "add": func(a, b int) int { return a + b },
- }).Parse(pageHTML))
- })
- return pageTmplCache
-}
-
-const pageHTML = `
-{{template "Prolog" .}}
-{{template "StatusTable" .}}
-{{template "Epilog" .}}
-
-{{define "Prolog"}}
-<html>
- <head>
- <title>/debug/requests</title>
- <style type="text/css">
- body {
- font-family: sans-serif;
- }
- table#tr-status td.family {
- padding-right: 2em;
- }
- table#tr-status td.active {
- padding-right: 1em;
- }
- table#tr-status td.latency-first {
- padding-left: 1em;
- }
- table#tr-status td.empty {
- color: #aaa;
- }
- table#reqs {
- margin-top: 1em;
- }
- table#reqs tr.first {
- {{if $.Expanded}}font-weight: bold;{{end}}
- }
- table#reqs td {
- font-family: monospace;
- }
- table#reqs td.when {
- text-align: right;
- white-space: nowrap;
- }
- table#reqs td.elapsed {
- padding: 0 0.5em;
- text-align: right;
- white-space: pre;
- width: 10em;
- }
- address {
- font-size: smaller;
- margin-top: 5em;
- }
- </style>
- </head>
- <body>
-
-<h1>/debug/requests</h1>
-{{end}} {{/* end of Prolog */}}
-
-{{define "StatusTable"}}
-<table id="tr-status">
- {{range $fam := .Families}}
- <tr>
- <td class="family">{{$fam}}</td>
-
- {{$n := index $.ActiveTraceCount $fam}}
- <td class="active {{if not $n}}empty{{end}}">
- {{if $n}}<a href="?fam={{$fam}}&b=-1{{if $.Expanded}}&exp=1{{end}}">{{end}}
- [{{$n}} active]
- {{if $n}}</a>{{end}}
- </td>
-
- {{$f := index $.CompletedTraces $fam}}
- {{range $i, $b := $f.Buckets}}
- {{$empty := $b.Empty}}
- <td {{if $empty}}class="empty"{{end}}>
- {{if not $empty}}<a href="?fam={{$fam}}&b={{$i}}{{if $.Expanded}}&exp=1{{end}}">{{end}}
- [{{.Cond}}]
- {{if not $empty}}</a>{{end}}
- </td>
- {{end}}
-
- {{$nb := len $f.Buckets}}
- <td class="latency-first">
- <a href="?fam={{$fam}}&b={{$nb}}">[minute]</a>
- </td>
- <td>
- <a href="?fam={{$fam}}&b={{add $nb 1}}">[hour]</a>
- </td>
- <td>
- <a href="?fam={{$fam}}&b={{add $nb 2}}">[total]</a>
- </td>
-
- </tr>
- {{end}}
-</table>
-{{end}} {{/* end of StatusTable */}}
-
-{{define "Epilog"}}
-{{if $.Traces}}
-<hr />
-<h3>Family: {{$.Family}}</h3>
-
-{{if or $.Expanded $.Traced}}
- <a href="?fam={{$.Family}}&b={{$.Bucket}}">[Normal/Summary]</a>
-{{else}}
- [Normal/Summary]
-{{end}}
-
-{{if or (not $.Expanded) $.Traced}}
- <a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1">[Normal/Expanded]</a>
-{{else}}
- [Normal/Expanded]
-{{end}}
-
-{{if not $.Active}}
- {{if or $.Expanded (not $.Traced)}}
- <a href="?fam={{$.Family}}&b={{$.Bucket}}&rtraced=1">[Traced/Summary]</a>
- {{else}}
- [Traced/Summary]
- {{end}}
- {{if or (not $.Expanded) (not $.Traced)}}
- <a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1&rtraced=1">[Traced/Expanded]</a>
- {{else}}
- [Traced/Expanded]
- {{end}}
-{{end}}
-
-{{if $.Total}}
-<p><em>Showing <b>{{len $.Traces}}</b> of <b>{{$.Total}}</b> traces.</em></p>
-{{end}}
-
-<table id="reqs">
- <caption>
- {{if $.Active}}Active{{else}}Completed{{end}} Requests
- </caption>
- <tr><th>When</th><th>Elapsed&nbsp;(s)</th></tr>
- {{range $tr := $.Traces}}
- <tr class="first">
- <td class="when">{{$tr.When}}</td>
- <td class="elapsed">{{$tr.ElapsedTime}}</td>
- <td>{{$tr.Title}}</td>
- {{/* TODO: include traceID/spanID */}}
- </tr>
- {{if $.Expanded}}
- {{range $tr.Events}}
- <tr>
- <td class="when">{{.WhenString}}</td>
- <td class="elapsed">{{elapsed .Elapsed}}</td>
- <td>{{if or $.ShowSensitive (not .Sensitive)}}... {{.What}}{{else}}<em>[redacted]</em>{{end}}</td>
- </tr>
- {{end}}
- {{end}}
- {{end}}
-</table>
-{{end}} {{/* if $.Traces */}}
-
-{{if $.Histogram}}
-<h4>Latency (&micro;s) of {{$.Family}} over {{$.HistogramWindow}}</h4>
-{{$.Histogram}}
-{{end}} {{/* if $.Histogram */}}
-
- </body>
-</html>
-{{end}} {{/* end of Epilog */}}
-`
diff --git a/vendor/golang.org/x/net/trace/trace_go16.go b/vendor/golang.org/x/net/trace/trace_go16.go
deleted file mode 100644
index d60819118..000000000
--- a/vendor/golang.org/x/net/trace/trace_go16.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.7
-
-package trace
-
-import "golang.org/x/net/context"
-
-// NewContext returns a copy of the parent context
-// and associates it with a Trace.
-func NewContext(ctx context.Context, tr Trace) context.Context {
- return context.WithValue(ctx, contextKey, tr)
-}
-
-// FromContext returns the Trace bound to the context, if any.
-func FromContext(ctx context.Context) (tr Trace, ok bool) {
- tr, ok = ctx.Value(contextKey).(Trace)
- return
-}
diff --git a/vendor/golang.org/x/net/trace/trace_go17.go b/vendor/golang.org/x/net/trace/trace_go17.go
deleted file mode 100644
index df6e1fba7..000000000
--- a/vendor/golang.org/x/net/trace/trace_go17.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.7
-
-package trace
-
-import "context"
-
-// NewContext returns a copy of the parent context
-// and associates it with a Trace.
-func NewContext(ctx context.Context, tr Trace) context.Context {
- return context.WithValue(ctx, contextKey, tr)
-}
-
-// FromContext returns the Trace bound to the context, if any.
-func FromContext(ctx context.Context) (tr Trace, ok bool) {
- tr, ok = ctx.Value(contextKey).(Trace)
- return
-}
diff --git a/vendor/golang.org/x/net/trace/trace_test.go b/vendor/golang.org/x/net/trace/trace_test.go
deleted file mode 100644
index bfd9dfe94..000000000
--- a/vendor/golang.org/x/net/trace/trace_test.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package trace
-
-import (
- "net/http"
- "reflect"
- "testing"
-)
-
-type s struct{}
-
-func (s) String() string { return "lazy string" }
-
-// TestReset checks whether all the fields are zeroed after reset.
-func TestReset(t *testing.T) {
- tr := New("foo", "bar")
- tr.LazyLog(s{}, false)
- tr.LazyPrintf("%d", 1)
- tr.SetRecycler(func(_ interface{}) {})
- tr.SetTraceInfo(3, 4)
- tr.SetMaxEvents(100)
- tr.SetError()
- tr.Finish()
-
- tr.(*trace).reset()
-
- if !reflect.DeepEqual(tr, new(trace)) {
- t.Errorf("reset didn't clear all fields: %+v", tr)
- }
-}
-
-// TestResetLog checks whether all the fields are zeroed after reset.
-func TestResetLog(t *testing.T) {
- el := NewEventLog("foo", "bar")
- el.Printf("message")
- el.Errorf("error")
- el.Finish()
-
- el.(*eventLog).reset()
-
- if !reflect.DeepEqual(el, new(eventLog)) {
- t.Errorf("reset didn't clear all fields: %+v", el)
- }
-}
-
-func TestAuthRequest(t *testing.T) {
- testCases := []struct {
- host string
- want bool
- }{
- {host: "192.168.23.1", want: false},
- {host: "192.168.23.1:8080", want: false},
- {host: "malformed remote addr", want: false},
- {host: "localhost", want: true},
- {host: "localhost:8080", want: true},
- {host: "127.0.0.1", want: true},
- {host: "127.0.0.1:8080", want: true},
- {host: "::1", want: true},
- {host: "[::1]:8080", want: true},
- }
- for _, tt := range testCases {
- req := &http.Request{RemoteAddr: tt.host}
- any, sensitive := AuthRequest(req)
- if any != tt.want || sensitive != tt.want {
- t.Errorf("AuthRequest(%q) = %t, %t; want %t, %t", tt.host, any, sensitive, tt.want, tt.want)
- }
- }
-}
-
-// TestParseTemplate checks that all templates used by this package are valid
-// as they are parsed on first usage
-func TestParseTemplate(t *testing.T) {
- if tmpl := distTmpl(); tmpl == nil {
- t.Error("invalid template returned from distTmpl()")
- }
- if tmpl := pageTmpl(); tmpl == nil {
- t.Error("invalid template returned from pageTmpl()")
- }
- if tmpl := eventsTmpl(); tmpl == nil {
- t.Error("invalid template returned from eventsTmpl()")
- }
-}
-
-func benchmarkTrace(b *testing.B, maxEvents, numEvents int) {
- numSpans := (b.N + numEvents + 1) / numEvents
-
- for i := 0; i < numSpans; i++ {
- tr := New("test", "test")
- tr.SetMaxEvents(maxEvents)
- for j := 0; j < numEvents; j++ {
- tr.LazyPrintf("%d", j)
- }
- tr.Finish()
- }
-}
-
-func BenchmarkTrace_Default_2(b *testing.B) {
- benchmarkTrace(b, 0, 2)
-}
-
-func BenchmarkTrace_Default_10(b *testing.B) {
- benchmarkTrace(b, 0, 10)
-}
-
-func BenchmarkTrace_Default_100(b *testing.B) {
- benchmarkTrace(b, 0, 100)
-}
-
-func BenchmarkTrace_Default_1000(b *testing.B) {
- benchmarkTrace(b, 0, 1000)
-}
-
-func BenchmarkTrace_Default_10000(b *testing.B) {
- benchmarkTrace(b, 0, 10000)
-}
-
-func BenchmarkTrace_10_2(b *testing.B) {
- benchmarkTrace(b, 10, 2)
-}
-
-func BenchmarkTrace_10_10(b *testing.B) {
- benchmarkTrace(b, 10, 10)
-}
-
-func BenchmarkTrace_10_100(b *testing.B) {
- benchmarkTrace(b, 10, 100)
-}
-
-func BenchmarkTrace_10_1000(b *testing.B) {
- benchmarkTrace(b, 10, 1000)
-}
-
-func BenchmarkTrace_10_10000(b *testing.B) {
- benchmarkTrace(b, 10, 10000)
-}
-
-func BenchmarkTrace_100_2(b *testing.B) {
- benchmarkTrace(b, 100, 2)
-}
-
-func BenchmarkTrace_100_10(b *testing.B) {
- benchmarkTrace(b, 100, 10)
-}
-
-func BenchmarkTrace_100_100(b *testing.B) {
- benchmarkTrace(b, 100, 100)
-}
-
-func BenchmarkTrace_100_1000(b *testing.B) {
- benchmarkTrace(b, 100, 1000)
-}
-
-func BenchmarkTrace_100_10000(b *testing.B) {
- benchmarkTrace(b, 100, 10000)
-}
-
-func BenchmarkTrace_1000_2(b *testing.B) {
- benchmarkTrace(b, 1000, 2)
-}
-
-func BenchmarkTrace_1000_10(b *testing.B) {
- benchmarkTrace(b, 1000, 10)
-}
-
-func BenchmarkTrace_1000_100(b *testing.B) {
- benchmarkTrace(b, 1000, 100)
-}
-
-func BenchmarkTrace_1000_1000(b *testing.B) {
- benchmarkTrace(b, 1000, 1000)
-}
-
-func BenchmarkTrace_1000_10000(b *testing.B) {
- benchmarkTrace(b, 1000, 10000)
-}