aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBastien Orivel <eijebong@bananium.fr>2018-08-27 18:36:52 +0200
committerBastien Orivel <eijebong@bananium.fr>2018-11-01 19:17:36 +0100
commit024b40b39d3848f1a1f7020bd7ed8c901817f09c (patch)
tree27508f102b0973cbae3dca22143ea4aedd349f4b
parent95bfaa0a770479fb3bf6bf0b1f85c9ae343e66ff (diff)
downloadservo-024b40b39d3848f1a1f7020bd7ed8c901817f09c.tar.gz
servo-024b40b39d3848f1a1f7020bd7ed8c901817f09c.zip
Update hyper to 0.12
-rw-r--r--Cargo.lock845
-rw-r--r--components/constellation/Cargo.toml2
-rw-r--r--components/constellation/lib.rs2
-rw-r--r--components/constellation/network_listener.rs4
-rw-r--r--components/devtools/Cargo.toml7
-rw-r--r--components/devtools/actors/network_event.rs109
-rw-r--r--components/devtools/lib.rs3
-rw-r--r--components/devtools_traits/Cargo.toml3
-rw-r--r--components/devtools_traits/lib.rs10
-rw-r--r--components/malloc_size_of/Cargo.toml4
-rw-r--r--components/malloc_size_of/lib.rs51
-rw-r--r--components/net/Cargo.toml27
-rw-r--r--components/net/blob_loader.rs44
-rw-r--r--components/net/connector.rs157
-rw-r--r--components/net/cookie.rs8
-rw-r--r--components/net/cookie_storage.rs12
-rw-r--r--components/net/data_loader.rs5
-rw-r--r--components/net/fetch/cors_cache.rs17
-rw-r--r--components/net/fetch/methods.rs200
-rw-r--r--components/net/http_cache.rs336
-rw-r--r--components/net/http_loader.rs692
-rw-r--r--components/net/lib.rs7
-rw-r--r--components/net/mime_classifier.rs244
-rw-r--r--components/net/resource_thread.rs11
-rw-r--r--components/net/subresource_integrity.rs5
-rw-r--r--components/net/tests/cookie.rs12
-rw-r--r--components/net/tests/cookie_http_state.rs12
-rw-r--r--components/net/tests/data_loader.rs37
-rw-r--r--components/net/tests/fetch.rs412
-rw-r--r--components/net/tests/http_loader.rs626
-rw-r--r--components/net/tests/main.rs112
-rw-r--r--components/net/tests/mime_classifier.rs305
-rw-r--r--components/net/websocket_loader.rs35
-rw-r--r--components/net_traits/Cargo.toml10
-rw-r--r--components/net_traits/lib.rs83
-rw-r--r--components/net_traits/quality.rs80
-rw-r--r--components/net_traits/request.rs16
-rw-r--r--components/net_traits/response.rs48
-rw-r--r--components/profile/Cargo.toml3
-rw-r--r--components/profile/lib.rs1
-rw-r--r--components/profile/time.rs8
-rw-r--r--components/script/Cargo.toml15
-rw-r--r--components/script/body.rs33
-rw-r--r--components/script/dom/bindings/trace.rs10
-rw-r--r--components/script/dom/document.rs35
-rw-r--r--components/script/dom/domimplementation.rs16
-rw-r--r--components/script/dom/eventsource.rs28
-rw-r--r--components/script/dom/filereader.rs11
-rw-r--r--components/script/dom/headers.rs63
-rwxr-xr-xcomponents/script/dom/htmlformelement.rs71
-rw-r--r--components/script/dom/htmlimageelement.rs23
-rw-r--r--components/script/dom/htmlmediaelement.rs22
-rw-r--r--components/script/dom/request.rs41
-rw-r--r--components/script/dom/response.rs12
-rw-r--r--components/script/dom/servoparser/mod.rs31
-rw-r--r--components/script/dom/xmlhttprequest.rs238
-rw-r--r--components/script/lib.rs5
-rw-r--r--components/script/script_thread.rs92
-rw-r--r--components/script/stylesheet_loader.rs22
-rw-r--r--components/script/webdriver_handlers.rs6
-rw-r--r--components/script_traits/Cargo.toml7
-rw-r--r--components/script_traits/lib.rs11
-rw-r--r--components/webdriver_server/Cargo.toml11
-rw-r--r--components/webdriver_server/lib.rs463
-rw-r--r--servo-tidy.toml6
-rw-r--r--tests/unit/metrics/paint_time.rs2
-rw-r--r--tests/wpt/metadata/cors/access-control-expose-headers-parsing.window.js.ini1
-rw-r--r--tests/wpt/metadata/cors/allow-headers.htm.ini15
-rw-r--r--tests/wpt/metadata/cors/origin.htm.ini16
-rw-r--r--tests/wpt/metadata/cors/redirect-origin.htm.ini24
-rw-r--r--tests/wpt/metadata/cors/redirect-userinfo.htm.ini5
-rw-r--r--tests/wpt/metadata/cors/request-headers.htm.ini4
-rw-r--r--tests/wpt/metadata/cors/status-async.htm.ini37
-rw-r--r--tests/wpt/metadata/cors/status-preflight.htm.ini7
-rw-r--r--tests/wpt/metadata/css/CSS2/backgrounds/background-043.xht.ini1
-rw-r--r--tests/wpt/metadata/css/CSS2/backgrounds/background-048.xht.ini4
-rw-r--r--tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini1
-rw-r--r--tests/wpt/metadata/css/cssom-view/elementFromPoint-dynamic-anon-box.html.ini1
-rw-r--r--tests/wpt/metadata/eventsource/format-mime-trailing-semicolon.htm.ini4
-rw-r--r--tests/wpt/metadata/fetch/api/abort/general.any.js.ini4
-rw-r--r--tests/wpt/metadata/fetch/api/cors/cors-cookies-redirect.any.js.ini4
-rw-r--r--tests/wpt/metadata/fetch/api/cors/cors-redirect.any.js.ini60
-rw-r--r--tests/wpt/metadata/fetch/api/redirect/redirect-empty-location.any.js.ini6
-rw-r--r--tests/wpt/metadata/fetch/api/redirect/redirect-origin.any.js.ini33
-rw-r--r--tests/wpt/metadata/fetch/api/request/request-error.html.ini2
-rw-r--r--tests/wpt/metadata/fetch/api/response/response-consume.html.ini3
-rw-r--r--tests/wpt/metadata/fetch/data-urls/processing.any.js.ini84
-rw-r--r--tests/wpt/metadata/fetch/nosniff/importscripts.html.ini5
-rw-r--r--tests/wpt/metadata/fetch/nosniff/script.html.ini4
-rw-r--r--tests/wpt/metadata/fetch/nosniff/stylesheet.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini46
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html.ini4
-rw-r--r--tests/wpt/metadata/url/a-element-origin-xhtml.xhtml.ini3
-rw-r--r--tests/wpt/metadata/url/a-element-origin.html.ini4
-rw-r--r--tests/wpt/metadata/url/a-element-xhtml.xhtml.ini102
-rw-r--r--tests/wpt/metadata/url/a-element.html.ini102
-rw-r--r--tests/wpt/metadata/url/failure.html.ini115
-rw-r--r--tests/wpt/metadata/url/url-constructor.html.ini102
-rw-r--r--tests/wpt/metadata/url/url-origin.html.ini2
-rw-r--r--tests/wpt/metadata/url/url-setters.html.ini162
-rw-r--r--tests/wpt/metadata/websockets/basic-auth.any.js.ini12
-rw-r--r--tests/wpt/metadata/xhr/access-control-and-redirects.htm.ini5
-rw-r--r--tests/wpt/metadata/xhr/access-control-basic-allow-access-control-origin-header-data-url.htm.ini5
-rw-r--r--tests/wpt/metadata/xhr/allow-lists-starting-with-comma.htm.ini4
-rw-r--r--tests/wpt/metadata/xhr/getresponseheader-chunked-trailer.htm.ini3
-rw-r--r--tests/wpt/metadata/xhr/headers-normalize-response.htm.ini6
-rw-r--r--tests/wpt/metadata/xhr/overridemimetype-blob.html.ini42
-rw-r--r--tests/wpt/metadata/xhr/preserve-ua-header-on-redirect.htm.ini5
-rw-r--r--tests/wpt/metadata/xhr/responsexml-media-type.htm.ini4
-rw-r--r--tests/wpt/metadata/xhr/send-accept-language.htm.ini5
-rw-r--r--tests/wpt/metadata/xhr/send-content-type-charset.htm.ini12
-rw-r--r--tests/wpt/metadata/xhr/send-data-unexpected-tostring.htm.ini3
-rw-r--r--tests/wpt/metadata/xhr/send-redirect-no-location.htm.ini13
-rw-r--r--tests/wpt/metadata/xhr/setrequestheader-allow-empty-value.htm.ini11
-rw-r--r--tests/wpt/metadata/xhr/setrequestheader-allow-whitespace-in-value.htm.ini14
-rw-r--r--tests/wpt/metadata/xhr/setrequestheader-case-insensitive.htm.ini3
-rw-r--r--tests/wpt/metadata/xhr/setrequestheader-content-type.htm.ini66
-rw-r--r--tests/wpt/metadata/xhr/setrequestheader-header-allowed.htm.ini26
-rw-r--r--tests/wpt/metadata/xhr/status-async.htm.ini82
-rw-r--r--tests/wpt/metadata/xhr/status-basic.htm.ini82
-rw-r--r--tests/wpt/metadata/xhr/status-error.htm.ini13
122 files changed, 3829 insertions, 3442 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d785fe4ecff..cabae5e8e81 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -13,7 +13,7 @@ dependencies = [
[[package]]
name = "alloc-no-stdlib"
-version = "1.2.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -69,6 +69,11 @@ dependencies = [
]
[[package]]
+name = "arrayref"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "arrayvec"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -132,7 +137,7 @@ dependencies = [
[[package]]
name = "base64"
-version = "0.6.0"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -175,11 +180,6 @@ dependencies = [
[[package]]
name = "bitflags"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "bitflags"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -189,6 +189,15 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "block-buffer"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "bluetooth"
version = "0.0.1"
dependencies = [
@@ -251,19 +260,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "brotli"
-version = "1.1.2"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "brotli-decompressor 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "alloc-no-stdlib 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "brotli-decompressor 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "brotli-decompressor"
-version = "1.1.1"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "alloc-no-stdlib 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -277,13 +286,18 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "byte-tools"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "byteorder"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
-version = "0.4.6"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -533,7 +547,7 @@ dependencies = [
"gaol 0.0.1 (git+https://github.com/servo/gaol)",
"gfx 0.0.1",
"gfx_traits 0.0.1",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keyboard-types 0.4.2-servo (registry+https://github.com/rust-lang/crates.io-index)",
"layout_traits 0.0.1",
@@ -557,7 +571,7 @@ dependencies = [
[[package]]
name = "cookie"
-version = "0.10.1"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -640,6 +654,15 @@ dependencies = [
]
[[package]]
+name = "crossbeam-deque"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "crossbeam-epoch"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -655,6 +678,19 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-epoch"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -688,7 +724,7 @@ dependencies = [
"dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -702,7 +738,7 @@ name = "cssparser-macros"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -754,7 +790,7 @@ version = "0.0.1"
dependencies = [
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_channel 0.0.1",
- "ws 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -797,8 +833,11 @@ name = "devtools"
version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-core 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-ext 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper_serde 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@@ -813,8 +852,7 @@ name = "devtools_traits"
version = "0.0.1"
dependencies = [
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1",
"malloc_size_of_derive 0.0.1",
@@ -825,6 +863,14 @@ dependencies = [
]
[[package]]
+name = "digest"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "dirs"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1015,6 +1061,11 @@ dependencies = [
]
[[package]]
+name = "fake-simd"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "fallible"
version = "0.0.1"
dependencies = [
@@ -1098,6 +1149,20 @@ dependencies = [
]
[[package]]
+name = "futures"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "futures-cpupool"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1125,6 +1190,14 @@ dependencies = [
]
[[package]]
+name = "generic-array"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "getopts"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1453,6 +1526,23 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "h2"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "half"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1476,6 +1566,41 @@ dependencies = [
]
[[package]]
+name = "headers-core"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "headers-derive"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "headers-ext"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-core 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-derive 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "heartbeats-simple"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1513,8 +1638,18 @@ dependencies = [
]
[[package]]
+name = "http"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "httparse"
-version = "1.2.1"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1527,40 +1662,56 @@ dependencies = [
[[package]]
name = "hyper"
-version = "0.10.13"
+version = "0.12.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hyper-openssl"
-version = "0.2.6"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-openssl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hyper_serde"
-version = "0.8.0"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-ext 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1609,6 +1760,11 @@ dependencies = [
]
[[package]]
+name = "indexmap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "inflate"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1618,10 +1774,16 @@ dependencies = [
[[package]]
name = "influent"
-version = "0.4.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1655,7 +1817,7 @@ dependencies = [
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1744,11 +1906,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "language-tags"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
name = "layout"
version = "0.0.1"
dependencies = [
@@ -1863,7 +2020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazycell"
-version = "0.6.0"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1983,6 +2140,19 @@ dependencies = [
]
[[package]]
+name = "linked-hash-map"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "linked_hash_set"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "lock_api"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2033,8 +2203,8 @@ dependencies = [
"cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashglobe 0.1.0",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper_serde 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keyboard-types 0.4.2-servo (registry+https://github.com/rust-lang/crates.io-index)",
"mozjs 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.20.0",
@@ -2047,7 +2217,7 @@ dependencies = [
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_api 0.57.2 (git+https://github.com/servo/webrender)",
"xml5ever 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2075,8 +2245,8 @@ name = "markup5ever"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2146,21 +2316,21 @@ dependencies = [
[[package]]
name = "mime"
-version = "0.2.4"
+version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mime_guess"
-version = "1.8.1"
+version = "2.0.0-alpha.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2194,14 +2364,14 @@ dependencies = [
[[package]]
name = "mio"
-version = "0.6.15"
+version = "0.6.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2211,6 +2381,27 @@ dependencies = [
]
[[package]]
+name = "mio-extras"
+version = "2.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio-uds"
+version = "0.6.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2288,15 +2479,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "net"
version = "0.0.1"
dependencies = [
- "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "brotli 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "brotli 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"devtools_traits 0.0.1",
"embedder_traits 0.0.1",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper-openssl 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-core 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-ext 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper-openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper_serde 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"immeta 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2304,11 +2500,11 @@ dependencies = [
"malloc_size_of 0.0.1",
"malloc_size_of_derive 0.0.1",
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
- "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)",
"pixels 0.0.1",
"profile_traits 0.0.1",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2321,11 +2517,13 @@ dependencies = [
"std_test_override 0.0.1",
"threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-openssl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_api 0.57.2 (git+https://github.com/servo/webrender)",
- "ws 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2342,16 +2540,20 @@ dependencies = [
name = "net_traits"
version = "0.0.1"
dependencies = [
- "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"embedder_traits 0.0.1",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-core 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-ext 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper_serde 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1",
"malloc_size_of_derive 0.0.1",
+ "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pixels 0.0.1",
@@ -2360,7 +2562,7 @@ dependencies = [
"servo_config 0.0.1",
"servo_url 0.0.1",
"std_test_override 0.0.1",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_api 0.57.2 (git+https://github.com/servo/webrender)",
]
@@ -2502,19 +2704,20 @@ dependencies = [
[[package]]
name = "openssl"
-version = "0.9.24"
+version = "0.10.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys"
-version = "0.9.27"
+version = "0.9.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2612,37 +2815,37 @@ dependencies = [
[[package]]
name = "phf"
-version = "0.7.21"
+version = "0.7.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_codegen"
-version = "0.7.21"
+version = "0.7.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_generator"
-version = "0.7.21"
+version = "0.7.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf_shared"
-version = "0.7.21"
+version = "0.7.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2715,7 +2918,7 @@ name = "profile"
version = "0.0.1"
dependencies = [
"heartbeats-simple 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "influent 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "influent 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2727,6 +2930,7 @@ dependencies = [
"servo_config 0.0.1",
"task_info 0.0.1",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2939,14 +3143,6 @@ version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "rustc_version"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "safemem"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2975,7 +3171,7 @@ version = "0.0.1"
dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bluetooth_traits 0.0.1",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2983,7 +3179,7 @@ dependencies = [
"caseless 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
"deny_public_fields 0.0.1",
"devtools_traits 0.0.1",
@@ -2996,9 +3192,12 @@ dependencies = [
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"half 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-core 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "headers-ext 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper_serde 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3010,8 +3209,8 @@ dependencies = [
"malloc_size_of 0.0.1",
"malloc_size_of_derive 0.0.1",
"metrics 0.0.1",
- "mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mozjs 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3020,9 +3219,9 @@ dependencies = [
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"pixels 0.0.1",
"profile_traits 0.0.1",
"ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3051,7 +3250,7 @@ dependencies = [
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"tinyfiledialogs 3.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_api 0.57.2 (git+https://github.com/servo/webrender)",
@@ -3118,13 +3317,14 @@ version = "0.0.1"
dependencies = [
"bluetooth_traits 0.0.1",
"canvas_traits 0.0.1",
- "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"devtools_traits 0.0.1",
"embedder_traits 0.0.1",
"euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper_serde 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keyboard-types 0.4.2-servo (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3140,7 +3340,7 @@ dependencies = [
"servo_url 0.0.1",
"style_traits 0.0.1",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_api 0.57.2 (git+https://github.com/servo/webrender)",
"webvr_traits 0.0.1",
]
@@ -3154,8 +3354,8 @@ dependencies = [
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_arc 0.1.1",
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3163,11 +3363,6 @@ dependencies = [
]
[[package]]
-name = "semver"
-version = "0.1.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
name = "serde"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3392,7 +3587,7 @@ dependencies = [
"servo_geometry 0.0.1",
"servo_url 0.0.1",
"std_test_override 0.0.1",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3442,14 +3637,25 @@ dependencies = [
"malloc_size_of_derive 0.0.1",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_rand 0.0.1",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "sha-1"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "sha1"
-version = "0.2.0"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -3482,11 +3688,6 @@ version = "0.0.1"
[[package]]
name = "slab"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "slab"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3533,13 +3734,18 @@ dependencies = [
]
[[package]]
+name = "string"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "string_cache"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3551,8 +3757,8 @@ name = "string_cache_codegen"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_generator 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3703,6 +3909,16 @@ dependencies = [
]
[[package]]
+name = "syn"
+version = "0.15.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "synstructure"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3813,17 +4029,170 @@ dependencies = [
]
[[package]]
-name = "toml"
-version = "0.4.5"
+name = "tokio"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-current-thread 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "traitobject"
+name = "tokio-codec"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-current-thread"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-executor"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-fs"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-io"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-openssl"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-reactor"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-tcp"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-threadpool"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-timer"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-udp"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-uds"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "toml"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "truetype"
@@ -3831,8 +4200,13 @@ version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "typeable"
-version = "0.1.2"
+name = "try-lock"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "typenum"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -3855,10 +4229,18 @@ dependencies = [
[[package]]
name = "unicase"
-version = "1.4.0"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicase"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3909,7 +4291,7 @@ dependencies = [
[[package]]
name = "url"
-version = "1.6.1"
+version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3923,7 +4305,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3969,6 +4351,11 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "version_check"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3983,6 +4370,16 @@ dependencies = [
]
[[package]]
+name = "want"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "wayland-client"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4034,27 +4431,33 @@ dependencies = [
[[package]]
name = "webdriver"
-version = "0.35.1"
+version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webdriver_server"
version = "0.0.1"
dependencies = [
- "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keyboard-types 0.4.2-servo (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4062,23 +4465,24 @@ dependencies = [
"msg 0.0.1",
"net_traits 0.0.1",
"regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"script_traits 0.0.1",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_channel 0.0.1",
"servo_config 0.0.1",
"servo_url 0.0.1",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "webdriver 0.35.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "webdriver 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webrender"
version = "0.57.2"
-source = "git+https://github.com/servo/webrender#923ee495bd9b0fda8a4a94c5a6cf42e2f0548731"
+source = "git+https://github.com/servo/webrender#f0221fabc87c5b69a49689eeaa69bd5c380599f0"
dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4104,13 +4508,13 @@ dependencies = [
"thread_profiler 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_api 0.57.2 (git+https://github.com/servo/webrender)",
- "ws 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webrender_api"
version = "0.57.2"
-source = "git+https://github.com/servo/webrender#923ee495bd9b0fda8a4a94c5a6cf42e2f0548731"
+source = "git+https://github.com/servo/webrender#f0221fabc87c5b69a49689eeaa69bd5c380599f0"
dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4230,19 +4634,20 @@ dependencies = [
[[package]]
name = "ws"
-version = "0.7.3"
+version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -4329,7 +4734,7 @@ dependencies = [
[metadata]
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
"checksum aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0ba20154ea1f47ce2793322f049c5646cc6d0fa9759d5f333f286e507bf8080"
-"checksum alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b21f6ad9c9957eb5d70c3dee16d31c092b3cab339628f821766b05e6833d72b8"
+"checksum alloc-no-stdlib 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71877e174a5d78c969228d628c4f7f3b545d13452bd3d9393fa07aacfb7c6894"
"checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407"
"checksum android_injected_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80b9e34fcbf29c0563547cb2ecce9b49504597cad6166769b1e4efb45c6c2951"
"checksum android_log-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b8052e2d8aabbb8d556d6abbcce2a22b9590996c5f849b9c7ce4544a2e3b984e"
@@ -4338,6 +4743,7 @@ dependencies = [
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
"checksum app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9dadc668390b373e73e4abbfc1f07238b09a25858f2f39c06cebc6d8e141d774"
"checksum array-init 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c3cc8456d0ae81a8c76f59e384683a601548c38949a4bfcb65dd31ded5c75ff3"
+"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
"checksum arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0ef4a9820019a0c91d918918c93dc71d469f581a49b47ddc1d285d4270bbe2"
"checksum ascii 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae7d751998c189c1d4468cf0a39bb2eae052a9c58d50ebb3b9591ee3813ad50"
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
@@ -4345,24 +4751,25 @@ dependencies = [
"checksum azure 0.34.0 (git+https://github.com/servo/rust-azure)" = "<none>"
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
-"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
+"checksum base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85415d2594767338a74a30c1d370b2f3262ec1b4ed2d7bba5b3faf4de40467d9"
"checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
"checksum bindgen 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eac4ed5f2de9efc3c87cb722468fa49d0763e98f999d539bfc5e452c13d85c91"
-"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
+"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
"checksum blurdroid 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "19b23557dd27704797128f9db2816416bef20dad62d4a9768714eeb65f07d296"
"checksum blurmac 0.1.0 (git+https://github.com/servo/devices)" = "<none>"
"checksum blurmock 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "68dd72da3a3bb40f3d3bdd366c4cf8e2b1d208c366304f382c80cef8126ca8da"
"checksum blurz 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e73bda0f4c71c63a047351070097f3f507e6718e86b9ee525173371ef7b94b73"
"checksum boxfnonce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbec60c560f322d8e3cd403f91d8908cfd965fff53ba97154bd1b9d90149d98e"
-"checksum brotli 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fe87b40996b84fdc56e57c165d93079f4b50cb806598118e692ddfaa3d3c57c0"
-"checksum brotli-decompressor 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "313f4b6cc0b365d6b88eda5aa40175ee34ac6efa9a79e0b3b8202eca90247ba8"
+"checksum brotli 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6236055e28bc092d6d370f3219e6939d8ba8352b397e290391bb8af0d94f25"
+"checksum brotli-decompressor 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "471bf19486c9aaf5b817ed04c49ccc8acd8d28c70d5114e710e8b9f530df89cd"
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
"checksum byte-slice-cast 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28346c117b50270785fbc123bd6e4ecad20d0c6d5f43d081dc80a3abcc62be64"
+"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
-"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9"
+"checksum bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e178b8e0e239e844b083d5a0d4a156b2654e67f9f80144d48398fcd736a24fb8"
"checksum bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b"
"checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b"
"checksum caseless 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "808dab3318747be122cb31d36de18d4d1c81277a76f8332a02b81a3d73463d7f"
@@ -4381,7 +4788,7 @@ dependencies = [
"checksum cocoa 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5cd1afb83b2de9c41e5dfedb2bcccb779d433b958404876009ae4b01746ff23"
"checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d"
"checksum combine 3.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54cedd8056314afe0d844a37a207007edf8a45f2cc452fd77629cd63c221740e"
-"checksum cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "746858cae4eae40fff37e1998320068df317bc247dc91a67c6cfa053afdc2abb"
+"checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf"
"checksum core-foundation 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "58667b9a618a37ea8c4c4cb5298703e5dfadcd3698c79f54fc43e6a2e94733ea"
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
"checksum core-graphics 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92801c908ea6301ae619ed842a72e01098085fc321b9c2f3f833dad555bba055"
@@ -4390,7 +4797,9 @@ dependencies = [
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
"checksum crossbeam-channel 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a5716fadb87a5633db34c5e83ee6e036e6edc229f8a6bfb7c7c84ed340ba95df"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
+"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1"
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
+"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9"
"checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
@@ -4402,6 +4811,7 @@ dependencies = [
"checksum dbus 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "acd824d45fad5ff0e178fcb3c040f13780e73f63a0a6d5cde59e7894f251ab0e"
"checksum deflate 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebb02aaf4b775afc96684b8402510a338086974e38570a1f65bea8c202eb77a7"
"checksum device 0.0.1 (git+https://github.com/servo/devices)" = "<none>"
+"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
"checksum dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37a76dd8b997af7107d0bb69d43903cf37153a18266f8b3fdb9911f28efb5444"
"checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
"checksum downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "18df8ce4470c189d18aa926022da57544f31e154631eb4cfe796aea97051fe6c"
@@ -4421,6 +4831,7 @@ dependencies = [
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
"checksum euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70a2ebdf55fb9d6329046e026329a55ef8fbaae5ea833f56e170beb3125a8a5f"
"checksum expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
+"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
@@ -4431,9 +4842,12 @@ dependencies = [
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
+"checksum futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "884dbe32a6ae4cd7da5c6db9b78114449df9953b8d490c9d7e1b51720b922c62"
+"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gaol 0.0.1 (git+https://github.com/servo/gaol)" = "<none>"
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
+"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05"
"checksum gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3414b424657317e708489d2857d9575f4403698428b040b609b9d1c1a84a2c"
"checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a"
@@ -4457,23 +4871,29 @@ dependencies = [
"checksum gstreamer-video 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c1f04816d7e183714830da26274f97e7aeff09ae6641058538d21443b4ec07d"
"checksum gstreamer-video-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e2efb301a0b94fa4af503122faa04247085936dd888fd59fa4e21eab3cbd37"
"checksum gvr-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1334b94d8ce67319ddc44663daef53d8c1538629a11562530c981dbd9085b9a"
+"checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c"
"checksum half 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63d68db75012a85555434ee079e7e6337931f87a087ab2988becbadf64673a7f"
"checksum harfbuzz-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87a29ce223fee4727c0c4810a1419a3412f65b29146339fb6a47ee39456c34ea"
+"checksum headers-core 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7794c3bca3a5fb812a06d43f715cf857f7b037d52d6d8e054231d439dd839073"
+"checksum headers-derive 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93b8509be5e3893b8c9c37805a05aa57e4561cf1f1a2aab30cec4931127f36ca"
+"checksum headers-ext 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6657fda27978455d69652a0c817d5c73d6d3694d97027924477a1e1c66e33f61"
"checksum heartbeats-simple 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad003ce233955e9d95f2c69cde84e68302ba9ba4a673d351c9bff93c738aadc"
"checksum heartbeats-simple-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e1a408c0011427cc0e0049f7861c70377819aedfc006e8c901b1c70fd98fb1a4"
"checksum histogram 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1bdcec4094c1ca961b685384ea7af76af5718230b3f34657d1a71fd2dcf4cc9d"
"checksum html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b04478cf718862650a0bf66acaf8f2f8c906fbc703f35c916c1f4211b069a364"
-"checksum httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a6e7a63e511f9edffbab707141fbb8707d1a3098615fb2adbd5769cdfcc9b17d"
+"checksum http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "24f58e8c2d8e886055c3ead7b28793e1455270b5fb39650984c224bc538ba581"
+"checksum httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7b6288d7db100340ca12873fd4d08ad1b8f206a9457798dfb17c018a33fee540"
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
-"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
-"checksum hyper-openssl 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "85a372eb692590b3fe014c196c30f9f52d4c42f58cd49dd94caeee1593c9cc37"
-"checksum hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0997ad463f64ce6ba02cf5af320622bb9782e4f8355b650a2cc7ccca69a7cc2e"
+"checksum hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4aca412c241a2dd53af261efc7adf7736fdebd67dc0d1cc1ffdbcb9407e0e810"
+"checksum hyper-openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddca42b55aaf1755b417d286d5eaa1f435cd626b53ffbb53bb9cef4d8819ac86"
+"checksum hyper_serde 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af6cd576f3bf6d7dabc34828c16a08c99e71dca01c87e4a5d754c6ea3995f3d9"
"checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a"
"checksum immeta 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7371aa3c98fad60de2d9b517e2e1ed45593c32b0c77249310fa507749a2a318b"
+"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220"
"checksum inflate 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6f53b811ee8e2057ccf9643ca6b4277de90efaf5e61e55fd5254576926bb4245"
-"checksum influent 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9bc265d6f1f53ae16fd3c18cc737c8c91ec1381afc6a15bee35fecd16a83070e"
+"checksum influent 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f06f65fa332019cbf57b927cd5a5da53cfce506109f38312fd597745a8a48c0"
"checksum io-surface 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9a33981dff54baaff80f4decb487a65d148a3c00facc97820d0f09128f74dd"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd75debad4ffd295c00c6e3634d254df30050b0837a85e5cd039ac424365f24a"
@@ -4486,15 +4906,16 @@ dependencies = [
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum keyboard-types 0.4.2-servo (registry+https://github.com/rust-lang/crates.io-index)" = "75082c134a78e0fc2232d2f30bf3dfdea1cd28591846b85a73b4b46cd776b482"
"checksum khronos_api 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ef23fcc4059260c5936f638c9805ebfc87cb172fa6661d130cba7f97d58f55"
-"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
-"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
+"checksum lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d33a48d0365c96081958cc663eef834975cb1e8d8bea3378513fc72bdbf11e50"
"checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73"
"checksum leaky-cow 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40a8225d44241fd324a8af2806ba635fc7c8a7e9a7de4d5cf3ef54e71f5926fc"
"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
"checksum libdbus-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8720f9274907052cb50313f91201597868da9d625f8dd125f2aca5bddb7e83a1"
"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2"
"checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
+"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
+"checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c"
"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
@@ -4506,12 +4927,14 @@ dependencies = [
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
-"checksum mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d69889cdc6336ed56b174514ce876c4c3dc564cc23dd872e7bca589bb2a36c8"
-"checksum mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76da6df85047af8c0edfa53f48eb1073012ce1cc95c8fedc0a374f659a89dd65"
+"checksum mime 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "0a907b83e7b9e987032439a387e187119cddafc92d5c2aaeb1d92580a793f630"
+"checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed"
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
"checksum miniz_oxide 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba430291c9d6cedae28bcd2d49d1c32fc57d60cd49086646c5dd5673a870eb5"
"checksum miniz_oxide_c_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5a5b8234d6103ebfba71e29786da4608540f862de5ce980a1c94f86a40ca0d51"
-"checksum mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4fcfcb32d63961fb6f367bfd5d21e4600b92cd310f71f9dca25acae196eb1560"
+"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432"
+"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
+"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f"
"checksum mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "45a8a18a41cfab0fde25cc2f43ea89064d211a0fbb33225b8ff93ab20406e0e7"
@@ -4535,8 +4958,8 @@ dependencies = [
"checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
"checksum objc_id 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e4730aa1c64d722db45f7ccc4113a3e2c465d018de6db4d3e7dfe031e8c8a297"
"checksum offscreen_gl_context 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95f2e39e3b8c95495cfec835b6fefee3f1e7d63c6f81d99796b4f9926c02db3c"
-"checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985"
-"checksum openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdc5c4a02e69ce65046f1763a0181107038e02176233acb0b3351d7cc588f9"
+"checksum openssl 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6c24d3508b4fb6da175c10baac54c578b33f09c89ae90c6fe9788b3b4768efdc"
+"checksum openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)" = "912f301a749394e1025d9dcddef6106ddee9252620e6d0a0e5f8d0681de9b129"
"checksum ordered-float 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a3c8db0fca1fdb34404f0b1286db252f23930b9f7a481e376c16c0d5c309d4"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum osmesa-src 0.1.0 (git+https://github.com/servo/osmesa-src)" = "<none>"
@@ -4549,10 +4972,10 @@ dependencies = [
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
-"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
-"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
-"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
-"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
+"checksum phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)" = "cec29da322b242f4c3098852c77a0ca261c9c01b806cae85a5572a1eb94db9a6"
+"checksum phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)" = "7d187f00cd98d5afbcd8898f6cf181743a449162aeb329dcd2f3849009e605ad"
+"checksum phf_generator 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)" = "03dc191feb9b08b0dc1330d6549b795b9d81aec19efe6b4a45aec8d4caee0c4b"
+"checksum phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)" = "b539898d22d4273ded07f64a05737649dc69095d92cb87c7097ec68e3f150b93"
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum plane-split 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d252db71f3d2109c4936e87d9f29f3c737e89f9ac239999d78866bdd60b9deda"
"checksum png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b"
@@ -4582,12 +5005,10 @@ dependencies = [
"checksum rust-webvr-api 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "712e22ba3c03a7075b40842ae91029a0ab96a81f95e97c0cf623800ec0cbac07"
"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
-"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
"checksum scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef399c8893e8cb7aa9696e895427fab3a6bf265977bb96e126f24ddd2cda85a"
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
-"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
"checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95"
"checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
"checksum serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "0a90213fa7e0f5eac3f7afe2d5ff6b088af515052cc7303bd68c7e3b91a3fb79"
@@ -4602,17 +5023,18 @@ dependencies = [
"checksum servo-media-player 0.1.0 (git+https://github.com/servo/media)" = "<none>"
"checksum servo-skia 0.30000019.1 (registry+https://github.com/rust-lang/crates.io-index)" = "82eddddcf9512dd7c60eccdb486e60e5bd4930afaa4da2d7d4afdff75950fb88"
"checksum servo_media_derive 0.1.0 (git+https://github.com/servo/media)" = "<none>"
-"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
+"checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
+"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
"checksum shared_library 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8254bf098ce4d8d7cc7cc6de438c5488adc5297e5b7ffef88816c0a91bd289c1"
"checksum sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6649e43c1a1e68d29ed56d0dc3b5b6cf3b901da77cf107c4066b9e3da036df5"
"checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "<none>"
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
-"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
"checksum smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c63726029f0069f88467873e47f392575f28f9f16b72ac65465263db4b3a13c"
"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8"
"checksum smithay-client-toolkit 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2051bffc6cbf271176e8ba1527f801b6444567daee15951ff5152aaaf7777b2f"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
+"checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970"
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
@@ -4620,6 +5042,7 @@ dependencies = [
"checksum swapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e454d048db5527d000bfddb77bd072bbf3a1e2ae785f16d9bd116e07c2ab45eb"
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
"checksum syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c67da57e61ebc7b7b6fff56bb34440ca3a83db037320b0507af4c10368deda7d"
+"checksum syn 0.15.6 (registry+https://github.com/rust-lang/crates.io-index)" = "854b08a640fc8f54728fb95321e3ec485b365a97fe47609797c671addd1dde69"
"checksum synstructure 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "98cad891cd238c98e1f0aec9f7c0f620aa696e4e5f7daba56ac67b5e86a6b049"
"checksum tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47776f63b85777d984a50ce49d6b9e58826b6a3766a449fc95bc66cd5663c15b"
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
@@ -4632,14 +5055,28 @@ dependencies = [
"checksum threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59f6d3eff89920113dac9db44dde461d71d01e88a5b57b258a0466c32b5d7fe1"
"checksum time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd7ccbf969a892bf83f1e441126968a07a3941c24ff522a26af9f9f4585d1a3"
"checksum tinyfiledialogs 3.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d79833ca2c493c726ea6a7b651ba0ff8a790add5156cd11bf3743f346005c0c8"
+"checksum tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fbb6a6e9db2702097bfdfddcb09841211ad423b86c75b5ddaca1d62842ac492c"
+"checksum tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb"
+"checksum tokio-current-thread 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdfb899688ac16f618076bd09215edbfda0fd5dfecb375b6942636cb31fa8a7"
+"checksum tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "84823b932d566bc3c6aa644df4ca36cb38593c50b7db06011fd4e12e31e4047e"
+"checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135"
+"checksum tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6cc2de7725863c86ac71b0b9068476fec50834f055a243558ef1655bbd34cb"
+"checksum tokio-openssl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4646ae1fd623393de3d796ea53af75acd02938dd5579544fbd6d236d041978a6"
+"checksum tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8703a5762ff6913510dc64272c714c4389ffd8c4b3cf602879b8bd14ff06b604"
+"checksum tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565"
+"checksum tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a5758cecb6e0633cea5d563ac07c975e04961690b946b04fd84e7d6445a8f6af"
+"checksum tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d03fa701f9578a01b7014f106b47f0a363b4727a7f3f75d666e312ab7acbbf1c"
+"checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c"
+"checksum tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "424c1ed15a0132251813ccea50640b224c809d6ceafb88154c1a8775873a0e89"
"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
-"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec30350633d6dac9dc1a625786b6cbe9150664be941aac2c35ad7199eab877"
-"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
+"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
+"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe4fa6e588762366f1eb4991ce59ad1b93651d0b769dfb4e4d1c5c4b943d1159"
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
"checksum uluru 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2606e9192f308ddc4f0b3c5d1bf3400e28a70fff956e9d9f46d23b094746d9f"
-"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
+"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
+"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a"
"checksum unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a6a2c4e3710edd365cd7e78383153ed739fa31af19f9172f72d3575060f5a43a"
"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f"
"checksum unicode-script 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bd7bbf020b2885113e6304f68bcc33881c5552657c58d4e9699cd1b6606e81"
@@ -4647,7 +5084,7 @@ dependencies = [
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
-"checksum url 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23ef1b2df9b1541244318407f1ed96e754dab6efac4121dc1c4c16d38daf215e"
+"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
"checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
"checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47"
"checksum utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f923c601c7ac48ef1d66f7d5b5b2d9a7ba9c51333ab75a3ddf8d0309185a56"
@@ -4655,14 +5092,16 @@ dependencies = [
"checksum uuid 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4670e1e935f7edd193a413f802e2ee52274aed62a09ccaab1656515c9c53a66"
"checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
+"checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
+"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
"checksum wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0f3ed65542a0be13ea0fdcc55c9a011fcc44c3882e6e1a9b4dfddb25182897dd"
"checksum wayland-commons 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac5c79f1d050f4047a82ddce77acda026c142c0023e7b7e20eea5ad76fb7dbf"
"checksum wayland-protocols 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)" = "be56e3d80559177a70bc78f9396fbe1705b7baed4951ae6e34d28bb59681b1a8"
"checksum wayland-scanner 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)" = "93cf4ef48caedf3fc1a9b2bf0df64e6d425bd628b85830a08432dd25b61de17c"
"checksum wayland-sys 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d2dbe7b51c16b8a8153806aaa21f346333074482bb57bc5cb059cc828f8c6842"
-"checksum webdriver 0.35.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6d14048509ec30805ee10b9d610d3d1987e560f5d3be5c599c2c812a34bbfe"
+"checksum webdriver 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)" = "426afe4e337c88343569b65ed0d84c44655c1d66c5570f3e50da98b64c38298f"
"checksum webrender 0.57.2 (git+https://github.com/servo/webrender)" = "<none>"
"checksum webrender_api 0.57.2 (git+https://github.com/servo/webrender)" = "<none>"
"checksum which 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4be6cfa54dab45266e98b5d7be2f8ce959ddd49abd141a05d52dce4b07f803bb"
@@ -4674,7 +5113,7 @@ dependencies = [
"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
"checksum winit 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51fe58cceab36bef11fcb57d0a86f4cdf0c8668ad51fdbc6d48efa6b2db0cddd"
"checksum winres 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "27d9192d6356d7efe8405dec6c5506b67543cf64b6049968f39f4c4623b4f25d"
-"checksum ws 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "89c48c53bf9dee34411a08993c10b879c36e105d609b46e25673befe3a5c1320"
+"checksum ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "329d3e6dd450a9c5c73024e1047f0be7e24121a68484eb0b5368977bee3cf8c3"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum x11 2.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5c4ac579b5d324dc4add02312b5d0e3e0218521e2d5779d526ac39ee4bb171"
"checksum x11-clipboard 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d8617c6185c96e5fcf57ff156496d73c9c82b7f09a5fea21b518dd32c10e2e05"
diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml
index 7c1ee6b99af..a036f0036d2 100644
--- a/components/constellation/Cargo.toml
+++ b/components/constellation/Cargo.toml
@@ -22,7 +22,7 @@ euclid = "0.19"
embedder_traits = { path = "../embedder_traits" }
gfx = {path = "../gfx"}
gfx_traits = {path = "../gfx_traits"}
-hyper = "0.10"
+http = "0.1"
ipc-channel = "0.11"
layout_traits = {path = "../layout_traits"}
keyboard-types = {version = "0.4.2-servo", features = ["serde"]}
diff --git a/components/constellation/lib.rs b/components/constellation/lib.rs
index f5e23ba3c09..57b59960eb3 100644
--- a/components/constellation/lib.rs
+++ b/components/constellation/lib.rs
@@ -20,7 +20,7 @@ extern crate euclid;
extern crate gaol;
extern crate gfx;
extern crate gfx_traits;
-extern crate hyper;
+extern crate http;
extern crate ipc_channel;
extern crate keyboard_types;
extern crate layout_traits;
diff --git a/components/constellation/network_listener.rs b/components/constellation/network_listener.rs
index 3f58d029acf..457a2021ced 100644
--- a/components/constellation/network_listener.rs
+++ b/components/constellation/network_listener.rs
@@ -6,7 +6,7 @@
//! Any redirects that are encountered are followed. Whenever a non-redirect
//! response is received, it is forwarded to the appropriate script thread.
-use hyper::header::Location;
+use http::header::LOCATION;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use msg::constellation_msg::PipelineId;
@@ -99,7 +99,7 @@ impl NetworkListener {
};
match metadata.headers {
- Some(ref headers) if headers.has::<Location>() => {
+ Some(ref headers) if headers.contains_key(LOCATION) => {
if self.req_init.url_list.is_empty() {
self.req_init.url_list.push(self.req_init.url.clone());
}
diff --git a/components/devtools/Cargo.toml b/components/devtools/Cargo.toml
index 1bcbc1290b2..ba0b4d172c6 100644
--- a/components/devtools/Cargo.toml
+++ b/components/devtools/Cargo.toml
@@ -11,8 +11,11 @@ path = "lib.rs"
[dependencies]
devtools_traits = {path = "../devtools_traits"}
-hyper = "0.10"
-hyper_serde = "0.8"
+headers-core = "0.0.1"
+headers-ext = "0.0.3"
+http = "0.1"
+hyper = "0.12"
+hyper_serde = "0.9"
ipc-channel = "0.11"
log = "0.4"
msg = {path = "../msg"}
diff --git a/components/devtools/actors/network_event.rs b/components/devtools/actors/network_event.rs
index 5e4fe01bcf3..8bc3cf9850a 100644
--- a/components/devtools/actors/network_event.rs
+++ b/components/devtools/actors/network_event.rs
@@ -9,13 +9,12 @@
use actor::{Actor, ActorMessageStatus, ActorRegistry};
use devtools_traits::HttpRequest as DevtoolsHttpRequest;
use devtools_traits::HttpResponse as DevtoolsHttpResponse;
-use hyper::header::{ContentType, Cookie};
-use hyper::header::Headers;
-use hyper::http::RawStatus;
-use hyper::method::Method;
+use headers_core::HeaderMapExt;
+use headers_ext::{ContentType, Cookie};
+use http::{header, HeaderMap};
+use hyper::{Method, StatusCode};
use protocol::JsonPacketStream;
use serde_json::{Map, Value};
-use std::borrow::Cow;
use std::net::TcpStream;
use time;
use time::Tm;
@@ -23,7 +22,7 @@ use time::Tm;
struct HttpRequest {
url: String,
method: Method,
- headers: Headers,
+ headers: HeaderMap,
body: Option<Vec<u8>>,
startedDateTime: Tm,
timeStamp: i64,
@@ -32,9 +31,9 @@ struct HttpRequest {
}
struct HttpResponse {
- headers: Option<Headers>,
- status: Option<RawStatus>,
- body: Option<Vec<u8>>,
+ headers: Option<HeaderMap>,
+ status: Option<(StatusCode, String)>,
+ body: Option<Vec<u8>>
}
pub struct NetworkEventActor {
@@ -189,15 +188,11 @@ impl Actor for NetworkEventActor {
let mut headers = Vec::new();
let mut rawHeadersString = "".to_owned();
let mut headersSize = 0;
- for item in self.request.headers.iter() {
- let name = item.name();
- let value = item.value_string();
- rawHeadersString = rawHeadersString + name + ":" + &value + "\r\n";
- headersSize += name.len() + value.len();
- headers.push(Header {
- name: name.to_owned(),
- value: value.to_owned(),
- });
+ for (name, value) in self.request.headers.iter() {
+ let value = &value.to_str().unwrap().to_string();
+ rawHeadersString = rawHeadersString + name.as_str() + ":" + &value + "\r\n";
+ headersSize += name.as_str().len() + value.len();
+ headers.push(Header { name: name.as_str().to_owned(), value: value.to_owned() });
}
let msg = GetRequestHeadersReply {
from: self.name(),
@@ -210,11 +205,10 @@ impl Actor for NetworkEventActor {
},
"getRequestCookies" => {
let mut cookies = Vec::new();
- if let Some(req_cookies) = self.request.headers.get_raw("Cookie") {
- for cookie in &*req_cookies {
- if let Ok(cookie_value) = String::from_utf8(cookie.clone()) {
- cookies = cookie_value.into_bytes();
- }
+
+ for cookie in self.request.headers.get_all(header::COOKIE) {
+ if let Ok(cookie_value) = String::from_utf8(cookie.as_bytes().to_vec()) {
+ cookies = cookie_value.into_bytes();
}
}
@@ -239,17 +233,15 @@ impl Actor for NetworkEventActor {
let mut headers = vec![];
let mut rawHeadersString = "".to_owned();
let mut headersSize = 0;
- for item in response_headers.iter() {
- let name = item.name();
- let value = item.value_string();
+ for (name, value) in response_headers.iter() {
headers.push(Header {
- name: name.to_owned(),
- value: value.clone(),
+ name: name.as_str().to_owned(),
+ value: value.to_str().unwrap().to_owned(),
});
- headersSize += name.len() + value.len();
- rawHeadersString.push_str(name);
+ headersSize += name.as_str().len() + value.len();
+ rawHeadersString.push_str(name.as_str());
rawHeadersString.push_str(":");
- rawHeadersString.push_str(&value);
+ rawHeadersString.push_str(value.to_str().unwrap());
rawHeadersString.push_str("\r\n");
}
let msg = GetResponseHeadersReply {
@@ -264,11 +256,10 @@ impl Actor for NetworkEventActor {
},
"getResponseCookies" => {
let mut cookies = Vec::new();
- if let Some(res_cookies) = self.request.headers.get_raw("set-cookie") {
- for cookie in &*res_cookies {
- if let Ok(cookie_value) = String::from_utf8(cookie.clone()) {
- cookies = cookie_value.into_bytes();
- }
+ // TODO: This seems quite broken
+ for cookie in self.request.headers.get_all(header::SET_COOKIE) {
+ if let Ok(cookie_value) = String::from_utf8(cookie.as_bytes().to_vec()) {
+ cookies = cookie_value.into_bytes();
}
}
@@ -330,8 +321,8 @@ impl NetworkEventActor {
name: name,
request: HttpRequest {
url: String::new(),
- method: Method::Get,
- headers: Headers::new(),
+ method: Method::GET,
+ headers: HeaderMap::new(),
body: None,
startedDateTime: time::now(),
timeStamp: time::get_time().sec,
@@ -363,7 +354,7 @@ impl NetworkEventActor {
self.response.headers = response.headers.clone();
self.response.status = response.status.as_ref().map(|&(s, ref st)| {
let status_text = String::from_utf8_lossy(st).into_owned();
- RawStatus(s, Cow::from(status_text))
+ (StatusCode::from_u16(s).unwrap(), status_text)
});
self.response.body = response.body.clone();
}
@@ -385,13 +376,8 @@ impl NetworkEventActor {
// TODO: Send the correct values for all these fields.
let hSizeOption = self.response.headers.as_ref().map(|headers| headers.len());
let hSize = hSizeOption.unwrap_or(0);
- let (status_code, status_message) = self
- .response
- .status
- .as_ref()
- .map_or((0, "".to_owned()), |&RawStatus(ref code, ref text)| {
- (*code, text.clone().into_owned())
- });
+ let (status_code, status_message) = self.response.status.as_ref()
+ .map_or((0, "".to_owned()), |(code, text)| (code.as_u16(), text.clone()));
// TODO: Send the correct values for remoteAddress and remotePort and http_version.
ResponseStartMsg {
httpVersion: "HTTP/1.1".to_owned(),
@@ -407,9 +393,9 @@ impl NetworkEventActor {
pub fn response_content(&self) -> ResponseContentMsg {
let mut mString = "".to_owned();
if let Some(ref headers) = self.response.headers {
- mString = match headers.get() {
- Some(&ContentType(ref mime)) => mime.to_string(),
- None => "".to_owned(),
+ mString = match headers.typed_get::<ContentType>() {
+ Some(ct) => ct.to_string(),
+ _ => "".to_owned()
};
}
// TODO: Set correct values when response's body is sent to the devtools in http_loader.
@@ -424,9 +410,9 @@ impl NetworkEventActor {
pub fn response_cookies(&self) -> ResponseCookiesMsg {
let mut cookies_size = 0;
if let Some(ref headers) = self.response.headers {
- cookies_size = match headers.get() {
- Some(&Cookie(ref cookie)) => cookie.len(),
- None => 0,
+ cookies_size = match headers.typed_get::<Cookie>() {
+ Some(ref cookie) => cookie.len(),
+ _ => 0,
};
}
ResponseCookiesMsg {
@@ -439,8 +425,8 @@ impl NetworkEventActor {
let mut headers_byte_count = 0;
if let Some(ref headers) = self.response.headers {
headers_size = headers.len();
- for item in headers.iter() {
- headers_byte_count += item.name().len() + item.value_string().len();
+ for (name, value) in headers.iter() {
+ headers_byte_count += name.as_str().len() + value.len();
}
}
ResponseHeadersMsg {
@@ -450,11 +436,10 @@ impl NetworkEventActor {
}
pub fn request_headers(&self) -> RequestHeadersMsg {
- let size = self
- .request
- .headers
- .iter()
- .fold(0, |acc, h| acc + h.name().len() + h.value_string().len());
+ let size = self.request
+ .headers
+ .iter()
+ .fold(0, |acc, (name, value)| acc + name.as_str().len() + value.len());
RequestHeadersMsg {
headers: self.request.headers.len(),
headersSize: size,
@@ -462,9 +447,9 @@ impl NetworkEventActor {
}
pub fn request_cookies(&self) -> RequestCookiesMsg {
- let cookies_size = match self.request.headers.get() {
- Some(&Cookie(ref cookie)) => cookie.len(),
- None => 0,
+ let cookies_size = match self.request.headers.typed_get::<Cookie>() {
+ Some(ref cookie) => cookie.len(),
+ _ => 0
};
RequestCookiesMsg {
cookies: cookies_size,
diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs
index 547f96bc445..9541d553de3 100644
--- a/components/devtools/lib.rs
+++ b/components/devtools/lib.rs
@@ -13,6 +13,9 @@
#![deny(unsafe_code)]
extern crate devtools_traits;
+extern crate headers_core;
+extern crate headers_ext;
+extern crate http;
extern crate hyper;
extern crate ipc_channel;
#[macro_use]
diff --git a/components/devtools_traits/Cargo.toml b/components/devtools_traits/Cargo.toml
index 34359dadf41..26769dfba3d 100644
--- a/components/devtools_traits/Cargo.toml
+++ b/components/devtools_traits/Cargo.toml
@@ -11,8 +11,7 @@ path = "lib.rs"
[dependencies]
bitflags = "1.0"
-hyper = "0.10"
-hyper_serde = "0.8"
+http = "0.1"
ipc-channel = "0.11"
malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs
index 764af5da0a2..9d95adb3d26 100644
--- a/components/devtools_traits/lib.rs
+++ b/components/devtools_traits/lib.rs
@@ -13,7 +13,7 @@
#[macro_use]
extern crate bitflags;
-extern crate hyper;
+extern crate http;
extern crate ipc_channel;
extern crate malloc_size_of;
#[macro_use]
@@ -24,8 +24,8 @@ extern crate serde;
extern crate servo_url;
extern crate time;
-use hyper::header::Headers;
-use hyper::method::Method;
+use http::HeaderMap;
+use http::method::Method;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use servo_url::ServoUrl;
@@ -301,7 +301,7 @@ pub enum CachedConsoleMessage {
pub struct HttpRequest {
pub url: ServoUrl,
pub method: Method,
- pub headers: Headers,
+ pub headers: HeaderMap,
pub body: Option<Vec<u8>>,
pub pipeline_id: PipelineId,
pub startedDateTime: Tm,
@@ -313,7 +313,7 @@ pub struct HttpRequest {
#[derive(Debug, PartialEq)]
pub struct HttpResponse {
- pub headers: Option<Headers>,
+ pub headers: Option<HeaderMap>,
pub status: Option<(u16, Vec<u8>)>,
pub body: Option<Vec<u8>>,
pub pipeline_id: PipelineId,
diff --git a/components/malloc_size_of/Cargo.toml b/components/malloc_size_of/Cargo.toml
index 04df21fd628..fff432e3fbc 100644
--- a/components/malloc_size_of/Cargo.toml
+++ b/components/malloc_size_of/Cargo.toml
@@ -29,8 +29,8 @@ app_units = "0.7"
cssparser = "0.24.0"
euclid = "0.19"
hashglobe = { path = "../hashglobe" }
-hyper = { version = "0.10", optional = true }
-hyper_serde = { version = "0.8", optional = true }
+hyper = { version = "0.12", optional = true }
+hyper_serde = { version = "0.9", optional = true }
keyboard-types = {version = "0.4.2-servo", features = ["serde"], optional = true}
mozjs = { version = "0.9.3", optional = true }
selectors = { path = "../selectors" }
diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs
index 52b8412f64e..e0f638a843d 100644
--- a/components/malloc_size_of/lib.rs
+++ b/components/malloc_size_of/lib.rs
@@ -978,48 +978,6 @@ impl MallocSizeOf for xml5ever::QualName {
}
#[cfg(feature = "servo")]
-impl MallocSizeOf for hyper::header::Headers {
- fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
- self.iter().fold(0, |acc, x| {
- let name = x.name();
- let raw = self.get_raw(name);
- acc + raw.size_of(ops)
- })
- }
-}
-
-#[cfg(feature = "servo")]
-impl MallocSizeOf for hyper::header::ContentType {
- fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
- self.0.size_of(ops)
- }
-}
-
-#[cfg(feature = "servo")]
-impl MallocSizeOf for hyper::mime::Mime {
- fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
- self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops)
- }
-}
-
-#[cfg(feature = "servo")]
-impl MallocSizeOf for hyper::mime::Attr {
- fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
- match *self {
- hyper::mime::Attr::Ext(ref s) => s.size_of(ops),
- _ => 0,
- }
- }
-}
-
-#[cfg(feature = "servo")]
-impl MallocSizeOf for hyper::mime::Value {
- fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
- self.len() // Length of string value in bytes (not the char length of a string)!
- }
-}
-
-#[cfg(feature = "servo")]
malloc_size_of_is_0!(time::Duration);
#[cfg(feature = "servo")]
malloc_size_of_is_0!(time::Tm);
@@ -1046,12 +1004,9 @@ impl<T> MallocSizeOf for servo_channel::Sender<T> {
}
#[cfg(feature = "servo")]
-impl MallocSizeOf for hyper::status::StatusCode {
- fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
- match *self {
- hyper::status::StatusCode::Unregistered(u) => u.size_of(ops),
- _ => 0,
- }
+impl MallocSizeOf for hyper::StatusCode {
+ fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
+ 0
}
}
diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml
index 402044c1ecd..099f2c17f71 100644
--- a/components/net/Cargo.toml
+++ b/components/net/Cargo.toml
@@ -13,15 +13,19 @@ test = false
doctest = false
[dependencies]
-base64 = "0.6"
-brotli = "1.0.6"
-cookie = "0.10"
+base64 = "0.9"
+brotli = "2.5"
+bytes = "0.4"
+cookie = "0.11"
devtools_traits = {path = "../devtools_traits"}
embedder_traits = { path = "../embedder_traits" }
flate2 = "1"
-hyper = "0.10"
-hyper_serde = "0.8"
-hyper-openssl = "0.2.2"
+headers-core = "0.0.1"
+headers-ext = "0.0.3"
+http = "0.1"
+hyper = "0.12"
+hyper_serde = "0.9"
+hyper-openssl = "0.6"
immeta = "0.4"
ipc-channel = "0.11"
lazy_static = "1"
@@ -29,11 +33,11 @@ log = "0.4"
malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
matches = "0.1"
-mime = "0.2.1"
-mime_guess = "1.8.0"
+mime = "0.3"
+mime_guess = "2.0.0-alpha.6"
msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
-openssl = "0.9"
+openssl = "0.10"
pixels = {path = "../pixels"}
profile_traits = {path = "../profile_traits"}
serde = "1.0"
@@ -43,9 +47,10 @@ servo_arc = {path = "../servo_arc"}
servo_channel = {path = "../channel"}
servo_config = {path = "../config"}
servo_url = {path = "../url"}
+tokio = "0.1"
+tokio-timer = "0.2"
threadpool = "1.0"
time = "0.1.17"
-unicase = "1.4.0"
url = "1.2"
uuid = {version = "0.6", features = ["v4"]}
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
@@ -53,6 +58,8 @@ ws = { version = "0.7", features = ["ssl"] }
[dev-dependencies]
std_test_override = { path = "../std_test_override" }
+futures = "0.1"
+tokio-openssl = "0.2"
[[test]]
name = "main"
diff --git a/components/net/blob_loader.rs b/components/net/blob_loader.rs
index 1fe05cc1c20..3af4d531549 100644
--- a/components/net/blob_loader.rs
+++ b/components/net/blob_loader.rs
@@ -3,11 +3,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use filemanager_thread::FileManager;
-use hyper::header::{Charset, ContentLength, ContentType, Headers};
-use hyper::header::{ContentDisposition, DispositionParam, DispositionType};
+use headers_core::HeaderMapExt;
+use headers_ext::{ContentLength, ContentType};
+use http::HeaderMap;
+use http::header::{self, HeaderValue};
use ipc_channel::ipc;
-use mime::{Attr, Mime};
-use net_traits::NetworkError;
+use mime::{self, Mime};
+use net_traits::{http_percent_encode, NetworkError};
use net_traits::blob_url_store::parse_blob_url;
use net_traits::filemanager_thread::ReadFileProgress;
use servo_url::ServoUrl;
@@ -20,7 +22,7 @@ use servo_url::ServoUrl;
pub fn load_blob_sync
(url: ServoUrl,
filemanager: FileManager)
- -> Result<(Headers, Vec<u8>), NetworkError> {
+ -> Result<(HeaderMap, Vec<u8>), NetworkError> {
let (id, origin) = match parse_blob_url(&url) {
Ok((id, origin)) => (id, origin),
Err(()) => {
@@ -43,26 +45,32 @@ pub fn load_blob_sync
}
};
- let content_type: Mime = blob_buf.type_string.parse().unwrap_or(mime!(Text / Plain));
- let charset = content_type.get_param(Attr::Charset);
+ let content_type: Mime = blob_buf.type_string.parse().unwrap_or(mime::TEXT_PLAIN);
+ let charset = content_type.get_param(mime::CHARSET);
- let mut headers = Headers::new();
+ let mut headers = HeaderMap::new();
if let Some(name) = blob_buf.filename {
- let charset = charset.and_then(|c| c.as_str().parse().ok());
- headers.set(ContentDisposition {
- disposition: DispositionType::Inline,
- parameters: vec![
- DispositionParam::Filename(charset.unwrap_or(Charset::Us_Ascii),
- None, name.as_bytes().to_vec())
- ]
- });
+ let charset = charset.map(|c| c.as_ref().into()).unwrap_or("us-ascii".to_owned());
+ // TODO(eijebong): Replace this once the typed header is there
+ headers.insert(
+ header::CONTENT_DISPOSITION,
+ HeaderValue::from_bytes(
+ format!("inline; {}",
+ if charset.to_lowercase() == "utf-8" {
+ format!("filename=\"{}\"", String::from_utf8(name.as_bytes().into()).unwrap())
+ } else {
+ format!("filename*=\"{}\"''{}", charset, http_percent_encode(name.as_bytes()))
+ }
+ ).as_bytes()
+ ).unwrap()
+ );
}
// Basic fetch, Step 4.
- headers.set(ContentLength(blob_buf.size as u64));
+ headers.typed_insert(ContentLength(blob_buf.size as u64));
// Basic fetch, Step 5.
- headers.set(ContentType(content_type.clone()));
+ headers.typed_insert(ContentType::from(content_type.clone()));
let mut bytes = blob_buf.bytes;
loop {
diff --git a/components/net/connector.rs b/components/net/connector.rs
index 03ee7e5459d..0311b05b125 100644
--- a/components/net/connector.rs
+++ b/components/net/connector.rs
@@ -2,60 +2,132 @@
* 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/. */
+use flate2::read::GzDecoder;
use hosts::replace_host;
-use hyper::client::Pool;
-use hyper::error::{Result as HyperResult, Error as HyperError};
-use hyper::net::{NetworkConnector, HttpsStream, HttpStream, SslClient};
-use hyper_openssl::OpensslClient;
-use openssl::ssl::{SSL_OP_NO_COMPRESSION, SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3};
-use openssl::ssl::{SslConnector, SslConnectorBuilder, SslMethod};
+use http_loader::Decoder;
+use hyper::{Body, Client};
+use hyper::body::Payload;
+use hyper::client::HttpConnector as HyperHttpConnector;
+use hyper::client::connect::{Connect, Destination};
+use hyper::rt::Future;
+use hyper_openssl::HttpsConnector;
+use openssl::ssl::{SslConnector, SslConnectorBuilder, SslMethod, SslOptions};
use openssl::x509;
-use std::io;
-use std::net::TcpStream;
+use std::io::{Cursor, Read};
+use tokio::prelude::{Async, Stream};
+use tokio::prelude::future::Executor;
-pub struct HttpsConnector {
- ssl: OpensslClient,
+pub const BUF_SIZE: usize = 32768;
+
+pub struct HttpConnector {
+ inner: HyperHttpConnector
}
-impl HttpsConnector {
- fn new(ssl: OpensslClient) -> HttpsConnector {
- HttpsConnector {
- ssl: ssl,
+impl HttpConnector {
+ fn new() -> HttpConnector {
+ let mut inner = HyperHttpConnector::new(4);
+ inner.enforce_http(false);
+ inner.set_happy_eyeballs_timeout(None);
+ HttpConnector {
+ inner
}
}
}
-impl NetworkConnector for HttpsConnector {
- type Stream = HttpsStream<<OpensslClient as SslClient>::Stream>;
-
- fn connect(&self, host: &str, port: u16, scheme: &str) -> HyperResult<Self::Stream> {
- if scheme != "http" && scheme != "https" {
- return Err(HyperError::Io(io::Error::new(io::ErrorKind::InvalidInput,
- "Invalid scheme for Http")));
- }
+impl Connect for HttpConnector {
+ type Transport = <HyperHttpConnector as Connect>::Transport;
+ type Error = <HyperHttpConnector as Connect>::Error;
+ type Future = <HyperHttpConnector as Connect>::Future;
+ fn connect(&self, dest: Destination) -> Self::Future {
// Perform host replacement when making the actual TCP connection.
- let addr = &(&*replace_host(host), port);
- let stream = HttpStream(TcpStream::connect(addr)?);
+ let mut new_dest = dest.clone();
+ let addr = replace_host(dest.host());
+ new_dest.set_host(&*addr).unwrap();
+ self.inner.connect(new_dest)
+ }
+}
- if scheme == "http" {
- Ok(HttpsStream::Http(stream))
- } else {
- // Do not perform host replacement on the host that is used
- // for verifying any SSL certificate encountered.
- self.ssl.wrap_client(stream, host).map(HttpsStream::Https)
+pub type Connector = HttpsConnector<HttpConnector>;
+pub struct WrappedBody {
+ pub body: Body,
+ pub decoder: Decoder,
+}
+
+impl WrappedBody {
+ pub fn new(body: Body) -> Self {
+ Self::new_with_decoder(body, Decoder::Plain)
+ }
+
+ pub fn new_with_decoder(body: Body, decoder: Decoder) -> Self {
+ WrappedBody {
+ body,
+ decoder,
}
}
}
-pub type Connector = HttpsConnector;
+impl Payload for WrappedBody {
+ type Data = <Body as Payload>::Data;
+ type Error = <Body as Payload>::Error;
+ fn poll_data(&mut self) -> Result<Async<Option<Self::Data>>, Self::Error> {
+ self.body.poll_data()
+ }
+}
-pub fn create_ssl_connector(certs: &str) -> SslConnector {
+impl Stream for WrappedBody {
+ type Item = <Body as Stream>::Item;
+ type Error = <Body as Stream>::Error;
+ fn poll(&mut self) -> Result<Async<Option<Self::Item>>, Self::Error> {
+ self.body.poll().map(|res| {
+ res.map(|maybe_chunk| {
+ if let Some(chunk) = maybe_chunk {
+ match self.decoder {
+ Decoder::Plain => Some(chunk),
+ Decoder::Gzip(Some(ref mut decoder)) => {
+ let mut buf = vec![0; BUF_SIZE];
+ *decoder.get_mut() = Cursor::new(chunk.into_bytes());
+ let len = decoder.read(&mut buf).ok()?;
+ buf.truncate(len);
+ Some(buf.into())
+ }
+ Decoder::Gzip(None) => {
+ let mut buf = vec![0; BUF_SIZE];
+ let mut decoder = GzDecoder::new(Cursor::new(chunk.into_bytes()));
+ let len = decoder.read(&mut buf).ok()?;
+ buf.truncate(len);
+ self.decoder = Decoder::Gzip(Some(decoder));
+ Some(buf.into())
+ }
+ Decoder::Deflate(ref mut decoder) => {
+ let mut buf = vec![0; BUF_SIZE];
+ *decoder.get_mut() = Cursor::new(chunk.into_bytes());
+ let len = decoder.read(&mut buf).ok()?;
+ buf.truncate(len);
+ Some(buf.into())
+ }
+ Decoder::Brotli(ref mut decoder) => {
+ let mut buf = vec![0; BUF_SIZE];
+ decoder.get_mut().get_mut().extend(&chunk.into_bytes());
+ let len = decoder.read(&mut buf).ok()?;
+ buf.truncate(len);
+ Some(buf.into())
+ }
+ }
+ } else {
+ None
+ }
+ })
+ })
+ }
+}
+
+pub fn create_ssl_connector_builder(certs: &str) -> SslConnectorBuilder {
// certs include multiple certificates. We could add all of them at once,
// but if any of them were already added, openssl would fail to insert all
// of them.
let mut certs = certs;
- let mut ssl_connector_builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
+ let mut ssl_connector_builder = SslConnector::builder(SslMethod::tls()).unwrap();
loop {
let token = "-----END CERTIFICATE-----";
if let Some(index) = certs.find(token) {
@@ -78,18 +150,17 @@ pub fn create_ssl_connector(certs: &str) -> SslConnector {
}
}
ssl_connector_builder.set_cipher_list(DEFAULT_CIPHERS).expect("could not set ciphers");
- ssl_connector_builder.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION);
- ssl_connector_builder.build()
-}
-
-pub fn create_ssl_client(certs: &str) -> OpensslClient {
- let ssl_connector = create_ssl_connector(certs);
- OpensslClient::from(ssl_connector)
+ ssl_connector_builder.set_options(SslOptions::NO_SSLV2 | SslOptions::NO_SSLV3 | SslOptions::NO_COMPRESSION);
+ ssl_connector_builder
}
-pub fn create_http_connector(ssl_client: OpensslClient) -> Pool<Connector> {
- let https_connector = HttpsConnector::new(ssl_client);
- Pool::with_connector(Default::default(), https_connector)
+pub fn create_http_client<E>(ssl_connector_builder: SslConnectorBuilder, executor: E)
+ -> Client<Connector, WrappedBody>
+ where
+ E: Executor<Box<Future<Error=(), Item=()> + Send + 'static>> + Sync + Send + 'static
+{
+ let connector = HttpsConnector::with_connector(HttpConnector::new(), ssl_connector_builder).unwrap();
+ Client::builder().http1_title_case_headers(true).executor(executor).build(connector)
}
// The basic logic here is to prefer ciphers with ECDSA certificates, Forward
diff --git a/components/net/cookie.rs b/components/net/cookie.rs
index e8e7be6733d..fb403628107 100644
--- a/components/net/cookie.rs
+++ b/components/net/cookie.rs
@@ -94,14 +94,14 @@ impl Cookie {
// Step 10
- if cookie.http_only() && source == CookieSource::NonHTTP {
+ if cookie.http_only().unwrap_or(false) && source == CookieSource::NonHTTP {
return None;
}
// https://tools.ietf.org/html/draft-west-cookie-prefixes-04#section-4
// Step 1 of cookie prefixes
if (cookie.name().starts_with("__Secure-") || cookie.name().starts_with("__Host-")) &&
- !(cookie.secure() && request.is_secure_scheme())
+ !(cookie.secure().unwrap_or(false) && request.is_secure_scheme())
{
return None;
}
@@ -197,10 +197,10 @@ impl Cookie {
}
}
- if self.cookie.secure() && !url.is_secure_scheme() {
+ if self.cookie.secure().unwrap_or(false) && !url.is_secure_scheme() {
return false;
}
- if self.cookie.http_only() && source == CookieSource::NonHTTP {
+ if self.cookie.http_only().unwrap_or(false) && source == CookieSource::NonHTTP {
return false;
}
diff --git a/components/net/cookie_storage.rs b/components/net/cookie_storage.rs
index 4dc7075a9fd..cb066d416fe 100644
--- a/components/net/cookie_storage.rs
+++ b/components/net/cookie_storage.rs
@@ -38,7 +38,7 @@ impl CookieStorage {
let cookies = self.cookies_map.entry(domain).or_insert(vec![]);
// https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt Step 2
- if !cookie.cookie.secure() && !url.is_secure_scheme() {
+ if !cookie.cookie.secure().unwrap_or(false) && !url.is_secure_scheme() {
let new_domain = cookie.cookie.domain().as_ref().unwrap().to_owned();
let new_path = cookie.cookie.path().as_ref().unwrap().to_owned();
@@ -47,7 +47,7 @@ impl CookieStorage {
let existing_path = c.cookie.path().as_ref().unwrap().to_owned();
c.cookie.name() == cookie.cookie.name() &&
- c.cookie.secure() &&
+ c.cookie.secure().unwrap_or(false) &&
(Cookie::domain_match(new_domain, existing_domain) ||
Cookie::domain_match(existing_domain, new_domain)) &&
Cookie::path_match(new_path, existing_path)
@@ -70,7 +70,7 @@ impl CookieStorage {
let c = cookies.remove(ind);
// http://tools.ietf.org/html/rfc6265#section-5.3 step 11.2
- if c.cookie.http_only() && source == CookieSource::NonHTTP {
+ if c.cookie.http_only().unwrap_or(false) && source == CookieSource::NonHTTP {
// Undo the removal.
cookies.push(c);
Err(())
@@ -85,7 +85,7 @@ impl CookieStorage {
// http://tools.ietf.org/html/rfc6265#section-5.3
pub fn push(&mut self, mut cookie: Cookie, url: &ServoUrl, source: CookieSource) {
// https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt Step 1
- if cookie.cookie.secure() && !url.is_secure_scheme() {
+ if cookie.cookie.secure().unwrap_or(false) && !url.is_secure_scheme() {
return;
}
@@ -111,7 +111,7 @@ impl CookieStorage {
let new_len = cookies.len();
// https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt
- if new_len == old_len && !evict_one_cookie(cookie.cookie.secure(), cookies) {
+ if new_len == old_len && !evict_one_cookie(cookie.cookie.secure().unwrap_or(false), cookies) {
return;
}
}
@@ -219,7 +219,7 @@ fn evict_one_cookie(is_secure_cookie: bool, cookies: &mut Vec<Cookie>) -> bool {
fn get_oldest_accessed(is_secure_cookie: bool, cookies: &mut Vec<Cookie>) -> Option<(usize, Tm)> {
let mut oldest_accessed: Option<(usize, Tm)> = None;
for (i, c) in cookies.iter().enumerate() {
- if (c.cookie.secure() == is_secure_cookie) &&
+ if (c.cookie.secure().unwrap_or(false) == is_secure_cookie) &&
oldest_accessed.as_ref().map_or(true, |a| c.last_access < a.1) {
oldest_accessed = Some((i, c.last_access));
}
diff --git a/components/net/data_loader.rs b/components/net/data_loader.rs
index b95a2ab3412..16ffb75a323 100644
--- a/components/net/data_loader.rs
+++ b/components/net/data_loader.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use base64;
-use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value};
+use mime::Mime;
use servo_url::ServoUrl;
use url::Position;
use url::percent_encoding::percent_decode;
@@ -37,8 +37,7 @@ pub fn decode(url: &ServoUrl) -> Result<DecodeData, DecodeError> {
};
let content_type = ct_str.parse().unwrap_or_else(|_| {
- Mime(TopLevel::Text, SubLevel::Plain,
- vec![(Attr::Charset, Value::Ext("US-ASCII".to_owned()))])
+ "text/plain; charset=US-ASCII".parse().unwrap()
});
let mut bytes = percent_decode(parts[1].as_bytes()).collect::<Vec<_>>();
diff --git a/components/net/fetch/cors_cache.rs b/components/net/fetch/cors_cache.rs
index 8962dd2c998..95e070cfc8e 100644
--- a/components/net/fetch/cors_cache.rs
+++ b/components/net/fetch/cors_cache.rs
@@ -9,7 +9,8 @@
//! This library will eventually become the core of the Fetch crate
//! with CORSRequest being expanded into FetchRequest (etc)
-use hyper::method::Method;
+use http::header::HeaderName;
+use hyper::Method;
use net_traits::request::{CredentialsMode, Origin, Request};
use servo_url::ServoUrl;
use time::{self, Timespec};
@@ -19,14 +20,14 @@ use time::{self, Timespec};
/// Each entry might pertain to a header or method
#[derive(Clone, Debug)]
pub enum HeaderOrMethod {
- HeaderData(String),
+ HeaderData(HeaderName),
MethodData(Method)
}
impl HeaderOrMethod {
- fn match_header(&self, header_name: &str) -> bool {
+ fn match_header(&self, header_name: &HeaderName) -> bool {
match *self {
- HeaderOrMethod::HeaderData(ref s) => (&**s).eq_ignore_ascii_case(header_name),
+ HeaderOrMethod::HeaderData(ref n) => n == header_name,
_ => false
}
}
@@ -80,7 +81,7 @@ impl CorsCache {
}
fn find_entry_by_header<'a>(&'a mut self, request: &Request,
- header_name: &str) -> Option<&'a mut CorsCacheEntry> {
+ header_name: &HeaderName) -> Option<&'a mut CorsCacheEntry> {
self.cleanup();
self.0.iter_mut().find(|e| match_headers(e, request) && e.header_or_method.match_header(header_name))
}
@@ -113,7 +114,7 @@ impl CorsCache {
/// Returns true if an entry with a
/// [matching header](https://fetch.spec.whatwg.org/#concept-cache-match-header) is found
- pub fn match_header(&mut self, request: &Request, header_name: &str) -> bool {
+ pub fn match_header(&mut self, request: &Request, header_name: &HeaderName) -> bool {
self.find_entry_by_header(&request, header_name).is_some()
}
@@ -122,13 +123,13 @@ impl CorsCache {
///
/// If not, it will insert an equivalent entry
pub fn match_header_and_update(&mut self, request: &Request,
- header_name: &str, new_max_age: u32) -> bool {
+ header_name: &HeaderName, new_max_age: u32) -> bool {
match self.find_entry_by_header(&request, header_name).map(|e| e.max_age = new_max_age) {
Some(_) => true,
None => {
self.insert(CorsCacheEntry::new(request.origin.clone(), request.current_url(), new_max_age,
request.credentials_mode == CredentialsMode::Include,
- HeaderOrMethod::HeaderData(header_name.to_owned())));
+ HeaderOrMethod::HeaderData(header_name.clone())));
false
}
}
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs
index bec31fe81a2..edc6e3be45a 100644
--- a/components/net/fetch/methods.rs
+++ b/components/net/fetch/methods.rs
@@ -7,16 +7,15 @@ use data_loader::decode;
use devtools_traits::DevtoolsControlMsg;
use fetch::cors_cache::CorsCache;
use filemanager_thread::FileManager;
+use headers_core::HeaderMapExt;
+use headers_ext::{AccessControlExposeHeaders, ContentType, Range};
+use http::header::{self, HeaderMap, HeaderName, HeaderValue};
use http_loader::{HttpState, determine_request_referrer, http_fetch};
use http_loader::{set_default_accept, set_default_accept_language};
-use hyper::{Error, Result as HyperResult};
-use hyper::header;
-use hyper::header::{Accept, AcceptLanguage, AccessControlExposeHeaders, ContentLanguage, ContentType};
-use hyper::header::{Header, HeaderFormat, HeaderView, Headers, Referer as RefererHeader};
-use hyper::method::Method;
-use hyper::mime::{Mime, SubLevel, TopLevel};
-use hyper::status::StatusCode;
+use hyper::Method;
+use hyper::StatusCode;
use ipc_channel::ipc::IpcReceiver;
+use mime::{self, Mime};
use mime_guess::guess_mime_type;
use net_traits::{FetchTaskTarget, NetworkError, ReferrerPolicy};
use net_traits::request::{CredentialsMode, Destination, Referrer, Request, RequestMode};
@@ -25,16 +24,20 @@ use net_traits::response::{Response, ResponseBody, ResponseType};
use servo_channel::{channel, Sender, Receiver};
use servo_url::ServoUrl;
use std::borrow::Cow;
-use std::fmt;
use std::fs::File;
use std::io::{BufReader, BufRead, Seek, SeekFrom};
use std::mem;
+use std::ops::Bound;
use std::str;
use std::sync::{Arc, Mutex};
use std::sync::atomic::Ordering;
use std::thread;
use subresource_integrity::is_response_integrity_valid;
+lazy_static! {
+ static ref X_CONTENT_TYPE_OPTIONS: HeaderName = HeaderName::from_static("x-content-type-options");
+}
+
const FILE_CHUNK_SIZE: usize = 32768; //32 KB
pub type Target<'a> = &'a mut (FetchTaskTarget + Send);
@@ -173,11 +176,11 @@ pub fn main_fetch(request: &mut Request,
Referrer::Client => {
// FIXME(#14507): We should never get this value here; it should
// already have been handled in the script thread.
- request.headers.remove::<RefererHeader>();
+ request.headers.remove(header::REFERER);
None
},
Referrer::ReferrerUrl(url) => {
- request.headers.remove::<RefererHeader>();
+ request.headers.remove(header::REFERER);
let current_url = request.current_url().clone();
determine_request_referrer(&mut request.headers,
request.referrer_policy.unwrap(),
@@ -238,7 +241,7 @@ pub fn main_fetch(request: &mut Request,
} else if request.use_cors_preflight ||
(request.unsafe_request &&
(!is_cors_safelisted_method(&request.method) ||
- request.headers.iter().any(|h| !is_cors_safelisted_request_header(&h)))) {
+ request.headers.iter().any(|(name, value)| !is_cors_safelisted_request_header(&name, &value)))) {
// Substep 1.
request.response_tainting = ResponseTainting::CorsTainting;
// Substep 2.
@@ -269,18 +272,19 @@ pub fn main_fetch(request: &mut Request,
// Substep 1.
if request.response_tainting == ResponseTainting::CorsTainting {
// Subsubstep 1.
- let header_names = response.headers.get::<AccessControlExposeHeaders>();
+ let header_names: Option<Vec<HeaderName>> = response.headers.typed_get::<AccessControlExposeHeaders>()
+ .map(|v| v.iter().collect());
match header_names {
// Subsubstep 2.
- Some(list) if request.credentials_mode != CredentialsMode::Include => {
+ Some(ref list) if request.credentials_mode != CredentialsMode::Include => {
if list.len() == 1 && list[0] == "*" {
response.cors_exposed_header_name_list =
- response.headers.iter().map(|h| h.name().to_owned()).collect();
+ response.headers.iter().map(|(name, _)| name.as_str().to_owned()).collect();
}
},
// Subsubstep 3.
Some(list) => {
- response.cors_exposed_header_name_list = list.iter().map(|h| (**h).clone()).collect();
+ response.cors_exposed_header_name_list = list.iter().map(|h| h.as_str().to_owned()).collect();
},
_ => (),
}
@@ -341,7 +345,7 @@ pub fn main_fetch(request: &mut Request,
let not_network_error = !response_is_network_error && !internal_response.is_network_error();
if not_network_error && (is_null_body_status(&internal_response.status) ||
match request.method {
- Method::Head | Method::Connect => true,
+ Method::HEAD | Method::CONNECT => true,
_ => false }) {
// when Fetch is used only asynchronously, we will need to make sure
// that nothing tries to write to the body at this point
@@ -463,7 +467,7 @@ fn scheme_fetch(request: &mut Request,
match url.scheme() {
"about" if url.path() == "blank" => {
let mut response = Response::new(url);
- response.headers.set(ContentType(mime!(Text / Html; Charset = Utf8)));
+ response.headers.typed_insert(ContentType::from(mime::TEXT_HTML_UTF_8));
*response.body.lock().unwrap() = ResponseBody::Done(vec![]);
response
},
@@ -477,7 +481,7 @@ fn scheme_fetch(request: &mut Request,
Ok((mime, bytes)) => {
let mut response = Response::new(url);
*response.body.lock().unwrap() = ResponseBody::Done(bytes);
- response.headers.set(ContentType(mime));
+ response.headers.typed_insert(ContentType::from(mime));
response
},
Err(_) => Response::network_error(NetworkError::Internal("Decoding data URL failed".into()))
@@ -485,7 +489,7 @@ fn scheme_fetch(request: &mut Request,
},
"file" => {
- if request.method == Method::Get {
+ if request.method == Method::GET {
match url.to_file_path() {
Ok(file_path) => {
match File::open(file_path.clone()) {
@@ -493,7 +497,7 @@ fn scheme_fetch(request: &mut Request,
let mime = guess_mime_type(file_path);
let mut response = Response::new(url);
- response.headers.set(ContentType(mime));
+ response.headers.typed_insert(ContentType::from(mime));
let (done_sender, done_receiver) = channel();
*done_chan = Some((done_sender.clone(), done_receiver));
@@ -503,22 +507,22 @@ fn scheme_fetch(request: &mut Request,
let cancellation_listener = context.cancellation_listener.clone();
- let range = request.headers.get::<header::Range>();
- let (start, end) = if let Some(&header::Range::Bytes(ref range)) = range {
- match range.first().unwrap() {
- &header::ByteRangeSpec::AllFrom(start) => (start, None),
- &header::ByteRangeSpec::FromTo(start, end) => {
+ let (start, end) = if let Some(ref range) = request.headers.typed_get::<Range>() {
+ match range.iter().collect::<Vec<(Bound<u64>, Bound<u64>)>>().first() {
+ Some(&(Bound::Included(start), Bound::Unbounded)) => (start, None),
+ Some(&(Bound::Included(start), Bound::Included(end))) => {
// `end` should be less or equal to `start`.
(start, Some(u64::max(start, end)))
},
- &header::ByteRangeSpec::Last(offset) => {
+ Some(&(Bound::Unbounded, Bound::Included(offset))) => {
if let Ok(metadata) = file.metadata() {
// `offset` cannot be bigger than the file size.
(metadata.len() - u64::min(metadata.len(), offset), None)
} else {
(0, None)
}
- }
+ },
+ _ => (0, None)
}
} else {
(0, None)
@@ -591,7 +595,7 @@ fn scheme_fetch(request: &mut Request,
"blob" => {
println!("Loading blob {}", url.as_str());
// Step 2.
- if request.method != Method::Get {
+ if request.method != Method::GET {
return Response::network_error(NetworkError::Internal("Unexpected method for blob".into()));
}
@@ -619,33 +623,33 @@ fn scheme_fetch(request: &mut Request,
}
/// <https://fetch.spec.whatwg.org/#cors-safelisted-request-header>
-pub fn is_cors_safelisted_request_header(h: &HeaderView) -> bool {
- if h.is::<ContentType>() {
- match h.value() {
- Some(&ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) |
- Some(&ContentType(Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _))) |
- Some(&ContentType(Mime(TopLevel::Multipart, SubLevel::FormData, _))) => true,
- _ => false
-
+pub fn is_cors_safelisted_request_header(name: &HeaderName, value: &HeaderValue) -> bool {
+ if name == header::CONTENT_TYPE {
+ if let Some(m) = value.to_str().ok().and_then(|s| s.parse::<Mime>().ok()) {
+ m.type_() == mime::TEXT && m.subtype() == mime::PLAIN ||
+ m.type_() == mime::APPLICATION && m.subtype() == mime::WWW_FORM_URLENCODED ||
+ m.type_() == mime::MULTIPART && m.subtype() == mime::FORM_DATA
+ } else {
+ false
}
} else {
- h.is::<Accept>() || h.is::<AcceptLanguage>() || h.is::<ContentLanguage>()
+ name == header::ACCEPT || name == header::ACCEPT_LANGUAGE || name == header::CONTENT_LANGUAGE
}
}
/// <https://fetch.spec.whatwg.org/#cors-safelisted-method>
pub fn is_cors_safelisted_method(m: &Method) -> bool {
match *m {
- Method::Get | Method::Head | Method::Post => true,
+ Method::GET | Method::HEAD | Method::POST => true,
_ => false
}
}
-fn is_null_body_status(status: &Option<StatusCode>) -> bool {
+fn is_null_body_status(status: &Option<(StatusCode, String)>) -> bool {
match *status {
- Some(status) => match status {
- StatusCode::SwitchingProtocols | StatusCode::NoContent |
- StatusCode::ResetContent | StatusCode::NotModified => true,
+ Some((status, _)) => match status {
+ StatusCode::SWITCHING_PROTOCOLS | StatusCode::NO_CONTENT |
+ StatusCode::RESET_CONTENT | StatusCode::NOT_MODIFIED => true,
_ => false
},
_ => false
@@ -653,84 +657,56 @@ fn is_null_body_status(status: &Option<StatusCode>) -> bool {
}
/// <https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-nosniff?>
-pub fn should_be_blocked_due_to_nosniff(destination: Destination, response_headers: &Headers) -> bool {
- /// <https://fetch.spec.whatwg.org/#x-content-type-options-header>
- /// This is needed to parse `X-Content-Type-Options` according to spec,
- /// which requires that we inspect only the first value.
- ///
- /// A [unit-like struct](https://doc.rust-lang.org/book/structs.html#unit-like-structs)
- /// is sufficient since a valid header implies that we use `nosniff`.
- #[derive(Clone, Copy, Debug)]
- struct XContentTypeOptions;
-
- impl Header for XContentTypeOptions {
- fn header_name() -> &'static str {
- "X-Content-Type-Options"
- }
-
- /// https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-nosniff%3F #2
- fn parse_header(raw: &[Vec<u8>]) -> HyperResult<Self> {
- raw.first()
- .and_then(|v| str::from_utf8(v).ok())
- .and_then(|s| if s.trim().eq_ignore_ascii_case("nosniff") {
- Some(XContentTypeOptions)
- } else {
- None
- })
- .ok_or(Error::Header)
- }
- }
-
- impl HeaderFormat for XContentTypeOptions {
- fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.write_str("nosniff")
- }
- }
-
+pub fn should_be_blocked_due_to_nosniff(destination: Destination, response_headers: &HeaderMap) -> bool {
// Steps 1-3.
- if response_headers.get::<XContentTypeOptions>().is_none() {
+ // TODO(eijebong): Replace this once typed headers allow custom ones...
+ if response_headers.get("x-content-type-options")
+ .map_or(true, |val| val.to_str().unwrap_or("").to_lowercase() != "nosniff")
+ {
return false;
}
// Step 4
// Note: an invalid MIME type will produce a `None`.
- let content_type_header = response_headers.get::<ContentType>();
+ let content_type_header = response_headers.typed_get::<ContentType>();
/// <https://html.spec.whatwg.org/multipage/#scriptingLanguages>
#[inline]
fn is_javascript_mime_type(mime_type: &Mime) -> bool {
let javascript_mime_types: [Mime; 16] = [
- mime!(Application / ("ecmascript")),
- mime!(Application / ("javascript")),
- mime!(Application / ("x-ecmascript")),
- mime!(Application / ("x-javascript")),
- mime!(Text / ("ecmascript")),
- mime!(Text / ("javascript")),
- mime!(Text / ("javascript1.0")),
- mime!(Text / ("javascript1.1")),
- mime!(Text / ("javascript1.2")),
- mime!(Text / ("javascript1.3")),
- mime!(Text / ("javascript1.4")),
- mime!(Text / ("javascript1.5")),
- mime!(Text / ("jscript")),
- mime!(Text / ("livescript")),
- mime!(Text / ("x-ecmascript")),
- mime!(Text / ("x-javascript")),
+ "application/ecmascript".parse().unwrap(),
+ "application/javascript".parse().unwrap(),
+ "application/x-ecmascript".parse().unwrap(),
+ "application/x-javascript".parse().unwrap(),
+ "text/ecmascript".parse().unwrap(),
+ "text/javascript".parse().unwrap(),
+ "text/javascript1.0".parse().unwrap(),
+ "text/javascript1.1".parse().unwrap(),
+ "text/javascript1.2".parse().unwrap(),
+ "text/javascript1.3".parse().unwrap(),
+ "text/javascript1.4".parse().unwrap(),
+ "text/javascript1.5".parse().unwrap(),
+ "text/jscript".parse().unwrap(),
+ "text/livescript".parse().unwrap(),
+ "text/x-ecmascript".parse().unwrap(),
+ "text/x-javascript".parse().unwrap(),
];
javascript_mime_types.iter()
- .any(|mime| mime.0 == mime_type.0 && mime.1 == mime_type.1)
+ .any(|mime| mime.type_() == mime_type.type_() && mime.subtype() == mime_type.subtype())
}
- // Assumes str::starts_with is equivalent to mime::TopLevel
match content_type_header {
// Step 6
- Some(&ContentType(ref mime_type)) if destination.is_script_like()
- => !is_javascript_mime_type(mime_type),
+ Some(ref ct) if destination.is_script_like()
+ => !is_javascript_mime_type(&ct.clone().into()),
// Step 7
- Some(&ContentType(Mime(ref tl, ref sl, _))) if destination == Destination::Style
- => *tl != TopLevel::Text && *sl != SubLevel::Css,
+ Some(ref ct) if destination == Destination::Style
+ => {
+ let m: mime::Mime = ct.clone().into();
+ m.type_() != mime::TEXT && m.subtype() != mime::CSS
+ },
None if destination == Destination::Style || destination.is_script_like() => true,
// Step 8
@@ -739,23 +715,23 @@ pub fn should_be_blocked_due_to_nosniff(destination: Destination, response_heade
}
/// <https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-mime-type?>
-fn should_be_blocked_due_to_mime_type(destination: Destination, response_headers: &Headers) -> bool {
+fn should_be_blocked_due_to_mime_type(destination: Destination, response_headers: &HeaderMap) -> bool {
// Step 1
- let mime_type = match response_headers.get::<ContentType>() {
- Some(header) => header,
+ let mime_type: mime::Mime = match response_headers.typed_get::<ContentType>() {
+ Some(header) => header.into(),
None => return false,
};
// Step 2-3
- destination.is_script_like() && match *mime_type {
- ContentType(Mime(TopLevel::Audio, _, _)) |
- ContentType(Mime(TopLevel::Video, _, _)) |
- ContentType(Mime(TopLevel::Image, _, _)) => true,
- ContentType(Mime(TopLevel::Text, SubLevel::Ext(ref ext), _)) => ext == "csv",
-
- // Step 4
- _ => false,
- }
+ destination.is_script_like() &&
+ match mime_type.type_() {
+ mime::AUDIO |
+ mime::VIDEO |
+ mime::IMAGE => true,
+ mime::TEXT if mime_type.subtype() == mime::CSV => true,
+ // Step 4
+ _ => false
+ }
}
/// <https://fetch.spec.whatwg.org/#block-bad-port>
diff --git a/components/net/http_cache.rs b/components/net/http_cache.rs
index 1fcafc92952..dbb777eb103 100644
--- a/components/net/http_cache.rs
+++ b/components/net/http_cache.rs
@@ -8,12 +8,11 @@
//! and <http://tools.ietf.org/html/rfc7232>.
use fetch::methods::{Data, DoneChannel};
-use hyper::header;
-use hyper::header::ContentType;
-use hyper::header::Headers;
-use hyper::method::Method;
-use hyper::status::StatusCode;
-use hyper_serde::Serde;
+use headers_core::HeaderMapExt;
+use headers_ext::{CacheControl, ContentRange, Expires, LastModified, Pragma, Range, Vary};
+use http::{header, HeaderMap};
+use http::header::HeaderValue;
+use hyper::{Method, StatusCode};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalSizeOf, MallocUnconditionalShallowSizeOf};
use malloc_size_of::Measurable;
use net_traits::{Metadata, FetchMetadata};
@@ -24,11 +23,12 @@ use servo_channel::{Sender, channel};
use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use std::collections::HashMap;
-use std::str;
+use std::ops::Bound;
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};
+use std::time::SystemTime;
use time;
-use time::{Duration, Tm};
+use time::{Duration, Timespec, Tm};
/// The key used to differentiate requests in the cache.
@@ -59,7 +59,7 @@ impl CacheKey {
/// A complete cached resource.
#[derive(Clone)]
struct CachedResource {
- request_headers: Arc<Mutex<Headers>>,
+ request_headers: Arc<Mutex<HeaderMap>>,
body: Arc<Mutex<ResponseBody>>,
aborted: Arc<AtomicBool>,
awaiting_body: Arc<Mutex<Vec<Sender<Data>>>>,
@@ -71,7 +71,7 @@ struct MeasurableCachedResource {
metadata: CachedMetadata,
location_url: Option<Result<ServoUrl, String>>,
https_state: HttpsState,
- status: Option<StatusCode>,
+ status: Option<(StatusCode, String)>,
raw_status: Option<(u16, Vec<u8>)>,
url_list: Vec<ServoUrl>,
expires: Duration,
@@ -80,7 +80,7 @@ struct MeasurableCachedResource {
impl MallocSizeOf for CachedResource {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
- self.request_headers.unconditional_size_of(ops) +
+ // TODO: self.request_headers.unconditional_size_of(ops) +
self.body.unconditional_size_of(ops) +
self.aborted.unconditional_size_of(ops) +
self.awaiting_body.unconditional_size_of(ops) +
@@ -92,7 +92,7 @@ impl MallocSizeOf for CachedResource {
#[derive(Clone)]
struct CachedMetadata {
/// Headers
- pub headers: Arc<Mutex<Headers>>,
+ pub headers: Arc<Mutex<HeaderMap>>,
/// Fields that implement MallocSizeOf
pub data: Measurable<MeasurableCachedMetadata>
}
@@ -102,7 +102,7 @@ struct MeasurableCachedMetadata {
/// Final URL after redirects.
pub final_url: ServoUrl,
/// MIME type / subtype.
- pub content_type: Option<Serde<ContentType>>,
+ pub content_type: Option<String>,
/// Character set.
pub charset: Option<String>,
/// HTTP Status
@@ -112,7 +112,7 @@ struct MeasurableCachedMetadata {
impl MallocSizeOf for CachedMetadata {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.headers.unconditional_shallow_size_of(ops) +
- self.headers.size_of(ops) +
+ // TODO: self.headers.size_of(ops) +
self.data.size_of(ops)
}
}
@@ -141,23 +141,25 @@ fn response_is_cacheable(metadata: &Metadata) -> bool {
// 2. check for absence of the Authorization header field.
let mut is_cacheable = false;
let headers = metadata.headers.as_ref().unwrap();
- if headers.has::<header::Expires>() ||
- headers.has::<header::LastModified>() ||
- headers.has::<header::ETag>() {
+ if headers.contains_key(header::EXPIRES) ||
+ headers.contains_key(header::LAST_MODIFIED) ||
+ headers.contains_key(header::ETAG) {
is_cacheable = true;
}
- if let Some(&header::CacheControl(ref directive)) = headers.get::<header::CacheControl>() {
- for directive in directive.iter() {
- match *directive {
- header::CacheDirective::NoStore => return false,
- header::CacheDirective::Public | header::CacheDirective::SMaxAge(_)
- | header::CacheDirective::MaxAge(_) | header::CacheDirective::NoCache => is_cacheable = true,
- _ => {},
- }
+ if let Some(ref directive) = headers.typed_get::<CacheControl>() {
+ if directive.no_store() {
+ return false
+ }
+ if directive.public() || directive.s_max_age().is_some() ||
+ directive.max_age().is_some() || directive.no_cache()
+ {
+ is_cacheable = true;
}
}
- if let Some(&header::Pragma::NoCache) = headers.get::<header::Pragma>() {
- return false;
+ if let Some(pragma) = headers.typed_get::<Pragma>() {
+ if pragma.is_no_cache() {
+ return false;
+ }
}
is_cacheable
}
@@ -166,10 +168,11 @@ fn response_is_cacheable(metadata: &Metadata) -> bool {
/// <https://tools.ietf.org/html/rfc7234#section-4.2.3>
fn calculate_response_age(response: &Response) -> Duration {
// TODO: follow the spec more closely (Date headers, request/response lag, ...)
- if let Some(secs) = response.headers.get_raw("Age") {
- let seconds_string = String::from_utf8_lossy(&secs[0]);
- if let Ok(secs) = seconds_string.parse::<i64>() {
- return Duration::seconds(secs);
+ if let Some(secs) = response.headers.get(header::AGE) {
+ if let Ok(seconds_string) = secs.to_str() {
+ if let Ok(secs) = seconds_string.parse::<i64>() {
+ return Duration::seconds(secs);
+ }
}
}
Duration::seconds(0i64)
@@ -180,42 +183,37 @@ fn calculate_response_age(response: &Response) -> Duration {
fn get_response_expiry(response: &Response) -> Duration {
// Calculating Freshness Lifetime <https://tools.ietf.org/html/rfc7234#section-4.2.1>
let age = calculate_response_age(&response);
- if let Some(&header::CacheControl(ref directives)) = response.headers.get::<header::CacheControl>() {
- let has_no_cache_directive = directives.iter().any(|directive| {
- header::CacheDirective::NoCache == *directive
- });
- if has_no_cache_directive {
+ if let Some(directives) = response.headers.typed_get::<CacheControl>() {
+ if directives.no_cache() {
// Requires validation on first use.
return Duration::seconds(0i64);
} else {
- for directive in directives {
- match *directive {
- header::CacheDirective::SMaxAge(secs) | header::CacheDirective::MaxAge(secs) => {
- let max_age = Duration::seconds(secs as i64);
- if max_age < age {
- return Duration::seconds(0i64);
- }
- return max_age - age;
- },
- _ => (),
+ if let Some(secs) = directives.max_age().or(directives.s_max_age()) {
+ let max_age = Duration::from_std(secs).unwrap();
+ if max_age < age {
+ return Duration::seconds(0i64);
}
+ return max_age - age;
}
}
}
- if let Some(&header::Expires(header::HttpDate(t))) = response.headers.get::<header::Expires>() {
- // store the period of time from now until expiry
- let desired = t.to_timespec();
- let current = time::now().to_timespec();
- if desired > current {
- return desired - current;
- } else {
- return Duration::seconds(0i64);
- }
- } else {
- if let Some(_) = response.headers.get_raw("Expires") {
- // Malformed Expires header, shouldn't be used to construct a valid response.
- return Duration::seconds(0i64);
- }
+ match response.headers.typed_get::<Expires>() {
+ Some(t) => {
+ // store the period of time from now until expiry
+ let t: SystemTime = t.into();
+ let t = t.duration_since(SystemTime::UNIX_EPOCH).unwrap();
+ let desired = Timespec::new(t.as_secs() as i64, 0);
+ let current = time::now().to_timespec();
+
+ if desired > current {
+ return desired - current;
+ } else {
+ return Duration::seconds(0i64);
+ }
+ },
+ // Malformed Expires header, shouldn't be used to construct a valid response.
+ None if response.headers.contains_key(header::EXPIRES) => return Duration::seconds(0i64),
+ _ => {},
}
// Calculating Heuristic Freshness
// <https://tools.ietf.org/html/rfc7234#section-4.2.2>
@@ -224,13 +222,15 @@ fn get_response_expiry(response: &Response) -> Duration {
// Since presently we do not generate a Warning header field with a 113 warn-code,
// 24 hours minus response age is the max for heuristic calculation.
let max_heuristic = Duration::hours(24) - age;
- let heuristic_freshness = if let Some(&header::LastModified(header::HttpDate(t))) =
+ let heuristic_freshness = if let Some(last_modified) =
// If the response has a Last-Modified header field,
// caches are encouraged to use a heuristic expiration value
// that is no more than some fraction of the interval since that time.
- response.headers.get::<header::LastModified>() {
- let last_modified = t.to_timespec();
+ response.headers.typed_get::<LastModified>() {
let current = time::now().to_timespec();
+ let last_modified: SystemTime = last_modified.into();
+ let last_modified = last_modified.duration_since(SystemTime::UNIX_EPOCH).unwrap();
+ let last_modified = Timespec::new(last_modified.as_secs() as i64, 0);
// A typical setting of this fraction might be 10%.
let raw_heuristic_calc = (current - last_modified) / 10;
let result = if raw_heuristic_calc < max_heuristic {
@@ -249,11 +249,9 @@ fn get_response_expiry(response: &Response) -> Duration {
},
_ => {
// Other status codes can only use heuristic freshness if the public cache directive is present.
- if let Some(&header::CacheControl(ref directives)) = response.headers.get::<header::CacheControl>() {
- let has_public_directive = directives.iter().any(|directive| {
- header::CacheDirective::Public == *directive
- });
- if has_public_directive {
+ if let Some(ref directives) = response.headers.typed_get::<CacheControl>()
+ {
+ if directives.public() {
return heuristic_freshness;
}
}
@@ -267,48 +265,39 @@ fn get_response_expiry(response: &Response) -> Duration {
/// Request Cache-Control Directives
/// <https://tools.ietf.org/html/rfc7234#section-5.2.1>
fn get_expiry_adjustment_from_request_headers(request: &Request, expires: Duration) -> Duration {
- let directive_data = match request.headers.get_raw("cache-control") {
+ let directive = match request.headers.typed_get::<CacheControl>() {
Some(data) => data,
None => return expires,
};
- let directives_string = String::from_utf8_lossy(&directive_data[0]);
- for directive in directives_string.split(",") {
- let mut directive_info = directive.split("=");
- match (directive_info.next(), directive_info.next()) {
- (Some("max-stale"), Some(sec_str)) => {
- if let Ok(secs) = sec_str.parse::<i64>() {
- return expires + Duration::seconds(secs);
- }
- },
- (Some("max-age"), Some(sec_str)) => {
- if let Ok(secs) = sec_str.parse::<i64>() {
- let max_age = Duration::seconds(secs);
- if expires > max_age {
- return Duration::min_value();
- }
- return expires - max_age;
- }
- },
- (Some("min-fresh"), Some(sec_str)) => {
- if let Ok(secs) = sec_str.parse::<i64>() {
- let min_fresh = Duration::seconds(secs);
- if expires < min_fresh {
- return Duration::min_value();
- }
- return expires - min_fresh;
- }
- },
- (Some("no-cache"), _) | (Some("no-store"), _) => return Duration::min_value(),
- _ => {}
+
+ if let Some(max_age) = directive.max_stale() {
+ return expires + Duration::from_std(max_age).unwrap();
+ }
+ if let Some(max_age) = directive.max_age() {
+ let max_age = Duration::from_std(max_age).unwrap();
+ if expires > max_age {
+ return Duration::min_value();
}
+ return expires - max_age;
}
+ if let Some(min_fresh) = directive.min_fresh() {
+ let min_fresh = Duration::from_std(min_fresh).unwrap();
+ if expires < min_fresh {
+ return Duration::min_value();
+ }
+ return expires - min_fresh;
+ }
+ if directive.no_cache() || directive.no_store() {
+ return Duration::min_value()
+ }
+
expires
}
/// Create a CachedResponse from a request and a CachedResource.
fn create_cached_response(request: &Request,
cached_resource: &CachedResource,
- cached_headers: &Headers,
+ cached_headers: &HeaderMap,
done_chan: &mut DoneChannel)
-> CachedResponse {
let mut response = Response::new(cached_resource.data.metadata.data.final_url.clone());
@@ -353,7 +342,7 @@ fn create_resource_with_bytes_from_resource(bytes: &[u8], resource: &CachedResou
metadata: resource.data.metadata.clone(),
location_url: resource.data.location_url.clone(),
https_state: resource.data.https_state.clone(),
- status: Some(StatusCode::PartialContent),
+ status: Some((StatusCode::PARTIAL_CONTENT, "Partial Content".into())),
raw_status: Some((206, b"Partial Content".to_vec())),
url_list: resource.data.url_list.clone(),
expires: resource.data.expires.clone(),
@@ -365,7 +354,7 @@ fn create_resource_with_bytes_from_resource(bytes: &[u8], resource: &CachedResou
/// Support for range requests <https://tools.ietf.org/html/rfc7233>.
fn handle_range_request(request: &Request,
candidates: Vec<&CachedResource>,
- range_spec: &[header::ByteRangeSpec],
+ range_spec: Vec<(Bound<u64>, Bound<u64>)>,
done_chan: &mut DoneChannel)
-> Option<CachedResponse> {
let mut complete_cached_resources = candidates.iter().filter(|resource| {
@@ -389,7 +378,7 @@ fn handle_range_request(request: &Request,
// see <https://tools.ietf.org/html/rfc7233#section-4.3>.
// TODO: add support for complete and partial resources,
// whose body is in the ResponseBody::Receiving state.
- (&header::ByteRangeSpec::FromTo(beginning, end), Some(ref complete_resource)) => {
+ (&(Bound::Included(beginning), Bound::Included(end)), Some(ref complete_resource)) => {
if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() {
let b = beginning as usize;
let e = end as usize + 1;
@@ -402,14 +391,18 @@ fn handle_range_request(request: &Request,
}
}
},
- (&header::ByteRangeSpec::FromTo(beginning, end), None) => {
+ (&(Bound::Included(beginning), Bound::Included(end)), None) => {
for partial_resource in partial_cached_resources {
let headers = partial_resource.data.metadata.headers.lock().unwrap();
- let content_range = headers.get::<header::ContentRange>();
+ let content_range = headers.typed_get::<ContentRange>();
let (res_beginning, res_end) = match content_range {
- Some(&header::ContentRange(
- header::ContentRangeSpec::Bytes {
- range: Some((res_beginning, res_end)), .. })) => (res_beginning, res_end),
+ Some(range) => {
+ if let Some(bytes_range) = range.bytes_range() {
+ bytes_range
+ } else {
+ continue
+ }
+ }
_ => continue,
};
if res_beginning - 1 < beginning && res_end + 1 > end {
@@ -430,7 +423,7 @@ fn handle_range_request(request: &Request,
}
}
},
- (&header::ByteRangeSpec::AllFrom(beginning), Some(ref complete_resource)) => {
+ (&(Bound::Included(beginning), Bound::Unbounded), Some(ref complete_resource)) => {
if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() {
let b = beginning as usize;
let requested = body.get(b..);
@@ -442,16 +435,17 @@ fn handle_range_request(request: &Request,
}
}
},
- (&header::ByteRangeSpec::AllFrom(beginning), None) => {
+ (&(Bound::Included(beginning), Bound::Unbounded), None) => {
for partial_resource in partial_cached_resources {
let headers = partial_resource.data.metadata.headers.lock().unwrap();
- let content_range = headers.get::<header::ContentRange>();
- let (res_beginning, res_end, total) = match content_range {
- Some(&header::ContentRange(
- header::ContentRangeSpec::Bytes {
- range: Some((res_beginning, res_end)),
- instance_length: Some(total) })) => (res_beginning, res_end, total),
- _ => continue,
+ let content_range = headers.typed_get::<ContentRange>();
+ let (res_beginning, res_end, total) = if let Some(range) = content_range {
+ match (range.bytes_range(), range.bytes_len()) {
+ (Some(bytes_range), Some(total)) => (bytes_range.0, bytes_range.1, total),
+ _ => continue,
+ }
+ } else {
+ continue;
};
if res_beginning < beginning && res_end == total - 1 {
let resource_body = &*partial_resource.body.lock().unwrap();
@@ -470,7 +464,7 @@ fn handle_range_request(request: &Request,
}
}
},
- (&header::ByteRangeSpec::Last(offset), Some(ref complete_resource)) => {
+ (&(Bound::Unbounded, Bound::Included(offset)), Some(ref complete_resource)) => {
if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() {
let from_byte = body.len() - offset as usize;
let requested = body.get(from_byte..);
@@ -482,16 +476,17 @@ fn handle_range_request(request: &Request,
}
}
},
- (&header::ByteRangeSpec::Last(offset), None) => {
+ (&(Bound::Unbounded, Bound::Included(offset)), None) => {
for partial_resource in partial_cached_resources {
let headers = partial_resource.data.metadata.headers.lock().unwrap();
- let content_range = headers.get::<header::ContentRange>();
- let (res_beginning, res_end, total) = match content_range {
- Some(&header::ContentRange(
- header::ContentRangeSpec::Bytes {
- range: Some((res_beginning, res_end)),
- instance_length: Some(total) })) => (res_beginning, res_end, total),
- _ => continue,
+ let content_range = headers.typed_get::<ContentRange>();
+ let (res_beginning, res_end, total) = if let Some(range) = content_range {
+ match (range.bytes_range(), range.bytes_len()) {
+ (Some(bytes_range), Some(total)) => (bytes_range.0, bytes_range.1, total),
+ _ => continue,
+ }
+ } else {
+ continue;
};
if (total - res_beginning) > (offset - 1 ) && (total - res_end) < offset + 1 {
let resource_body = &*partial_resource.body.lock().unwrap();
@@ -509,7 +504,9 @@ fn handle_range_request(request: &Request,
}
}
}
- }
+ },
+ // All the cases with Bound::Excluded should be unreachable anyway
+ _ => return None
}
None
}
@@ -527,7 +524,7 @@ impl HttpCache {
/// <https://tools.ietf.org/html/rfc7234#section-4>
pub fn construct_response(&self, request: &Request, done_chan: &mut DoneChannel) -> Option<CachedResponse> {
// TODO: generate warning headers as appropriate <https://tools.ietf.org/html/rfc7234#section-5.5>
- if request.method != Method::Get {
+ if request.method != Method::GET {
// Only Get requests are cached, avoid a url based match for others.
return None;
}
@@ -538,41 +535,35 @@ impl HttpCache {
let mut can_be_constructed = true;
let cached_headers = cached_resource.data.metadata.headers.lock().unwrap();
let original_request_headers = cached_resource.request_headers.lock().unwrap();
- if let Some(vary_data) = cached_headers.get_raw("Vary") {
- // Calculating Secondary Keys with Vary <https://tools.ietf.org/html/rfc7234#section-4.1>
- let vary_data_string = String::from_utf8_lossy(&vary_data[0]);
- let vary_values = vary_data_string.split(",").map(|val| val.trim());
- for vary_val in vary_values {
+ if let Some(vary_value) = cached_headers.typed_get::<Vary>() {
+ if vary_value.is_any() {
+ can_be_constructed = false
+ } else {
// For every header name found in the Vary header of the stored response.
- if vary_val == "*" {
- // A Vary header field-value of "*" always fails to match.
- can_be_constructed = false;
- break;
- }
- match request.headers.get_raw(vary_val) {
- Some(header_data) => {
- // If the header is present in the request.
- let request_header_data_string = String::from_utf8_lossy(&header_data[0]);
- if let Some(original_header_data) = original_request_headers.get_raw(vary_val) {
- // Check that the value of the nominated header field,
- // in the original request, matches the value in the current request.
- let original_request_header_data_string =
- String::from_utf8_lossy(&original_header_data[0]);
- if original_request_header_data_string != request_header_data_string {
- can_be_constructed = false;
- break;
+ // Calculating Secondary Keys with Vary <https://tools.ietf.org/html/rfc7234#section-4.1>
+ for vary_val in vary_value.iter_strs() {
+ match request.headers.get(vary_val) {
+ Some(header_data) => {
+ // If the header is present in the request.
+ if let Some(original_header_data) = original_request_headers.get(vary_val) {
+ // Check that the value of the nominated header field,
+ // in the original request, matches the value in the current request.
+ if original_header_data != header_data {
+ can_be_constructed = false;
+ break;
+ }
}
- }
- },
- None => {
- // If a header field is absent from a request,
- // it can only match a stored response if those headers,
- // were also absent in the original request.
- can_be_constructed = original_request_headers.get_raw(vary_val).is_none();
- },
- }
- if !can_be_constructed {
- break;
+ },
+ None => {
+ // If a header field is absent from a request,
+ // it can only match a stored response if those headers,
+ // were also absent in the original request.
+ can_be_constructed = original_request_headers.get(vary_val).is_none();
+ },
+ }
+ if !can_be_constructed {
+ break;
+ }
}
}
}
@@ -581,8 +572,8 @@ impl HttpCache {
}
}
// Support for range requests
- if let Some(&header::Range::Bytes(ref range_spec)) = request.headers.get::<header::Range>() {
- return handle_range_request(request, candidates, &range_spec, done_chan);
+ if let Some(range_spec) = request.headers.typed_get::<Range>() {
+ return handle_range_request(request, candidates, range_spec.iter().collect(), done_chan);
} else {
// Not a Range request.
if let Some(ref cached_resource) = candidates.first() {
@@ -620,7 +611,7 @@ impl HttpCache {
/// Freshening Stored Responses upon Validation.
/// <https://tools.ietf.org/html/rfc7234#section-4.3.4>
pub fn refresh(&mut self, request: &Request, response: Response, done_chan: &mut DoneChannel) -> Option<Response> {
- assert_eq!(response.status, Some(StatusCode::NotModified));
+ assert_eq!(response.status.map(|s| s.0), Some(StatusCode::NOT_MODIFIED));
let entry_key = CacheKey::new(request.clone());
if let Some(cached_resources) = self.entries.get_mut(&entry_key) {
for cached_resource in cached_resources.iter_mut() {
@@ -654,7 +645,7 @@ impl HttpCache {
constructed_response.url_list = cached_resource.data.url_list.clone();
cached_resource.data.expires = get_response_expiry(&constructed_response);
let mut stored_headers = cached_resource.data.metadata.headers.lock().unwrap();
- stored_headers.extend(response.headers.iter());
+ stored_headers.extend(response.headers);
constructed_response.headers = stored_headers.clone();
return Some(constructed_response);
}
@@ -674,17 +665,16 @@ impl HttpCache {
/// Invalidation.
/// <https://tools.ietf.org/html/rfc7234#section-4.4>
pub fn invalidate(&mut self, request: &Request, response: &Response) {
- if let Some(&header::Location(ref location)) = response.headers.get::<header::Location>() {
+ // TODO(eijebong): Once headers support typed_get, update this to use them
+ if let Some(Ok(location)) = response.headers.get(header::LOCATION).map(HeaderValue::to_str) {
if let Ok(url) = request.current_url().join(location) {
self.invalidate_for_url(&url);
}
}
- // TODO: update hyper to use typed getter.
- if let Some(url_data) = response.headers.get_raw("Content-Location") {
- if let Ok(content_location) = str::from_utf8(&url_data[0]) {
- if let Ok(url) = request.current_url().join(content_location) {
- self.invalidate_for_url(&url);
- }
+ if let Some(Ok(ref content_location)) = response.headers.get(header::CONTENT_LOCATION).map(HeaderValue::to_str)
+ {
+ if let Ok(url) = request.current_url().join(&content_location) {
+ self.invalidate_for_url(&url);
}
}
self.invalidate_for_url(&request.url());
@@ -696,7 +686,7 @@ impl HttpCache {
if PREFS.get("network.http-cache.disabled").as_boolean().unwrap_or(false) {
return
}
- if request.method != Method::Get {
+ if request.method != Method::GET {
// Only Get requests are cached.
return
}
@@ -716,7 +706,7 @@ impl HttpCache {
headers: Arc::new(Mutex::new(response.headers.clone())),
data: Measurable(MeasurableCachedMetadata {
final_url: metadata.final_url,
- content_type: metadata.content_type,
+ content_type: metadata.content_type.map(|v| v.0.to_string()),
charset: metadata.charset,
status: metadata.status
})
diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs
index fe85fc5a6f7..20aaaffc237 100644
--- a/components/net/http_loader.rs
+++ b/components/net/http_loader.rs
@@ -3,7 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use brotli::Decompressor;
-use connector::{Connector, create_http_connector};
+use bytes::Bytes;
+use connector::{BUF_SIZE, Connector, create_http_client, WrappedBody};
use cookie;
use cookie_storage::CookieStorage;
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, HttpRequest as DevtoolsHttpRequest};
@@ -12,60 +13,51 @@ use fetch::cors_cache::CorsCache;
use fetch::methods::{Data, DoneChannel, FetchContext, Target};
use fetch::methods::{is_cors_safelisted_request_header, is_cors_safelisted_method, main_fetch};
use flate2::read::{DeflateDecoder, GzDecoder};
+use headers_core::HeaderMapExt;
+use headers_ext::{AccessControlAllowCredentials, AccessControlAllowHeaders};
+use headers_ext::{AccessControlAllowMethods, AccessControlRequestHeaders, AccessControlRequestMethod, Authorization};
+use headers_ext::{AccessControlAllowOrigin, AccessControlMaxAge, Basic};
+use headers_ext::{CacheControl, ContentEncoding, ContentLength};
+use headers_ext::{Host, IfModifiedSince, LastModified, Origin as HyperOrigin, Pragma, Referer, UserAgent};
use hsts::HstsList;
+use http::{HeaderMap, Request as HyperRequest};
+use http::header::{self, HeaderName, HeaderValue};
+use http::uri::Authority;
use http_cache::HttpCache;
-use hyper::Error as HttpError;
-use hyper::LanguageTag;
-use hyper::client::{Pool, Request as HyperRequest, Response as HyperResponse};
-use hyper::header::{Accept, AccessControlAllowCredentials, AccessControlAllowHeaders};
-use hyper::header::{AccessControlAllowMethods, AccessControlAllowOrigin};
-use hyper::header::{AccessControlMaxAge, AccessControlRequestHeaders};
-use hyper::header::{AccessControlRequestMethod, AcceptEncoding, AcceptLanguage};
-use hyper::header::{Authorization, Basic, CacheControl, CacheDirective};
-use hyper::header::{ContentEncoding, ContentLength, Encoding, Header, Headers};
-use hyper::header::{Host, HttpDate, Origin as HyperOrigin, IfMatch, IfRange};
-use hyper::header::{IfUnmodifiedSince, IfModifiedSince, IfNoneMatch, Location};
-use hyper::header::{Pragma, Quality, QualityItem, Referer, SetCookie};
-use hyper::header::{UserAgent, q, qitem};
-use hyper::method::Method;
-use hyper::status::StatusCode;
-use hyper_openssl::OpensslClient;
+use hyper::{Body, Client, Method, StatusCode, Response as HyperResponse};
use hyper_serde::Serde;
use log;
+use mime;
use msg::constellation_msg::{HistoryStateId, PipelineId};
use net_traits::{CookieSource, FetchMetadata, NetworkError, ReferrerPolicy};
+use net_traits::quality::{quality_to_value, Quality, QualityItem};
use net_traits::request::{CacheMode, CredentialsMode, Destination, Origin};
use net_traits::request::{RedirectMode, Referrer, Request, RequestMode};
use net_traits::request::{ResponseTainting, ServiceWorkersMode};
use net_traits::response::{HttpsState, Response, ResponseBody, ResponseType};
+use openssl::ssl::SslConnectorBuilder;
use resource_thread::AuthCache;
use servo_channel::{channel, Sender};
use servo_url::{ImmutableOrigin, ServoUrl};
use std::collections::{HashMap, HashSet};
use std::error::Error;
-use std::io::{self, Read, Write};
+use std::io::Cursor;
use std::iter::FromIterator;
use std::mem;
use std::ops::Deref;
use std::str::FromStr;
+use std::sync::Mutex;
use std::sync::RwLock;
-use std::thread;
-use time;
-use time::Tm;
-use unicase::UniCase;
+use std::time::{Duration, SystemTime};
+use time::{self, Tm};
+use tokio::prelude::{Future, future, Stream};
+use tokio::runtime::Runtime;
use uuid;
-fn read_block<R: Read>(reader: &mut R) -> Result<Data, ()> {
- let mut buf = vec![0; 32768];
-
- match reader.read(&mut buf) {
- Ok(len) if len > 0 => {
- buf.truncate(len);
- Ok(Data::Payload(buf))
- }
- Ok(_) => Ok(Data::Done),
- Err(_) => Err(()),
- }
+lazy_static! {
+ pub static ref HANDLE: Mutex<Runtime> = {
+ Mutex::new(Runtime::new().unwrap())
+ };
}
pub struct HttpState {
@@ -74,20 +66,18 @@ pub struct HttpState {
pub http_cache: RwLock<HttpCache>,
pub auth_cache: RwLock<AuthCache>,
pub history_states: RwLock<HashMap<HistoryStateId, Vec<u8>>>,
- pub ssl_client: OpensslClient,
- pub connector: Pool<Connector>,
+ pub client: Client<Connector, WrappedBody>,
}
impl HttpState {
- pub fn new(ssl_client: OpensslClient) -> HttpState {
+ pub fn new(ssl_connector_builder: SslConnectorBuilder) -> HttpState {
HttpState {
hsts_list: RwLock::new(HstsList::new()),
cookie_jar: RwLock::new(CookieStorage::new(150)),
auth_cache: RwLock::new(AuthCache::new()),
history_states: RwLock::new(HashMap::new()),
http_cache: RwLock::new(HttpCache::new()),
- ssl_client: ssl_client.clone(),
- connector: create_http_connector(ssl_client),
+ client: create_http_client(ssl_connector_builder, HANDLE.lock().unwrap().executor()),
}
}
}
@@ -97,72 +87,63 @@ fn precise_time_ms() -> u64 {
}
// Step 3 of https://fetch.spec.whatwg.org/#concept-fetch.
-pub fn set_default_accept(destination: Destination, headers: &mut Headers) {
- if headers.has::<Accept>() {
+pub fn set_default_accept(destination: Destination, headers: &mut HeaderMap) {
+ if headers.contains_key(header::ACCEPT) {
return;
}
let value = match destination {
// Step 3.2.
Destination::Document => {
vec![
- qitem(mime!(Text / Html)),
- qitem(mime!(Application / ("xhtml+xml"))),
- QualityItem::new(mime!(Application / Xml), q(0.9)),
- QualityItem::new(mime!(_ / _), q(0.8)),
+ QualityItem::new(mime::TEXT_HTML, Quality::from_u16(1000)),
+ QualityItem::new("application/xhtml+xml".parse().unwrap(), Quality::from_u16(1000)),
+ QualityItem::new("application/xml".parse().unwrap(), Quality::from_u16(900)),
+ QualityItem::new(mime::STAR_STAR, Quality::from_u16(800))
]
},
// Step 3.3.
Destination::Image => {
vec![
- qitem(mime!(Image / Png)),
- qitem(mime!(Image / ("svg+xml") )),
- QualityItem::new(mime!(Image / _), q(0.8)),
- QualityItem::new(mime!(_ / _), q(0.5)),
+ QualityItem::new(mime::IMAGE_PNG, Quality::from_u16(1000)),
+ QualityItem::new(mime::IMAGE_SVG, Quality::from_u16(1000)),
+ QualityItem::new(mime::IMAGE_STAR, Quality::from_u16(800)),
+ QualityItem::new(mime::STAR_STAR, Quality::from_u16(500))
]
},
// Step 3.3.
Destination::Style => {
vec![
- qitem(mime!(Text / Css)),
- QualityItem::new(mime!(_ / _), q(0.1))
+ QualityItem::new(mime::TEXT_CSS, Quality::from_u16(1000)),
+ QualityItem::new(mime::STAR_STAR, Quality::from_u16(100))
]
},
// Step 3.1.
_ => {
- vec![qitem(mime!(_ / _))]
+ vec![QualityItem::new(mime::STAR_STAR, Quality::from_u16(1000))]
},
};
// Step 3.4.
- headers.set(Accept(value));
+ // TODO(eijebong): Change this once typed headers are done
+ headers.insert(header::ACCEPT, quality_to_value(value));
}
-fn set_default_accept_encoding(headers: &mut Headers) {
- if headers.has::<AcceptEncoding>() {
+fn set_default_accept_encoding(headers: &mut HeaderMap) {
+ if headers.contains_key(header::ACCEPT_ENCODING) {
return
}
- headers.set(AcceptEncoding(vec![
- qitem(Encoding::Gzip),
- qitem(Encoding::Deflate),
- qitem(Encoding::EncodingExt("br".to_owned()))
- ]));
+ // TODO(eijebong): Change this once typed headers are done
+ headers.insert(header::ACCEPT_ENCODING, HeaderValue::from_static("gzip, deflate, br"));
}
-pub fn set_default_accept_language(headers: &mut Headers) {
- if headers.has::<AcceptLanguage>() {
+pub fn set_default_accept_language(headers: &mut HeaderMap) {
+ if headers.contains_key(header::ACCEPT_LANGUAGE) {
return;
}
- let mut en_us: LanguageTag = Default::default();
- en_us.language = Some("en".to_owned());
- en_us.region = Some("US".to_owned());
- let mut en: LanguageTag = Default::default();
- en.language = Some("en".to_owned());
- headers.set(AcceptLanguage(vec![
- qitem(en_us),
- QualityItem::new(en, Quality(500)),
- ]));
+ // TODO(eijebong): Change this once typed headers are done
+ headers.insert(header::ACCEPT_LANGUAGE, HeaderValue::from_static("en-US, en; q=0.5"));
}
/// <https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-state-no-referrer-when-downgrade>
@@ -210,12 +191,12 @@ fn strip_url(mut referrer_url: ServoUrl, origin_only: bool) -> Option<ServoUrl>
/// <https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer>
/// Steps 4-6.
-pub fn determine_request_referrer(headers: &mut Headers,
+pub fn determine_request_referrer(headers: &mut HeaderMap,
referrer_policy: ReferrerPolicy,
referrer_source: ServoUrl,
current_url: ServoUrl)
-> Option<ServoUrl> {
- assert!(!headers.has::<Referer>());
+ assert!(!headers.contains_key(header::REFERER));
// FIXME(#14505): this does not seem to be the correct way of checking for
// same-origin requests.
let cross_origin = referrer_source.origin() != current_url.origin();
@@ -233,94 +214,65 @@ pub fn determine_request_referrer(headers: &mut Headers,
}
}
-pub fn set_request_cookies(url: &ServoUrl, headers: &mut Headers, cookie_jar: &RwLock<CookieStorage>) {
+pub fn set_request_cookies(url: &ServoUrl, headers: &mut HeaderMap, cookie_jar: &RwLock<CookieStorage>) {
let mut cookie_jar = cookie_jar.write().unwrap();
if let Some(cookie_list) = cookie_jar.cookies_for_url(url, CookieSource::HTTP) {
- let mut v = Vec::new();
- v.push(cookie_list.into_bytes());
- headers.set_raw("Cookie".to_owned(), v);
+ headers.insert(header::COOKIE, HeaderValue::from_bytes(cookie_list.as_bytes()).unwrap());
}
}
fn set_cookie_for_url(cookie_jar: &RwLock<CookieStorage>,
request: &ServoUrl,
- cookie_val: String) {
+ cookie_val: &str) {
let mut cookie_jar = cookie_jar.write().unwrap();
let source = CookieSource::HTTP;
- let header = Header::parse_header(&[cookie_val.into_bytes()]);
- if let Ok(SetCookie(cookies)) = header {
- for cookie in cookies {
- if let Some(cookie) = cookie::Cookie::from_cookie_string(cookie, request, source) {
- cookie_jar.push(cookie, request, source);
- }
- }
+ if let Some(cookie) = cookie::Cookie::from_cookie_string(cookie_val.into(), request, source) {
+ cookie_jar.push(cookie, request, source);
}
}
-fn set_cookies_from_headers(url: &ServoUrl, headers: &Headers, cookie_jar: &RwLock<CookieStorage>) {
- if let Some(cookies) = headers.get_raw("set-cookie") {
- for cookie in cookies.iter() {
- if let Ok(cookie_value) = String::from_utf8(cookie.clone()) {
- set_cookie_for_url(&cookie_jar,
- &url,
- cookie_value);
- }
+fn set_cookies_from_headers(url: &ServoUrl, headers: &HeaderMap, cookie_jar: &RwLock<CookieStorage>) {
+ for cookie in headers.get_all(header::SET_COOKIE) {
+ if let Ok(cookie_str) = cookie.to_str() {
+ set_cookie_for_url(&cookie_jar,
+ &url,
+ &cookie_str);
}
}
}
-struct StreamedResponse {
- decoder: Decoder,
-}
-
-
-impl Read for StreamedResponse {
- #[inline]
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- match self.decoder {
- Decoder::Gzip(ref mut d) => d.read(buf),
- Decoder::Deflate(ref mut d) => d.read(buf),
- Decoder::Brotli(ref mut d) => d.read(buf),
- Decoder::Plain(ref mut d) => d.read(buf)
- }
- }
-}
-
-impl StreamedResponse {
- fn from_http_response(response: HyperResponse) -> io::Result<StreamedResponse> {
- let decoder = {
- if let Some(ref encoding) = response.headers.get::<ContentEncoding>().cloned() {
- if encoding.contains(&Encoding::Gzip) {
- Decoder::Gzip(GzDecoder::new(response))
- }
- else if encoding.contains(&Encoding::Deflate) {
- Decoder::Deflate(DeflateDecoder::new(response))
- }
- else if encoding.contains(&Encoding::EncodingExt("br".to_owned())) {
- Decoder::Brotli(Decompressor::new(response, 1024))
- } else {
- Decoder::Plain(response)
- }
+impl Decoder {
+ fn from_http_response(response: &HyperResponse<Body>) -> Decoder {
+ if let Some(encoding) = response.headers().typed_get::<ContentEncoding>() {
+ if encoding.contains("gzip") {
+ Decoder::Gzip(None)
+ }
+ else if encoding.contains("deflate") {
+ Decoder::Deflate(DeflateDecoder::new(Cursor::new(Bytes::new())))
+ }
+ else if encoding.contains("br") {
+ Decoder::Brotli(Decompressor::new(Cursor::new(Bytes::new()), BUF_SIZE))
} else {
- Decoder::Plain(response)
+ Decoder::Plain
}
- };
- Ok(StreamedResponse { decoder: decoder })
+ } else {
+ Decoder::Plain
+ }
}
}
-enum Decoder {
- Gzip(GzDecoder<HyperResponse>),
- Deflate(DeflateDecoder<HyperResponse>),
- Brotli(Decompressor<HyperResponse>),
- Plain(HyperResponse)
+pub enum Decoder {
+ Gzip(Option<GzDecoder<Cursor<Bytes>>>),
+ Deflate(DeflateDecoder<Cursor<Bytes>>),
+ Brotli(Decompressor<Cursor<Bytes>>),
+ Plain,
}
fn prepare_devtools_request(request_id: String,
url: ServoUrl,
method: Method,
- headers: Headers,
+ headers: HeaderMap,
body: Option<Vec<u8>>,
pipeline_id: PipelineId,
now: Tm,
@@ -351,7 +303,7 @@ fn send_request_to_devtools(msg: ChromeToDevtoolsControlMsg,
fn send_response_to_devtools(devtools_chan: &Sender<DevtoolsControlMsg>,
request_id: String,
- headers: Option<Headers>,
+ headers: Option<HeaderMap>,
status: Option<(u16, Vec<u8>)>,
pipeline_id: PipelineId) {
let response = DevtoolsHttpResponse { headers: headers, status: status, body: None, pipeline_id: pipeline_id };
@@ -361,111 +313,93 @@ fn send_response_to_devtools(devtools_chan: &Sender<DevtoolsControlMsg>,
let _ = devtools_chan.send(DevtoolsControlMsg::FromChrome(msg));
}
-fn auth_from_cache(auth_cache: &RwLock<AuthCache>, origin: &ImmutableOrigin) -> Option<Basic> {
+fn auth_from_cache(auth_cache: &RwLock<AuthCache>, origin: &ImmutableOrigin) -> Option<Authorization<Basic>> {
if let Some(ref auth_entry) = auth_cache.read().unwrap().entries.get(&origin.ascii_serialization()) {
- let user_name = auth_entry.user_name.clone();
- let password = Some(auth_entry.password.clone());
- Some(Basic { username: user_name, password: password })
+ let user_name = &auth_entry.user_name;
+ let password = &auth_entry.password;
+ Some(Authorization::basic(user_name, password))
} else {
None
}
}
-fn obtain_response(connector: &Pool<Connector>,
+fn obtain_response(client: &Client<Connector, WrappedBody>,
url: &ServoUrl,
method: &Method,
- request_headers: &Headers,
+ request_headers: &HeaderMap,
data: &Option<Vec<u8>>,
load_data_method: &Method,
pipeline_id: &Option<PipelineId>,
iters: u32,
request_id: Option<&str>,
is_xhr: bool)
- -> Result<(HyperResponse, Option<ChromeToDevtoolsControlMsg>), NetworkError> {
- let null_data = None;
-
- // loop trying connections in connection pool
- // they may have grown stale (disconnected), in which case we'll get
- // a ConnectionAborted error. this loop tries again with a new
- // connection.
- loop {
- let mut headers = request_headers.clone();
-
- // Avoid automatically sending request body if a redirect has occurred.
- //
- // TODO - This is the wrong behaviour according to the RFC. However, I'm not
- // sure how much "correctness" vs. real-world is important in this case.
- //
- // https://tools.ietf.org/html/rfc7231#section-6.4
- let is_redirected_request = iters != 1;
- let request_body;
- match data {
- &Some(ref d) if !is_redirected_request => {
- headers.set(ContentLength(d.len() as u64));
- request_body = data;
- }
- _ => {
- if *load_data_method != Method::Get && *load_data_method != Method::Head {
- headers.set(ContentLength(0))
- }
- request_body = &null_data;
- }
+ -> Box<Future<Item=(HyperResponse<WrappedBody>, Option<ChromeToDevtoolsControlMsg>),
+ Error = NetworkError>> {
+ let mut headers = request_headers.clone();
+
+ // Avoid automatically sending request body if a redirect has occurred.
+ //
+ // TODO - This is the wrong behaviour according to the RFC. However, I'm not
+ // sure how much "correctness" vs. real-world is important in this case.
+ //
+ // https://tools.ietf.org/html/rfc7231#section-6.4
+ let is_redirected_request = iters != 1;
+ let request_body;
+ match data {
+ &Some(ref d) if !is_redirected_request => {
+ headers.typed_insert(ContentLength(d.len() as u64));
+ request_body = d.clone();
}
-
- if log_enabled!(log::Level::Info) {
- info!("{} {}", method, url);
- for header in headers.iter() {
- info!(" - {}", header);
+ _ => {
+ if *load_data_method != Method::GET && *load_data_method != Method::HEAD {
+ headers.typed_insert(ContentLength(0))
}
- info!("{:?}", data);
+ request_body = vec![];
}
+ }
- let connect_start = precise_time_ms();
-
- let request = HyperRequest::with_connector(method.clone(),
- url.clone().into_url(),
- &*connector);
- let mut request = match request {
- Ok(request) => request,
- Err(e) => return Err(NetworkError::from_hyper_error(&url, e)),
- };
- *request.headers_mut() = headers.clone();
-
- let connect_end = precise_time_ms();
-
- let send_start = precise_time_ms();
+ if log_enabled!(log::Level::Info) {
+ info!("{} {}", method, url);
+ for header in headers.iter() {
+ info!(" - {:?}", header);
+ }
+ info!("{:?}", data);
+ }
- let mut request_writer = match request.start() {
- Ok(streaming) => streaming,
- Err(e) => return Err(NetworkError::Internal(e.description().to_owned())),
- };
+ let connect_start = precise_time_ms();
+ // https://url.spec.whatwg.org/#percent-encoded-bytes
+ let request = HyperRequest::builder()
+ .method(method)
+ .uri(url.clone().into_url().as_ref().replace("|", "%7C").replace("{", "%7B").replace("}", "%7D"))
+ .body(WrappedBody::new(request_body.clone().into()));
- if let Some(ref data) = *request_body {
- if let Err(e) = request_writer.write_all(&data) {
- return Err(NetworkError::Internal(e.description().to_owned()))
- }
- }
+ let mut request = match request {
+ Ok(request) => request,
+ Err(e) => return Box::new(future::result(Err(NetworkError::from_http_error(&e)))),
+ };
+ *request.headers_mut() = headers.clone();
+ let connect_end = precise_time_ms();
- let response = match request_writer.send() {
- Ok(w) => w,
- Err(HttpError::Io(ref io_error))
- if io_error.kind() == io::ErrorKind::ConnectionAborted ||
- io_error.kind() == io::ErrorKind::ConnectionReset => {
- debug!("connection aborted ({:?}), possibly stale, trying new connection", io_error.description());
- continue;
- },
- Err(e) => return Err(NetworkError::Internal(e.description().to_owned())),
- };
+ let request_id = request_id.map(|v| v.to_owned());
+ let pipeline_id = pipeline_id.clone();
+ let closure_url = url.clone();
+ let method = method.clone();
+ let send_start = precise_time_ms();
+ Box::new(client.request(request).and_then(move |res| {
let send_end = precise_time_ms();
let msg = if let Some(request_id) = request_id {
- if let Some(pipeline_id) = *pipeline_id {
+ if let Some(pipeline_id) = pipeline_id {
Some(prepare_devtools_request(
- request_id.into(),
- url.clone(), method.clone(), headers,
- request_body.clone(), pipeline_id, time::now(),
+ request_id,
+ closure_url, method.clone(), headers,
+ Some(request_body.clone()), pipeline_id, time::now(),
connect_end - connect_start, send_end - send_start, is_xhr))
+ // TODO: ^This is not right, connect_start is taken before contructing the
+ // request and connect_end at the end of it. send_start is takend before the
+ // connection too. I'm not sure it's currently possible to get the time at the
+ // point between the connection and the start of a request.
} else {
debug!("Not notifying devtools (no pipeline_id)");
None
@@ -474,8 +408,9 @@ fn obtain_response(connector: &Pool<Connector>,
debug!("Not notifying devtools (no request_id)");
None
};
- return Ok((response, msg));
- }
+ let decoder = Decoder::from_http_response(&res);
+ Ok((res.map(move |r| WrappedBody::new_with_decoder(r, decoder)), msg))
+ }).map_err(move |e| NetworkError::from_hyper_error(&e)))
}
/// [HTTP fetch](https://fetch.spec.whatwg.org#http-fetch)
@@ -543,8 +478,8 @@ pub fn http_fetch(request: &mut Request,
let method_mismatch = !method_cache_match && (!is_cors_safelisted_method(&request.method) ||
request.use_cors_preflight);
- let header_mismatch = request.headers.iter().any(|view|
- !cache.match_header(&*request, view.name()) && !is_cors_safelisted_request_header(&view)
+ let header_mismatch = request.headers.iter().any(|(name, value)|
+ !cache.match_header(&*request, &name) && !is_cors_safelisted_request_header(&name, &value)
);
// Sub-substep 1
@@ -579,16 +514,19 @@ pub fn http_fetch(request: &mut Request,
let mut response = response.unwrap();
// Step 5
- if response.actual_response().status.map_or(false, is_redirect_status) {
+ if response.actual_response().status.as_ref().map_or(false, is_redirect_status) {
// Substep 1.
- if response.actual_response().status.map_or(true, |s| s != StatusCode::SeeOther) {
+ if response.actual_response().status.as_ref().map_or(true, |s| s.0 != StatusCode::SEE_OTHER) {
// TODO: send RST_STREAM frame
}
// Substep 2-3.
- let location = response.actual_response().headers.get::<Location>().map(
- |l| ServoUrl::parse_with_base(response.actual_response().url(), l)
- .map_err(|err| err.description().into()));
+ let location = response.actual_response().headers.get(header::LOCATION)
+ .and_then(|v| HeaderValue::to_str(v).map(|l| {
+ ServoUrl::parse_with_base(response.actual_response().url(), &l)
+ .map_err(|err| err.description().into())
+ }).ok()
+ );
// Substep 4.
response.actual_response_mut().location_url = location;
@@ -664,7 +602,7 @@ pub fn http_redirect_fetch(request: &mut Request,
}
// Step 9
- if response.actual_response().status.map_or(true, |s| s != StatusCode::SeeOther) &&
+ if response.actual_response().status.as_ref().map_or(true, |s| s.0 != StatusCode::SEE_OTHER) &&
request.body.as_ref().map_or(false, |b| b.is_empty()) {
return Response::network_error(NetworkError::Internal("Request body is not done".into()));
}
@@ -675,10 +613,10 @@ pub fn http_redirect_fetch(request: &mut Request,
}
// Step 11
- if response.actual_response().status.map_or(false, |code|
- ((code == StatusCode::MovedPermanently || code == StatusCode::Found) && request.method == Method::Post) ||
- (code == StatusCode::SeeOther && request.method != Method::Head)) {
- request.method = Method::Get;
+ if response.actual_response().status.as_ref().map_or(false, |(code, _)|
+ ((*code == StatusCode::MOVED_PERMANENTLY || *code == StatusCode::FOUND) && request.method == Method::POST) ||
+ (*code == StatusCode::SEE_OTHER && request.method != Method::HEAD)) {
+ request.method = Method::GET;
request.body = None;
}
@@ -701,10 +639,9 @@ pub fn http_redirect_fetch(request: &mut Request,
fn try_immutable_origin_to_hyper_origin(url_origin: &ImmutableOrigin) -> Option<HyperOrigin> {
match *url_origin {
- // TODO (servo/servo#15569) Set "Origin: null" when hyper supports it
- ImmutableOrigin::Opaque(_) => None,
+ ImmutableOrigin::Opaque(_) => Some(HyperOrigin::NULL),
ImmutableOrigin::Tuple(ref scheme, ref host, ref port) =>
- Some(HyperOrigin::new(scheme.clone(), host.to_string(), Some(port.clone())))
+ HyperOrigin::try_from_parts(&scheme, &host.to_string(), Some(port.clone())).ok()
}
}
@@ -742,7 +679,7 @@ fn http_network_or_cache_fetch(request: &mut Request,
None =>
match http_request.method {
// Step 6
- Method::Post | Method::Put =>
+ Method::POST | Method::PUT =>
Some(0),
// Step 5
_ => None
@@ -753,7 +690,7 @@ fn http_network_or_cache_fetch(request: &mut Request,
// Step 8
if let Some(content_length_value) = content_length_value {
- http_request.headers.set(ContentLength(content_length_value));
+ http_request.headers.typed_insert(ContentLength(content_length_value));
if http_request.keep_alive {
// Step 9 TODO: needs request's client object
}
@@ -764,7 +701,7 @@ fn http_network_or_cache_fetch(request: &mut Request,
match http_request.referrer {
Referrer::NoReferrer => (),
Referrer::ReferrerUrl(ref http_request_referrer) =>
- http_request.headers.set(Referer(http_request_referrer.to_string())),
+ http_request.headers.typed_insert::<Referer>(http_request_referrer.to_string().parse().unwrap()),
Referrer::Client =>
// it should be impossible for referrer to be anything else during fetching
// https://fetch.spec.whatwg.org/#concept-request-referrer
@@ -772,19 +709,19 @@ fn http_network_or_cache_fetch(request: &mut Request,
};
// Step 11
- if cors_flag || (http_request.method != Method::Get && http_request.method != Method::Head) {
+ if cors_flag || (http_request.method != Method::GET && http_request.method != Method::HEAD) {
debug_assert_ne!(http_request.origin, Origin::Client);
if let Origin::Origin(ref url_origin) = http_request.origin {
if let Some(hyper_origin) = try_immutable_origin_to_hyper_origin(url_origin) {
- http_request.headers.set(hyper_origin)
+ http_request.headers.typed_insert(hyper_origin)
}
}
}
// Step 12
- if !http_request.headers.has::<UserAgent>() {
+ if !http_request.headers.contains_key(header::USER_AGENT) {
let user_agent = context.user_agent.clone().into_owned();
- http_request.headers.set(UserAgent(user_agent));
+ http_request.headers.typed_insert::<UserAgent>(user_agent.parse().unwrap());
}
match http_request.cache_mode {
@@ -794,20 +731,20 @@ fn http_network_or_cache_fetch(request: &mut Request,
},
// Step 14
- CacheMode::NoCache if !http_request.headers.has::<CacheControl>() => {
- http_request.headers.set(CacheControl(vec![CacheDirective::MaxAge(0)]));
+ CacheMode::NoCache if !http_request.headers.contains_key(header::CACHE_CONTROL) => {
+ http_request.headers.typed_insert(CacheControl::new().with_max_age(Duration::from_secs(0)));
},
// Step 15
CacheMode::Reload | CacheMode::NoStore => {
// Substep 1
- if !http_request.headers.has::<Pragma>() {
- http_request.headers.set(Pragma::NoCache);
+ if !http_request.headers.contains_key(header::PRAGMA) {
+ http_request.headers.typed_insert(Pragma::no_cache());
}
// Substep 2
- if !http_request.headers.has::<CacheControl>() {
- http_request.headers.set(CacheControl(vec![CacheDirective::NoCache]));
+ if !http_request.headers.contains_key(header::CACHE_CONTROL) {
+ http_request.headers.typed_insert(CacheControl::new().with_no_cache());
}
},
@@ -816,11 +753,13 @@ fn http_network_or_cache_fetch(request: &mut Request,
// Step 16
let current_url = http_request.current_url();
- let host = Host {
- hostname: current_url.host_str().unwrap().to_owned(),
- port: current_url.port()
- };
- http_request.headers.set(host);
+ let host = Host::from(
+ format!("{}{}", current_url.host_str().unwrap(),
+ current_url.port().map(|v| format!(":{}", v)).unwrap_or("".into())
+ ).parse::<Authority>().unwrap()
+ );
+
+ http_request.headers.typed_insert(host);
// unlike http_loader, we should not set the accept header
// here, according to the fetch spec
set_default_accept_encoding(&mut http_request.headers);
@@ -835,7 +774,7 @@ fn http_network_or_cache_fetch(request: &mut Request,
&mut http_request.headers,
&context.state.cookie_jar);
// Substep 2
- if !http_request.headers.has::<Authorization<String>>() {
+ if !http_request.headers.contains_key(header::AUTHORIZATION) {
// Substep 3
let mut authorization_value = None;
@@ -849,16 +788,16 @@ fn http_network_or_cache_fetch(request: &mut Request,
// Substep 5
if authentication_fetch_flag && authorization_value.is_none() {
if has_credentials(&current_url) {
- authorization_value = Some(Basic {
- username: current_url.username().to_owned(),
- password: current_url.password().map(str::to_owned)
- })
+ authorization_value = Some(Authorization::basic(
+ current_url.username(),
+ current_url.password().unwrap_or("")
+ ));
}
}
// Substep 6
if let Some(basic) = authorization_value {
- http_request.headers.set(Authorization(basic));
+ http_request.headers.typed_insert(basic);
}
}
}
@@ -886,17 +825,12 @@ fn http_network_or_cache_fetch(request: &mut Request,
if needs_revalidation {
revalidating_flag = true;
// Substep 5
- // TODO: find out why the typed header getter return None from the headers of cached responses.
- if let Some(date_slice) = response_headers.get_raw("Last-Modified") {
- let date_string = String::from_utf8_lossy(&date_slice[0]);
- if let Ok(http_date) = HttpDate::from_str(&date_string) {
- http_request.headers.set(IfModifiedSince(http_date));
- }
+ if let Some(http_date) = response_headers.typed_get::<LastModified>() {
+ let http_date: SystemTime = http_date.into();
+ http_request.headers.typed_insert(IfModifiedSince::from(http_date));
}
- if let Some(entity_tag) =
- response_headers.get_raw("ETag") {
- http_request.headers.set_raw("If-None-Match", entity_tag.to_vec());
-
+ if let Some(entity_tag) = response_headers.get(header::ETAG) {
+ http_request.headers.insert(header::IF_NONE_MATCH, entity_tag.clone());
}
} else {
// Substep 6
@@ -945,14 +879,14 @@ fn http_network_or_cache_fetch(request: &mut Request,
done_chan, context);
// Substep 3
if let Some((200...399, _)) = forward_response.raw_status {
- if !http_request.method.safe() {
+ if !http_request.method.is_safe() {
if let Ok(mut http_cache) = context.state.http_cache.write() {
http_cache.invalidate(&http_request, &forward_response);
}
}
}
// Substep 4
- if revalidating_flag && forward_response.status.map_or(false, |s| s == StatusCode::NotModified) {
+ if revalidating_flag && forward_response.status.as_ref().map_or(false, |s| s.0 == StatusCode::NOT_MODIFIED) {
if let Ok(mut http_cache) = context.state.http_cache.write() {
response = http_cache.refresh(&http_request, forward_response.clone(), done_chan);
wait_for_cached_response(done_chan, &mut response);
@@ -976,7 +910,9 @@ fn http_network_or_cache_fetch(request: &mut Request,
// Step 23
// FIXME: Figure out what to do with request window objects
- if let (Some(StatusCode::Unauthorized), false, true) = (response.status, cors_flag, credentials_flag) {
+ if let (Some((StatusCode::UNAUTHORIZED, _)), false, true) =
+ (response.status.as_ref(), cors_flag, credentials_flag)
+ {
// Substep 1
// TODO: Spec says requires testing on multiple WWW-Authenticate headers
@@ -1002,7 +938,7 @@ fn http_network_or_cache_fetch(request: &mut Request,
}
// Step 24
- if let Some(StatusCode::ProxyAuthenticationRequired) = response.status {
+ if let Some((StatusCode::PROXY_AUTHENTICATION_REQUIRED, _)) = response.status.as_ref() {
// Step 1
if request_has_no_window {
return Response::network_error(NetworkError::Internal("Can't find Window object".into()));
@@ -1062,38 +998,38 @@ fn http_network_fetch(request: &Request,
// do not. Once we support other kinds of fetches we'll need to be more fine grained here
// since things like image fetches are classified differently by devtools
let is_xhr = request.destination == Destination::None;
- let wrapped_response = obtain_response(&context.state.connector,
- &url,
- &request.method,
- &request.headers,
- &request.body, &request.method,
- &request.pipeline_id, request.redirect_count + 1,
- request_id.as_ref().map(Deref::deref), is_xhr);
+ let response_future = obtain_response(&context.state.client,
+ &url,
+ &request.method,
+ &request.headers,
+ &request.body, &request.method,
+ &request.pipeline_id, request.redirect_count + 1,
+ request_id.as_ref().map(Deref::deref), is_xhr);
let pipeline_id = request.pipeline_id;
- let (res, msg) = match wrapped_response {
+ // This will only get the headers, the body is read later
+ let (res, msg) = match response_future.wait() {
Ok(wrapped_response) => wrapped_response,
Err(error) => return Response::network_error(error),
};
if log_enabled!(log::Level::Info) {
info!("response for {}", url);
- for header in res.headers.iter() {
- info!(" - {}", header);
+ for header in res.headers().iter() {
+ info!(" - {:?}", header);
}
}
let mut response = Response::new(url.clone());
- response.status = Some(res.status);
- response.raw_status = Some((res.status_raw().0,
- res.status_raw().1.as_bytes().to_vec()));
- response.headers = res.headers.clone();
+ response.status = Some((res.status(), res.status().canonical_reason().unwrap_or("").into()));
+ response.raw_status = Some((res.status().as_u16(), res.status().canonical_reason().unwrap_or("").into()));
+ response.headers = res.headers().clone();
response.referrer = request.referrer.to_url().cloned();
response.referrer_policy = request.referrer_policy.clone();
let res_body = response.body.clone();
- // We're about to spawn a thread to be waited on here
+ // We're about to spawn a future to be waited on here
let (done_sender, done_receiver) = channel();
*done_chan = Some((done_sender.clone(), done_receiver));
let meta = match response.metadata().expect("Response metadata should exist at this stage") {
@@ -1107,68 +1043,56 @@ fn http_network_fetch(request: &Request,
if cancellation_listener.lock().unwrap().cancelled() {
return Response::network_error(NetworkError::Internal("Fetch aborted".into()))
}
- thread::Builder::new().name(format!("fetch worker thread")).spawn(move || {
- match StreamedResponse::from_http_response(res) {
- Ok(mut res) => {
- *res_body.lock().unwrap() = ResponseBody::Receiving(vec![]);
-
- if let Some(ref sender) = devtools_sender {
- if let Some(m) = msg {
- send_request_to_devtools(m, &sender);
- }
- // --- Tell devtools that we got a response
- // Send an HttpResponse message to devtools with the corresponding request_id
- if let Some(pipeline_id) = pipeline_id {
- send_response_to_devtools(
- &sender, request_id.unwrap(),
- meta_headers.map(Serde::into_inner),
- meta_status,
- pipeline_id);
- }
- }
+ *res_body.lock().unwrap() = ResponseBody::Receiving(vec![]);
- loop {
- if cancellation_listener.lock().unwrap().cancelled() {
- *res_body.lock().unwrap() = ResponseBody::Done(vec![]);
- let _ = done_sender.send(Data::Cancelled);
- return;
- }
- match read_block(&mut res) {
- Ok(Data::Payload(chunk)) => {
- if let ResponseBody::Receiving(ref mut body) = *res_body.lock().unwrap() {
- body.extend_from_slice(&chunk);
- let _ = done_sender.send(Data::Payload(chunk));
- }
- },
- Ok(Data::Done) | Err(_) => {
- let mut body = res_body.lock().unwrap();
- let completed_body = match *body {
- ResponseBody::Receiving(ref mut body) => {
- mem::replace(body, vec![])
- },
- _ => vec![],
- };
- *body = ResponseBody::Done(completed_body);
- let _ = done_sender.send(Data::Done);
- break;
- }
- Ok(Data::Cancelled) => unreachable!() // read_block doesn't return Data::Cancelled
- }
- }
- }
- Err(_) => {
- // XXXManishearth we should propagate this error somehow
- *res_body.lock().unwrap() = ResponseBody::Done(vec![]);
- let _ = done_sender.send(Data::Done);
- }
+ if let Some(ref sender) = devtools_sender {
+ if let Some(m) = msg {
+ send_request_to_devtools(m, &sender);
}
- }).expect("Thread spawning failed");
- // TODO these substeps aren't possible yet
- // Substep 1
+ // --- Tell devtools that we got a response
+ // Send an HttpResponse message to devtools with the corresponding request_id
+ if let Some(pipeline_id) = pipeline_id {
+ send_response_to_devtools(
+ &sender, request_id.unwrap(),
+ meta_headers.map(Serde::into_inner),
+ meta_status,
+ pipeline_id);
+ }
+ }
- // Substep 2
+ let done_sender = done_sender.clone();
+ let done_sender2 = done_sender.clone();
+ HANDLE.lock().unwrap().spawn(res.into_body().map_err(|_|()).fold(res_body, move |res_body, chunk| {
+ if cancellation_listener.lock().unwrap().cancelled() {
+ *res_body.lock().unwrap() = ResponseBody::Done(vec![]);
+ let _ = done_sender.send(Data::Cancelled);
+ return future::failed(());
+ }
+ if let ResponseBody::Receiving(ref mut body) = *res_body.lock().unwrap() {
+ let bytes = chunk.into_bytes();
+ body.extend_from_slice(&*bytes);
+ let _ = done_sender.send(Data::Payload(bytes.to_vec()));
+ }
+ future::ok(res_body)
+ }).and_then(move |res_body| {
+ let mut body = res_body.lock().unwrap();
+ let completed_body = match *body {
+ ResponseBody::Receiving(ref mut body) => {
+ mem::replace(body, vec![])
+ },
+ _ => vec![],
+ };
+ *body = ResponseBody::Done(completed_body);
+ let _ = done_sender2.send(Data::Done);
+ future::ok(())
+ }).map_err(|_| ()));
+
+ // TODO these substeps aren't possible yet
+ // Substep 1
+
+ // Substep 2
// TODO Determine if response was retrieved over HTTPS
// TODO Servo needs to decide what ciphers are to be treated as "deprecated"
@@ -1183,11 +1107,11 @@ fn http_network_fetch(request: &Request,
// TODO when https://bugzilla.mozilla.org/show_bug.cgi?id=1030660
// is resolved, this step will become uneccesary
// TODO this step
- if let Some(encoding) = response.headers.get::<ContentEncoding>() {
- if encoding.contains(&Encoding::Gzip) {
+ if let Some(encoding) = response.headers.typed_get::<ContentEncoding>() {
+ if encoding.contains("gzip") {
}
- else if encoding.contains(&Encoding::Compress) {
+ else if encoding.contains("compress") {
}
};
@@ -1228,7 +1152,7 @@ fn cors_preflight_fetch(request: &Request,
-> Response {
// Step 1
let mut preflight = Request::new(request.current_url(), Some(request.origin.clone()), request.pipeline_id);
- preflight.method = Method::Options;
+ preflight.method = Method::OPTIONS;
preflight.initiator = request.initiator.clone();
preflight.destination = request.destination.clone();
preflight.origin = request.origin.clone();
@@ -1236,20 +1160,24 @@ fn cors_preflight_fetch(request: &Request,
preflight.referrer_policy = request.referrer_policy;
// Step 2
- preflight.headers.set::<AccessControlRequestMethod>(
- AccessControlRequestMethod(request.method.clone()));
+ preflight.headers.typed_insert::<AccessControlRequestMethod>(
+ AccessControlRequestMethod::from(request.method.clone()));
// Step 3
let mut headers = request.headers
.iter()
- .filter(|view| !is_cors_safelisted_request_header(view))
- .map(|view| UniCase(view.name().to_ascii_lowercase().to_owned()))
- .collect::<Vec<UniCase<String>>>();
+ .filter(|(name, value)| !is_cors_safelisted_request_header(&name, &value))
+ .map(|(name, _)| name.as_str())
+ .collect::<Vec<&str>>();
headers.sort();
+ let headers = headers
+ .iter()
+ .map(|name| HeaderName::from_str(name).unwrap())
+ .collect::<Vec<HeaderName>>();
// Step 4
if !headers.is_empty() {
- preflight.headers.set::<AccessControlRequestHeaders>(AccessControlRequestHeaders(headers));
+ preflight.headers.typed_insert(AccessControlRequestHeaders::from_iter(headers));
}
// Step 5
@@ -1257,11 +1185,11 @@ fn cors_preflight_fetch(request: &Request,
// Step 6
if cors_check(&request, &response).is_ok() &&
- response.status.map_or(false, |status| status.is_success()) {
+ response.status.as_ref().map_or(false, |(status, _)| status.is_success()) {
// Substep 1, 2
- let mut methods = if response.headers.has::<AccessControlAllowMethods>() {
- match response.headers.get::<AccessControlAllowMethods>() {
- Some(&AccessControlAllowMethods(ref m)) => m.clone(),
+ let mut methods = if response.headers.contains_key(header::ACCESS_CONTROL_ALLOW_METHODS) {
+ match response.headers.typed_get::<AccessControlAllowMethods>() {
+ Some(methods) => methods.iter().collect(),
// Substep 4
None => return Response::network_error(NetworkError::Internal("CORS ACAM check failed".into()))
}
@@ -1270,9 +1198,9 @@ fn cors_preflight_fetch(request: &Request,
};
// Substep 3
- let header_names = if response.headers.has::<AccessControlAllowHeaders>() {
- match response.headers.get::<AccessControlAllowHeaders>() {
- Some(&AccessControlAllowHeaders(ref hn)) => hn.clone(),
+ let header_names = if response.headers.contains_key(header::ACCESS_CONTROL_ALLOW_HEADERS) {
+ match response.headers.typed_get::<AccessControlAllowHeaders>() {
+ Some(names) => names.iter().collect(),
// Substep 4
None => return Response::network_error(NetworkError::Internal("CORS ACAH check failed".into()))
}
@@ -1282,7 +1210,7 @@ fn cors_preflight_fetch(request: &Request,
// Substep 5
if (methods.iter().any(|m| m.as_ref() == "*") ||
- header_names.iter().any(|hn| &**hn == "*")) &&
+ header_names.iter().any(|hn| hn.as_str() == "*")) &&
request.credentials_mode == CredentialsMode::Include {
return Response::network_error(
NetworkError::Internal("CORS ACAH/ACAM and request credentials mode mismatch".into()));
@@ -1304,22 +1232,24 @@ fn cors_preflight_fetch(request: &Request,
// Substep 8
if request.headers.iter().any(
- |header| header.name() == "authorization" &&
- header_names.iter().all(|hn| *hn != UniCase(header.name()))) {
+ |(name, _)| name == header::AUTHORIZATION &&
+ header_names.iter().all(|hn| hn != name)) {
return Response::network_error(NetworkError::Internal("CORS authorization check failed".into()));
}
// Substep 9
debug!("CORS check: Allowed headers: {:?}, current headers: {:?}", header_names, request.headers);
- let set: HashSet<&UniCase<String>> = HashSet::from_iter(header_names.iter());
+ let set: HashSet<&HeaderName> = HashSet::from_iter(header_names.iter());
if request.headers.iter().any(
- |ref hv| !set.contains(&UniCase(hv.name().to_owned())) && !is_cors_safelisted_request_header(hv)) {
+ |(name, value)| !set.contains(name) && !is_cors_safelisted_request_header(&name, &value)) {
return Response::network_error(NetworkError::Internal("CORS headers check failed".into()));
}
// Substep 10, 11
- let max_age = response.headers.get::<AccessControlMaxAge>().map(|acma| acma.0).unwrap_or(0);
-
+ let max_age: Duration = response.headers.typed_get::<AccessControlMaxAge>()
+ .map(|acma| acma.into())
+ .unwrap_or(Duration::from_secs(0));
+ let max_age = max_age.as_secs() as u32;
// Substep 12
// TODO: Need to define what an imposed limit on max-age is
@@ -1346,26 +1276,26 @@ fn cors_preflight_fetch(request: &Request,
/// [CORS check](https://fetch.spec.whatwg.org#concept-cors-check)
fn cors_check(request: &Request, response: &Response) -> Result<(), ()> {
// Step 1
- let origin = response.headers.get::<AccessControlAllowOrigin>().cloned();
+ let origin = response.headers.typed_get::<AccessControlAllowOrigin>();
// Step 2
let origin = origin.ok_or(())?;
// Step 3
if request.credentials_mode != CredentialsMode::Include &&
- origin == AccessControlAllowOrigin::Any {
+ origin == AccessControlAllowOrigin::ANY {
return Ok(());
}
// Step 4
- let origin = match origin {
- AccessControlAllowOrigin::Value(origin) => origin,
+ let origin = match origin.origin() {
+ Some(origin) => origin,
// if it's Any or Null at this point, there's nothing to do but return Err(())
- _ => return Err(())
+ None => return Err(())
};
match request.origin {
- Origin::Origin(ref o) if o.ascii_serialization() == origin.trim() => {},
+ Origin::Origin(ref o) if o.ascii_serialization() == origin.to_string().trim() => {},
_ => return Err(())
}
@@ -1375,7 +1305,7 @@ fn cors_check(request: &Request, response: &Response) -> Result<(), ()> {
}
// Step 6
- let credentials = response.headers.get::<AccessControlAllowCredentials>().cloned();
+ let credentials = response.headers.typed_get::<AccessControlAllowCredentials>();
// Step 7
if credentials.is_some() {
@@ -1390,20 +1320,20 @@ fn has_credentials(url: &ServoUrl) -> bool {
!url.username().is_empty() || url.password().is_some()
}
-fn is_no_store_cache(headers: &Headers) -> bool {
- headers.has::<IfModifiedSince>() | headers.has::<IfNoneMatch>() |
- headers.has::<IfUnmodifiedSince>() | headers.has::<IfMatch>() |
- headers.has::<IfRange>()
+fn is_no_store_cache(headers: &HeaderMap) -> bool {
+ headers.contains_key(header::IF_MODIFIED_SINCE) | headers.contains_key(header::IF_NONE_MATCH) |
+ headers.contains_key(header::IF_UNMODIFIED_SINCE) | headers.contains_key(header::IF_MATCH) |
+ headers.contains_key(header::IF_RANGE)
}
/// <https://fetch.spec.whatwg.org/#redirect-status>
-pub fn is_redirect_status(status: StatusCode) -> bool {
- match status {
- StatusCode::MovedPermanently |
- StatusCode::Found |
- StatusCode::SeeOther |
- StatusCode::TemporaryRedirect |
- StatusCode::PermanentRedirect => true,
+pub fn is_redirect_status(status: &(StatusCode, String)) -> bool {
+ match status.0 {
+ StatusCode::MOVED_PERMANENTLY |
+ StatusCode::FOUND |
+ StatusCode::SEE_OTHER |
+ StatusCode::TEMPORARY_REDIRECT |
+ StatusCode::PERMANENT_REDIRECT => true,
_ => false,
}
}
diff --git a/components/net/lib.rs b/components/net/lib.rs
index 285a755a9e9..cebeb447aef 100644
--- a/components/net/lib.rs
+++ b/components/net/lib.rs
@@ -6,10 +6,14 @@
extern crate base64;
extern crate brotli;
+extern crate bytes;
extern crate cookie as cookie_rs;
extern crate devtools_traits;
extern crate embedder_traits;
extern crate flate2;
+extern crate headers_core;
+extern crate headers_ext;
+extern crate http;
extern crate hyper;
extern crate hyper_openssl;
extern crate hyper_serde;
@@ -21,7 +25,6 @@ extern crate lazy_static;
extern crate malloc_size_of;
#[macro_use] extern crate malloc_size_of_derive;
#[macro_use] #[no_link] extern crate matches;
-#[macro_use]
extern crate mime;
extern crate mime_guess;
extern crate msg;
@@ -38,7 +41,7 @@ extern crate servo_channel;
extern crate servo_config;
extern crate servo_url;
extern crate time;
-extern crate unicase;
+extern crate tokio;
extern crate url;
extern crate uuid;
extern crate webrender_api;
diff --git a/components/net/mime_classifier.rs b/components/net/mime_classifier.rs
index f59dc2b925d..801f5bce9b3 100644
--- a/components/net/mime_classifier.rs
+++ b/components/net/mime_classifier.rs
@@ -2,9 +2,8 @@
* 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/. */
-use hyper::mime::TopLevel;
+use mime::{self, Mime};
use net_traits::LoadContext;
-use std::borrow::ToOwned;
pub struct MimeClassifier {
image_classifier: GroupedClassifier,
@@ -49,34 +48,28 @@ pub enum NoSniffFlag {
Off
}
-pub type MimeType = (TopLevel, String);
-
impl MimeClassifier {
//Performs MIME Type Sniffing Algorithm (sections 7 and 8)
- pub fn classify(&self,
+ pub fn classify<'a>(&'a self,
context: LoadContext,
no_sniff_flag: NoSniffFlag,
apache_bug_flag: ApacheBugFlag,
- supplied_type: &Option<MimeType>,
- data: &[u8]) -> MimeType {
- let supplied_type_or_octet_stream = supplied_type.clone()
- .unwrap_or((TopLevel::Application,
- "octet-stream".to_owned()));
+ supplied_type: &Option<Mime>,
+ data: &'a [u8]) -> Mime {
+ let supplied_type_or_octet_stream = supplied_type.clone().unwrap_or(mime::APPLICATION_OCTET_STREAM);
match context {
LoadContext::Browsing => match *supplied_type {
None => self.sniff_unknown_type(no_sniff_flag, data),
Some(ref supplied_type) => {
- let &(ref media_type, ref media_subtype) = supplied_type;
- if MimeClassifier::is_explicit_unknown(media_type, media_subtype) {
+ if MimeClassifier::is_explicit_unknown(supplied_type) {
self.sniff_unknown_type(no_sniff_flag, data)
} else {
match no_sniff_flag {
NoSniffFlag::On => supplied_type.clone(),
NoSniffFlag::Off => match apache_bug_flag {
ApacheBugFlag::On => self.sniff_text_or_data(data),
- ApacheBugFlag::Off => match MimeClassifier::get_media_type(media_type,
- media_subtype) {
+ ApacheBugFlag::Off => match MimeClassifier::get_media_type(supplied_type) {
Some(MediaType::Html) => self.feeds_classifier.classify(data),
Some(MediaType::Image) => self.image_classifier.classify(data),
Some(MediaType::AudioVideo) => self.audio_video_classifier.classify(data),
@@ -107,7 +100,7 @@ impl MimeClassifier {
// This section was *not* finalized in the specs at the time
// of this implementation.
match *supplied_type {
- None => (TopLevel::Application, "octet-stream".to_owned()),
+ None => mime::APPLICATION_OCTET_STREAM,
_ => supplied_type_or_octet_stream,
}
},
@@ -117,7 +110,7 @@ impl MimeClassifier {
// This section was *not* finalized in the specs at the time
// of this implementation.
match *supplied_type {
- None => (TopLevel::Text, "css".to_owned()),
+ None => mime::TEXT_CSS,
_ => supplied_type_or_octet_stream,
}
},
@@ -127,7 +120,7 @@ impl MimeClassifier {
// This section was *not* finalized in the specs at the time
// of this implementation.
match *supplied_type {
- None => (TopLevel::Text, "javascript".to_owned()),
+ None => mime::TEXT_JAVASCRIPT,
_ => supplied_type_or_octet_stream,
}
},
@@ -143,14 +136,14 @@ impl MimeClassifier {
//
// This section was *not* finalized in the specs at the time
// of this implementation.
- (TopLevel::Text, "vtt".to_owned())
+ "text/vtt".parse().unwrap()
},
LoadContext::CacheManifest => {
// 8.9 Sniffing in a cache manifest context
//
// This section was *not* finalized in the specs at the time
// of this implementation.
- (TopLevel::Text, "cache-manifest".to_owned())
+ "text/cache-manifest".parse().unwrap()
},
}
}
@@ -181,7 +174,7 @@ impl MimeClassifier {
}
//some sort of iterator over the classifiers might be better?
- fn sniff_unknown_type(&self, no_sniff_flag: NoSniffFlag, data: &[u8]) -> MimeType {
+ fn sniff_unknown_type(&self, no_sniff_flag: NoSniffFlag, data: &[u8]) -> Mime {
let should_sniff_scriptable = no_sniff_flag == NoSniffFlag::Off;
let sniffed = if should_sniff_scriptable {
self.scriptable_classifier.classify(data)
@@ -197,72 +190,60 @@ impl MimeClassifier {
.expect("BinaryOrPlaintextClassifier always succeeds")
}
- fn sniff_text_or_data(&self, data: &[u8]) -> MimeType {
+ fn sniff_text_or_data<'a>(&'a self, data: &'a [u8]) -> Mime {
self.binary_or_plaintext.classify(data).expect("BinaryOrPlaintextClassifier always succeeds")
}
- fn is_xml(tp: &TopLevel, sub_tp: &str) -> bool {
- sub_tp.ends_with("+xml") ||
- match (tp, sub_tp) {
- (&TopLevel::Application, "xml") | (&TopLevel::Text, "xml") => true,
- _ => false
- }
+ fn is_xml(mt: &Mime) -> bool {
+ mt.suffix() == Some(mime::XML) ||
+ (mt.type_() == mime::APPLICATION && mt.subtype() == mime::XML) ||
+ (mt.type_() == mime::TEXT && mt.subtype() == mime::XML)
}
- fn is_html(tp: &TopLevel, sub_tp: &str) -> bool {
- *tp == TopLevel::Text && sub_tp == "html"
+ fn is_html(mt: &Mime) -> bool {
+ mt.type_() == mime::TEXT && mt.subtype() == mime::HTML
}
- fn is_image(tp: &TopLevel) -> bool {
- *tp == TopLevel::Image
+ fn is_image(mt: &Mime) -> bool {
+ mt.type_() == mime::IMAGE
}
- fn is_audio_video(tp: &TopLevel, sub_tp: &str) -> bool {
- *tp == TopLevel::Audio ||
- *tp == TopLevel::Video ||
- (*tp == TopLevel::Application && sub_tp == "ogg")
+ fn is_audio_video(mt: &Mime) -> bool {
+ mt.type_() == mime::AUDIO ||
+ mt.type_() == mime::VIDEO ||
+ mt.type_() == mime::APPLICATION && mt.subtype() == mime::OGG
}
- fn is_explicit_unknown(tp: &TopLevel, sub_tp: &str) -> bool {
- if let TopLevel::Ext(ref e) = *tp {
- return e == "unknown" && sub_tp == "unknown";
- }
- match (tp, sub_tp) {
- (&TopLevel::Application, "unknown") |
- (&TopLevel::Star, "*") => true,
- _ => false
- }
+ fn is_explicit_unknown(mt: &Mime) -> bool {
+ mt.type_().as_str() == "unknown" && mt.subtype().as_str() == "unknown" ||
+ mt.type_() == mime::APPLICATION && mt.subtype().as_str() == "unknown" ||
+ mt.type_() == mime::STAR && mt.subtype() == mime::STAR
}
- fn get_media_type(media_type: &TopLevel,
- media_subtype: &str) -> Option<MediaType> {
- if MimeClassifier::is_xml(media_type, media_subtype) {
+ fn get_media_type(mime: &Mime) -> Option<MediaType> {
+ if MimeClassifier::is_xml(&mime) {
Some(MediaType::Xml)
- } else if MimeClassifier::is_html(media_type, media_subtype) {
+ } else if MimeClassifier::is_html(&mime) {
Some(MediaType::Html)
- } else if MimeClassifier::is_image(media_type) {
+ } else if MimeClassifier::is_image(&mime) {
Some(MediaType::Image)
- } else if MimeClassifier::is_audio_video(media_type, media_subtype) {
+ } else if MimeClassifier::is_audio_video(&mime) {
Some(MediaType::AudioVideo)
} else {
None
}
}
- fn maybe_get_media_type(supplied_type: &Option<MimeType>) -> Option<MediaType> {
- supplied_type.as_ref().and_then(|&(ref media_type, ref media_subtype)| {
- MimeClassifier::get_media_type(media_type, media_subtype)
+ fn maybe_get_media_type(supplied_type: &Option<Mime>) -> Option<MediaType> {
+ supplied_type.as_ref().and_then(|ref mime| {
+ MimeClassifier::get_media_type(mime)
})
}
}
-pub fn as_string_option(tup: Option<(TopLevel, &'static str)>) -> Option<MimeType> {
- tup.map(|(a, b)| (a.to_owned(), b.to_owned()))
-}
-
//Interface used for composite types
trait MIMEChecker {
- fn classify(&self, data: &[u8]) -> Option<MimeType>;
+ fn classify(&self, data: &[u8]) -> Option<Mime>;
/// Validate the MIME checker configuration
fn validate(&self) -> Result<(), String>;
}
@@ -303,7 +284,7 @@ struct ByteMatcher {
pattern: &'static [u8],
mask: &'static [u8],
leading_ignore: &'static [u8],
- content_type: (TopLevel, &'static str)
+ content_type: Mime,
}
impl ByteMatcher {
@@ -328,31 +309,31 @@ impl ByteMatcher {
}
impl MIMEChecker for ByteMatcher {
- fn classify(&self, data: &[u8]) -> Option<MimeType> {
+ fn classify(&self, data: &[u8]) -> Option<Mime> {
self.matches(data).map(|_| {
- (self.content_type.0.to_owned(), self.content_type.1.to_owned())
+ self.content_type.clone()
})
}
fn validate(&self) -> Result<(), String> {
if self.pattern.len() == 0 {
return Err(format!(
- "Zero length pattern for {}/{}",
- self.content_type.0, self.content_type.1
+ "Zero length pattern for {:?}",
+ self.content_type
))
}
if self.pattern.len() != self.mask.len() {
return Err(format!(
- "Unequal pattern and mask length for {}/{}",
- self.content_type.0, self.content_type.1
+ "Unequal pattern and mask length for {:?}",
+ self.content_type
))
}
if self.pattern.iter().zip(self.mask.iter()).any(
|(&pattern, &mask)| pattern & mask != pattern
) {
return Err(format!(
- "Pattern not pre-masked for {}/{}",
- self.content_type.0, self.content_type.1
+ "Pattern not pre-masked for {:?}",
+ self.content_type
))
}
Ok(())
@@ -364,11 +345,10 @@ struct TagTerminatedByteMatcher {
}
impl MIMEChecker for TagTerminatedByteMatcher {
- fn classify(&self, data: &[u8]) -> Option<MimeType> {
+ fn classify(&self, data: &[u8]) -> Option<Mime> {
self.matcher.matches(data).and_then(|j|
if j < data.len() && (data[j] == b' ' || data[j] == b'>') {
- Some((self.matcher.content_type.0.to_owned(),
- self.matcher.content_type.1.to_owned()))
+ Some(self.matcher.content_type.clone())
} else {
None
})
@@ -405,9 +385,9 @@ impl Mp4Matcher {
}
impl MIMEChecker for Mp4Matcher {
- fn classify(&self, data: &[u8]) -> Option<MimeType> {
+ fn classify(&self, data: &[u8]) -> Option<Mime> {
if self.matches(data) {
- Some((TopLevel::Video, "mp4".to_owned()))
+ Some("video/mp4".parse().unwrap())
} else {
None
}
@@ -421,25 +401,25 @@ impl MIMEChecker for Mp4Matcher {
struct BinaryOrPlaintextClassifier;
impl BinaryOrPlaintextClassifier {
- fn classify_impl(&self, data: &[u8]) -> (TopLevel, &'static str) {
+ fn classify_impl(&self, data: &[u8]) -> Mime {
if data.starts_with(&[0xFFu8, 0xFEu8]) ||
data.starts_with(&[0xFEu8, 0xFFu8]) ||
data.starts_with(&[0xEFu8, 0xBBu8, 0xBFu8])
{
- (TopLevel::Text, "plain")
+ mime::TEXT_PLAIN
} else if data.iter().any(|&x| x <= 0x08u8 ||
x == 0x0Bu8 ||
(x >= 0x0Eu8 && x <= 0x1Au8) ||
(x >= 0x1Cu8 && x <= 0x1Fu8)) {
- (TopLevel::Application, "octet-stream")
+ mime::APPLICATION_OCTET_STREAM
} else {
- (TopLevel::Text, "plain")
+ mime::TEXT_PLAIN
}
}
}
impl MIMEChecker for BinaryOrPlaintextClassifier {
- fn classify(&self, data: &[u8]) -> Option<MimeType> {
- as_string_option(Some(self.classify_impl(data)))
+ fn classify(&self, data: &[u8]) -> Option<Mime> {
+ Some(self.classify_impl(data))
}
fn validate(&self) -> Result<(), String> {
@@ -538,7 +518,7 @@ impl GroupedClassifier {
}
}
impl MIMEChecker for GroupedClassifier {
- fn classify(&self, data: &[u8]) -> Option<MimeType> {
+ fn classify(&self, data: &[u8]) -> Option<Mime> {
self.byte_matchers
.iter()
.filter_map(|matcher| matcher.classify(data))
@@ -591,7 +571,7 @@ where T: Iterator<Item=&'a u8> + Clone {
struct FeedsClassifier;
impl FeedsClassifier {
// Implements sniffing for mislabeled feeds (https://mimesniff.spec.whatwg.org/#sniffing-a-mislabeled-feed)
- fn classify_impl(&self, data: &[u8]) -> Option<(TopLevel, &'static str)> {
+ fn classify_impl(&self, data: &[u8]) -> Option<Mime> {
// Step 4: can not be feed unless length is > 3
if data.len() < 3 {
return None;
@@ -622,11 +602,11 @@ impl FeedsClassifier {
// Step 5.2.5
if matcher.matches(b"rss") {
- return Some((TopLevel::Application, "rss+xml"));
+ return Some("application/rss+xml".parse().unwrap());
}
// Step 5.2.6
if matcher.matches(b"feed") {
- return Some((TopLevel::Application, "atom+xml"));
+ return Some("application/atom+xml".parse().unwrap());
}
// Step 5.2.7
if matcher.matches(b"rdf:RDF") {
@@ -637,7 +617,7 @@ impl FeedsClassifier {
.chain(|| eats_until(&mut matcher,
b"http://www.w3.org/1999/02/22-rdf-syntax-ns#",
b"http://purl.org/rss/1.0/")) {
- Match::StartAndEnd => return Some((TopLevel::Application, "rss+xml")),
+ Match::StartAndEnd => return Some("application/rss+xml".parse().unwrap()),
Match::DidNotMatch => {},
Match::Start => return None
}
@@ -649,8 +629,8 @@ impl FeedsClassifier {
}
impl MIMEChecker for FeedsClassifier {
- fn classify(&self, data: &[u8]) -> Option<MimeType> {
- as_string_option(self.classify_impl(data))
+ fn classify(&self, data: &[u8]) -> Option<Mime> {
+ self.classify_impl(data)
}
fn validate(&self) -> Result<(), String> {
@@ -666,7 +646,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\x00\x00\x01\x00",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Image, "x-icon"),
+ content_type: "image/x-icon".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -675,7 +655,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\x00\x00\x02\x00",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Image, "x-icon"),
+ content_type: "image/x-icon".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -684,7 +664,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"BM",
mask: b"\xFF\xFF",
- content_type: (TopLevel::Image, "bmp"),
+ content_type: mime::IMAGE_BMP,
leading_ignore: &[]
}
}
@@ -693,7 +673,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"GIF89a",
mask: b"\xFF\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Image, "gif"),
+ content_type: mime::IMAGE_GIF,
leading_ignore: &[]
}
}
@@ -702,7 +682,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"GIF87a",
mask: b"\xFF\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Image, "gif"),
+ content_type: mime::IMAGE_GIF,
leading_ignore: &[]
}
}
@@ -711,7 +691,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"RIFF\x00\x00\x00\x00WEBPVP",
mask: b"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Image, "webp"),
+ content_type: "image/webp".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -721,7 +701,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\x89PNG\r\n\x1A\n",
mask: b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Image, "png"),
+ content_type: mime::IMAGE_PNG,
leading_ignore: &[]
}
}
@@ -730,7 +710,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\xFF\xD8\xFF",
mask: b"\xFF\xFF\xFF",
- content_type: (TopLevel::Image, "jpeg"),
+ content_type: mime::IMAGE_JPEG,
leading_ignore: &[]
}
}
@@ -739,7 +719,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\x1A\x45\xDF\xA3",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Video, "webm"),
+ content_type: "video/webm".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -748,7 +728,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b".snd",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Audio, "basic"),
+ content_type: "audio/basic".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -757,7 +737,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"FORM\x00\x00\x00\x00AIFF",
mask: b"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Audio, "aiff"),
+ content_type: "audio/aiff".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -766,7 +746,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"ID3",
mask: b"\xFF\xFF\xFF",
- content_type: (TopLevel::Audio, "mpeg"),
+ content_type: "audio/mpeg".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -775,7 +755,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"OggS\x00",
mask: b"\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "ogg"),
+ content_type: "application/ogg".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -785,7 +765,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"MThd\x00\x00\x00\x06",
mask: b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Audio, "midi"),
+ content_type: "audio/midi".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -794,7 +774,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"RIFF\x00\x00\x00\x00AVI ",
mask: b"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Video, "avi"),
+ content_type: "video/avi".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -803,7 +783,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"RIFF\x00\x00\x00\x00WAVE",
mask: b"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Audio, "wave"),
+ content_type: "audio/wave".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -813,7 +793,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<!DOCTYPE HTML",
mask: b"\xFF\xFF\xDF\xDF\xDF\xDF\xDF\xDF\xDF\xFF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -825,7 +805,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<HTML",
mask: b"\xFF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -837,7 +817,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<HEAD",
mask: b"\xFF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -849,7 +829,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<SCRIPT",
mask: b"\xFF\xDF\xDF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -861,7 +841,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<IFRAME",
mask: b"\xFF\xDF\xDF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -873,7 +853,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<H1",
mask: b"\xFF\xDF\xFF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -885,7 +865,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<DIV",
mask: b"\xFF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -897,7 +877,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<FONT",
mask: b"\xFF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -909,7 +889,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<TABLE",
mask: b"\xFF\xDF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -921,7 +901,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<A",
mask: b"\xFF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -933,7 +913,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<STYLE",
mask: b"\xFF\xDF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -945,7 +925,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<TITLE",
mask: b"\xFF\xDF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -957,7 +937,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<B",
mask: b"\xFF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -969,7 +949,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<BODY",
mask: b"\xFF\xDF\xDF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -981,7 +961,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<BR",
mask: b"\xFF\xDF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -993,7 +973,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<P",
mask: b"\xFF\xDF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -1005,7 +985,7 @@ impl ByteMatcher {
matcher: ByteMatcher {
pattern: b"<!--",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Text, "html"),
+ content_type: mime::TEXT_HTML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -1016,7 +996,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"<?xml",
mask: b"\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Text, "xml"),
+ content_type: mime::TEXT_XML,
leading_ignore: b"\t\n\x0C\r "
}
}
@@ -1025,7 +1005,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"%PDF-",
mask: b"\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "pdf"),
+ content_type: mime::APPLICATION_PDF,
leading_ignore: &[]
}
}
@@ -1038,7 +1018,7 @@ impl ByteMatcher {
mask: b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\xFF\xFF",
- content_type: (TopLevel::Application, "vnd.ms-fontobject"),
+ content_type: "application/vnd.ms-fontobject".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1047,7 +1027,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\x00\x01\x00\x00",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "font-sfnt"),
+ content_type: "application/font-sfnt".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1056,7 +1036,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"OTTO",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "font-sfnt"),
+ content_type: "application/font-sfnt".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1065,7 +1045,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"ttcf",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "font-sfnt"),
+ content_type: "application/font-sfnt".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1074,7 +1054,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"wOFF",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "font-woff"),
+ content_type: "application/font-woff".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1083,7 +1063,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\x1F\x8B\x08",
mask: b"\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "x-gzip"),
+ content_type: "application/x-gzip".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1092,7 +1072,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"PK\x03\x04",
mask: b"\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "zip"),
+ content_type: "application/zip".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1101,7 +1081,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"Rar \x1A\x07\x00",
mask: b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "x-rar-compressed"),
+ content_type: "application/x-rar-compressed".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1110,7 +1090,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"%!PS-Adobe-",
mask: b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
- content_type: (TopLevel::Application, "postscript"),
+ content_type: "application/postscript".parse().unwrap(),
leading_ignore: &[]
}
}
@@ -1119,7 +1099,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\xFE\xFF\x00\x00",
mask: b"\xFF\xFF\x00\x00",
- content_type: (TopLevel::Text, "plain"),
+ content_type: mime::TEXT_PLAIN,
leading_ignore: &[]
}
}
@@ -1128,7 +1108,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\xFF\xFE\x00\x00",
mask: b"\xFF\xFF\x00\x00",
- content_type: (TopLevel::Text, "plain"),
+ content_type: mime::TEXT_PLAIN,
leading_ignore: &[]
}
}
@@ -1137,7 +1117,7 @@ impl ByteMatcher {
ByteMatcher {
pattern: b"\xEF\xBB\xBF\x00",
mask: b"\xFF\xFF\xFF\x00",
- content_type: (TopLevel::Text, "plain"),
+ content_type: mime::TEXT_PLAIN,
leading_ignore: &[]
}
}
diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs
index 0754750a952..74a18760cb0 100644
--- a/components/net/resource_thread.rs
+++ b/components/net/resource_thread.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! A thread that takes a URL and streams back the binary data.
-use connector::{create_http_connector, create_ssl_client};
+use connector::{create_http_client, create_ssl_connector_builder};
use cookie;
use cookie_rs;
use cookie_storage::CookieStorage;
@@ -15,7 +15,7 @@ use fetch::methods::{CancellationListener, FetchContext, fetch};
use filemanager_thread::FileManager;
use hsts::HstsList;
use http_cache::HttpCache;
-use http_loader::{HttpState, http_redirect_fetch};
+use http_loader::{HANDLE, HttpState, http_redirect_fetch};
use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
@@ -129,18 +129,17 @@ fn create_http_states(config_dir: Option<&Path>) -> (Arc<HttpState>, Arc<HttpSta
},
};
- let ssl_client = create_ssl_client(&certs);
+ let ssl_connector_builder = create_ssl_connector_builder(&certs);
let http_state = HttpState {
cookie_jar: RwLock::new(cookie_jar),
auth_cache: RwLock::new(auth_cache),
http_cache: RwLock::new(http_cache),
hsts_list: RwLock::new(hsts_list),
history_states: RwLock::new(HashMap::new()),
- ssl_client: ssl_client.clone(),
- connector: create_http_connector(ssl_client),
+ client: create_http_client(ssl_connector_builder, HANDLE.lock().unwrap().executor()),
};
- let private_ssl_client = create_ssl_client(&certs);
+ let private_ssl_client = create_ssl_connector_builder(&certs);
let private_http_state = HttpState::new(private_ssl_client);
(Arc::new(http_state), Arc::new(private_http_state))
diff --git a/components/net/subresource_integrity.rs b/components/net/subresource_integrity.rs
index 5088cc114b2..e0a7168de97 100644
--- a/components/net/subresource_integrity.rs
+++ b/components/net/subresource_integrity.rs
@@ -4,10 +4,11 @@
use base64;
use net_traits::response::{Response, ResponseBody, ResponseType};
-use openssl::hash::{MessageDigest, hash2};
+use openssl::hash::{MessageDigest, hash};
use std::iter::Filter;
use std::str::Split;
use std::sync::MutexGuard;
+
const SUPPORTED_ALGORITHM: &'static [&'static str] = &[
"sha256",
"sha384",
@@ -119,7 +120,7 @@ fn apply_algorithm_to_response(body: MutexGuard<ResponseBody>,
message_digest: MessageDigest)
-> String {
if let ResponseBody::Done(ref vec) = *body {
- let response_digest = hash2(message_digest, vec).unwrap(); //Now hash2
+ let response_digest = hash(message_digest, vec).unwrap(); //Now hash
base64::encode(&response_digest)
} else {
unreachable!("Tried to calculate digest of incomplete response body")
diff --git a/components/net/tests/cookie.rs b/components/net/tests/cookie.rs
index 68149736680..3702f93fee2 100644
--- a/components/net/tests/cookie.rs
+++ b/components/net/tests/cookie.rs
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cookie_rs;
-use hyper::header::{Header, SetCookie};
use net::cookie::Cookie;
use net::cookie_storage::CookieStorage;
use net_traits::CookieSource;
@@ -90,7 +89,7 @@ fn fn_cookie_constructor() {
let cookie = Cookie::new_wrapped(cookie, url, CookieSource::HTTP).unwrap();
assert_eq!(cookie.cookie.value(), "bar");
assert_eq!(cookie.cookie.name(), "baz");
- assert!(cookie.cookie.secure());
+ assert!(cookie.cookie.secure().unwrap_or(false));
assert_eq!(&cookie.cookie.path().as_ref().unwrap()[..], "/foo/bar/");
assert_eq!(&cookie.cookie.domain().as_ref().unwrap()[..], "example.com");
assert!(cookie.host_only);
@@ -324,13 +323,8 @@ fn add_retrieve_cookies(set_location: &str,
// Add all cookies to the store
for str_cookie in set_cookies {
- let bytes = str_cookie.to_string().into_bytes();
- let header = Header::parse_header(&[bytes]).unwrap();
- let SetCookie(cookies) = header;
- for bare_cookie in cookies {
- let cookie = Cookie::from_cookie_string(bare_cookie, &url, source).unwrap();
- storage.push(cookie, &url, source);
- }
+ let cookie = Cookie::from_cookie_string(str_cookie.to_owned(), &url, source).unwrap();
+ storage.push(cookie, &url, source);
}
// Get cookies for the test location
diff --git a/components/net/tests/cookie_http_state.rs b/components/net/tests/cookie_http_state.rs
index 30cec8b26b2..ab310f6a35e 100644
--- a/components/net/tests/cookie_http_state.rs
+++ b/components/net/tests/cookie_http_state.rs
@@ -2,13 +2,11 @@
* 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/. */
-use hyper::header::{Header, SetCookie};
use net::cookie::Cookie;
use net::cookie_storage::CookieStorage;
use net_traits::CookieSource;
use servo_url::ServoUrl;
-
fn run(set_location: &str, set_cookies: &[&str], final_location: &str) -> String {
let mut storage = CookieStorage::new(150);
let url = ServoUrl::parse(set_location).unwrap();
@@ -16,14 +14,8 @@ fn run(set_location: &str, set_cookies: &[&str], final_location: &str) -> String
// Add all cookies to the store
for str_cookie in set_cookies {
- let bytes = str_cookie.to_string().into_bytes();
- let header = Header::parse_header(&[bytes]);
- if let Ok(SetCookie(cookies)) = header {
- for bare_cookie in cookies {
- if let Some(cookie) = Cookie::from_cookie_string(bare_cookie, &url, source) {
- storage.push(cookie, &url, source);
- }
- }
+ if let Some(cookie) = Cookie::from_cookie_string(str_cookie.to_owned().into(), &url, source) {
+ storage.push(cookie, &url, source);
}
}
diff --git a/components/net/tests/data_loader.rs b/components/net/tests/data_loader.rs
index 4ad73dee080..56b70af9e99 100644
--- a/components/net/tests/data_loader.rs
+++ b/components/net/tests/data_loader.rs
@@ -3,9 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use fetch;
-use hyper::header::ContentType;
-use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value};
+use headers_core::HeaderMapExt;
+use headers_ext::ContentType;
use hyper_serde::Serde;
+use mime::{self, Mime};
use net_traits::{FetchMetadata, FilteredMetadata, NetworkError};
use net_traits::request::{Origin, Request};
use net_traits::response::ResponseBody;
@@ -28,8 +29,8 @@ fn assert_parse(url: &'static str,
assert!(!response.is_network_error());
assert_eq!(response.headers.len(), 1);
- let header_content_type = response.headers.get::<ContentType>();
- assert_eq!(header_content_type, content_type.as_ref());
+ let header_content_type = response.headers.typed_get::<ContentType>();
+ assert_eq!(header_content_type, content_type);
let metadata = match response.metadata() {
Ok(FetchMetadata::Filtered { filtered: FilteredMetadata::Basic(m), .. }) => m,
@@ -62,9 +63,8 @@ fn empty_invalid() {
fn plain() {
assert_parse(
"data:,hello%20world",
- Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain,
- vec!((Attr::Charset, Value::Ext("US-ASCII".to_owned())))))),
- Some("US-ASCII"),
+ Some(ContentType::from("text/plain; charset=US-ASCII".parse::<Mime>().unwrap())),
+ Some("us-ascii"),
Some(b"hello world"));
}
@@ -72,7 +72,7 @@ fn plain() {
fn plain_ct() {
assert_parse(
"data:text/plain,hello",
- Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec!()))),
+ Some(ContentType::from(mime::TEXT_PLAIN)),
None,
Some(b"hello"));
}
@@ -81,7 +81,7 @@ fn plain_ct() {
fn plain_html() {
assert_parse(
"data:text/html,<p>Servo</p>",
- Some(ContentType(Mime(TopLevel::Text, SubLevel::Html, vec!()))),
+ Some(ContentType::from(mime::TEXT_HTML)),
None,
Some(b"<p>Servo</p>"));
}
@@ -90,9 +90,7 @@ fn plain_html() {
fn plain_charset() {
assert_parse(
"data:text/plain;charset=latin1,hello",
- Some(ContentType(Mime(TopLevel::Text,
- SubLevel::Plain,
- vec!((Attr::Charset, Value::Ext("latin1".to_owned())))))),
+ Some(ContentType::from("text/plain; charset=latin1".parse::<Mime>().unwrap())),
Some("latin1"),
Some(b"hello"));
}
@@ -101,9 +99,7 @@ fn plain_charset() {
fn plain_only_charset() {
assert_parse(
"data:;charset=utf-8,hello",
- Some(ContentType(Mime(TopLevel::Text,
- SubLevel::Plain,
- vec!((Attr::Charset, Value::Utf8))))),
+ Some(ContentType::from(mime::TEXT_PLAIN_UTF_8)),
Some("utf-8"),
Some(b"hello"));
}
@@ -112,10 +108,8 @@ fn plain_only_charset() {
fn base64() {
assert_parse(
"data:;base64,C62+7w==",
- Some(ContentType(Mime(TopLevel::Text,
- SubLevel::Plain,
- vec!((Attr::Charset, Value::Ext("US-ASCII".to_owned())))))),
- Some("US-ASCII"),
+ Some(ContentType::from("text/plain; charset=US-ASCII".parse::<Mime>().unwrap())),
+ Some("us-ascii"),
Some(&[0x0B, 0xAD, 0xBE, 0xEF]));
}
@@ -123,7 +117,7 @@ fn base64() {
fn base64_ct() {
assert_parse(
"data:application/octet-stream;base64,C62+7w==",
- Some(ContentType(Mime(TopLevel::Application, SubLevel::Ext("octet-stream".to_owned()), vec!()))),
+ Some(ContentType::from(mime::APPLICATION_OCTET_STREAM)),
None,
Some(&[0x0B, 0xAD, 0xBE, 0xEF]));
}
@@ -132,8 +126,7 @@ fn base64_ct() {
fn base64_charset() {
assert_parse(
"data:text/plain;charset=koi8-r;base64,8PLl9+XkIO3l5Pfl5A==",
- Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain,
- vec!((Attr::Charset, Value::Ext("koi8-r".to_owned())))))),
+ Some(ContentType::from("text/plain; charset=koi8-r".parse::<Mime>().unwrap())),
Some("koi8-r"),
Some(&[0xF0, 0xF2, 0xE5, 0xF7, 0xE5, 0xE4, 0x20, 0xED, 0xE5, 0xE4, 0xF7, 0xE5, 0xE4]));
}
diff --git a/components/net/tests/fetch.rs b/components/net/tests/fetch.rs
index 2e33727e37f..d0d472614f9 100644
--- a/components/net/tests/fetch.rs
+++ b/components/net/tests/fetch.rs
@@ -2,27 +2,24 @@
* 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/. */
-use {DEFAULT_USER_AGENT, new_fetch_context, create_embedder_proxy, fetch, make_server};
+use {DEFAULT_USER_AGENT, new_fetch_context, create_embedder_proxy, fetch, make_server, make_ssl_server};
use devtools_traits::HttpRequest as DevtoolsHttpRequest;
use devtools_traits::HttpResponse as DevtoolsHttpResponse;
use fetch_with_context;
use fetch_with_cors_cache;
+use headers_core::HeaderMapExt;
+use headers_ext::{AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowOrigin};
+use headers_ext::{AccessControlAllowMethods, AccessControlMaxAge};
+use headers_ext::{CacheControl, ContentLength, ContentType, Expires, Host, LastModified, Pragma, UserAgent};
+use http::{Method, StatusCode};
+use http::header::{self, HeaderMap, HeaderName, HeaderValue};
+use http::uri::Authority;
use http_loader::{expect_devtools_http_request, expect_devtools_http_response};
-use hyper::LanguageTag;
-use hyper::header::{Accept, AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowOrigin};
-use hyper::header::{AcceptEncoding, AcceptLanguage, AccessControlAllowMethods, AccessControlMaxAge};
-use hyper::header::{AccessControlRequestHeaders, AccessControlRequestMethod, Date, UserAgent};
-use hyper::header::{CacheControl, ContentLanguage, ContentLength, ContentType, Expires, LastModified};
-use hyper::header::{Encoding, Location, Pragma, Quality, QualityItem, SetCookie, qitem};
-use hyper::header::{Headers, Host, HttpDate, Referer as HyperReferer};
-use hyper::method::Method;
-use hyper::mime::{Mime, SubLevel, TopLevel};
-use hyper::server::{Request as HyperRequest, Response as HyperResponse, Server};
-use hyper::status::StatusCode;
-use hyper::uri::RequestUri;
-use hyper_openssl;
+use hyper::{Request as HyperRequest, Response as HyperResponse};
+use hyper::body::Body;
+use mime::{self, Mime};
use msg::constellation_msg::TEST_PIPELINE_ID;
-use net::connector::create_ssl_client;
+use net::connector::create_ssl_connector_builder;
use net::fetch::cors_cache::CorsCache;
use net::fetch::methods::{CancellationListener, FetchContext};
use net::filemanager_thread::FileManager;
@@ -37,21 +34,21 @@ use servo_channel::{channel, Sender};
use servo_url::{ImmutableOrigin, ServoUrl};
use std::fs::File;
use std::io::Read;
+use std::iter::FromIterator;
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicUsize, Ordering};
-use time::{self, Duration};
-use unicase::UniCase;
+use std::time::{SystemTime, Duration};
// TODO write a struct that impls Handler for storing test values
#[test]
fn test_fetch_response_is_not_network_error() {
static MESSAGE: &'static [u8] = b"";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -79,10 +76,10 @@ fn test_fetch_on_bad_port_is_network_error() {
#[test]
fn test_fetch_response_body_matches_const_message() {
static MESSAGE: &'static [u8] = b"Hello World!";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -142,11 +139,11 @@ fn test_fetch_blob() {
assert_eq!(fetch_response.headers.len(), 2);
- let content_type: &ContentType = fetch_response.headers.get().unwrap();
- assert_eq!(**content_type, Mime(TopLevel::Text, SubLevel::Plain, vec![]));
+ let content_type: Mime = fetch_response.headers.typed_get::<ContentType>().unwrap().into();
+ assert_eq!(content_type, mime::TEXT_PLAIN);
- let content_length: &ContentLength = fetch_response.headers.get().unwrap();
- assert_eq!(**content_length, bytes.len() as u64);
+ let content_length: ContentLength = fetch_response.headers.typed_get().unwrap();
+ assert_eq!(content_length.0, bytes.len() as u64);
assert_eq!(*fetch_response.body.lock().unwrap(),
ResponseBody::Done(bytes.to_vec()));
@@ -162,8 +159,8 @@ fn test_fetch_file() {
let fetch_response = fetch(&mut request, None);
assert!(!fetch_response.is_network_error());
assert_eq!(fetch_response.headers.len(), 1);
- let content_type: &ContentType = fetch_response.headers.get().unwrap();
- assert_eq!(**content_type, Mime(TopLevel::Text, SubLevel::Css, vec![]));
+ let content_type: Mime = fetch_response.headers.typed_get::<ContentType>().unwrap().into();
+ assert_eq!(content_type, mime::TEXT_CSS);
let resp_body = fetch_response.body.lock().unwrap();
let mut file = File::open(path).unwrap();
@@ -202,20 +199,20 @@ fn test_fetch_bogus_scheme() {
fn test_cors_preflight_fetch() {
static ACK: &'static [u8] = b"ACK";
let state = Arc::new(AtomicUsize::new(0));
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- if request.method == Method::Options && state.clone().fetch_add(1, Ordering::SeqCst) == 0 {
- assert!(request.headers.has::<AccessControlRequestMethod>());
- assert!(!request.headers.has::<AccessControlRequestHeaders>());
- assert!(!request.headers.get::<HyperReferer>().unwrap().contains("a.html"));
- response.headers_mut().set(AccessControlAllowOrigin::Any);
- response.headers_mut().set(AccessControlAllowCredentials);
- response.headers_mut().set(AccessControlAllowMethods(vec![Method::Get]));
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ if request.method() == Method::OPTIONS && state.clone().fetch_add(1, Ordering::SeqCst) == 0 {
+ assert!(request.headers().contains_key(header::ACCESS_CONTROL_REQUEST_METHOD));
+ assert!(!request.headers().contains_key(header::ACCESS_CONTROL_REQUEST_HEADERS));
+ assert!(!request.headers().get(header::REFERER).unwrap().to_str().unwrap().contains("a.html"));
+ response.headers_mut().typed_insert(AccessControlAllowOrigin::ANY);
+ response.headers_mut().typed_insert(AccessControlAllowCredentials);
+ response.headers_mut().typed_insert(AccessControlAllowMethods::from_iter(vec![Method::GET]));
} else {
- response.headers_mut().set(AccessControlAllowOrigin::Any);
- response.send(ACK).unwrap();
+ response.headers_mut().typed_insert(AccessControlAllowOrigin::ANY);
+ *response.body_mut() = ACK.to_vec().into();
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let target_url = url.clone().join("a.html").unwrap();
@@ -241,20 +238,20 @@ fn test_cors_preflight_cache_fetch() {
let state = Arc::new(AtomicUsize::new(0));
let counter = state.clone();
let mut cache = CorsCache::new();
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- if request.method == Method::Options && state.clone().fetch_add(1, Ordering::SeqCst) == 0 {
- assert!(request.headers.has::<AccessControlRequestMethod>());
- assert!(!request.headers.has::<AccessControlRequestHeaders>());
- response.headers_mut().set(AccessControlAllowOrigin::Any);
- response.headers_mut().set(AccessControlAllowCredentials);
- response.headers_mut().set(AccessControlAllowMethods(vec![Method::Get]));
- response.headers_mut().set(AccessControlMaxAge(6000));
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ if request.method() == Method::OPTIONS && state.clone().fetch_add(1, Ordering::SeqCst) == 0 {
+ assert!(request.headers().contains_key(header::ACCESS_CONTROL_REQUEST_METHOD));
+ assert!(!request.headers().contains_key(header::ACCESS_CONTROL_REQUEST_HEADERS));
+ response.headers_mut().typed_insert(AccessControlAllowOrigin::ANY);
+ response.headers_mut().typed_insert(AccessControlAllowCredentials);
+ response.headers_mut().typed_insert(AccessControlAllowMethods::from_iter(vec![Method::GET]));
+ response.headers_mut().typed_insert(AccessControlMaxAge::from(Duration::new(6000, 0)));
} else {
- response.headers_mut().set(AccessControlAllowOrigin::Any);
- response.send(ACK).unwrap();
+ response.headers_mut().typed_insert(AccessControlAllowOrigin::ANY);
+ *response.body_mut() = ACK.to_vec().into();
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(ImmutableOrigin::new_opaque());
let mut request = Request::new(url.clone(), Some(origin.clone()), None);
@@ -274,8 +271,8 @@ fn test_cors_preflight_cache_fetch() {
assert_eq!(1, counter.load(Ordering::SeqCst));
// The entry exists in the CORS-preflight cache
- assert_eq!(true, cache.match_method(&wrapped_request0, Method::Get));
- assert_eq!(true, cache.match_method(&wrapped_request1, Method::Get));
+ assert_eq!(true, cache.match_method(&wrapped_request0, Method::GET));
+ assert_eq!(true, cache.match_method(&wrapped_request1, Method::GET));
match *fetch_response0.body.lock().unwrap() {
ResponseBody::Done(ref body) => assert_eq!(&**body, ACK),
@@ -291,23 +288,23 @@ fn test_cors_preflight_cache_fetch() {
fn test_cors_preflight_fetch_network_error() {
static ACK: &'static [u8] = b"ACK";
let state = Arc::new(AtomicUsize::new(0));
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- if request.method == Method::Options && state.clone().fetch_add(1, Ordering::SeqCst) == 0 {
- assert!(request.headers.has::<AccessControlRequestMethod>());
- assert!(!request.headers.has::<AccessControlRequestHeaders>());
- response.headers_mut().set(AccessControlAllowOrigin::Any);
- response.headers_mut().set(AccessControlAllowCredentials);
- response.headers_mut().set(AccessControlAllowMethods(vec![Method::Get]));
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ if request.method() == Method::OPTIONS && state.clone().fetch_add(1, Ordering::SeqCst) == 0 {
+ assert!(request.headers().contains_key(header::ACCESS_CONTROL_REQUEST_METHOD));
+ assert!(!request.headers().contains_key(header::ACCESS_CONTROL_REQUEST_HEADERS));
+ response.headers_mut().typed_insert(AccessControlAllowOrigin::ANY);
+ response.headers_mut().typed_insert(AccessControlAllowCredentials);
+ response.headers_mut().typed_insert(AccessControlAllowMethods::from_iter(vec![Method::GET]));
} else {
- response.headers_mut().set(AccessControlAllowOrigin::Any);
- response.send(ACK).unwrap();
+ response.headers_mut().typed_insert(AccessControlAllowOrigin::ANY);
+ *response.body_mut() = ACK.to_vec().into();
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(ImmutableOrigin::new_opaque());
let mut request = Request::new(url, Some(origin), None);
- request.method = Method::Extension("CHICKEN".to_owned());
+ request.method = Method::from_bytes(b"CHICKEN").unwrap();
request.referrer = Referrer::NoReferrer;
request.use_cors_preflight = true;
request.mode = RequestMode::CorsMode;
@@ -320,14 +317,17 @@ fn test_cors_preflight_fetch_network_error() {
#[test]
fn test_fetch_response_is_basic_filtered() {
static MESSAGE: &'static [u8] = b"";
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(SetCookie(vec![]));
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::SET_COOKIE, HeaderValue::from_static(""));
// this header is obsoleted, so hyper doesn't implement it, but it's still covered by the spec
- response.headers_mut().set_raw("Set-Cookie2", vec![]);
+ response.headers_mut().insert(
+ HeaderName::from_static("set-cookie2"),
+ HeaderValue::from_bytes(&vec![]).unwrap()
+ );
- response.send(MESSAGE).unwrap();
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -339,39 +339,42 @@ fn test_fetch_response_is_basic_filtered() {
assert_eq!(fetch_response.response_type, ResponseType::Basic);
let headers = fetch_response.headers;
- assert!(!headers.has::<SetCookie>());
- assert!(headers.get_raw("Set-Cookie2").is_none());
+ assert!(!headers.contains_key(header::SET_COOKIE));
+ assert!(headers.get(HeaderName::from_static("set-cookie2")).is_none());
}
#[test]
fn test_fetch_response_is_cors_filtered() {
static MESSAGE: &'static [u8] = b"";
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
// this is mandatory for the Cors Check to pass
// TODO test using different url encodings with this value ie. punycode
- response.headers_mut().set(AccessControlAllowOrigin::Any);
+ response.headers_mut().typed_insert(AccessControlAllowOrigin::ANY);
// these are the headers that should be kept after filtering
- response.headers_mut().set(CacheControl(vec![]));
- response.headers_mut().set(ContentLanguage(vec![]));
- response.headers_mut().set(ContentType::html());
- response.headers_mut().set(Expires(HttpDate(time::now() + Duration::days(1))));
- response.headers_mut().set(LastModified(HttpDate(time::now())));
- response.headers_mut().set(Pragma::NoCache);
+ response.headers_mut().typed_insert(CacheControl::new());
+ response.headers_mut().insert(header::CONTENT_LANGUAGE, HeaderValue::from_bytes(&vec![]).unwrap());
+ response.headers_mut().typed_insert(ContentType::from(mime::TEXT_HTML));
+ response.headers_mut().typed_insert(Expires::from(SystemTime::now() + Duration::new(86400, 0)));
+ response.headers_mut().typed_insert(LastModified::from(SystemTime::now()));
+ response.headers_mut().typed_insert(Pragma::no_cache());
// these headers should not be kept after filtering, even though they are given a pass
- response.headers_mut().set(SetCookie(vec![]));
- response.headers_mut().set_raw("Set-Cookie2", vec![]);
- response.headers_mut().set(
- AccessControlAllowHeaders(vec![
- UniCase("set-cookie".to_owned()),
- UniCase("set-cookie2".to_owned())
+ response.headers_mut().insert(header::SET_COOKIE, HeaderValue::from_static(""));
+ response.headers_mut().insert(
+ HeaderName::from_static("set-cookie2"),
+ HeaderValue::from_bytes(&vec![]).unwrap()
+ );
+ response.headers_mut().typed_insert(
+ AccessControlAllowHeaders::from_iter(vec![
+ HeaderName::from_static("set-cookie"),
+ HeaderName::from_static("set-cookie2")
])
);
- response.send(MESSAGE).unwrap();
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
// an origin mis-match will stop it from defaulting to a basic filtered response
let origin = Origin::Origin(ImmutableOrigin::new_opaque());
@@ -385,25 +388,25 @@ fn test_fetch_response_is_cors_filtered() {
assert_eq!(fetch_response.response_type, ResponseType::Cors);
let headers = fetch_response.headers;
- assert!(headers.has::<CacheControl>());
- assert!(headers.has::<ContentLanguage>());
- assert!(headers.has::<ContentType>());
- assert!(headers.has::<Expires>());
- assert!(headers.has::<LastModified>());
- assert!(headers.has::<Pragma>());
-
- assert!(!headers.has::<AccessControlAllowOrigin>());
- assert!(!headers.has::<SetCookie>());
- assert!(headers.get_raw("Set-Cookie2").is_none());
+ assert!(headers.contains_key(header::CACHE_CONTROL));
+ assert!(headers.contains_key(header::CONTENT_LANGUAGE));
+ assert!(headers.contains_key(header::CONTENT_TYPE));
+ assert!(headers.contains_key(header::EXPIRES));
+ assert!(headers.contains_key(header::LAST_MODIFIED));
+ assert!(headers.contains_key(header::PRAGMA));
+
+ assert!(!headers.contains_key(header::ACCESS_CONTROL_ALLOW_ORIGIN));
+ assert!(!headers.contains_key(header::SET_COOKIE));
+ assert!(headers.get(HeaderName::from_static("set-cookie2")).is_none());
}
#[test]
fn test_fetch_response_is_opaque_filtered() {
static MESSAGE: &'static [u8] = b"";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
// an origin mis-match will fall through to an Opaque filtered response
let origin = Origin::Origin(ImmutableOrigin::new_opaque());
@@ -419,7 +422,7 @@ fn test_fetch_response_is_opaque_filtered() {
assert!(fetch_response.url_list.is_empty());
// this also asserts that status message is "the empty byte sequence"
assert!(fetch_response.status.is_none());
- assert_eq!(fetch_response.headers, Headers::new());
+ assert_eq!(fetch_response.headers, HeaderMap::new());
match *fetch_response.body.lock().unwrap() {
ResponseBody::Empty => { },
_ => panic!()
@@ -433,25 +436,18 @@ fn test_fetch_response_is_opaque_filtered() {
#[test]
fn test_fetch_response_is_opaque_redirect_filtered() {
static MESSAGE: &'static [u8] = b"";
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- let redirects = match request.uri {
- RequestUri::AbsolutePath(url) =>
- url.split("/").collect::<String>().parse::<u32>().unwrap_or(0),
- RequestUri::AbsoluteUri(url) =>
- url.path_segments().unwrap().next_back().unwrap().parse::<u32>().unwrap_or(0),
- _ => panic!()
- };
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ let redirects = request.uri().path().split("/").collect::<String>().parse::<u32>().unwrap_or(0);
if redirects == 1 {
- response.send(MESSAGE).unwrap();
+ *response.body_mut() = MESSAGE.to_vec().into();
} else {
- *response.status_mut() = StatusCode::Found;
- let url = format!("{}", 1);
- response.headers_mut().set(Location(url.to_owned()));
+ *response.status_mut() = StatusCode::FOUND;
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_static("1"));
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -465,7 +461,7 @@ fn test_fetch_response_is_opaque_redirect_filtered() {
// this also asserts that status message is "the empty byte sequence"
assert!(fetch_response.status.is_none());
- assert_eq!(fetch_response.headers, Headers::new());
+ assert_eq!(fetch_response.headers, HeaderMap::new());
match *fetch_response.body.lock().unwrap() {
ResponseBody::Empty => { },
_ => panic!()
@@ -481,10 +477,10 @@ fn test_fetch_with_local_urls_only() {
// If flag `local_urls_only` is set, fetching a non-local URL must result in network error.
static MESSAGE: &'static [u8] = b"";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, server_url) = make_server(handler);
+ let (server, server_url) = make_server(handler);
let do_fetch = |url: ServoUrl| {
let origin = Origin::Origin(url.origin());
@@ -506,7 +502,6 @@ fn test_fetch_with_local_urls_only() {
assert!(!local_response.is_network_error());
assert!(server_response.is_network_error());
}
-
// NOTE(emilio): If this test starts failing:
//
// openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
@@ -517,22 +512,17 @@ fn test_fetch_with_local_urls_only() {
#[test]
fn test_fetch_with_hsts() {
static MESSAGE: &'static [u8] = b"";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
let cert_path = Path::new("../../resources/self_signed_certificate_for_testing.crt").canonicalize().unwrap();
let key_path = Path::new("../../resources/privatekey_for_testing.key").canonicalize().unwrap();
-
- let ssl = hyper_openssl::OpensslServer::from_files(key_path, cert_path.clone())
- .unwrap();
-
- //takes an address and something that implements hyper::net::Ssl
- let mut server = Server::https("0.0.0.0:0", ssl).unwrap().handle_threads(handler, 1).unwrap();
+ let (server, url) = make_ssl_server(handler, cert_path.clone(), key_path.clone());
let mut ca_content = String::new();
File::open(cert_path).unwrap().read_to_string(&mut ca_content).unwrap();
- let ssl_client = create_ssl_client(&ca_content);
+ let ssl_client = create_ssl_connector_builder(&ca_content);
let context = FetchContext {
state: Arc::new(HttpState::new(ssl_client)),
@@ -547,15 +537,13 @@ fn test_fetch_with_hsts() {
list.push(HstsEntry::new("localhost".to_owned(), IncludeSubdomains::NotIncluded, None)
.unwrap());
}
- let url_string = format!("http://localhost:{}", server.socket.port());
- let url = ServoUrl::parse(&url_string).unwrap();
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
request.referrer = Referrer::NoReferrer;
// Set the flag.
request.local_urls_only = false;
let response = fetch_with_context(&mut request, &context);
- let _ = server.close();
+ server.close();
assert_eq!(response.internal_response.unwrap().url().unwrap().scheme(),
"https");
}
@@ -563,10 +551,10 @@ fn test_fetch_with_hsts() {
#[test]
fn test_fetch_with_sri_network_error() {
static MESSAGE: &'static [u8] = b"alert('Hello, Network Error');";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -587,10 +575,10 @@ fn test_fetch_with_sri_network_error() {
#[test]
fn test_fetch_with_sri_sucess() {
static MESSAGE: &'static [u8] = b"alert('Hello, world.');";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -616,20 +604,20 @@ fn test_fetch_blocked_nosniff() {
mime: Mime,
should_error: bool) {
const MESSAGE: &'static [u8] = b"";
- const HEADER: &'static str = "X-Content-Type-Options";
+ const HEADER: &'static str = "x-content-type-options";
const VALUE: &'static [u8] = b"nosniff";
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- let mime_header = ContentType(mime.clone());
- response.headers_mut().set(mime_header);
- assert!(response.headers().has::<ContentType>());
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ let mime_header = ContentType::from(mime.clone());
+ response.headers_mut().typed_insert(mime_header);
+ assert!(response.headers().contains_key(header::CONTENT_TYPE));
// Add the nosniff header
- response.headers_mut().set_raw(HEADER, vec![VALUE.to_vec()]);
+ response.headers_mut().insert(HeaderName::from_static(HEADER), HeaderValue::from_bytes(VALUE).unwrap());
- response.send(MESSAGE).unwrap();
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -641,9 +629,9 @@ fn test_fetch_blocked_nosniff() {
}
let tests = vec![
- (Destination::Script, Mime(TopLevel::Text, SubLevel::Javascript, vec![]), false),
- (Destination::Script, Mime(TopLevel::Text, SubLevel::Css, vec![]), true),
- (Destination::Style, Mime(TopLevel::Text, SubLevel::Css, vec![]), false),
+ (Destination::Script, mime::TEXT_JAVASCRIPT, false),
+ (Destination::Script, mime::TEXT_CSS, true),
+ (Destination::Style, mime::TEXT_CSS, false),
];
for test in tests {
@@ -653,25 +641,19 @@ fn test_fetch_blocked_nosniff() {
}
fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response {
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- let redirects = match request.uri {
- RequestUri::AbsolutePath(url) =>
- url.split("/").collect::<String>().parse::<u32>().unwrap_or(0),
- RequestUri::AbsoluteUri(url) =>
- url.path_segments().unwrap().next_back().unwrap().parse::<u32>().unwrap_or(0),
- _ => panic!()
- };
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ let redirects = request.uri().path().split("/").collect::<String>().parse::<u32>().unwrap_or(0);
if redirects >= redirect_cap {
- response.send(message).unwrap();
+ *response.body_mut() = message.to_vec().into();
} else {
- *response.status_mut() = StatusCode::Found;
+ *response.status_mut() = StatusCode::FOUND;
let url = format!("{redirects}", redirects = redirects + 1);
- response.headers_mut().set(Location(url.to_owned()));
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&url).unwrap());
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -720,30 +702,24 @@ fn test_fetch_redirect_updates_method_runner(tx: Sender<bool>, status_code: Stat
let handler_method = method.clone();
let handler_tx = Arc::new(Mutex::new(tx));
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- let redirects = match request.uri {
- RequestUri::AbsolutePath(url) =>
- url.split("/").collect::<String>().parse::<u32>().unwrap_or(0),
- RequestUri::AbsoluteUri(url) =>
- url.path_segments().unwrap().next_back().unwrap().parse::<u32>().unwrap_or(0),
- _ => panic!()
- };
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ let redirects = request.uri().path().split("/").collect::<String>().parse::<u32>().unwrap_or(0);
let mut test_pass = true;
if redirects == 0 {
- *response.status_mut() = StatusCode::TemporaryRedirect;
- response.headers_mut().set(Location("1".to_owned()));
+ *response.status_mut() = StatusCode::TEMPORARY_REDIRECT;
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_static("1"));
} else if redirects == 1 {
// this makes sure that the request method does't change from the wrong status code
- if handler_method != Method::Get && request.method == Method::Get {
+ if handler_method != Method::GET && request.method() == Method::GET {
test_pass = false;
}
*response.status_mut() = status_code;
- response.headers_mut().set(Location("2".to_owned()));
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_static("2"));
- } else if request.method != Method::Get {
+ } else if request.method() != Method::GET {
test_pass = false;
}
@@ -754,7 +730,7 @@ fn test_fetch_redirect_updates_method_runner(tx: Sender<bool>, status_code: Stat
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -769,36 +745,36 @@ fn test_fetch_redirect_updates_method_runner(tx: Sender<bool>, status_code: Stat
fn test_fetch_redirect_updates_method() {
let (tx, rx) = channel();
- test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::MovedPermanently, Method::Post);
+ test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::MOVED_PERMANENTLY, Method::POST);
assert_eq!(rx.recv().unwrap(), true);
assert_eq!(rx.recv().unwrap(), true);
// make sure the test doesn't send more data than expected
assert_eq!(rx.try_recv().is_none(), true);
- test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::Found, Method::Post);
+ test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::FOUND, Method::POST);
assert_eq!(rx.recv().unwrap(), true);
assert_eq!(rx.recv().unwrap(), true);
assert_eq!(rx.try_recv().is_none(), true);
- test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::SeeOther, Method::Get);
+ test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::SEE_OTHER, Method::GET);
assert_eq!(rx.recv().unwrap(), true);
assert_eq!(rx.recv().unwrap(), true);
assert_eq!(rx.try_recv().is_none(), true);
- let extension = Method::Extension("FOO".to_owned());
+ let extension = Method::from_bytes(b"FOO").unwrap();
- test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::MovedPermanently, extension.clone());
+ test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::MOVED_PERMANENTLY, extension.clone());
assert_eq!(rx.recv().unwrap(), true);
// for MovedPermanently and Found, Method should only be changed if it was Post
assert_eq!(rx.recv().unwrap(), false);
assert_eq!(rx.try_recv().is_none(), true);
- test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::Found, extension.clone());
+ test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::FOUND, extension.clone());
assert_eq!(rx.recv().unwrap(), true);
assert_eq!(rx.recv().unwrap(), false);
assert_eq!(rx.try_recv().is_none(), true);
- test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::SeeOther, extension.clone());
+ test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::SEE_OTHER, extension.clone());
assert_eq!(rx.recv().unwrap(), true);
// for SeeOther, Method should always be changed, so this should be true
assert_eq!(rx.recv().unwrap(), true);
@@ -826,10 +802,10 @@ fn response_is_done(response: &Response) -> bool {
#[test]
fn test_fetch_async_returns_complete_response() {
static MESSAGE: &'static [u8] = b"this message should be retrieved in full";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -844,10 +820,10 @@ fn test_fetch_async_returns_complete_response() {
#[test]
fn test_opaque_filtered_fetch_async_returns_complete_response() {
static MESSAGE: &'static [u8] = b"";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
// an origin mis-match will fall through to an Opaque filtered response
let origin = Origin::Origin(ImmutableOrigin::new_opaque());
@@ -865,25 +841,18 @@ fn test_opaque_filtered_fetch_async_returns_complete_response() {
#[test]
fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() {
static MESSAGE: &'static [u8] = b"";
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- let redirects = match request.uri {
- RequestUri::AbsolutePath(url) =>
- url.split("/").collect::<String>().parse::<u32>().unwrap_or(0),
- RequestUri::AbsoluteUri(url) =>
- url.path_segments().unwrap().last().unwrap().parse::<u32>().unwrap_or(0),
- _ => panic!()
- };
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ let redirects = request.uri().path().split("/").collect::<String>().parse::<u32>().unwrap_or(0);
if redirects == 1 {
- response.send(MESSAGE).unwrap();
+ *response.body_mut() = MESSAGE.to_vec().into();
} else {
- *response.status_mut() = StatusCode::Found;
- let url = format!("{}", 1);
- response.headers_mut().set(Location(url.to_owned()));
+ *response.status_mut() = StatusCode::FOUND;
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_static("1"));
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), None);
@@ -901,11 +870,11 @@ fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() {
#[test]
fn test_fetch_with_devtools() {
static MESSAGE: &'static [u8] = b"Yay!";
- let handler = move |_: HyperRequest, response: HyperResponse| {
- response.send(MESSAGE).unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.body_mut() = MESSAGE.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url.clone(), Some(origin), Some(TEST_PIPELINE_ID));
@@ -921,36 +890,23 @@ fn test_fetch_with_devtools() {
let mut devhttpresponse = expect_devtools_http_response(&devtools_port);
//Creating default headers for request
- let mut headers = Headers::new();
-
- headers.set(AcceptEncoding(vec![
- qitem(Encoding::Gzip),
- qitem(Encoding::Deflate),
- qitem(Encoding::EncodingExt("br".to_owned()))
- ]));
+ let mut headers = HeaderMap::new();
- headers.set(Host { hostname: url.host_str().unwrap().to_owned() , port: url.port().to_owned() });
+ headers.insert(header::ACCEPT_ENCODING, HeaderValue::from_static("gzip, deflate, br"));
+ headers.typed_insert(
+ Host::from(format!("{}:{}", url.host_str().unwrap(), url.port().unwrap()).parse::<Authority>().unwrap()));
- let accept = Accept(vec![qitem(Mime(TopLevel::Star, SubLevel::Star, vec![]))]);
- headers.set(accept);
+ headers.insert(header::ACCEPT, HeaderValue::from_static("*/*"));
- let mut en_us: LanguageTag = Default::default();
- en_us.language = Some("en".to_owned());
- en_us.region = Some("US".to_owned());
- let mut en: LanguageTag = Default::default();
- en.language = Some("en".to_owned());
- headers.set(AcceptLanguage(vec![
- qitem(en_us),
- QualityItem::new(en, Quality(500)),
- ]));
+ headers.insert(header::ACCEPT_LANGUAGE, HeaderValue::from_static("en-US, en; q=0.5"));
- headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned()));
+ headers.typed_insert::<UserAgent>(DEFAULT_USER_AGENT.parse().unwrap());
let httprequest = DevtoolsHttpRequest {
url: url,
- method: Method::Get,
+ method: Method::GET,
headers: headers,
- body: None,
+ body: Some(vec![]),
pipeline_id: TEST_PIPELINE_ID,
startedDateTime: devhttprequest.startedDateTime,
timeStamp: devhttprequest.timeStamp,
@@ -960,9 +916,9 @@ fn test_fetch_with_devtools() {
};
let content = "Yay!";
- let mut response_headers = Headers::new();
- response_headers.set(ContentLength(content.len() as u64));
- devhttpresponse.headers.as_mut().unwrap().remove::<Date>();
+ let mut response_headers = HeaderMap::new();
+ response_headers.typed_insert(ContentLength(content.len() as u64));
+ devhttpresponse.headers.as_mut().unwrap().remove(header::DATE);
let httpresponse = DevtoolsHttpResponse {
headers: Some(response_headers),
diff --git a/components/net/tests/http_loader.rs b/components/net/tests/http_loader.rs
index 96c424469d1..4d327029ccd 100644
--- a/components/net/tests/http_loader.rs
+++ b/components/net/tests/http_loader.rs
@@ -10,16 +10,15 @@ use fetch;
use fetch_with_context;
use flate2::Compression;
use flate2::write::{DeflateEncoder, GzEncoder};
-use hyper::LanguageTag;
-use hyper::header::{Accept, AcceptEncoding, ContentEncoding, ContentLength, Cookie as CookieHeader};
-use hyper::header::{AcceptLanguage, AccessControlAllowOrigin, Authorization, Basic, Date};
-use hyper::header::{Encoding, Headers, Host, Location, Origin, Quality, QualityItem, SetCookie, qitem};
-use hyper::header::{StrictTransportSecurity, UserAgent};
-use hyper::method::Method;
-use hyper::mime::{Mime, SubLevel, TopLevel};
-use hyper::server::{Request as HyperRequest, Response as HyperResponse};
-use hyper::status::StatusCode;
-use hyper::uri::RequestUri;
+use futures::{self, Future, Stream};
+use headers_core::HeaderMapExt;
+use headers_ext::{Authorization, Basic, AccessControlAllowOrigin, ContentLength, Date, Host, Origin};
+use headers_ext::{StrictTransportSecurity, UserAgent};
+use http::{Method, StatusCode};
+use http::header::{self, HeaderMap, HeaderValue};
+use http::uri::Authority;
+use hyper::{Request as HyperRequest, Response as HyperResponse};
+use hyper::body::Body;
use make_server;
use msg::constellation_msg::TEST_PIPELINE_ID;
use net::cookie::Cookie;
@@ -33,25 +32,21 @@ use new_fetch_context;
use servo_channel::{channel, Receiver};
use servo_url::{ServoUrl, ImmutableOrigin};
use std::collections::HashMap;
-use std::io::{Read, Write};
-use std::str::FromStr;
+use std::io::Write;
+use std::str;
use std::sync::{Arc, Mutex, RwLock};
use std::sync::atomic::{AtomicBool, Ordering};
+use std::time::Duration;
fn mock_origin() -> ImmutableOrigin {
ServoUrl::parse("http://servo.org").unwrap().origin()
}
-fn read_response(reader: &mut Read) -> String {
- let mut buf = vec![0; 1024];
- match reader.read(&mut buf) {
- Ok(len) if len > 0 => {
- unsafe { buf.set_len(len); }
- String::from_utf8(buf).unwrap()
- },
- Ok(_) => "".to_owned(),
- Err(e) => panic!("problem reading response {}", e)
- }
+fn read_response(req: HyperRequest<Body>) -> impl Future<Item=String, Error=()> {
+ req.into_body()
+ .concat2()
+ .and_then(|body| futures::future::ok(str::from_utf8(&body).unwrap().to_owned()))
+ .map_err(|_| ())
}
fn assert_cookie_for_domain(cookie_jar: &RwLock<CookieStorage>, domain: &str, cookie: Option<&str>) {
@@ -97,90 +92,71 @@ pub fn expect_devtools_http_response(devtools_port: &Receiver<DevtoolsControlMsg
fn test_check_default_headers_loaded_in_every_request() {
let expected_headers = Arc::new(Mutex::new(None));
let expected_headers_clone = expected_headers.clone();
- let handler = move |request: HyperRequest, _: HyperResponse| {
- assert_eq!(request.headers, expected_headers_clone.lock().unwrap().take().unwrap());
+ let handler = move |request: HyperRequest<Body>, _: &mut HyperResponse<Body>| {
+ assert_eq!(request.headers().clone(), expected_headers_clone.lock().unwrap().take().unwrap());
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
- let mut headers = Headers::new();
+ let mut headers = HeaderMap::new();
- headers.set(AcceptEncoding(vec![qitem(Encoding::Gzip),
- qitem(Encoding::Deflate),
- qitem(Encoding::EncodingExt("br".to_owned()))]));
-
- let hostname = match url.host_str() {
- Some(hostname) => hostname.to_owned(),
- _ => panic!()
- };
+ headers.insert(header::ACCEPT_ENCODING, HeaderValue::from_static("gzip, deflate, br"));
- headers.set(Host { hostname: hostname, port: url.port() });
+ headers.typed_insert(
+ Host::from(format!("{}:{}", url.host_str().unwrap(), url.port().unwrap()).parse::<Authority>().unwrap()));
- let accept = Accept(vec![
- qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])),
- qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_owned()), vec![])),
- QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), Quality(900u16)),
- QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), Quality(800u16)),
- ]);
- headers.set(accept);
+ headers.insert(header::ACCEPT,
+ HeaderValue::from_static("text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8"));
- let mut en_us: LanguageTag = Default::default();
- en_us.language = Some("en".to_owned());
- en_us.region = Some("US".to_owned());
- let mut en: LanguageTag = Default::default();
- en.language = Some("en".to_owned());
- headers.set(AcceptLanguage(vec![
- qitem(en_us),
- QualityItem::new(en, Quality(500)),
- ]));
+ headers.insert(header::ACCEPT_LANGUAGE, HeaderValue::from_static("en-US, en; q=0.5"));
- headers.set(UserAgent(::DEFAULT_USER_AGENT.to_owned()));
+ headers.typed_insert::<UserAgent>(::DEFAULT_USER_AGENT.parse().unwrap());
*expected_headers.lock().unwrap() = Some(headers.clone());
// Testing for method.GET
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: url.clone().origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
.. RequestInit::default()
});
let response = fetch(&mut request, None);
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
// Testing for method.POST
let mut post_headers = headers.clone();
- post_headers.set(ContentLength(0 as u64));
+ post_headers.typed_insert(ContentLength(0 as u64));
let url_str = url.as_str();
// request gets header "Origin: http://example.com" but expected_headers has
// "Origin: http://example.com/" which do not match for equality so strip trailing '/'
- post_headers.set(Origin::from_str(&url_str[..url_str.len()-1]).unwrap());
+ post_headers.insert(header::ORIGIN, HeaderValue::from_str(&url_str[..url_str.len()-1]).unwrap());
*expected_headers.lock().unwrap() = Some(post_headers);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Post,
+ method: Method::POST,
destination: Destination::Document,
origin: url.clone().origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
.. RequestInit::default()
});
let response = fetch(&mut request, None);
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
let _ = server.close();
}
#[test]
fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length_should_be_set_to_0() {
- let handler = move |request: HyperRequest, _: HyperResponse| {
- assert_eq!(request.headers.get::<ContentLength>(), Some(&ContentLength(0)));
+ let handler = move |request: HyperRequest<Body>, _: &mut HyperResponse<Body>| {
+ assert_eq!(request.headers().typed_get::<ContentLength>(), Some(ContentLength(0)));
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Post,
+ method: Method::POST,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -188,24 +164,24 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length
.. RequestInit::default()
});
let response = fetch(&mut request, None);
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
let _ = server.close();
}
#[test]
fn test_request_and_response_data_with_network_messages() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(Host { hostname: "foo.bar".to_owned(), port: None });
- response.send(b"Yay!").unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().typed_insert(Host::from("foo.bar".parse::<Authority>().unwrap()));
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
- let mut request_headers = Headers::new();
- request_headers.set(Host { hostname: "bar.foo".to_owned(), port: None });
+ let mut request_headers = HeaderMap::new();
+ request_headers.typed_insert(Host::from("bar.foo".parse::<Authority>().unwrap()));
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
headers: request_headers,
body: None,
destination: Destination::Document,
@@ -215,7 +191,7 @@ fn test_request_and_response_data_with_network_messages() {
});
let (devtools_chan, devtools_port) = channel();
let response = fetch(&mut request, Some(devtools_chan));
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
let _ = server.close();
@@ -224,41 +200,23 @@ fn test_request_and_response_data_with_network_messages() {
let devhttpresponse = expect_devtools_http_response(&devtools_port);
//Creating default headers for request
- let mut headers = Headers::new();
-
- headers.set(AcceptEncoding(vec![
- qitem(Encoding::Gzip),
- qitem(Encoding::Deflate),
- qitem(Encoding::EncodingExt("br".to_owned()))
- ]));
-
- headers.set(Host { hostname: url.host_str().unwrap().to_owned() , port: url.port() });
-
- let accept = Accept(vec![
- qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])),
- qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_owned()), vec![])),
- QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), Quality(900u16)),
- QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), Quality(800u16)),
- ]);
- headers.set(accept);
-
- let mut en_us: LanguageTag = Default::default();
- en_us.language = Some("en".to_owned());
- en_us.region = Some("US".to_owned());
- let mut en: LanguageTag = Default::default();
- en.language = Some("en".to_owned());
- headers.set(AcceptLanguage(vec![
- qitem(en_us),
- QualityItem::new(en, Quality(500)),
- ]));
-
- headers.set(UserAgent(::DEFAULT_USER_AGENT.to_owned()));
+ let mut headers = HeaderMap::new();
+
+ headers.insert(header::ACCEPT_ENCODING, HeaderValue::from_static("gzip, deflate, br"));
+ headers.typed_insert(
+ Host::from(format!("{}:{}", url.host_str().unwrap(), url.port().unwrap()).parse::<Authority>().unwrap()));
+
+ headers.insert(header::ACCEPT,
+ HeaderValue::from_static("text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8"));
+
+ headers.insert(header::ACCEPT_LANGUAGE, HeaderValue::from_static("en-US, en; q=0.5"));
+ headers.typed_insert::<UserAgent>(::DEFAULT_USER_AGENT.parse().unwrap());
let httprequest = DevtoolsHttpRequest {
url: url,
- method: Method::Get,
+ method: Method::GET,
headers: headers,
- body: None,
+ body: Some(b"".to_vec()),
pipeline_id: TEST_PIPELINE_ID,
startedDateTime: devhttprequest.startedDateTime,
timeStamp: devhttprequest.timeStamp,
@@ -268,10 +226,10 @@ fn test_request_and_response_data_with_network_messages() {
};
let content = "Yay!";
- let mut response_headers = Headers::new();
- response_headers.set(ContentLength(content.len() as u64));
- response_headers.set(Host { hostname: "foo.bar".to_owned(), port: None });
- response_headers.set(devhttpresponse.headers.as_ref().unwrap().get::<Date>().unwrap().clone());
+ let mut response_headers = HeaderMap::new();
+ response_headers.typed_insert(ContentLength(content.len() as u64));
+ response_headers.typed_insert(Host::from("foo.bar".parse::<Authority>().unwrap()));
+ response_headers.typed_insert(devhttpresponse.headers.as_ref().unwrap().typed_get::<Date>().unwrap().clone());
let httpresponse = DevtoolsHttpResponse {
headers: Some(response_headers),
@@ -286,15 +244,15 @@ fn test_request_and_response_data_with_network_messages() {
#[test]
fn test_request_and_response_message_from_devtool_without_pipeline_id() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(Host { hostname: "foo.bar".to_owned(), port: None });
- response.send(b"Yay!").unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().typed_insert(Host::from("foo.bar".parse::<Authority>().unwrap()));
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: None,
@@ -302,7 +260,7 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() {
});
let (devtools_chan, devtools_port) = channel();
let response = fetch(&mut request, Some(devtools_chan));
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
let _ = server.close();
@@ -312,24 +270,23 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() {
#[test]
fn test_redirected_request_to_devtools() {
- let post_handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.method, Method::Get);
- response.send(b"Yay!").unwrap();
+ let post_handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.method(), Method::GET);
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut post_server, post_url) = make_server(post_handler);
+ let (post_server, post_url) = make_server(post_handler);
let post_redirect_url = post_url.clone();
- let pre_handler = move |request: HyperRequest, mut response: HyperResponse| {
- assert_eq!(request.method, Method::Post);
- response.headers_mut().set(Location(post_redirect_url.to_string()));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ let pre_handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.method(), Method::POST);
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&post_redirect_url.to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
};
- let (mut pre_server, pre_url) = make_server(pre_handler);
+ let (pre_server, pre_url) = make_server(pre_handler);
let mut request = Request::from_init(RequestInit {
url: pre_url.clone(),
- method: Method::Post,
+ method: Method::POST,
destination: Destination::Document,
pipeline_id: Some(TEST_PIPELINE_ID),
.. RequestInit::default()
@@ -343,14 +300,14 @@ fn test_redirected_request_to_devtools() {
let devhttprequest = expect_devtools_http_request(&devtools_port);
let devhttpresponse = expect_devtools_http_response(&devtools_port);
- assert_eq!(devhttprequest.method, Method::Post);
+ assert_eq!(devhttprequest.method, Method::POST);
assert_eq!(devhttprequest.url, pre_url);
assert_eq!(devhttpresponse.status, Some((301, b"Moved Permanently".to_vec())));
let devhttprequest = expect_devtools_http_request(&devtools_port);
let devhttpresponse = expect_devtools_http_response(&devtools_port);
- assert_eq!(devhttprequest.method, Method::Get);
+ assert_eq!(devhttprequest.method, Method::GET);
assert_eq!(devhttprequest.url, post_url);
assert_eq!(devhttpresponse.status, Some((200, b"OK".to_vec())));
}
@@ -359,24 +316,23 @@ fn test_redirected_request_to_devtools() {
#[test]
fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() {
- let post_handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.method, Method::Get);
- response.send(b"Yay!").unwrap();
+ let post_handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.method(), Method::GET);
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut post_server, post_url) = make_server(post_handler);
+ let (post_server, post_url) = make_server(post_handler);
let post_redirect_url = post_url.clone();
- let pre_handler = move |request: HyperRequest, mut response: HyperResponse| {
- assert_eq!(request.method, Method::Post);
- response.headers_mut().set(Location(post_redirect_url.to_string()));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ let pre_handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.method(), Method::POST);
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&post_redirect_url.to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
};
- let (mut pre_server, pre_url) = make_server(pre_handler);
+ let (pre_server, pre_url) = make_server(pre_handler);
let mut request = Request::from_init(RequestInit {
url: pre_url.clone(),
- method: Method::Post,
+ method: Method::POST,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -387,23 +343,23 @@ fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() {
let _ = pre_server.close();
let _ = post_server.close();
- assert!(response.to_actual().status.unwrap().is_success());
+ assert!(response.to_actual().status.unwrap().0.is_success());
}
#[test]
fn test_load_should_decode_the_response_as_deflate_when_response_headers_have_content_encoding_deflate() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(ContentEncoding(vec![Encoding::Deflate]));
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::CONTENT_ENCODING, HeaderValue::from_static("deflate"));
let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
e.write(b"Yay!").unwrap();
let encoded_content = e.finish().unwrap();
- response.send(&encoded_content).unwrap();
+ *response.body_mut() = encoded_content.into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -415,25 +371,25 @@ fn test_load_should_decode_the_response_as_deflate_when_response_headers_have_co
let _ = server.close();
let internal_response = response.internal_response.unwrap();
- assert!(internal_response.status.unwrap().is_success());
+ assert!(internal_response.status.clone().unwrap().0.is_success());
assert_eq!(*internal_response.body.lock().unwrap(),
ResponseBody::Done(b"Yay!".to_vec()));
}
#[test]
fn test_load_should_decode_the_response_as_gzip_when_response_headers_have_content_encoding_gzip() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(ContentEncoding(vec![Encoding::Gzip]));
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::CONTENT_ENCODING, HeaderValue::from_static("gzip"));
let mut e = GzEncoder::new(Vec::new(), Compression::default());
e.write(b"Yay!").unwrap();
let encoded_content = e.finish().unwrap();
- response.send(&encoded_content).unwrap();
+ *response.body_mut() = encoded_content.into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -445,35 +401,36 @@ fn test_load_should_decode_the_response_as_gzip_when_response_headers_have_conte
let _ = server.close();
let internal_response = response.internal_response.unwrap();
- assert!(internal_response.status.unwrap().is_success());
+ assert!(internal_response.status.clone().unwrap().0.is_success());
assert_eq!(*internal_response.body.lock().unwrap(),
ResponseBody::Done(b"Yay!".to_vec()));
}
#[test]
fn test_load_doesnt_send_request_body_on_any_redirect() {
- let post_handler = move |mut request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.method, Method::Get);
- let data = read_response(&mut request);
- assert_eq!(data, "");
- response.send(b"Yay!").unwrap();
+ let post_handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.method(), Method::GET);
+ read_response(request).and_then(|data| {
+ assert_eq!(data, ""); futures::future::ok(())
+ }).poll().unwrap();
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut post_server, post_url) = make_server(post_handler);
+ let (post_server, post_url) = make_server(post_handler);
let post_redirect_url = post_url.clone();
- let pre_handler = move |mut request: HyperRequest, mut response: HyperResponse| {
- let data = read_response(&mut request);
- assert_eq!(data, "Body on POST!");
- response.headers_mut().set(Location(post_redirect_url.to_string()));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ let pre_handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ read_response(request).and_then(|data| {
+ assert_eq!(data, "Body on POST"); futures::future::ok(())
+ }).poll().unwrap();
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&post_redirect_url.to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
};
- let (mut pre_server, pre_url) = make_server(pre_handler);
+ let (pre_server, pre_url) = make_server(pre_handler);
let mut request = Request::from_init(RequestInit {
url: pre_url.clone(),
body: Some(b"Body on POST!".to_vec()),
- method: Method::Post,
+ method: Method::POST,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -484,20 +441,21 @@ fn test_load_doesnt_send_request_body_on_any_redirect() {
let _ = pre_server.close();
let _ = post_server.close();
- assert!(response.to_actual().status.unwrap().is_success());
+ assert!(response.to_actual().status.unwrap().0.is_success());
}
#[test]
fn test_load_doesnt_add_host_to_sts_list_when_url_is_http_even_if_sts_headers_are_present() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(StrictTransportSecurity::excluding_subdomains(31536000));
- response.send(b"Yay!").unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().typed_insert(
+ StrictTransportSecurity::excluding_subdomains(Duration::from_secs(31536000)));
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -509,17 +467,17 @@ fn test_load_doesnt_add_host_to_sts_list_when_url_is_http_even_if_sts_headers_ar
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
assert_eq!(context.state.hsts_list.read().unwrap().is_host_secure(url.host_str().unwrap()), false);
}
#[test]
fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_in_response() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(SetCookie(vec!["mozillaIs=theBest".to_owned()]));
- response.send(b"Yay!").unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::SET_COOKIE, HeaderValue::from_static("mozillaIs=theBest"));
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let context = new_fetch_context(None, None);
@@ -527,7 +485,7 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -539,19 +497,18 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), Some("mozillaIs=theBest"));
}
#[test]
fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_resource_manager() {
- let handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.headers.get::<CookieHeader>(),
- Some(&CookieHeader(vec!["mozillaIs=theBest".to_owned()])));
- response.send(b"Yay!").unwrap();
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.headers().get(header::COOKIE).unwrap().as_bytes(), b"mozillaIs=theBest");
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let context = new_fetch_context(None, None);
@@ -567,7 +524,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -579,17 +536,16 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
}
#[test]
fn test_load_sends_cookie_if_nonhttp() {
- let handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.headers.get::<CookieHeader>(),
- Some(&CookieHeader(vec!["mozillaIs=theBest".to_owned()])));
- response.send(b"Yay!").unwrap();
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.headers().get(header::COOKIE).unwrap().as_bytes(), b"mozillaIs=theBest");
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let context = new_fetch_context(None, None);
@@ -605,7 +561,7 @@ fn test_load_sends_cookie_if_nonhttp() {
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -617,17 +573,16 @@ fn test_load_sends_cookie_if_nonhttp() {
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
}
#[test]
fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- let pair = vec!["mozillaIs=theBest; HttpOnly".to_owned()];
- response.headers_mut().set(SetCookie(pair));
- response.send(b"Yay!").unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::SET_COOKIE, HeaderValue::from_static("mozillaIs=theBest; HttpOnly"));
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let context = new_fetch_context(None, None);
@@ -635,7 +590,7 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl(
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -647,7 +602,7 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl(
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), Some("mozillaIs=theBest"));
let mut cookie_jar = context.state.cookie_jar.write().unwrap();
@@ -656,12 +611,11 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl(
#[test]
fn test_when_cookie_received_marked_secure_is_ignored_for_http() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- let pair = vec!["mozillaIs=theBest; Secure".to_owned()];
- response.headers_mut().set(SetCookie(pair));
- response.send(b"Yay!").unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::SET_COOKIE, HeaderValue::from_static("mozillaIs=theBest; Secure"));
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let context = new_fetch_context(None, None);
@@ -669,7 +623,7 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() {
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -681,7 +635,7 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() {
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
assert_cookie_for_domain(&context.state.cookie_jar, url.as_str(), None);
}
@@ -689,16 +643,16 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() {
#[test]
fn test_load_sets_content_length_to_length_of_request_body() {
let content = b"This is a request body";
- let content_length = ContentLength(content.len() as u64);
- let handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.headers.get::<ContentLength>(), Some(&content_length));
- response.send(content).unwrap();
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ let content_length = ContentLength(content.len() as u64);
+ assert_eq!(request.headers().typed_get::<ContentLength>(), Some(content_length));
+ *response.body_mut() = content.to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Post,
+ method: Method::POST,
body: Some(content.to_vec()),
destination: Destination::Document,
origin: mock_origin(),
@@ -709,24 +663,22 @@ fn test_load_sets_content_length_to_length_of_request_body() {
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
}
#[test]
fn test_load_uses_explicit_accept_from_headers_in_load_data() {
- let accept = Accept(vec![qitem(Mime(TopLevel::Text, SubLevel::Html, vec![]))]);
- let expected_accept = accept.clone();
- let handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.headers.get::<Accept>(), Some(&expected_accept));
- response.send(b"Yay!").unwrap();
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.headers().get(header::ACCEPT).unwrap().to_str().unwrap(), "text/html");
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
- let mut accept_headers = Headers::new();
- accept_headers.set(accept);
+ let mut accept_headers = HeaderMap::new();
+ accept_headers.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
headers: accept_headers,
destination: Destination::Document,
origin: mock_origin(),
@@ -737,25 +689,21 @@ fn test_load_uses_explicit_accept_from_headers_in_load_data() {
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
}
#[test]
fn test_load_sets_default_accept_to_html_xhtml_xml_and_then_anything_else() {
- let handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.headers.get::<Accept>(), Some(&Accept(vec![
- qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])),
- qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_owned()), vec![])),
- QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), Quality(900)),
- QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), Quality(800)),
- ])));
- response.send(b"Yay!").unwrap();
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.headers().get(header::ACCEPT).unwrap().to_str().unwrap(),
+ "text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8");
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -765,24 +713,22 @@ fn test_load_sets_default_accept_to_html_xhtml_xml_and_then_anything_else() {
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
}
#[test]
fn test_load_uses_explicit_accept_encoding_from_load_data_headers() {
- let accept_encoding = AcceptEncoding(vec![qitem(Encoding::Chunked)]);
- let expected_accept_encoding = accept_encoding.clone();
- let handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.headers.get::<AcceptEncoding>(), Some(&expected_accept_encoding));
- response.send(b"Yay!").unwrap();
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.headers().get(header::ACCEPT_ENCODING).unwrap().to_str().unwrap(), "chunked");
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
- let mut accept_encoding_headers = Headers::new();
- accept_encoding_headers.set(accept_encoding);
+ let mut accept_encoding_headers = HeaderMap::new();
+ accept_encoding_headers.insert(header::ACCEPT_ENCODING, HeaderValue::from_static("chunked"));
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
headers: accept_encoding_headers,
destination: Destination::Document,
origin: mock_origin(),
@@ -793,24 +739,20 @@ fn test_load_uses_explicit_accept_encoding_from_load_data_headers() {
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
}
#[test]
fn test_load_sets_default_accept_encoding_to_gzip_and_deflate() {
- let handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.headers.get::<AcceptEncoding>(), Some(&AcceptEncoding(vec![
- qitem(Encoding::Gzip),
- qitem(Encoding::Deflate),
- qitem(Encoding::EncodingExt("br".to_owned()))
- ])));
- response.send(b"Yay!").unwrap();
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.headers().get(header::ACCEPT_ENCODING).unwrap().to_str().unwrap(), "gzip, deflate, br");
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -820,33 +762,32 @@ fn test_load_sets_default_accept_encoding_to_gzip_and_deflate() {
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
}
#[test]
fn test_load_errors_when_there_a_redirect_loop() {
let url_b_for_a = Arc::new(Mutex::new(None::<ServoUrl>));
let url_b_for_a_clone = url_b_for_a.clone();
- let handler_a = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(Location(url_b_for_a_clone.lock().unwrap().as_ref().unwrap().to_string()));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ let handler_a = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::LOCATION,
+ HeaderValue::from_str(&url_b_for_a_clone.lock().unwrap().as_ref().unwrap().to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
};
- let (mut server_a, url_a) = make_server(handler_a);
+ let (server_a, url_a) = make_server(handler_a);
let url_a_for_b = url_a.clone();
- let handler_b = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(Location(url_a_for_b.to_string()));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ let handler_b = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&url_a_for_b.to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
};
- let (mut server_b, url_b) = make_server(handler_b);
+ let (server_b, url_b) = make_server(handler_b);
*url_b_for_a.lock().unwrap() = Some(url_b.clone());
let mut request = Request::from_init(RequestInit {
url: url_a.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -866,30 +807,29 @@ fn test_load_succeeds_with_a_redirect_loop() {
let url_b_for_a = Arc::new(Mutex::new(None::<ServoUrl>));
let url_b_for_a_clone = url_b_for_a.clone();
let handled_a = AtomicBool::new(false);
- let handler_a = move |_: HyperRequest, mut response: HyperResponse| {
+ let handler_a = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
if !handled_a.swap(true, Ordering::SeqCst) {
- response.headers_mut().set(Location(url_b_for_a_clone.lock().unwrap().as_ref().unwrap().to_string()));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ response.headers_mut().insert(header::LOCATION,
+ HeaderValue::from_str(&url_b_for_a_clone.lock().unwrap().as_ref().unwrap().to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
} else {
- response.send(b"Success").unwrap();
+ *response.body_mut() = b"Success".to_vec().into()
}
};
- let (mut server_a, url_a) = make_server(handler_a);
+ let (server_a, url_a) = make_server(handler_a);
let url_a_for_b = url_a.clone();
- let handler_b = move |_: HyperRequest, mut response: HyperResponse| {
- response.headers_mut().set(Location(url_a_for_b.to_string()));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ let handler_b = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&url_a_for_b.to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
};
- let (mut server_b, url_b) = make_server(handler_b);
+ let (server_b, url_b) = make_server(handler_b);
*url_b_for_a.lock().unwrap() = Some(url_b.clone());
let mut request = Request::from_init(RequestInit {
url: url_a.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -908,24 +848,23 @@ fn test_load_succeeds_with_a_redirect_loop() {
#[test]
fn test_load_follows_a_redirect() {
- let post_handler = move |request: HyperRequest, response: HyperResponse| {
- assert_eq!(request.method, Method::Get);
- response.send(b"Yay!").unwrap();
+ let post_handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.method(), Method::GET);
+ *response.body_mut() = b"Yay!".to_vec().into();
};
- let (mut post_server, post_url) = make_server(post_handler);
+ let (post_server, post_url) = make_server(post_handler);
let post_redirect_url = post_url.clone();
- let pre_handler = move |request: HyperRequest, mut response: HyperResponse| {
- assert_eq!(request.method, Method::Get);
- response.headers_mut().set(Location(post_redirect_url.to_string()));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ let pre_handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ assert_eq!(request.method(), Method::GET);
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&post_redirect_url.to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
};
- let (mut pre_server, pre_url) = make_server(pre_handler);
+ let (pre_server, pre_url) = make_server(pre_handler);
let mut request = Request::from_init(RequestInit {
url: pre_url.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -937,7 +876,7 @@ fn test_load_follows_a_redirect() {
let _ = post_server.close();
let internal_response = response.internal_response.unwrap();
- assert!(internal_response.status.unwrap().is_success());
+ assert!(internal_response.status.clone().unwrap().0.is_success());
assert_eq!(*internal_response.body.lock().unwrap(),
ResponseBody::Done(b"Yay!".to_vec()));
}
@@ -946,27 +885,21 @@ fn test_load_follows_a_redirect() {
fn test_redirect_from_x_to_y_provides_y_cookies_from_y() {
let shared_url_y = Arc::new(Mutex::new(None::<ServoUrl>));
let shared_url_y_clone = shared_url_y.clone();
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- let path = match request.uri {
- RequestUri::AbsolutePath(path) => path,
- uri => panic!("Unexpected uri: {:?}", uri),
- };
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ let path = request.uri().path();
if path == "/com/" {
- assert_eq!(request.headers.get(),
- Some(&CookieHeader(vec!["mozillaIsNot=dotOrg".to_owned()])));
+ assert_eq!(request.headers().get(header::COOKIE).unwrap().as_bytes(), b"mozillaIsNot=dotOrg");
let location = shared_url_y.lock().unwrap().as_ref().unwrap().to_string();
- response.headers_mut().set(Location(location));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&location.to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
} else if path == "/org/" {
- assert_eq!(request.headers.get(),
- Some(&CookieHeader(vec!["mozillaIs=theBest".to_owned()])));
- response.send(b"Yay!").unwrap();
+ assert_eq!(request.headers().get(header::COOKIE).unwrap().as_bytes(), b"mozillaIs=theBest");
+ *response.body_mut() = b"Yay!".to_vec().into();
} else {
panic!("unexpected path {:?}", path)
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let port = url.port().unwrap();
assert_eq!(url.host_str(), Some("localhost"));
@@ -1002,7 +935,7 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() {
let mut request = Request::from_init(RequestInit {
url: url_x.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -1014,39 +947,34 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() {
let _ = server.close();
let internal_response = response.internal_response.unwrap();
- assert!(internal_response.status.unwrap().is_success());
+ assert!(internal_response.status.clone().unwrap().0.is_success());
assert_eq!(*internal_response.body.lock().unwrap(),
ResponseBody::Done(b"Yay!".to_vec()));
}
#[test]
fn test_redirect_from_x_to_x_provides_x_with_cookie_from_first_response() {
- let handler = move |request: HyperRequest, mut response: HyperResponse| {
- let path = match request.uri {
- ::hyper::uri::RequestUri::AbsolutePath(path) => path,
- uri => panic!("Unexpected uri: {:?}", uri),
- };
+ let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ let path = request.uri().path();
if path == "/initial/" {
- response.headers_mut().set_raw("set-cookie", vec![b"mozillaIs=theBest; path=/;".to_vec()]);
+ response.headers_mut().insert(header::SET_COOKIE, HeaderValue::from_static("mozillaIs=theBest; path=/;"));
let location = "/subsequent/".to_string();
- response.headers_mut().set(Location(location));
- *response.status_mut() = StatusCode::MovedPermanently;
- response.send(b"").unwrap();
+ response.headers_mut().insert(header::LOCATION, HeaderValue::from_str(&location.to_string()).unwrap());
+ *response.status_mut() = StatusCode::MOVED_PERMANENTLY;
} else if path == "/subsequent/" {
- assert_eq!(request.headers.get(),
- Some(&CookieHeader(vec!["mozillaIs=theBest".to_owned()])));
- response.send(b"Yay!").unwrap();
+ assert_eq!(request.headers().get(header::COOKIE).unwrap().as_bytes(), b"mozillaIs=theBest");
+ *response.body_mut() = b"Yay!".to_vec().into();
} else {
panic!("unexpected path {:?}", path)
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let url = url.join("/initial/").unwrap();
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
destination: Destination::Document,
origin: mock_origin(),
pipeline_id: Some(TEST_PIPELINE_ID),
@@ -1058,26 +986,22 @@ fn test_redirect_from_x_to_x_provides_x_with_cookie_from_first_response() {
let _ = server.close();
let internal_response = response.internal_response.unwrap();
- assert!(internal_response.status.unwrap().is_success());
+ assert!(internal_response.status.clone().unwrap().0.is_success());
assert_eq!(*internal_response.body.lock().unwrap(),
ResponseBody::Done(b"Yay!".to_vec()));
}
#[test]
fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() {
- let handler = move |request: HyperRequest, response: HyperResponse| {
- let expected = Authorization(Basic {
- username: "username".to_owned(),
- password: Some("test".to_owned())
- });
- assert_eq!(request.headers.get(), Some(&expected));
- response.send(b"").unwrap();
+ let handler = move |request: HyperRequest<Body>, _response: &mut HyperResponse<Body>| {
+ let expected = Authorization::basic("username", "test");
+ assert_eq!(request.headers().typed_get::<Authorization<Basic>>(), Some(expected));
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -1098,20 +1022,19 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() {
let _ = server.close();
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
}
#[test]
fn test_auth_ui_needs_www_auth() {
- let handler = move |_: HyperRequest, mut response: HyperResponse| {
- *response.status_mut() = StatusCode::Unauthorized;
- response.send(b"").unwrap();
+ let handler = move |_: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
+ *response.status_mut() = StatusCode::UNAUTHORIZED;
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
body: None,
destination: Destination::Document,
origin: mock_origin(),
@@ -1124,41 +1047,50 @@ fn test_auth_ui_needs_www_auth() {
let _ = server.close();
- assert_eq!(response.internal_response.unwrap().status.unwrap(), StatusCode::Unauthorized);
+ assert_eq!(response.internal_response.unwrap().status.unwrap().0, StatusCode::UNAUTHORIZED);
}
#[test]
fn test_origin_set() {
let origin_header = Arc::new(Mutex::new(None));
let origin_header_clone = origin_header.clone();
- let handler = move |request: HyperRequest, mut resp: HyperResponse| {
+ let handler = move |request: HyperRequest<Body>, resp: &mut HyperResponse<Body>| {
let origin_header_clone = origin_header.clone();
- resp.headers_mut().set(AccessControlAllowOrigin::Any);
- match request.headers.get::<Origin>() {
+ resp.headers_mut().typed_insert(AccessControlAllowOrigin::ANY);
+ match request.headers().typed_get::<Origin>() {
None => assert_eq!(origin_header_clone.lock().unwrap().take(), None),
- Some(h) => assert_eq!(*h, origin_header_clone.lock().unwrap().take().unwrap()),
+ Some(h) => assert_eq!(h, origin_header_clone.lock().unwrap().take().unwrap()),
}
};
- let (mut server, url) = make_server(handler);
+ let (server, url) = make_server(handler);
- let mut origin = Origin::new(url.scheme(), url.host_str().unwrap(), url.port());
+ let mut origin = Origin::try_from_parts(
+ url.scheme(),
+ url.host_str().unwrap(),
+ url.port()
+ ).unwrap();
*origin_header_clone.lock().unwrap() = Some(origin.clone());
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Post,
+ method: Method::POST,
body: None,
origin: url.clone().origin(),
.. RequestInit::default()
});
let response = fetch(&mut request, None);
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
let origin_url = ServoUrl::parse("http://example.com").unwrap();
- origin = Origin::new(origin_url.scheme(), origin_url.host_str().unwrap(), origin_url.port());
+ // XXX: Not sure about the Some(80) here. origin_url.origin() returns 80 for the port but origin_url returns None.
+ origin = Origin::try_from_parts(
+ origin_url.scheme(),
+ origin_url.host_str().unwrap(),
+ Some(80)
+ ).unwrap();
// Test Origin header is set on Get request with CORS mode
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Get,
+ method: Method::GET,
mode: RequestMode::CorsMode,
body: None,
origin: origin_url.clone().origin(),
@@ -1167,12 +1099,12 @@ fn test_origin_set() {
*origin_header_clone.lock().unwrap() = Some(origin.clone());
let response = fetch(&mut request, None);
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
// Test Origin header is not set on method Head
let mut request = Request::from_init(RequestInit {
url: url.clone(),
- method: Method::Head,
+ method: Method::HEAD,
body: None,
origin: url.clone().origin(),
.. RequestInit::default()
@@ -1180,7 +1112,7 @@ fn test_origin_set() {
*origin_header_clone.lock().unwrap() = None;
let response = fetch(&mut request, None);
- assert!(response.internal_response.unwrap().status.unwrap().is_success());
+ assert!(response.internal_response.unwrap().status.unwrap().0.is_success());
let _ = server.close();
}
diff --git a/components/net/tests/main.rs b/components/net/tests/main.rs
index aeddb5105d1..ad666198a07 100644
--- a/components/net/tests/main.rs
+++ b/components/net/tests/main.rs
@@ -8,19 +8,27 @@ extern crate cookie as cookie_rs;
extern crate devtools_traits;
extern crate embedder_traits;
extern crate flate2;
+extern crate futures;
+extern crate headers_core;
+extern crate headers_ext;
+extern crate http;
extern crate hyper;
-extern crate hyper_openssl;
extern crate hyper_serde;
extern crate ipc_channel;
+#[macro_use]
+extern crate lazy_static;
+extern crate mime;
extern crate msg;
extern crate net;
extern crate net_traits;
+extern crate openssl;
extern crate profile_traits;
extern crate servo_channel;
extern crate servo_config;
extern crate servo_url;
extern crate time;
-extern crate unicase;
+extern crate tokio;
+extern crate tokio_openssl;
extern crate url;
mod cookie;
@@ -38,8 +46,12 @@ mod subresource_integrity;
use devtools_traits::DevtoolsControlMsg;
use embedder_traits::{EmbedderProxy, EventLoopWaker};
use embedder_traits::resources::{self, Resource};
-use hyper::server::{Handler, Listening, Server};
-use net::connector::create_ssl_client;
+use futures::{Future, Stream};
+use hyper::{Body, Request as HyperRequest, Response as HyperResponse};
+use hyper::server::Server as HyperServer;
+use hyper::server::conn::Http;
+use hyper::service::service_fn_ok;
+use net::connector::create_ssl_connector_builder;
use net::fetch::cors_cache::CorsCache;
use net::fetch::methods::{self, CancellationListener, FetchContext};
use net::filemanager_thread::FileManager;
@@ -47,9 +59,21 @@ use net::test::HttpState;
use net_traits::FetchTaskTarget;
use net_traits::request::Request;
use net_traits::response::Response;
+use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use servo_channel::{channel, Sender};
use servo_url::ServoUrl;
+use std::net::TcpListener as StdTcpListener;
+use std::path::PathBuf;
use std::sync::{Arc, Mutex};
+use tokio::net::TcpListener;
+use tokio::runtime::Runtime;
+use tokio_openssl::SslAcceptorExt;
+
+lazy_static! {
+ pub static ref HANDLE: Mutex<Runtime> = {
+ Mutex::new(Runtime::new().unwrap())
+ };
+}
const DEFAULT_USER_AGENT: &'static str = "Such Browser. Very Layout. Wow.";
@@ -84,10 +108,10 @@ fn create_embedder_proxy() -> EmbedderProxy {
}
fn new_fetch_context(dc: Option<Sender<DevtoolsControlMsg>>, fc: Option<EmbedderProxy>) -> FetchContext {
- let ssl_client = create_ssl_client(&resources::read_string(Resource::SSLCertificates));
+ let ssl_connector = create_ssl_connector_builder(&resources::read_string(Resource::SSLCertificates));
let sender = fc.unwrap_or_else(|| create_embedder_proxy());
FetchContext {
- state: Arc::new(HttpState::new(ssl_client)),
+ state: Arc::new(HttpState::new(ssl_connector)),
user_agent: DEFAULT_USER_AGENT.into(),
devtools_chan: dc,
filemanager: FileManager::new(sender),
@@ -131,10 +155,78 @@ fn fetch_with_cors_cache(request: &mut Request, cache: &mut CorsCache) -> Respon
receiver.recv().unwrap()
}
-fn make_server<H: Handler + 'static>(handler: H) -> (Listening, ServoUrl) {
- // this is a Listening server because of handle_threads()
- let server = Server::http("0.0.0.0:0").unwrap().handle_threads(handler, 2).unwrap();
- let url_string = format!("http://localhost:{}", server.socket.port());
+pub(crate) struct Server {
+ pub close_channel: futures::sync::oneshot::Sender<()>,
+}
+
+impl Server {
+ fn close(self) {
+ self.close_channel.send(()).unwrap();
+ }
+}
+
+fn make_server<H>(handler: H) -> (Server, ServoUrl)
+ where
+ H: Fn(HyperRequest<Body>, &mut HyperResponse<Body>) + Send + Sync + 'static,
+{
+ let handler = Arc::new(handler);
+ let listener = StdTcpListener::bind("0.0.0.0:0").unwrap();
+ let url_string = format!("http://localhost:{}", listener.local_addr().unwrap().port());
let url = ServoUrl::parse(&url_string).unwrap();
+ let (tx, rx) = futures::sync::oneshot::channel::<()>();
+ let server = HyperServer::from_tcp(listener).unwrap().serve(
+ move || {
+ let handler = handler.clone();
+ service_fn_ok(move |req: HyperRequest<Body>| {
+ let mut response = HyperResponse::new(Vec::<u8>::new().into());
+ handler(req, &mut response);
+ response
+ })
+ }
+ )
+ .with_graceful_shutdown(rx)
+ .map_err(|_|());
+
+ HANDLE.lock().unwrap().spawn(server);
+ let server = Server { close_channel: tx };
+ (server, url)
+}
+
+fn make_ssl_server<H>(handler: H, cert_path: PathBuf, key_path: PathBuf) -> (Server, ServoUrl)
+ where
+ H: Fn(HyperRequest<Body>, &mut HyperResponse<Body>) + Send + Sync + 'static,
+{
+ let handler = Arc::new(handler);
+ let listener = StdTcpListener::bind("[::0]:0").unwrap();
+ let listener = TcpListener::from_std(listener, &HANDLE.lock().unwrap().reactor()).unwrap();
+ let url_string = format!("http://localhost:{}", listener.local_addr().unwrap().port());
+ let url = ServoUrl::parse(&url_string).unwrap();
+
+ let server = listener.incoming()
+ .map_err(|_| ())
+ .for_each(move |sock| {
+ let mut ssl_builder = SslAcceptor::mozilla_modern(SslMethod::tls()).unwrap();
+ ssl_builder.set_certificate_file(&cert_path, SslFiletype::PEM).unwrap();
+ ssl_builder.set_private_key_file(&key_path, SslFiletype::PEM).unwrap();
+
+ let handler = handler.clone();
+ ssl_builder.build().accept_async(sock).map_err(|_| ()).and_then(move |ssl| {
+ Http::new().serve_connection(ssl,
+ service_fn_ok(move |req: HyperRequest<Body>| {
+ let mut response = HyperResponse::new(Vec::<u8>::new().into());
+ handler(req, &mut response);
+ response
+ })
+ )
+ .map_err(|_|())
+ })
+ });
+
+ let (tx, rx) = futures::sync::oneshot::channel::<()>();
+ let server = server.select(rx.map_err(|_| ())).map(|_| ()).map_err(|_| ());
+
+ HANDLE.lock().unwrap().spawn(server);
+
+ let server = Server { close_channel: tx };
(server, url)
}
diff --git a/components/net/tests/mime_classifier.rs b/components/net/tests/mime_classifier.rs
index 1a4757ded5f..593017c7f2c 100644
--- a/components/net/tests/mime_classifier.rs
+++ b/components/net/tests/mime_classifier.rs
@@ -2,8 +2,8 @@
* 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/. */
+use mime::{self, Mime};
use net::mime_classifier::{ApacheBugFlag, MimeClassifier, Mp4Matcher, NoSniffFlag};
-use net::mime_classifier::as_string_option;
use net_traits::LoadContext;
use std::env;
use std::fs::File;
@@ -58,11 +58,10 @@ fn test_validate_classifier() {
#[cfg(test)]
fn test_sniff_with_flags(filename_orig: &path::Path,
- type_string: &str,
- subtype_string: &str,
- supplied_type: Option<(&'static str, &'static str)>,
- no_sniff_flag: NoSniffFlag,
- apache_bug_flag: ApacheBugFlag) {
+ expected_mime: Mime,
+ supplied_type: Option<Mime>,
+ no_sniff_flag: NoSniffFlag,
+ apache_bug_flag: ApacheBugFlag) {
let current_working_directory = env::current_dir().unwrap();
println!("The current directory is {}", current_working_directory.display());
@@ -75,17 +74,15 @@ fn test_sniff_with_flags(filename_orig: &path::Path,
match read_result {
Ok(data) => {
- let supplied_type = supplied_type.map(|(x, y)| (x.parse().unwrap(), y));
- let (parsed_type, parsed_subtp) = classifier.classify(LoadContext::Browsing,
- no_sniff_flag,
- apache_bug_flag,
- &as_string_option(supplied_type),
- &data);
- if (&parsed_type[..] != type_string) ||
- (&parsed_subtp[..] != subtype_string) {
- panic!("File {:?} parsed incorrectly should be {}/{}, parsed as {}/{}",
- filename, type_string, subtype_string,
- parsed_type, parsed_subtp);
+ let parsed_mime = classifier.classify(LoadContext::Browsing,
+ no_sniff_flag,
+ apache_bug_flag,
+ &supplied_type,
+ &data);
+ if (parsed_mime.type_() != expected_mime.type_()) ||
+ (parsed_mime.subtype() != expected_mime.subtype()) {
+ panic!("File {:?} parsed incorrectly should be {:?}, parsed as {:?}",
+ filename, expected_mime, parsed_mime);
}
}
Err(e) => panic!("Couldn't read from file {:?} with error {}",
@@ -94,407 +91,407 @@ fn test_sniff_with_flags(filename_orig: &path::Path,
}
#[cfg(test)]
-fn test_sniff_full(filename_orig: &path::Path, type_string: &str, subtype_string: &str,
- supplied_type: Option<(&'static str, &'static str)>) {
+fn test_sniff_full(filename_orig: &path::Path, expected_mime: Mime,
+ supplied_type: Option<Mime>) {
test_sniff_with_flags(filename_orig,
- type_string,
- subtype_string,
+ expected_mime,
supplied_type,
NoSniffFlag::Off,
ApacheBugFlag::Off)
}
#[cfg(test)]
-fn test_sniff_classification(file: &str, type_string: &str, subtype_string: &str,
- supplied_type: Option<(&'static str, &'static str)>) {
+fn test_sniff_classification(file: &str, expected_mime: Mime, supplied_type: Option<Mime>) {
let mut x = PathBuf::from("./");
- x.push(type_string);
- x.push(subtype_string);
+ x.push(expected_mime.type_().as_str());
+ x.push(expected_mime.subtype().as_str());
x.push(file);
- test_sniff_full(&x, type_string, subtype_string, supplied_type);
+ test_sniff_full(&x, expected_mime, supplied_type);
}
#[cfg(test)]
-fn test_sniff_classification_sup(file: &str, type_string: &'static str, subtype_string: &str) {
- test_sniff_classification(file, type_string, subtype_string, None);
- let class_type = Some((type_string, ""));
- test_sniff_classification(file, type_string, subtype_string, class_type);
+fn test_sniff_classification_sup(file: &str, expected_mime: Mime) {
+ test_sniff_classification(file, expected_mime.clone(), None);
+ let no_sub = format!("{}/", expected_mime.type_()).parse().unwrap();
+ test_sniff_classification(file, expected_mime, Some(no_sub));
}
#[test]
fn test_sniff_x_icon() {
- test_sniff_classification_sup("test.ico", "image", "x-icon");
+ test_sniff_classification_sup("test.ico", "image/x-icon".parse().unwrap());
}
#[test]
fn test_sniff_x_icon_cursor() {
- test_sniff_classification_sup("test_cursor.ico", "image", "x-icon");
+ test_sniff_classification_sup("test_cursor.ico", "image/x-icon".parse().unwrap());
}
#[test]
fn test_sniff_bmp() {
- test_sniff_classification_sup("test.bmp", "image", "bmp");
+ test_sniff_classification_sup("test.bmp", mime::IMAGE_BMP);
}
#[test]
fn test_sniff_gif87a() {
- test_sniff_classification_sup("test87a", "image", "gif");
+ test_sniff_classification_sup("test87a", mime::IMAGE_GIF);
}
#[test]
fn test_sniff_gif89a() {
- test_sniff_classification_sup("test89a.gif", "image", "gif");
+ test_sniff_classification_sup("test89a.gif", mime::IMAGE_GIF);
}
#[test]
fn test_sniff_webp() {
- test_sniff_classification_sup("test.webp", "image", "webp");
+ test_sniff_classification_sup("test.webp", "image/webp".parse().unwrap());
}
#[test]
fn test_sniff_png() {
- test_sniff_classification_sup("test.png", "image", "png");
+ test_sniff_classification_sup("test.png", mime::IMAGE_PNG);
}
#[test]
fn test_sniff_jpg() {
- test_sniff_classification_sup("test.jpg", "image", "jpeg");
+ test_sniff_classification_sup("test.jpg", mime::IMAGE_JPEG);
}
#[test]
fn test_sniff_webm() {
- test_sniff_classification_sup("test.webm", "video", "webm");
+ test_sniff_classification_sup("test.webm", "video/webm".parse().unwrap());
}
#[test]
fn test_sniff_mp4() {
- test_sniff_classification_sup("test.mp4", "video", "mp4");
+ test_sniff_classification_sup("test.mp4", "video/mp4".parse().unwrap());
}
#[test]
fn test_sniff_avi() {
- test_sniff_classification_sup("test.avi", "video", "avi");
+ test_sniff_classification_sup("test.avi", "video/avi".parse().unwrap());
}
#[test]
fn test_sniff_basic() {
- test_sniff_classification_sup("test.au", "audio", "basic");
+ test_sniff_classification_sup("test.au", "audio/basic".parse().unwrap());
}
#[test]
fn test_sniff_aiff() {
- test_sniff_classification_sup("test.aif", "audio", "aiff");
+ test_sniff_classification_sup("test.aif", "audio/aiff".parse().unwrap());
}
#[test]
fn test_sniff_mpeg() {
- test_sniff_classification_sup("test.mp3", "audio", "mpeg");
+ test_sniff_classification_sup("test.mp3", "audio/mpeg".parse().unwrap());
}
#[test]
fn test_sniff_midi() {
- test_sniff_classification_sup("test.mid", "audio", "midi");
+ test_sniff_classification_sup("test.mid", "audio/midi".parse().unwrap());
}
#[test]
fn test_sniff_wave() {
- test_sniff_classification_sup("test.wav", "audio", "wave");
+ test_sniff_classification_sup("test.wav", "audio/wave".parse().unwrap());
}
#[test]
fn test_sniff_ogg() {
- test_sniff_classification("small.ogg", "application", "ogg", None);
- test_sniff_classification("small.ogg", "application", "ogg", Some(("audio", "")));
+ test_sniff_classification("small.ogg", "application/ogg".parse().unwrap(), None);
+ test_sniff_classification("small.ogg", "application/ogg".parse().unwrap(), Some("audio/".parse().unwrap()));
}
#[test]
#[should_panic]
fn test_sniff_vsn_ms_fontobject() {
- test_sniff_classification_sup("vnd.ms-fontobject", "application", "vnd.ms-fontobject");
+ test_sniff_classification_sup("vnd.ms-fontobject", "application/vnd.ms-fontobject".parse().unwrap());
}
#[test]
#[should_panic]
fn test_sniff_true_type() {
- test_sniff_full(&PathBuf::from("unknown/true_type.ttf"), "(TrueType)", "", None);
+ test_sniff_full(&PathBuf::from("unknown/true_type.ttf"), "(TrueType)/".parse().unwrap(), None);
}
#[test]
#[should_panic]
fn test_sniff_open_type() {
- test_sniff_full(&PathBuf::from("unknown/open_type"), "(OpenType)", "", None);
+ test_sniff_full(&PathBuf::from("unknown/open_type"), "(OpenType)/".parse().unwrap(), None);
}
#[test]
#[should_panic]
fn test_sniff_true_type_collection() {
- test_sniff_full(&PathBuf::from("unknown/true_type_collection.ttc"), "(TrueType Collection)", "", None);
+ test_sniff_full(&PathBuf::from("unknown/true_type_collection.ttc"), "(TrueType Collection)/".parse().unwrap(),
+ None);
}
#[test]
#[should_panic]
fn test_sniff_woff() {
- test_sniff_classification_sup("test.wof", "application", "font-woff");
+ test_sniff_classification_sup("test.wof", "application/font-woff".parse().unwrap());
}
#[test]
fn test_sniff_gzip() {
- test_sniff_classification("test.gz", "application", "x-gzip", None);
+ test_sniff_classification("test.gz", "application/x-gzip".parse().unwrap(), None);
}
#[test]
fn test_sniff_zip() {
- test_sniff_classification("test.zip", "application", "zip", None);
+ test_sniff_classification("test.zip", "application/zip".parse().unwrap(), None);
}
#[test]
fn test_sniff_rar() {
- test_sniff_classification("test.rar", "application", "x-rar-compressed", None);
+ test_sniff_classification("test.rar", "application/x-rar-compressed".parse().unwrap(), None);
}
#[test]
fn test_sniff_text_html_doctype_20() {
- test_sniff_classification("text_html_doctype_20.html", "text", "html", None);
- test_sniff_classification("text_html_doctype_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_doctype_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_doctype_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_doctype_3e() {
- test_sniff_classification("text_html_doctype_3e.html", "text", "html", None);
- test_sniff_classification("text_html_doctype_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_doctype_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_doctype_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_page_20() {
- test_sniff_classification("text_html_page_20.html", "text", "html", None);
- test_sniff_classification("text_html_page_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_page_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_page_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_page_3e() {
- test_sniff_classification("text_html_page_3e.html", "text", "html", None);
- test_sniff_classification("text_html_page_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_page_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_page_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_head_20() {
- test_sniff_classification("text_html_head_20.html", "text", "html", None);
- test_sniff_classification("text_html_head_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_head_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_head_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_head_3e() {
- test_sniff_classification("text_html_head_3e.html", "text", "html", None);
- test_sniff_classification("text_html_head_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_head_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_head_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_script_20() {
- test_sniff_classification("text_html_script_20.html", "text", "html", None);
- test_sniff_classification("text_html_script_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_script_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_script_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_script_3e() {
- test_sniff_classification("text_html_script_3e.html", "text", "html", None);
- test_sniff_classification("text_html_script_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_script_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_script_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_iframe_20() {
- test_sniff_classification("text_html_iframe_20.html", "text", "html", None);
- test_sniff_classification("text_html_iframe_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_iframe_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_iframe_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_iframe_3e() {
- test_sniff_classification("text_html_iframe_3e.html", "text", "html", None);
- test_sniff_classification("text_html_iframe_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_iframe_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_iframe_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_h1_20() {
- test_sniff_classification("text_html_h1_20.html", "text", "html", None);
- test_sniff_classification("text_html_h1_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_h1_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_h1_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_h1_3e() {
- test_sniff_classification("text_html_h1_3e.html", "text", "html", None);
- test_sniff_classification("text_html_h1_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_h1_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_h1_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_div_20() {
- test_sniff_classification("text_html_div_20.html", "text", "html", None);
- test_sniff_classification("text_html_div_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_div_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_div_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_div_3e() {
- test_sniff_classification("text_html_div_3e.html", "text", "html", None);
- test_sniff_classification("text_html_div_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_div_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_div_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_font_20() {
- test_sniff_classification("text_html_font_20.html", "text", "html", None);
- test_sniff_classification("text_html_font_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_font_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_font_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_font_3e() {
- test_sniff_classification("text_html_font_3e.html", "text", "html", None);
- test_sniff_classification("text_html_font_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_font_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_font_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_table_20() {
- test_sniff_classification("text_html_table_20.html", "text", "html", None);
- test_sniff_classification("text_html_table_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_table_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_table_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_table_3e() {
- test_sniff_classification("text_html_table_3e.html", "text", "html", None);
- test_sniff_classification("text_html_table_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_table_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_table_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_a_20() {
- test_sniff_classification("text_html_a_20.html", "text", "html", None);
- test_sniff_classification("text_html_a_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_a_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_a_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_a_3e() {
- test_sniff_classification("text_html_a_3e.html", "text", "html", None);
- test_sniff_classification("text_html_a_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_a_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_a_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_style_20() {
- test_sniff_classification("text_html_style_20.html", "text", "html", None);
- test_sniff_classification("text_html_style_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_style_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_style_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_style_3e() {
- test_sniff_classification("text_html_style_3e.html", "text", "html", None);
- test_sniff_classification("text_html_style_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_style_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_style_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_title_20() {
- test_sniff_classification("text_html_title_20.html", "text", "html", None);
- test_sniff_classification("text_html_title_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_title_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_title_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_title_3e() {
- test_sniff_classification("text_html_title_3e.html", "text", "html", None);
- test_sniff_classification("text_html_title_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_title_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_title_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_b_20() {
- test_sniff_classification("text_html_b_20.html", "text", "html", None);
- test_sniff_classification("text_html_b_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_b_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_b_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_b_3e() {
- test_sniff_classification("text_html_b_3e.html", "text", "html", None);
- test_sniff_classification("text_html_b_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_b_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_b_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_body_20() {
- test_sniff_classification("text_html_body_20.html", "text", "html", None);
- test_sniff_classification("text_html_body_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_body_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_body_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_body_3e() {
- test_sniff_classification("text_html_body_3e.html", "text", "html", None);
- test_sniff_classification("text_html_body_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_body_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_body_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_br_20() {
- test_sniff_classification("text_html_br_20.html", "text", "html", None);
- test_sniff_classification("text_html_br_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_br_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_br_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_br_3e() {
- test_sniff_classification("text_html_br_3e.html", "text", "html", None);
- test_sniff_classification("text_html_br_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_br_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_br_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_p_20() {
- test_sniff_classification("text_html_p_20.html", "text", "html", None);
- test_sniff_classification("text_html_p_20_u.html", "text", "html", None);
+ test_sniff_classification("text_html_p_20.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_p_20_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_p_3e() {
- test_sniff_classification("text_html_p_3e.html", "text", "html", None);
- test_sniff_classification("text_html_p_3e_u.html", "text", "html", None);
+ test_sniff_classification("text_html_p_3e.html", mime::TEXT_HTML, None);
+ test_sniff_classification("text_html_p_3e_u.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_comment_20() {
- test_sniff_classification("text_html_comment_20.html", "text", "html", None);
+ test_sniff_classification("text_html_comment_20.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_text_html_comment_3e() {
- test_sniff_classification("text_html_comment_3e.html", "text", "html", None);
+ test_sniff_classification("text_html_comment_3e.html", mime::TEXT_HTML, None);
}
#[test]
fn test_sniff_xml() {
- test_sniff_classification("test.xml", "text", "xml", None);
+ test_sniff_classification("test.xml", mime::TEXT_XML, None);
}
#[test]
fn test_sniff_pdf() {
- test_sniff_classification("test.pdf", "application", "pdf", None);
+ test_sniff_classification("test.pdf", mime::APPLICATION_PDF, None);
}
#[test]
fn test_sniff_postscript() {
- test_sniff_classification("test.ps", "application", "postscript", None);
+ test_sniff_classification("test.ps", "application/postscript".parse().unwrap(), None);
}
#[test]
fn test_sniff_utf_16be_bom() {
- test_sniff_classification("utf16bebom.txt", "text", "plain", None);
+ test_sniff_classification("utf16bebom.txt", mime::TEXT_PLAIN, None);
}
#[test]
fn test_sniff_utf_16le_bom() {
- test_sniff_classification("utf16lebom.txt", "text", "plain", None);
+ test_sniff_classification("utf16lebom.txt", mime::TEXT_PLAIN, None);
}
#[test]
fn test_sniff_utf_8_bom() {
- test_sniff_classification("utf8bom.txt", "text", "plain", None);
+ test_sniff_classification("utf8bom.txt", mime::TEXT_PLAIN, None);
}
#[test]
fn test_sniff_rss_feed() {
// RSS feeds
- test_sniff_full(&PathBuf::from("text/xml/feed.rss"), "application", "rss+xml", Some(("text", "html")));
- test_sniff_full(&PathBuf::from("text/xml/rdf_rss.xml"), "application", "rss+xml", Some(("text", "html")));
+ test_sniff_full(&PathBuf::from("text/xml/feed.rss"), "application/rss+xml".parse().unwrap(), Some(mime::TEXT_HTML));
+ test_sniff_full(&PathBuf::from("text/xml/rdf_rss.xml"), "application/rss+xml".parse().unwrap(),
+ Some(mime::TEXT_HTML));
// Not RSS feeds
- test_sniff_full(&PathBuf::from("text/xml/rdf_rss_ko_1.xml"), "text", "html", Some(("text", "html")));
- test_sniff_full(&PathBuf::from("text/xml/rdf_rss_ko_2.xml"), "text", "html", Some(("text", "html")));
- test_sniff_full(&PathBuf::from("text/xml/rdf_rss_ko_3.xml"), "text", "html", Some(("text", "html")));
- test_sniff_full(&PathBuf::from("text/xml/rdf_rss_ko_4.xml"), "text", "html", Some(("text", "html")));
+ test_sniff_full(&PathBuf::from("text/xml/rdf_rss_ko_1.xml"), mime::TEXT_HTML, Some(mime::TEXT_HTML));
+ test_sniff_full(&PathBuf::from("text/xml/rdf_rss_ko_2.xml"), mime::TEXT_HTML, Some(mime::TEXT_HTML));
+ test_sniff_full(&PathBuf::from("text/xml/rdf_rss_ko_3.xml"), mime::TEXT_HTML, Some(mime::TEXT_HTML));
+ test_sniff_full(&PathBuf::from("text/xml/rdf_rss_ko_4.xml"), mime::TEXT_HTML, Some(mime::TEXT_HTML));
}
#[test]
fn test_sniff_atom_feed() {
- test_sniff_full(&PathBuf::from("text/xml/feed.atom"), "application", "atom+xml", Some(("text", "html")));
+ test_sniff_full(&PathBuf::from("text/xml/feed.atom"), "application/atom+xml".parse().unwrap(),
+ Some(mime::TEXT_HTML));
}
#[test]
fn test_sniff_binary_file() {
- test_sniff_full(&PathBuf::from("unknown/binary_file"), "application", "octet-stream", None);
+ test_sniff_full(&PathBuf::from("unknown/binary_file"), mime::APPLICATION_OCTET_STREAM, None);
}
#[test]
fn test_sniff_atom_feed_with_no_sniff_flag_on() {
test_sniff_with_flags(&PathBuf::from("text/xml/feed.atom"),
- "text",
- "html",
- Some(("text", "html")),
+ mime::TEXT_HTML,
+ Some(mime::TEXT_HTML),
NoSniffFlag::On,
ApacheBugFlag::Off);
}
@@ -502,9 +499,8 @@ fn test_sniff_atom_feed_with_no_sniff_flag_on() {
#[test]
fn test_sniff_with_no_sniff_flag_on_and_apache_flag_on() {
test_sniff_with_flags(&PathBuf::from("text/xml/feed.atom"),
- "text",
- "html",
- Some(("text", "html")),
+ mime::TEXT_HTML,
+ Some(mime::TEXT_HTML),
NoSniffFlag::On,
ApacheBugFlag::On);
}
@@ -512,9 +508,8 @@ fn test_sniff_with_no_sniff_flag_on_and_apache_flag_on() {
#[test]
fn test_sniff_utf_8_bom_with_apache_flag_on() {
test_sniff_with_flags(&PathBuf::from("text/plain/utf8bom.txt"),
- "text",
- "plain",
- Some(("dummy", "text")),
+ mime::TEXT_PLAIN,
+ Some("dummy/text".parse().unwrap()),
NoSniffFlag::Off,
ApacheBugFlag::On);
}
@@ -522,9 +517,8 @@ fn test_sniff_utf_8_bom_with_apache_flag_on() {
#[test]
fn test_sniff_utf_16be_bom_with_apache_flag_on() {
test_sniff_with_flags(&PathBuf::from("text/plain/utf16bebom.txt"),
- "text",
- "plain",
- Some(("dummy", "text")),
+ mime::TEXT_PLAIN,
+ Some("dummy/text".parse().unwrap()),
NoSniffFlag::Off,
ApacheBugFlag::On);
}
@@ -532,9 +526,8 @@ fn test_sniff_utf_16be_bom_with_apache_flag_on() {
#[test]
fn test_sniff_utf_16le_bom_with_apache_flag_on() {
test_sniff_with_flags(&PathBuf::from("text/plain/utf16lebom.txt"),
- "text",
- "plain",
- Some(("dummy", "text")),
+ mime::TEXT_PLAIN,
+ Some("dummy/text".parse().unwrap()),
NoSniffFlag::Off,
ApacheBugFlag::On);
}
@@ -542,9 +535,8 @@ fn test_sniff_utf_16le_bom_with_apache_flag_on() {
#[test]
fn test_sniff_octet_stream_apache_flag_on() {
test_sniff_with_flags(&PathBuf::from("unknown/binary_file"),
- "application",
- "octet-stream",
- Some(("dummy", "binary")),
+ mime::APPLICATION_OCTET_STREAM,
+ Some("dummy/binary".parse().unwrap()),
NoSniffFlag::Off,
ApacheBugFlag::On);
}
@@ -552,9 +544,8 @@ fn test_sniff_octet_stream_apache_flag_on() {
#[test]
fn test_sniff_mp4_video_apache_flag_on() {
test_sniff_with_flags(&PathBuf::from("video/mp4/test.mp4"),
- "application",
- "octet-stream",
- Some(("video", "mp4")),
+ mime::APPLICATION_OCTET_STREAM,
+ Some("video/mp4".parse().unwrap()),
NoSniffFlag::Off,
ApacheBugFlag::On);
}
diff --git a/components/net/websocket_loader.rs b/components/net/websocket_loader.rs
index 5a676c904ad..8440e0b3c63 100644
--- a/components/net/websocket_loader.rs
+++ b/components/net/websocket_loader.rs
@@ -2,13 +2,15 @@
* 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/. */
-use connector::create_ssl_connector;
+use connector::create_ssl_connector_builder;
use cookie::Cookie;
use embedder_traits::resources::{self, Resource};
use fetch::methods::should_be_blocked_due_to_bad_port;
+use headers_ext::Host;
use hosts::replace_host;
+use http::header::{self, HeaderMap, HeaderName, HeaderValue};
+use http::uri::Authority;
use http_loader::HttpState;
-use hyper::header::{Headers, Host, SetCookie};
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use net_traits::{CookieSource, MessageData};
use net_traits::{WebSocketDomAction, WebSocketNetworkEvent};
@@ -69,17 +71,19 @@ impl<'a> Handler for Client<'a> {
}
fn on_open(&mut self, shake: Handshake) -> WebSocketResult<()> {
- let mut headers = Headers::new();
+ let mut headers = HeaderMap::new();
for &(ref name, ref value) in shake.response.headers().iter() {
- headers.set_raw(name.clone(), vec![value.clone()]);
+ let name = HeaderName::from_bytes(name.as_bytes()).unwrap();
+ let value = HeaderValue::from_bytes(&value).unwrap();
+
+ headers.insert(name, value);
}
- if let Some(cookies) = headers.get::<SetCookie>() {
- let mut jar = self.http_state.cookie_jar.write().unwrap();
- for cookie in &**cookies {
- if let Some(cookie) =
- Cookie::from_cookie_string(cookie.clone(), self.resource_url, CookieSource::HTTP)
- {
+ let mut jar = self.http_state.cookie_jar.write().unwrap();
+ // TODO(eijebong): Replace thise once typed headers settled on a cookie impl
+ for cookie in headers.get_all(header::SET_COOKIE) {
+ if let Ok(s) = cookie.to_str() {
+ if let Some(cookie) = Cookie::from_cookie_string(s.into(), self.resource_url, CookieSource::HTTP) {
jar.push(cookie, self.resource_url, CookieSource::HTTP);
}
}
@@ -144,7 +148,7 @@ impl<'a> Handler for Client<'a> {
WebSocketErrorKind::Protocol,
format!("Unable to parse domain from {}. Needed for SSL.", url),
))?;
- let connector = create_ssl_connector(&certs);
+ let connector = create_ssl_connector_builder(&certs).build();
connector.connect(domain, stream).map_err(WebSocketError::from)
}
@@ -180,10 +184,11 @@ pub fn init(
let mut net_url = req_init.url.clone().into_url();
net_url.set_host(Some(&host)).unwrap();
- let host = Host {
- hostname: req_init.url.host_str().unwrap().to_owned(),
- port: req_init.url.port_or_known_default(),
- };
+ let host = Host::from(
+ format!("{}{}", req_init.url.host_str().unwrap(),
+ req_init.url.port_or_known_default().map(|v| format!(":{}", v)).unwrap_or("".into())
+ ).parse::<Authority>().unwrap()
+ );
let client = Client {
origin: &req_init.origin.ascii_serialization(),
diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml
index f2046b9cfeb..4d89992ff11 100644
--- a/components/net_traits/Cargo.toml
+++ b/components/net_traits/Cargo.toml
@@ -12,16 +12,20 @@ test = false
doctest = false
[dependencies]
-cookie = "0.10"
+cookie = "0.11"
embedder_traits = { path = "../embedder_traits" }
-hyper = "0.10"
-hyper_serde = "0.8"
+headers-core = "0.0.1"
+headers-ext = "0.0.3"
+http = "0.1"
+hyper = "0.12"
+hyper_serde = "0.9"
image = "0.19"
ipc-channel = "0.11"
lazy_static = "1"
log = "0.4"
malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
+mime = "0.3"
msg = {path = "../msg"}
num-traits = "0.2"
pixels = {path = "../pixels"}
diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs
index 85862b99a11..5a6a1364fbf 100644
--- a/components/net_traits/lib.rs
+++ b/components/net_traits/lib.rs
@@ -7,6 +7,9 @@
extern crate cookie as cookie_rs;
extern crate embedder_traits;
+extern crate headers_core;
+extern crate headers_ext;
+extern crate http;
extern crate hyper;
extern crate hyper_serde;
extern crate image as piston_image;
@@ -15,38 +18,43 @@ extern crate ipc_channel;
#[macro_use] extern crate log;
#[macro_use] extern crate malloc_size_of;
#[macro_use] extern crate malloc_size_of_derive;
+extern crate mime;
extern crate msg;
extern crate num_traits;
extern crate pixels;
#[macro_use] extern crate serde;
extern crate servo_arc;
extern crate servo_url;
-extern crate url;
+#[macro_use] extern crate url;
extern crate uuid;
extern crate webrender_api;
use cookie_rs::Cookie;
use filemanager_thread::FileManagerThreadMsg;
+use headers_core::HeaderMapExt;
+use headers_ext::{ContentType, ReferrerPolicy as ReferrerPolicyHeader};
+use http::{Error as HttpError, HeaderMap};
use hyper::Error as HyperError;
-use hyper::header::{ContentType, Headers, ReferrerPolicy as ReferrerPolicyHeader};
-use hyper::http::RawStatus;
-use hyper::mime::{Attr, Mime};
+use hyper::StatusCode;
use hyper_serde::Serde;
use ipc_channel::Error as IpcError;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
+use mime::Mime;
use msg::constellation_msg::HistoryStateId;
use request::{Request, RequestInit};
use response::{HttpsState, Response, ResponseInit};
use servo_url::ServoUrl;
use std::error::Error;
use storage_thread::StorageThreadMsg;
+use url::percent_encoding;
pub mod blob_url_store;
pub mod filemanager_thread;
pub mod image_cache;
pub mod net_error_list;
pub mod pub_domains;
+pub mod quality;
pub mod request;
pub mod response;
pub mod storage_thread;
@@ -80,16 +88,16 @@ pub struct CustomResponse {
#[ignore_malloc_size_of = "Defined in hyper"]
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
- pub headers: Headers,
+ pub headers: HeaderMap,
#[ignore_malloc_size_of = "Defined in hyper"]
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
- pub raw_status: RawStatus,
+ pub raw_status: (StatusCode, String),
pub body: Vec<u8>,
}
impl CustomResponse {
- pub fn new(headers: Headers, raw_status: RawStatus, body: Vec<u8>) -> CustomResponse {
+ pub fn new(headers: HeaderMap, raw_status: (StatusCode, String), body: Vec<u8>) -> CustomResponse {
CustomResponse {
headers: headers,
raw_status: raw_status,
@@ -126,24 +134,24 @@ pub enum ReferrerPolicy {
StrictOriginWhenCrossOrigin,
}
-impl<'a> From<&'a ReferrerPolicyHeader> for ReferrerPolicy {
- fn from(policy: &'a ReferrerPolicyHeader) -> Self {
- match *policy {
- ReferrerPolicyHeader::NoReferrer =>
+impl From<ReferrerPolicyHeader> for ReferrerPolicy {
+ fn from(policy: ReferrerPolicyHeader) -> Self {
+ match policy {
+ ReferrerPolicyHeader::NO_REFERRER =>
ReferrerPolicy::NoReferrer,
- ReferrerPolicyHeader::NoReferrerWhenDowngrade =>
+ ReferrerPolicyHeader::NO_REFERRER_WHEN_DOWNGRADE =>
ReferrerPolicy::NoReferrerWhenDowngrade,
- ReferrerPolicyHeader::SameOrigin =>
+ ReferrerPolicyHeader::SAME_ORIGIN =>
ReferrerPolicy::SameOrigin,
- ReferrerPolicyHeader::Origin =>
+ ReferrerPolicyHeader::ORIGIN =>
ReferrerPolicy::Origin,
- ReferrerPolicyHeader::OriginWhenCrossOrigin =>
+ ReferrerPolicyHeader::ORIGIN_WHEN_CROSS_ORIGIN =>
ReferrerPolicy::OriginWhenCrossOrigin,
- ReferrerPolicyHeader::UnsafeUrl =>
+ ReferrerPolicyHeader::UNSAFE_URL =>
ReferrerPolicy::UnsafeUrl,
- ReferrerPolicyHeader::StrictOrigin =>
+ ReferrerPolicyHeader::STRICT_ORIGIN =>
ReferrerPolicy::StrictOrigin,
- ReferrerPolicyHeader::StrictOriginWhenCrossOrigin =>
+ ReferrerPolicyHeader::STRICT_ORIGIN_WHEN_CROSS_ORIGIN =>
ReferrerPolicy::StrictOriginWhenCrossOrigin,
}
}
@@ -419,7 +427,7 @@ pub struct Metadata {
#[ignore_malloc_size_of = "Defined in hyper"]
/// Headers
- pub headers: Option<Serde<Headers>>,
+ pub headers: Option<Serde<HeaderMap>>,
/// HTTP Status
pub status: Option<(u16, Vec<u8>)>,
@@ -454,16 +462,15 @@ impl Metadata {
/// Extract the parts of a Mime that we care about.
pub fn set_content_type(&mut self, content_type: Option<&Mime>) {
if self.headers.is_none() {
- self.headers = Some(Serde(Headers::new()));
+ self.headers = Some(Serde(HeaderMap::new()));
}
if let Some(mime) = content_type {
- self.headers.as_mut().unwrap().set(ContentType(mime.clone()));
- self.content_type = Some(Serde(ContentType(mime.clone())));
- let Mime(_, _, ref parameters) = *mime;
- for &(ref k, ref v) in parameters {
- if Attr::Charset == *k {
- self.charset = Some(v.to_string());
+ self.headers.as_mut().unwrap().typed_insert(ContentType::from(mime.clone()));
+ self.content_type = Some(Serde(ContentType::from(mime.clone())));
+ for (name, value) in mime.params() {
+ if mime::CHARSET == name {
+ self.charset = Some(value.to_string());
}
}
}
@@ -518,18 +525,16 @@ pub enum NetworkError {
}
impl NetworkError {
- pub fn from_hyper_error(url: &ServoUrl, error: HyperError) -> Self {
- if let HyperError::Ssl(ref ssl_error) = error {
- return NetworkError::from_ssl_error(url, &**ssl_error);
- }
+ pub fn from_hyper_error(error: &HyperError) -> Self {
NetworkError::Internal(error.description().to_owned())
}
- pub fn from_ssl_error(url: &ServoUrl, error: &Error) -> Self {
- NetworkError::SslValidation(url.clone(), error.description().to_owned())
+ pub fn from_http_error(error: &HttpError) -> Self {
+ NetworkError::Internal(error.description().to_owned())
}
}
+
/// Normalize `slice`, as defined by
/// [the Fetch Spec](https://fetch.spec.whatwg.org/#concept-header-value-normalize).
pub fn trim_http_whitespace(mut slice: &[u8]) -> &[u8] {
@@ -551,3 +556,17 @@ pub fn trim_http_whitespace(mut slice: &[u8]) -> &[u8] {
slice
}
+
+pub fn http_percent_encode(bytes: &[u8]) -> String {
+ define_encode_set! {
+ // This encode set is used for HTTP header values and is defined at
+ // https://tools.ietf.org/html/rfc5987#section-3.2
+ pub HTTP_VALUE = [percent_encoding::SIMPLE_ENCODE_SET] | {
+ ' ', '"', '%', '\'', '(', ')', '*', ',', '/', ':', ';', '<', '-', '>', '?',
+ '[', '\\', ']', '{', '}'
+ }
+ }
+
+ url::percent_encoding::percent_encode(bytes, HTTP_VALUE).to_string()
+}
+
diff --git a/components/net_traits/quality.rs b/components/net_traits/quality.rs
new file mode 100644
index 00000000000..72fed2304ca
--- /dev/null
+++ b/components/net_traits/quality.rs
@@ -0,0 +1,80 @@
+/* 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/. */
+
+//TODO(eijebong): Remove this once typed headers figure out quality
+// This is copy pasted from the old hyper headers to avoid hardcoding everything
+// (I would probably also make some silly mistakes while migrating...)
+
+use http::header::HeaderValue;
+use mime::Mime;
+use std::{fmt, str};
+
+/// A quality value, as specified in [RFC7231].
+///
+/// Quality values are decimal numbers between 0 and 1 (inclusive) with up to 3 fractional digits of precision.
+///
+/// [RFC7231]: https://tools.ietf.org/html/rfc7231#section-5.3.1
+#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
+pub struct Quality(u16);
+
+impl Quality {
+ /// Creates a quality value from a value between 0 and 1000 inclusive.
+ ///
+ /// This is semantically divided by 1000 to produce a value between 0 and 1.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the value is greater than 1000.
+ pub fn from_u16(quality: u16) -> Quality {
+ assert!(quality <= 1000);
+ Quality(quality)
+ }
+}
+
+/// A value paired with its "quality" as defined in [RFC7231].
+///
+/// Quality items are used in content negotiation headers such as `Accept` and `Accept-Encoding`.
+///
+/// [RFC7231]: https://tools.ietf.org/html/rfc7231#section-5.3
+#[derive(Clone, Debug, PartialEq)]
+pub struct QualityItem<T> {
+ pub item: T,
+ pub quality: Quality,
+}
+
+impl<T> QualityItem<T> {
+ /// Creates a new quality item.
+ pub fn new(item: T, quality: Quality) -> QualityItem<T> {
+ QualityItem { item, quality }
+ }
+}
+
+impl<T> fmt::Display for QualityItem<T>
+where
+ T: fmt::Display,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(&self.item, fmt)?;
+ match self.quality.0 {
+ 1000 => Ok(()),
+ 0 => fmt.write_str("; q=0"),
+ mut x => {
+ fmt.write_str("; q=0.")?;
+ let mut digits = *b"000";
+ digits[2] = (x % 10) as u8 + b'0';
+ x /= 10;
+ digits[1] = (x % 10) as u8 + b'0';
+ x /= 10;
+ digits[0] = (x % 10) as u8 + b'0';
+
+ let s = str::from_utf8(&digits[..]).unwrap();
+ fmt.write_str(s.trim_right_matches('0'))
+ }
+ }
+ }
+}
+
+pub fn quality_to_value(q: Vec<QualityItem<Mime>>) -> HeaderValue {
+ HeaderValue::from_str(&q.iter().map(|q| q.to_string()).collect::<Vec<String>>().join(", ")).unwrap()
+}
diff --git a/components/net_traits/request.rs b/components/net_traits/request.rs
index 822a39ee324..4113037a672 100644
--- a/components/net_traits/request.rs
+++ b/components/net_traits/request.rs
@@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use ReferrerPolicy;
-use hyper::header::Headers;
-use hyper::method::Method;
+use http::HeaderMap;
+use hyper::Method;
use msg::constellation_msg::PipelineId;
use servo_url::{ImmutableOrigin, ServoUrl};
use std::default::Default;
@@ -145,7 +145,7 @@ pub struct RequestInit {
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
#[ignore_malloc_size_of = "Defined in hyper"]
- pub headers: Headers,
+ pub headers: HeaderMap,
pub unsafe_request: bool,
pub body: Option<Vec<u8>>,
pub service_workers_mode: ServiceWorkersMode,
@@ -171,9 +171,9 @@ pub struct RequestInit {
impl Default for RequestInit {
fn default() -> RequestInit {
RequestInit {
- method: Method::Get,
+ method: Method::GET,
url: ServoUrl::parse("about:blank").unwrap(),
- headers: Headers::new(),
+ headers: HeaderMap::new(),
unsafe_request: false,
body: None,
service_workers_mode: ServiceWorkersMode::All,
@@ -208,7 +208,7 @@ pub struct Request {
pub sandboxed_storage_area_urls: bool,
/// <https://fetch.spec.whatwg.org/#concept-request-header-list>
#[ignore_malloc_size_of = "Defined in hyper"]
- pub headers: Headers,
+ pub headers: HeaderMap,
/// <https://fetch.spec.whatwg.org/#unsafe-request-flag>
pub unsafe_request: bool,
/// <https://fetch.spec.whatwg.org/#concept-request-body>
@@ -264,10 +264,10 @@ impl Request {
pipeline_id: Option<PipelineId>)
-> Request {
Request {
- method: Method::Get,
+ method: Method::GET,
local_urls_only: false,
sandboxed_storage_area_urls: false,
- headers: Headers::new(),
+ headers: HeaderMap::new(),
unsafe_request: false,
body: None,
window: Window::Client,
diff --git a/components/net_traits/response.rs b/components/net_traits/response.rs
index 4b0a64460ce..e7f39358c5a 100644
--- a/components/net_traits/response.rs
+++ b/components/net_traits/response.rs
@@ -5,8 +5,9 @@
//! The [Response](https://fetch.spec.whatwg.org/#responses) object
//! resulting from a [fetch operation](https://fetch.spec.whatwg.org/#concept-fetch)
use {FetchMetadata, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy};
-use hyper::header::{AccessControlExposeHeaders, ContentType, Headers};
-use hyper::status::StatusCode;
+use headers_core::HeaderMapExt;
+use headers_ext::{AccessControlExposeHeaders, ContentType};
+use http::{HeaderMap, StatusCode};
use hyper_serde::Serde;
use servo_arc::Arc;
use servo_url::ServoUrl;
@@ -81,7 +82,7 @@ pub struct ResponseInit {
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
#[ignore_malloc_size_of = "Defined in hyper"]
- pub headers: Headers,
+ pub headers: HeaderMap,
pub status_code: u16,
pub referrer: Option<ServoUrl>,
pub location_url: Option<Result<ServoUrl, String>>,
@@ -96,10 +97,10 @@ pub struct Response {
pub url_list: Vec<ServoUrl>,
/// `None` can be considered a StatusCode of `0`.
#[ignore_malloc_size_of = "Defined in hyper"]
- pub status: Option<StatusCode>,
+ pub status: Option<(StatusCode, String)>,
pub raw_status: Option<(u16, Vec<u8>)>,
#[ignore_malloc_size_of = "Defined in hyper"]
- pub headers: Headers,
+ pub headers: HeaderMap,
#[ignore_malloc_size_of = "Mutex heap size undefined"]
pub body: Arc<Mutex<ResponseBody>>,
pub cache_state: CacheState,
@@ -127,9 +128,9 @@ impl Response {
termination_reason: None,
url: Some(url),
url_list: vec![],
- status: Some(StatusCode::Ok),
+ status: Some((StatusCode::OK, "OK".to_string())),
raw_status: Some((200, b"OK".to_vec())),
- headers: Headers::new(),
+ headers: HeaderMap::new(),
body: Arc::new(Mutex::new(ResponseBody::Empty)),
cache_state: CacheState::None,
https_state: HttpsState::None,
@@ -148,7 +149,7 @@ impl Response {
res.location_url = init.location_url;
res.headers = init.headers;
res.referrer = init.referrer;
- res.status = Some(StatusCode::from_u16(init.status_code));
+ res.status = StatusCode::from_u16(init.status_code).map(|s| (s, s.to_string())).ok();
res
}
@@ -160,7 +161,7 @@ impl Response {
url_list: vec![],
status: None,
raw_status: None,
- headers: Headers::new(),
+ headers: HeaderMap::new(),
body: Arc::new(Mutex::new(ResponseBody::Empty)),
cache_state: CacheState::None,
https_state: HttpsState::None,
@@ -242,45 +243,43 @@ impl Response {
ResponseType::Error(..) => unreachable!(),
ResponseType::Basic => {
- let headers = old_headers.iter().filter(|header| {
- match &*header.name().to_ascii_lowercase() {
+ let headers = old_headers.iter().filter(|(name, _)| {
+ match &*name.as_str().to_ascii_lowercase() {
"set-cookie" | "set-cookie2" => false,
_ => true
}
- }).collect();
+ }).map(|(n, v)| (n.clone(), v.clone())).collect();
response.headers = headers;
},
ResponseType::Cors => {
- let access = old_headers.get::<AccessControlExposeHeaders>();
- let allowed_headers = access.as_ref().map(|v| &v[..]).unwrap_or(&[]);
-
- let headers = old_headers.iter().filter(|header| {
- match &*header.name().to_ascii_lowercase() {
+ let headers = old_headers.iter().filter(|(name, _)| {
+ match &*name.as_str().to_ascii_lowercase() {
"cache-control" | "content-language" | "content-type" |
"expires" | "last-modified" | "pragma" => true,
"set-cookie" | "set-cookie2" => false,
header => {
- let result =
- allowed_headers.iter().find(|h| *header == *h.to_ascii_lowercase());
+ let access = old_headers.typed_get::<AccessControlExposeHeaders>();
+ let result = access
+ .and_then(|v| v.iter().find(|h| *header == h.as_str().to_ascii_lowercase()));
result.is_some()
}
}
- }).collect();
+ }).map(|(n, v)| (n.clone(), v.clone())).collect();
response.headers = headers;
},
ResponseType::Opaque => {
response.url_list = vec![];
response.url = None;
- response.headers = Headers::new();
+ response.headers = HeaderMap::new();
response.status = None;
response.body = Arc::new(Mutex::new(ResponseBody::Empty));
response.cache_state = CacheState::None;
},
ResponseType::OpaqueRedirect => {
- response.headers = Headers::new();
+ response.headers = HeaderMap::new();
response.status = None;
response.body = Arc::new(Mutex::new(ResponseBody::Empty));
response.cache_state = CacheState::None;
@@ -293,10 +292,7 @@ impl Response {
pub fn metadata(&self) -> Result<FetchMetadata, NetworkError> {
fn init_metadata(response: &Response, url: &ServoUrl) -> Metadata {
let mut metadata = Metadata::default(url.clone());
- metadata.set_content_type(match response.headers.get() {
- Some(&ContentType(ref mime)) => Some(mime),
- None => None,
- });
+ metadata.set_content_type(response.headers.typed_get::<ContentType>().map(|v| v.into()).as_ref());
metadata.location_url = response.location_url.clone();
metadata.headers = Some(Serde(response.headers.clone()));
metadata.status = response.raw_status.clone();
diff --git a/components/profile/Cargo.toml b/components/profile/Cargo.toml
index 7b9d79a7a8f..890a9aa9336 100644
--- a/components/profile/Cargo.toml
+++ b/components/profile/Cargo.toml
@@ -14,7 +14,7 @@ unstable = ["jemalloc-sys"]
[dependencies]
profile_traits = {path = "../profile_traits"}
-influent = "0.4"
+influent = "0.5"
ipc-channel = "0.11"
heartbeats-simple = "0.4"
log = "0.4"
@@ -22,6 +22,7 @@ serde = "1.0"
serde_json = "1.0"
servo_config = {path = "../config"}
time = "0.1.12"
+tokio = "0.1"
[target.'cfg(target_os = "macos")'.dependencies]
task_info = {path = "../../support/rust-task_info"}
diff --git a/components/profile/lib.rs b/components/profile/lib.rs
index d01aad61cd0..248fd0ab19b 100644
--- a/components/profile/lib.rs
+++ b/components/profile/lib.rs
@@ -25,6 +25,7 @@ extern crate servo_config;
#[cfg(target_os = "macos")]
extern crate task_info;
extern crate time as std_time;
+extern crate tokio;
#[allow(unsafe_code)]
mod heartbeats;
diff --git a/components/profile/time.rs b/components/profile/time.rs
index 780a6e9da2f..e2d12ad5701 100644
--- a/components/profile/time.rs
+++ b/components/profile/time.rs
@@ -23,6 +23,8 @@ use std::io::{self, Write};
use std::path::Path;
use std::time::Duration;
use std_time::precise_time_ns;
+use tokio;
+use tokio::prelude::Future;
use trace_dump::TraceDump;
pub trait Formattable {
@@ -470,9 +472,9 @@ impl Profiler {
if let Some(ref meta) = *meta {
measurement.add_tag("host", meta.url.as_str());
};
- if client.write_one(measurement, None).is_err() {
- warn!("Could not write measurement to profiler db");
- }
+
+ tokio::run(client.write_one(measurement, None)
+ .map_err(|e| warn!("Could not write measurement to profiler db: {:?}", e)));
}
}
},
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index 12cb7c6c667..614f9fcded1 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -31,13 +31,13 @@ tinyfiledialogs = "3.0"
[dependencies]
app_units = "0.7"
backtrace = {version = "0.3", optional = true}
-base64 = "0.6"
+base64 = "0.9"
bitflags = "1.0"
bluetooth_traits = {path = "../bluetooth_traits"}
byteorder = "1.0"
canvas_traits = {path = "../canvas_traits"}
caseless = "0.2"
-cookie = "0.10"
+cookie = "0.11"
chrono = "0.4"
cssparser = "0.24"
deny_public_fields = {path = "../deny_public_fields"}
@@ -51,9 +51,12 @@ euclid = "0.19"
fnv = "1.0"
gleam = "0.6"
half = "1.0"
+headers-core = "0.0.1"
+headers-ext = "0.0.3"
html5ever = "0.22"
-hyper = "0.10"
-hyper_serde = "0.8"
+http = "0.1"
+hyper = "0.12"
+hyper_serde = "0.9"
image = "0.19"
ipc-channel = "0.11"
itertools = "0.7.6"
@@ -66,8 +69,8 @@ malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
metrics = {path = "../metrics"}
mitochondria = "1.1.2"
-mime = "0.2.1"
-mime_guess = "1.8.0"
+mime = "0.3"
+mime_guess = "2.0.0-alpha.6"
mozjs = "0.9.3"
msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
diff --git a/components/script/body.rs b/components/script/body.rs
index 9709043912b..cfc167d25b4 100644
--- a/components/script/body.rs
+++ b/components/script/body.rs
@@ -22,7 +22,7 @@ use js::jsval::UndefinedValue;
use js::rust::wrappers::JS_GetPendingException;
use js::rust::wrappers::JS_ParseJSON;
use js::typedarray::{ArrayBuffer, CreateWith};
-use mime::{Mime, TopLevel, SubLevel};
+use mime::{self, Mime};
use std::cell::Ref;
use std::ptr;
use std::rc::Rc;
@@ -175,23 +175,22 @@ fn run_form_data_algorithm(
} else {
""
};
- let mime: Mime = mime_str
- .parse()
- .map_err(|_| Error::Type("Inappropriate MIME-type for Body".to_string()))?;
- match mime {
- // TODO
- // ... Parser for Mime(TopLevel::Multipart, SubLevel::FormData, _)
- // ... is not fully determined yet.
- Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _) => {
- let entries = form_urlencoded::parse(&bytes);
- let formdata = FormData::new(None, root);
- for (k, e) in entries {
- formdata.Append(USVString(k.into_owned()), USVString(e.into_owned()));
- }
- return Ok(FetchedData::FormData(formdata));
- },
- _ => return Err(Error::Type("Inappropriate MIME-type for Body".to_string())),
+ let mime: Mime = mime_str.parse().map_err(
+ |_| Error::Type("Inappropriate MIME-type for Body".to_string()))?;
+
+ // TODO
+ // ... Parser for Mime(TopLevel::Multipart, SubLevel::FormData, _)
+ // ... is not fully determined yet.
+ if mime.type_() == mime::APPLICATION && mime.subtype() == mime::WWW_FORM_URLENCODED {
+ let entries = form_urlencoded::parse(&bytes);
+ let formdata = FormData::new(None, root);
+ for (k, e) in entries {
+ formdata.Append(USVString(k.into_owned()), USVString(e.into_owned()));
+ }
+ return Ok(FetchedData::FormData(formdata));
}
+
+ Err(Error::Type("Inappropriate MIME-type for Body".to_string()))
}
#[allow(unsafe_code)]
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 8e720f28e25..75fcfb42c16 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -55,10 +55,9 @@ use euclid::Length as EuclidLength;
use html5ever::{Prefix, LocalName, Namespace, QualName};
use html5ever::buffer_queue::BufferQueue;
use html5ever::tendril::IncompleteUtf8;
-use hyper::header::Headers;
-use hyper::method::Method;
-use hyper::mime::Mime;
-use hyper::status::StatusCode;
+use http::header::HeaderMap;
+use hyper::Method;
+use hyper::StatusCode;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use js::glue::{CallObjectTracer, CallValueTracer};
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
@@ -67,6 +66,7 @@ use js::rust::{GCMethods, Handle, Runtime};
use js::typedarray::TypedArray;
use js::typedarray::TypedArrayElement;
use metrics::{InteractiveMetrics, InteractiveWindow};
+use mime::Mime;
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TopLevelBrowsingContextId};
use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads};
use net_traits::filemanager_thread::RelativePos;
@@ -391,7 +391,7 @@ unsafe_no_jsmanaged_fields!(TimelineMarkerType);
unsafe_no_jsmanaged_fields!(WorkerId);
unsafe_no_jsmanaged_fields!(BufferQueue, QuirksMode, IncompleteUtf8);
unsafe_no_jsmanaged_fields!(Runtime);
-unsafe_no_jsmanaged_fields!(Headers, Method);
+unsafe_no_jsmanaged_fields!(HeaderMap, Method);
unsafe_no_jsmanaged_fields!(WindowProxyHandler);
unsafe_no_jsmanaged_fields!(UntrustedNodeAddress);
unsafe_no_jsmanaged_fields!(LengthOrPercentageOrAuto);
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 9b52ea86b08..75527a90efc 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -95,14 +95,13 @@ use encoding_rs::{Encoding, UTF_8};
use euclid::Point2D;
use fetch::FetchCanceller;
use html5ever::{LocalName, Namespace, QualName};
-use hyper::header::{Header, SetCookie};
use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSObject, JSRuntime};
use js::jsapi::JS_GetRuntime;
use keyboard_types::{Key, KeyState, Modifiers};
use metrics::{InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory, ProgressiveWebMetric};
-use mime::{Mime, TopLevel, SubLevel};
+use mime::{self, Mime};
use msg::constellation_msg::BrowsingContextId;
use net_traits::{FetchResponseMsg, IpcSend, ReferrerPolicy};
use net_traits::CookieSource::NonHTTP;
@@ -2530,14 +2529,12 @@ impl Document {
implementation: Default::default(),
content_type: match content_type {
Some(mime_data) => mime_data,
- None => Mime::from(match is_html_document {
+ None => match is_html_document {
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
- IsHTMLDocument::HTMLDocument => Mime(TopLevel::Text, SubLevel::Html, vec![]),
+ IsHTMLDocument::HTMLDocument => mime::TEXT_HTML,
// https://dom.spec.whatwg.org/#concept-document-content-type
- IsHTMLDocument::NonHTMLDocument => {
- Mime(TopLevel::Application, SubLevel::Xml, vec![])
- },
- }),
+ IsHTMLDocument::NonHTMLDocument => "application/xml".parse().unwrap(),
+ },
},
last_modified: last_modified,
url: DomRefCell::new(url),
@@ -3345,8 +3342,10 @@ impl DocumentMethods for Document {
local_name.make_ascii_lowercase();
}
- let is_xhtml = self.content_type.0 == TopLevel::Application &&
- self.content_type.1.as_str() == "xhtml+xml";
+ let is_xhtml = self.content_type.type_() == mime::APPLICATION &&
+ self.content_type.subtype().as_str() == "xhtml" &&
+ self.content_type.suffix() == Some(mime::XML);
+
let ns = if self.is_html_document || is_xhtml {
ns!(html)
} else {
@@ -3947,18 +3946,16 @@ impl DocumentMethods for Document {
return Err(Error::Security);
}
- if let Ok(cookie_header) = SetCookie::parse_header(&vec![cookie.to_string().into_bytes()]) {
- let cookies = cookie_header
- .0
- .into_iter()
- .filter_map(|cookie| cookie_rs::Cookie::parse(cookie).ok().map(Serde))
- .collect();
- let _ = self
- .window
+ let cookies = if let Some(cookie) = cookie_rs::Cookie::parse(cookie.to_string()).ok().map(Serde) {
+ vec![cookie]
+ } else {
+ vec![]
+ };
+
+ let _ = self.window
.upcast::<GlobalScope>()
.resource_threads()
.send(SetCookiesForUrl(self.url(), cookies, NonHTTP));
- }
Ok(())
}
diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs
index f20cc61f3df..8936cc8b391 100644
--- a/components/script/dom/domimplementation.rs
+++ b/components/script/dom/domimplementation.rs
@@ -24,7 +24,7 @@ use dom::node::Node;
use dom::text::Text;
use dom::xmldocument::XMLDocument;
use dom_struct::dom_struct;
-use mime::{Mime, TopLevel, SubLevel};
+use mime;
use script_traits::DocumentActivity;
// https://dom.spec.whatwg.org/#domimplementation
@@ -82,17 +82,9 @@ impl DOMImplementationMethods for DOMImplementation {
let namespace = namespace_from_domstring(maybe_namespace.to_owned());
let content_type = match namespace {
- ns!(html) => Mime(
- TopLevel::Application,
- SubLevel::Ext("xhtml+xml".to_string()),
- vec![],
- ),
- ns!(svg) => Mime(
- TopLevel::Image,
- SubLevel::Ext("svg+xml".to_string()),
- vec![],
- ),
- _ => Mime(TopLevel::Application, SubLevel::Xml, vec![]),
+ ns!(html) => "application/xhtml+xml".parse().unwrap(),
+ ns!(svg) => mime::IMAGE_SVG,
+ _ => "application/xml".parse().unwrap(),
};
// Step 1.
diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs
index 7aad98406a4..208d8aee8ed 100644
--- a/components/script/dom/eventsource.rs
+++ b/components/script/dom/eventsource.rs
@@ -17,13 +17,14 @@ use dom::messageevent::MessageEvent;
use dom_struct::dom_struct;
use euclid::Length;
use fetch::FetchCanceller;
-use hyper::header::{Accept, qitem};
+use headers_ext::ContentType;
+use http::header::{self, HeaderName, HeaderValue};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use js::conversions::ToJSValConvertible;
use js::jsapi::JSAutoCompartment;
use js::jsval::UndefinedValue;
-use mime::{Mime, TopLevel, SubLevel};
+use mime::{self, Mime};
use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata};
use net_traits::{FetchResponseMsg, FetchResponseListener, NetworkError};
use net_traits::request::{CacheMode, CorsSettings, CredentialsMode};
@@ -39,7 +40,6 @@ use task_source::{TaskSource, TaskSourceName};
use timers::OneshotTimerCallback;
use utf8;
-header! { (LastEventId, "Last-Event-ID") => [String] }
const DEFAULT_RECONNECTION_TIME: u64 = 5000;
@@ -338,13 +338,14 @@ impl FetchResponseListener for EventSourceContext {
};
match meta.content_type {
None => self.fail_the_connection(),
- Some(ct) => match ct.into_inner().0 {
- Mime(TopLevel::Text, SubLevel::EventStream, _) => {
+ Some(ct) => {
+ if <ContentType as Into<Mime>>::into(ct.into_inner()) == mime::TEXT_EVENT_STREAM {
self.origin = meta.final_url.origin().ascii_serialization();
self.announce_the_connection();
- },
- _ => self.fail_the_connection(),
- },
+ } else {
+ self.fail_the_connection()
+ }
+ }
}
},
Err(_) => {
@@ -501,9 +502,8 @@ impl EventSource {
..RequestInit::default()
};
// Step 10
- request
- .headers
- .set(Accept(vec![qitem(mime!(Text / EventStream))]));
+ // TODO(eijebong): Replace once typed headers allow it
+ request.headers.insert(header::ACCEPT, HeaderValue::from_static("text/event-stream"));
// Step 11
request.cache_mode = CacheMode::NoStore;
// Step 12
@@ -613,9 +613,9 @@ impl EventSourceTimeoutCallback {
let mut request = event_source.request();
// Step 5.3
if !event_source.last_event_id.borrow().is_empty() {
- request.headers.set(LastEventId(String::from(
- event_source.last_event_id.borrow().clone(),
- )));
+ //TODO(eijebong): Change this once typed header support custom values
+ request.headers.insert(HeaderName::from_static("last-event-id"),
+ HeaderValue::from_str(&String::from(event_source.last_event_id.borrow().clone())).unwrap());
}
// Step 5.4
global
diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs
index c816c943303..69ca537a75b 100644
--- a/components/script/dom/filereader.rs
+++ b/components/script/dom/filereader.rs
@@ -22,13 +22,13 @@ use dom::globalscope::GlobalScope;
use dom::progressevent::ProgressEvent;
use dom_struct::dom_struct;
use encoding_rs::{Encoding, UTF_8};
-use hyper::mime::{Attr, Mime};
use js::jsapi::Heap;
use js::jsapi::JSAutoCompartment;
use js::jsapi::JSContext;
use js::jsapi::JSObject;
use js::jsval::{self, JSVal};
use js::typedarray::{ArrayBuffer, CreateWith};
+use mime::{self, Mime};
use servo_atoms::Atom;
use std::cell::Cell;
use std::ptr;
@@ -115,11 +115,10 @@ impl FileReaderSharedFunctionality {
// Step 4 & 5
encoding = encoding.or_else(|| {
let resultmime = blob_type.parse::<Mime>().ok();
- resultmime.and_then(|Mime(_, _, ref parameters)| {
- parameters
- .iter()
- .find(|&&(ref k, _)| &Attr::Charset == k)
- .and_then(|&(_, ref v)| Encoding::for_label(v.as_str().as_bytes()))
+ resultmime.and_then(|mime| {
+ mime.params()
+ .find(|(ref k, _)| &mime::CHARSET == k)
+ .and_then(|(_, ref v)| Encoding::for_label(v.as_ref().as_bytes()))
})
});
diff --git a/components/script/dom/headers.rs b/components/script/dom/headers.rs
index 9ff08e7c07a..2cdb955b43f 100644
--- a/components/script/dom/headers.rs
+++ b/components/script/dom/headers.rs
@@ -11,11 +11,11 @@ use dom::bindings::root::DomRoot;
use dom::bindings::str::{ByteString, is_token};
use dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
-use hyper::header::Headers as HyperHeaders;
-use mime::{Mime, TopLevel, SubLevel};
+use http::header::{self, HeaderMap as HyperHeaders, HeaderName, HeaderValue};
+use mime::{self, Mime};
use std::cell::Cell;
use std::result::Result;
-use std::str;
+use std::str::{self, FromStr};
#[dom_struct]
pub struct Headers {
@@ -87,14 +87,14 @@ impl HeadersMethods for Headers {
}
// Step 7
let mut combined_value: Vec<u8> = vec![];
- if let Some(v) = self.header_list.borrow().get_raw(&valid_name) {
- combined_value = v[0].clone();
+ if let Some(v) = self.header_list.borrow().get(HeaderName::from_str(&valid_name).unwrap()) {
+ combined_value = v.as_bytes().to_vec();
combined_value.push(b',');
}
combined_value.extend(valid_value.iter().cloned());
self.header_list
.borrow_mut()
- .set_raw(valid_name, vec![combined_value]);
+ .insert(HeaderName::from_str(&valid_name).unwrap(), HeaderValue::from_bytes(&combined_value).unwrap());
Ok(())
}
@@ -121,19 +121,17 @@ impl HeadersMethods for Headers {
return Ok(());
}
// Step 6
- self.header_list.borrow_mut().remove_raw(&valid_name);
+ self.header_list.borrow_mut().remove(&valid_name);
Ok(())
}
// https://fetch.spec.whatwg.org/#dom-headers-get
fn Get(&self, name: ByteString) -> Fallible<Option<ByteString>> {
// Step 1
- let valid_name = &validate_name(name)?;
- Ok(self
- .header_list
- .borrow()
- .get_raw(&valid_name)
- .map(|v| ByteString::new(v[0].clone())))
+ let valid_name = validate_name(name)?;
+ Ok(self.header_list.borrow().get(HeaderName::from_str(&valid_name).unwrap()).map(|v| {
+ ByteString::new(v.as_bytes().to_vec())
+ }))
}
// https://fetch.spec.whatwg.org/#dom-headers-has
@@ -141,7 +139,7 @@ impl HeadersMethods for Headers {
// Step 1
let valid_name = validate_name(name)?;
// Step 2
- Ok(self.header_list.borrow_mut().get_raw(&valid_name).is_some())
+ Ok(self.header_list.borrow_mut().get(&valid_name).is_some())
}
// https://fetch.spec.whatwg.org/#dom-headers-set
@@ -173,7 +171,7 @@ impl HeadersMethods for Headers {
// https://fetch.spec.whatwg.org/#concept-header-list-set
self.header_list
.borrow_mut()
- .set_raw(valid_name, vec![valid_value]);
+ .insert(HeaderName::from_str(&valid_name).unwrap(), HeaderValue::from_bytes(&valid_value).unwrap());
Ok(())
}
}
@@ -184,10 +182,10 @@ impl Headers {
match filler {
// Step 1
Some(HeadersInit::Headers(h)) => {
- for header in h.header_list.borrow().iter() {
+ for (name, value) in h.header_list.borrow().iter() {
self.Append(
- ByteString::new(Vec::from(header.name())),
- ByteString::new(Vec::from(header.value_string().into_bytes())),
+ ByteString::new(Vec::from(name.as_str())),
+ ByteString::new(Vec::from(value.to_str().unwrap().as_bytes()))
)?;
}
Ok(())
@@ -248,26 +246,21 @@ impl Headers {
}
pub fn get_headers_list(&self) -> HyperHeaders {
- let mut headers = HyperHeaders::new();
- headers.extend(self.header_list.borrow_mut().iter());
- headers
+ self.header_list.borrow_mut().clone()
}
// https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
pub fn extract_mime_type(&self) -> Vec<u8> {
- self.header_list
- .borrow()
- .get_raw("content-type")
- .map_or(vec![], |v| v[0].clone())
+ self.header_list.borrow().get(header::CONTENT_TYPE).map_or(vec![], |v| v.as_bytes().to_owned())
}
pub fn sort_header_list(&self) -> Vec<(String, String)> {
let borrowed_header_list = self.header_list.borrow();
let headers_iter = borrowed_header_list.iter();
let mut header_vec = vec![];
- for header in headers_iter {
- let name = header.name().to_string();
- let value = header.value_string();
+ for (name, value) in headers_iter {
+ let name = name.as_str().to_owned();
+ let value = value.to_str().unwrap().to_owned();
let name_value = (name, value);
header_vec.push(name_value);
}
@@ -306,12 +299,14 @@ fn is_cors_safelisted_request_content_type(value: &[u8]) -> bool {
let value_mime_result: Result<Mime, _> = value_string.parse();
match value_mime_result {
Err(_) => false,
- Ok(value_mime) => match value_mime {
- Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _) |
- Mime(TopLevel::Multipart, SubLevel::FormData, _) |
- Mime(TopLevel::Text, SubLevel::Plain, _) => true,
- _ => false,
- },
+ Ok(value_mime) => {
+ match (value_mime.type_(), value_mime.subtype()) {
+ (mime::APPLICATION, mime::WWW_FORM_URLENCODED) |
+ (mime::MULTIPART, mime::FORM_DATA) |
+ (mime::TEXT, mime::PLAIN) => true,
+ _ => false,
+ }
+ }
}
}
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 96f011bbb8e..c1c3e0e4446 100755
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -44,9 +44,12 @@ use dom::virtualmethods::VirtualMethods;
use dom::window::Window;
use dom_struct::dom_struct;
use encoding_rs::{Encoding, UTF_8};
+use headers_core::HeaderMapExt;
+use headers_ext::ContentType;
use html5ever::{LocalName, Prefix};
-use hyper::header::{Charset, ContentDisposition, ContentType, DispositionParam, DispositionType};
-use hyper::method::Method;
+use hyper::Method;
+use mime::{self, Mime};
+use net_traits::http_percent_encode;
use script_thread::MainThreadScriptMsg;
use script_traits::LoadData;
use servo_rand::random;
@@ -379,23 +382,15 @@ impl HTMLFormElement {
// https://html.spec.whatwg.org/multipage/#submit-dialog
},
// https://html.spec.whatwg.org/multipage/#submit-mutate-action
- ("http", FormMethod::FormGet) |
- ("https", FormMethod::FormGet) |
- ("data", FormMethod::FormGet) => {
- load_data.headers.set(ContentType::form_url_encoded());
+ ("http", FormMethod::FormGet) | ("https", FormMethod::FormGet) | ("data", FormMethod::FormGet) => {
+ load_data.headers.typed_insert(ContentType::from(mime::APPLICATION_WWW_FORM_URLENCODED));
self.mutate_action_url(&mut form_data, load_data, encoding, &target_window);
},
// https://html.spec.whatwg.org/multipage/#submit-body
("http", FormMethod::FormPost) | ("https", FormMethod::FormPost) => {
- load_data.method = Method::Post;
- self.submit_entity_body(
- &mut form_data,
- load_data,
- enctype,
- encoding,
- &target_window,
- );
- },
+ load_data.method = Method::POST;
+ self.submit_entity_body(&mut form_data, load_data, enctype, encoding, &target_window);
+ }
// https://html.spec.whatwg.org/multipage/#submit-get-action
("file", _) |
("about", _) |
@@ -450,7 +445,7 @@ impl HTMLFormElement {
let bytes = match enctype {
FormEncType::UrlEncoded => {
let charset = encoding.name();
- load_data.headers.set(ContentType::form_url_encoded());
+ load_data.headers.typed_insert(ContentType::from(mime::APPLICATION_WWW_FORM_URLENCODED));
self.set_encoding_override(load_data.url.as_mut_url().query_pairs_mut())
.clear()
@@ -463,12 +458,12 @@ impl HTMLFormElement {
load_data.url.query().unwrap_or("").to_string().into_bytes()
},
FormEncType::FormDataEncoded => {
- let mime = mime!(Multipart / FormData; Boundary =(&boundary));
- load_data.headers.set(ContentType(mime));
+ let mime: Mime = format!("multipart/form-data; boundary={}", boundary).parse().unwrap();
+ load_data.headers.typed_insert(ContentType::from(mime));
encode_multipart_form_data(form_data, boundary, encoding)
},
FormEncType::TextPlainEncoded => {
- load_data.headers.set(ContentType(mime!(Text / Plain)));
+ load_data.headers.typed_insert(ContentType::from(mime::TEXT_PLAIN));
self.encode_plaintext(form_data).into_bytes()
},
};
@@ -1231,40 +1226,30 @@ pub fn encode_multipart_form_data(
// what spec says (that it should start with a '\r\n').
let mut boundary_bytes = format!("--{}\r\n", boundary).into_bytes();
result.append(&mut boundary_bytes);
- let mut content_disposition = ContentDisposition {
- disposition: DispositionType::Ext("form-data".to_owned()),
- parameters: vec![DispositionParam::Ext(
- "name".to_owned(),
- String::from(entry.name.clone()),
- )],
- };
+ // TODO(eijebong): Everthing related to content-disposition it to redo once typed headers
+ // are capable of it.
match entry.value {
FormDatumValue::String(ref s) => {
+ let content_disposition = format!("form-data; name=\"{}\"", entry.name);
let mut bytes =
format!("Content-Disposition: {}\r\n\r\n{}", content_disposition, s)
.into_bytes();
result.append(&mut bytes);
},
FormDatumValue::File(ref f) => {
- content_disposition
- .parameters
- .push(DispositionParam::Filename(
- Charset::Ext(String::from(charset.clone())),
- None,
- f.name().clone().into(),
- ));
+ let extra = if charset.to_lowercase() == "utf-8" {
+ format!("filename=\"{}\"", String::from_utf8(f.name().as_bytes().into()).unwrap())
+ } else {
+ format!("filename*=\"{}\"''{}", charset, http_percent_encode(f.name().as_bytes()))
+ };
+
+ let content_disposition = format!("form-data; name=\"{}\"; {}", entry.name, extra);
// https://tools.ietf.org/html/rfc7578#section-4.4
- let content_type = ContentType(
- f.upcast::<Blob>()
- .Type()
- .parse()
- .unwrap_or(mime!(Text / Plain)),
- );
- let mut type_bytes = format!(
- "Content-Disposition: {}\r\ncontent-type: {}\r\n\r\n",
- content_disposition, content_type
- ).into_bytes();
+ let content_type: Mime = f.upcast::<Blob>().Type().parse().unwrap_or(mime::TEXT_PLAIN);
+ let mut type_bytes = format!("Content-Disposition: {}\r\ncontent-type: {}\r\n\r\n",
+ content_disposition,
+ content_type).into_bytes();
result.append(&mut type_bytes);
let mut bytes = f.upcast::<Blob>().get_bytes().unwrap_or(vec![]);
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index b31c5e886af..c9de1995230 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -44,7 +44,7 @@ use html5ever::{LocalName, Prefix};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use microtask::{Microtask, MicrotaskRunnable};
-use mime::{Mime, TopLevel, SubLevel};
+use mime::{self, Mime};
use net_traits::{FetchResponseListener, FetchMetadata, NetworkError, FetchResponseMsg};
use net_traits::image::base::{Image, ImageMetadata};
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageOrMetadataAvailable};
@@ -180,13 +180,9 @@ impl FetchResponseListener for ImageContext {
// Step 14.5 of https://html.spec.whatwg.org/multipage/#img-environment-changes
if let Some(metadata) = metadata.as_ref() {
if let Some(ref content_type) = metadata.content_type {
- match content_type.clone().into_inner().0 {
- Mime(TopLevel::Multipart, SubLevel::Ext(s), _) => {
- if s == "x-mixed-replace" {
- self.aborted.set(true);
- }
- },
- _ => (),
+ let mime: Mime = content_type.clone().into_inner().into();
+ if mime.type_() == mime::MULTIPART && mime.subtype().as_str() == "x-mixed-replace" {
+ self.aborted.set(true);
}
}
}
@@ -570,11 +566,12 @@ impl HTMLImageElement {
// TODO Handle unsupported mime type
let mime = x.value().parse::<Mime>();
match mime {
- Ok(m) => match m {
- Mime(TopLevel::Image, _, _) => (),
- _ => continue,
- },
- _ => continue,
+ Ok(m) =>
+ match m.type_() {
+ mime::IMAGE => (),
+ _ => continue
+ },
+ _ => continue
}
}
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 04754712887..1cd0b5e825a 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -34,12 +34,14 @@ use dom::promise::Promise;
use dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use fetch::FetchCanceller;
+use headers_core::HeaderMapExt;
+use headers_ext::ContentLength;
use html5ever::{LocalName, Prefix};
-use hyper::header::{ByteRangeSpec, ContentLength, Headers, Range as HyperRange};
+use http::header::{self, HeaderMap, HeaderValue};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use microtask::{Microtask, MicrotaskRunnable};
-use mime::{Mime, SubLevel, TopLevel};
+use mime::{self, Mime};
use net_traits::{CoreResourceMsg, FetchChannels, FetchResponseListener, FetchMetadata, Metadata};
use net_traits::NetworkError;
use net_traits::request::{CredentialsMode, Destination, RequestInit};
@@ -686,10 +688,9 @@ impl HTMLMediaElement {
HTMLMediaElementTypeId::HTMLAudioElement => Destination::Audio,
HTMLMediaElementTypeId::HTMLVideoElement => Destination::Video,
};
- let mut headers = Headers::new();
- headers.set(HyperRange::Bytes(vec![ByteRangeSpec::AllFrom(
- offset.unwrap_or(0),
- )]));
+ let mut headers = HeaderMap::new();
+ // FIXME(eijebong): Use typed headers once we have a constructor for the range header
+ headers.insert(header::RANGE, HeaderValue::from_str(&format!("bytes={}-", offset.unwrap_or(0))).unwrap());
let request = RequestInit {
url: self.resource_url.borrow().as_ref().unwrap().clone(),
headers,
@@ -1271,7 +1272,10 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
// https://html.spec.whatwg.org/multipage/#dom-navigator-canplaytype
fn CanPlayType(&self, type_: DOMString) -> CanPlayTypeResult {
match type_.parse::<Mime>() {
- Ok(Mime(TopLevel::Application, SubLevel::OctetStream, _)) | Err(_) => {
+ Ok(ref mime) if (mime.type_() == mime::APPLICATION && mime.subtype() == mime::OCTET_STREAM) => {
+ CanPlayTypeResult::_empty
+ },
+ Err(_) => {
CanPlayTypeResult::_empty
},
_ => CanPlayTypeResult::Maybe,
@@ -1464,8 +1468,8 @@ impl FetchResponseListener for HTMLMediaElementContext {
if let Some(metadata) = self.metadata.as_ref() {
if let Some(headers) = metadata.headers.as_ref() {
- if let Some(content_length) = headers.get::<ContentLength>() {
- if let Err(e) = self.elem.root().player.set_input_size(**content_length) {
+ if let Some(content_length) = headers.typed_get::<ContentLength>() {
+ if let Err(e) = self.elem.root().player.set_input_size(content_length.0) {
eprintln!("Could not set player input size {:?}", e);
}
}
diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs
index 0415aba9203..ceb64ec45ce 100644
--- a/components/script/dom/request.rs
+++ b/components/script/dom/request.rs
@@ -25,7 +25,8 @@ use dom::headers::{Guard, Headers};
use dom::promise::Promise;
use dom::xmlhttprequest::Extractable;
use dom_struct::dom_struct;
-use hyper::method::Method as HttpMethod;
+use http::Method as HttpMethod;
+use http::method::InvalidMethod;
use net_traits::ReferrerPolicy as MsgReferrerPolicy;
use net_traits::request::{Origin, Window};
use net_traits::request::CacheMode as NetTraitsRequestCache;
@@ -38,6 +39,7 @@ use net_traits::request::RequestMode as NetTraitsRequestMode;
use servo_url::ServoUrl;
use std::cell::{Cell, Ref};
use std::rc::Rc;
+use std::str::FromStr;
#[dom_struct]
pub struct Request {
@@ -283,7 +285,7 @@ impl Request {
}
// Step 25.2
let method = match init_method.as_str() {
- Some(s) => normalize_method(s),
+ Some(s) => normalize_method(s).map_err(|e| Error::Type(format!("Method is not valid: {:?}", e)))?,
None => return Err(Error::Type("Method is not a valid UTF8".to_string())),
};
// Step 25.3
@@ -373,16 +375,10 @@ impl Request {
let req = r.request.borrow();
let req_method = &req.method;
match *req_method {
- HttpMethod::Get => {
- return Err(Error::Type(
- "Init's body is non-null, and request method is GET".to_string(),
- ))
- },
- HttpMethod::Head => {
- return Err(Error::Type(
- "Init's body is non-null, and request method is HEAD".to_string(),
- ))
- },
+ HttpMethod::GET => return Err(Error::Type(
+ "Init's body is non-null, and request method is GET".to_string())),
+ HttpMethod::HEAD => return Err(Error::Type(
+ "Init's body is non-null, and request method is HEAD".to_string())),
_ => {},
}
}
@@ -473,17 +469,18 @@ fn net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequ
}
// https://fetch.spec.whatwg.org/#concept-method-normalize
-fn normalize_method(m: &str) -> HttpMethod {
+fn normalize_method(m: &str) -> Result<HttpMethod, InvalidMethod> {
match_ignore_ascii_case! { m,
- "delete" => return HttpMethod::Delete,
- "get" => return HttpMethod::Get,
- "head" => return HttpMethod::Head,
- "options" => return HttpMethod::Options,
- "post" => return HttpMethod::Post,
- "put" => return HttpMethod::Put,
+ "delete" => return Ok(HttpMethod::DELETE),
+ "get" => return Ok(HttpMethod::GET),
+ "head" => return Ok(HttpMethod::HEAD),
+ "options" => return Ok(HttpMethod::OPTIONS),
+ "post" => return Ok(HttpMethod::POST),
+ "put" => return Ok(HttpMethod::PUT),
_ => (),
}
- HttpMethod::Extension(m.to_string())
+ debug!("Method: {:?}", m);
+ HttpMethod::from_str(m)
}
// https://fetch.spec.whatwg.org/#concept-method
@@ -503,7 +500,9 @@ fn is_forbidden_method(m: &ByteString) -> bool {
// https://fetch.spec.whatwg.org/#cors-safelisted-method
fn is_cors_safelisted_method(m: &HttpMethod) -> bool {
- m == &HttpMethod::Get || m == &HttpMethod::Head || m == &HttpMethod::Post
+ m == &HttpMethod::GET ||
+ m == &HttpMethod::HEAD ||
+ m == &HttpMethod::POST
}
// https://url.spec.whatwg.org/#include-credentials
diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs
index 613145a370a..828dfc56515 100644
--- a/components/script/dom/response.rs
+++ b/components/script/dom/response.rs
@@ -18,8 +18,8 @@ use dom::headers::{is_vchar, is_obs_text};
use dom::promise::Promise;
use dom::xmlhttprequest::Extractable;
use dom_struct::dom_struct;
-use hyper::header::Headers as HyperHeaders;
-use hyper::status::StatusCode;
+use http::header::HeaderMap as HyperHeaders;
+use hyper::StatusCode;
use hyper_serde::Serde;
use net_traits::response::{ResponseBody as NetTraitsResponseBody};
use servo_url::ServoUrl;
@@ -55,7 +55,7 @@ impl Response {
headers_reflector: Default::default(),
mime_type: DomRefCell::new("".to_string().into_bytes()),
body_used: Cell::new(false),
- status: DomRefCell::new(Some(StatusCode::Ok)),
+ status: DomRefCell::new(Some(StatusCode::OK)),
raw_status: DomRefCell::new(Some((200, b"OK".to_vec()))),
response_type: DomRefCell::new(DOMResponseType::Default),
url: DomRefCell::new(None),
@@ -99,7 +99,7 @@ impl Response {
let r = Response::new(global);
// Step 4
- *r.status.borrow_mut() = Some(StatusCode::from_u16(init.status));
+ *r.status.borrow_mut() = Some(StatusCode::from_u16(init.status).unwrap());
// Step 5
*r.raw_status.borrow_mut() = Some((init.status, init.statusText.clone().into()));
@@ -189,7 +189,7 @@ impl Response {
let r = Response::new(global);
// Step 5
- *r.status.borrow_mut() = Some(StatusCode::from_u16(status));
+ *r.status.borrow_mut() = Some(StatusCode::from_u16(status).unwrap());
*r.raw_status.borrow_mut() = Some((status, b"".to_vec()));
// Step 6
@@ -300,7 +300,7 @@ impl ResponseMethods for Response {
fn Ok(&self) -> bool {
match *self.status.borrow() {
Some(s) => {
- let status_num = s.to_u16();
+ let status_num = s.as_u16();
return status_num >= 200 && status_num <= 299;
},
None => false,
diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs
index e64580f68c1..cacd54d2f1a 100644
--- a/components/script/dom/servoparser/mod.rs
+++ b/components/script/dom/servoparser/mod.rs
@@ -35,9 +35,8 @@ use html5ever::{Attribute, ExpandedName, LocalName, QualName};
use html5ever::buffer_queue::BufferQueue;
use html5ever::tendril::{StrTendril, ByteTendril, IncompleteUtf8};
use html5ever::tree_builder::{NodeOrText, TreeSink, NextParserState, QuirksMode, ElementFlags};
-use hyper::header::ContentType;
-use hyper::mime::{Mime, SubLevel, TopLevel};
use hyper_serde::Serde;
+use mime::{self, Mime};
use msg::constellation_msg::PipelineId;
use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError};
use network_listener::PreInvoke;
@@ -697,10 +696,11 @@ impl FetchResponseListener for ParserContext {
},
Err(_) => None,
};
- let content_type = metadata
+ let content_type: Option<Mime> = metadata
.clone()
.and_then(|meta| meta.content_type)
- .map(Serde::into_inner);
+ .map(Serde::into_inner)
+ .map(Into::into);
let parser = match ScriptThread::page_headers_available(&self.id, metadata) {
Some(parser) => parser,
None => return,
@@ -712,7 +712,7 @@ impl FetchResponseListener for ParserContext {
self.parser = Some(Trusted::new(&*parser));
match content_type {
- Some(ContentType(Mime(TopLevel::Image, _, _))) => {
+ Some(ref mime) if mime.type_() == mime::IMAGE => {
self.is_synthesized_document = true;
let page = "<html><body></body></html>".into();
parser.push_string_input_chunk(page);
@@ -725,14 +725,14 @@ impl FetchResponseListener for ParserContext {
doc_body.AppendChild(&DomRoot::upcast::<Node>(img)).expect("Appending failed");
},
- Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => {
+ Some(ref mime) if mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN => {
// https://html.spec.whatwg.org/multipage/#read-text
let page = "<pre>\n".into();
parser.push_string_input_chunk(page);
parser.parse_sync();
parser.tokenizer.borrow_mut().set_plaintext_state();
},
- Some(ContentType(Mime(TopLevel::Text, SubLevel::Html, _))) => {
+ Some(ref mime) if mime.type_() == mime::TEXT && mime.subtype() == mime::HTML => {
// Handle text/html
if let Some(reason) = ssl_error {
self.is_synthesized_document = true;
@@ -749,15 +749,18 @@ impl FetchResponseListener for ParserContext {
parser.parse_sync();
}
},
- Some(ContentType(Mime(TopLevel::Text, SubLevel::Xml, _))) | // Handle text/xml, application/xml
- Some(ContentType(Mime(TopLevel::Application, SubLevel::Xml, _))) => {},
- Some(ContentType(Mime(TopLevel::Application, SubLevel::Ext(ref sub), _)))
- if sub.as_str() == "xhtml+xml".to_owned() => {}, // Handle xhtml (application/xhtml+xml)
- Some(ContentType(Mime(toplevel, sublevel, _))) => {
+ // Handle text/xml, application/xml
+ Some(ref mime) if (mime.type_() == mime::TEXT && mime.subtype() == mime::XML) ||
+ (mime.type_() == mime::APPLICATION && mime.subtype() == mime::XML) => {},
+ Some(ref mime) if mime.type_() == mime::APPLICATION &&
+ mime.subtype().as_str() == "xhtml" &&
+ mime.suffix() == Some(mime::XML)
+ => {}, // Handle xhtml (application/xhtml+xml)
+ Some(ref mime) => {
// Show warning page for unknown mime types.
let page = format!("<html><body><p>Unknown content type ({}/{}).</p></body></html>",
- toplevel.as_str(),
- sublevel.as_str());
+ mime.type_().as_str(),
+ mime.subtype().as_str());
self.is_synthesized_document = true;
parser.push_string_input_chunk(page);
parser.parse_sync();
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 38d206b3a1b..6ed6a7ffab4 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -39,12 +39,12 @@ use dom_struct::dom_struct;
use encoding_rs::{Encoding, UTF_8};
use euclid::Length;
use fetch::FetchCanceller;
+use headers_core::HeaderMapExt;
+use headers_ext::{ContentLength, ContentType};
use html5ever::serialize;
use html5ever::serialize::SerializeOpts;
-use hyper::header::{ContentLength, ContentType, ContentEncoding};
-use hyper::header::Headers;
-use hyper::method::Method;
-use hyper::mime::{self, Attr as MimeAttr, Mime, Value as MimeValue};
+use http::header::{self, HeaderMap, HeaderName, HeaderValue};
+use hyper::Method;
use hyper_serde::Serde;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
@@ -53,6 +53,7 @@ use js::jsapi::JS_ClearPendingException;
use js::jsval::{JSVal, NullValue, UndefinedValue};
use js::rust::wrappers::JS_ParseJSON;
use js::typedarray::{ArrayBuffer, CreateWith};
+use mime::{self, Mime, Name};
use net_traits::{FetchChannels, FetchMetadata, FilteredMetadata};
use net_traits::{FetchResponseListener, NetworkError, ReferrerPolicy};
use net_traits::CoreResourceMsg::Fetch;
@@ -68,7 +69,7 @@ use std::default::Default;
use std::ptr;
use std::ptr::NonNull;
use std::slice;
-use std::str;
+use std::str::{self, FromStr};
use std::sync::{Arc, Mutex};
use task_source::TaskSourceName;
use task_source::networking::NetworkingTaskSource;
@@ -100,7 +101,7 @@ struct XHRContext {
#[derive(Clone)]
pub enum XHRProgress {
/// Notify that headers have been received
- HeadersReceived(GenerationId, Option<Headers>, Option<(u16, Vec<u8>)>),
+ HeadersReceived(GenerationId, Option<HeaderMap>, Option<(u16, Vec<u8>)>),
/// Partial progress (after receiving headers), containing portion of the response
Loading(GenerationId, ByteString),
/// Loading is done
@@ -138,7 +139,7 @@ pub struct XMLHttpRequest {
#[ignore_malloc_size_of = "Defined in rust-mozjs"]
response_json: Heap<JSVal>,
#[ignore_malloc_size_of = "Defined in hyper"]
- response_headers: DomRefCell<Headers>,
+ response_headers: DomRefCell<HeaderMap>,
#[ignore_malloc_size_of = "Defined in hyper"]
override_mime_type: DomRefCell<Option<Mime>>,
override_charset: DomRefCell<Option<&'static Encoding>>,
@@ -148,7 +149,7 @@ pub struct XMLHttpRequest {
request_method: DomRefCell<Method>,
request_url: DomRefCell<Option<ServoUrl>>,
#[ignore_malloc_size_of = "Defined in hyper"]
- request_headers: DomRefCell<Headers>,
+ request_headers: DomRefCell<HeaderMap>,
request_body_len: Cell<usize>,
sync: Cell<bool>,
upload_complete: Cell<bool>,
@@ -188,13 +189,13 @@ impl XMLHttpRequest {
response_blob: Default::default(),
response_arraybuffer: Heap::default(),
response_json: Heap::default(),
- response_headers: DomRefCell::new(Headers::new()),
+ response_headers: DomRefCell::new(HeaderMap::new()),
override_mime_type: DomRefCell::new(None),
override_charset: DomRefCell::new(None),
- request_method: DomRefCell::new(Method::Get),
+ request_method: DomRefCell::new(Method::GET),
request_url: DomRefCell::new(None),
- request_headers: DomRefCell::new(Headers::new()),
+ request_headers: DomRefCell::new(HeaderMap::new()),
request_body_len: Cell::new(0),
sync: Cell::new(false),
upload_complete: Cell::new(false),
@@ -347,8 +348,8 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
match maybe_method {
// Step 4
- Some(Method::Connect) | Some(Method::Trace) => Err(Error::Security),
- Some(Method::Extension(ref t)) if &**t == "TRACK" => Err(Error::Security),
+ Some(Method::CONNECT) | Some(Method::TRACE) => Err(Error::Security),
+ Some(ref t) if t.as_str() == "TRACK" => Err(Error::Security),
Some(parsed_method) => {
// Step 3
if !is_token(&method) {
@@ -395,7 +396,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
*self.request_method.borrow_mut() = parsed_method;
*self.request_url.borrow_mut() = Some(parsed_url);
self.sync.set(!async);
- *self.request_headers.borrow_mut() = Headers::new();
+ *self.request_headers.borrow_mut() = HeaderMap::new();
self.send_flag.set(false);
*self.status_text.borrow_mut() = ByteString::new(vec![]);
self.status.set(0);
@@ -450,19 +451,17 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
let mut headers = self.request_headers.borrow_mut();
// Step 6
- let value = match headers.get_raw(name_str) {
+ let value = match headers.get(name_str).map(HeaderValue::as_bytes) {
Some(raw) => {
- debug!("SetRequestHeader: old value = {:?}", raw[0]);
- let mut buf = raw[0].clone();
+ let mut buf = raw.to_vec();
buf.extend_from_slice(b", ");
buf.extend_from_slice(value);
- debug!("SetRequestHeader: new value = {:?}", buf);
buf
},
None => value.into(),
};
- headers.set_raw(name_str.to_owned(), vec![value]);
+ headers.insert(HeaderName::from_str(name_str).unwrap(), HeaderValue::from_bytes(&value).unwrap());
Ok(())
}
@@ -532,8 +531,8 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// Step 3
let data = match *self.request_method.borrow() {
- Method::Get | Method::Head => None,
- _ => data,
+ Method::GET | Method::HEAD => None,
+ _ => data
};
// Step 4 (first half)
let extracted_or_serialized = match data {
@@ -638,30 +637,46 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// XHR spec differs from http, and says UTF-8 should be in capitals,
// instead of "utf-8", which is what Hyper defaults to. So not
// using content types provided by Hyper.
- {
- Some(MimeValue::Ext("UTF-8".to_string()))
- },
+ Some("UTF-8"),
_ => None,
};
let mut content_type_set = false;
if let Some(ref ct) = *content_type {
- if !request.headers.has::<ContentType>() {
- request
- .headers
- .set_raw("content-type", vec![ct.bytes().collect()]);
+ if !request.headers.contains_key(header::CONTENT_TYPE) {
+ request.headers.insert(header::CONTENT_TYPE, HeaderValue::from_str(ct).unwrap());
content_type_set = true;
}
}
if !content_type_set {
- let ct = request.headers.get_mut::<ContentType>();
+ let ct = request.headers.typed_get::<ContentType>();
if let Some(ct) = ct {
if let Some(encoding) = encoding {
- for param in &mut (ct.0).2 {
- if param.0 == MimeAttr::Charset {
- if !param.0.as_str().eq_ignore_ascii_case(encoding.as_str()) {
- *param = (MimeAttr::Charset, encoding.clone());
+ let mime: Mime = ct.into();
+ for param in mime.params() {
+ if param.0 == mime::CHARSET {
+ if !param.1.as_ref().eq_ignore_ascii_case(encoding) {
+ let new_params: Vec<(Name, Name)> =
+ mime.params()
+ .filter(|p| p.0 != mime::CHARSET)
+ .map(|p| (p.0, p.1))
+ .collect();
+
+ let new_mime =
+ format!("{}/{}; charset={}{}{}",
+ mime.type_().as_ref(),
+ mime.subtype().as_ref(),
+ encoding,
+ if new_params.is_empty() { "" } else { "; " },
+ new_params
+ .iter()
+ .map(|p| format!("{}={}", p.0, p.1))
+ .collect::<Vec<String>>()
+ .join("; ")
+ );
+ let new_mime: Mime = new_mime.parse().unwrap();
+ request.headers.typed_insert(ContentType::from(new_mime))
}
}
}
@@ -672,8 +687,6 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
_ => (),
}
- debug!("request.headers = {:?}", request.headers);
-
self.fetch_time.set(time::now().to_timespec().sec);
let rv = self.fetch(request, &self.global());
@@ -728,15 +741,48 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// https://xhr.spec.whatwg.org/#the-getresponseheader()-method
fn GetResponseHeader(&self, name: ByteString) -> Option<ByteString> {
- self.filter_response_headers()
- .iter()
- .find(|h| name.eq_ignore_case(&h.name().parse().unwrap()))
- .map(|h| ByteString::new(h.value_string().into_bytes()))
+ let headers = self.filter_response_headers();
+ let headers = headers.get_all(HeaderName::from_str(&name.as_str()?.to_lowercase()).ok()?);
+ let mut first = true;
+ let s = headers.iter()
+ .fold(Vec::new(), |mut vec, value| {
+ if !first {
+ vec.extend(", ".as_bytes());
+ }
+ first = false;
+ vec.extend(value.as_bytes());
+ vec
+ });
+
+ // There was no header with that name so we never got to change that value
+ if first {
+ None
+ } else {
+ Some(ByteString::new(s))
+ }
}
// https://xhr.spec.whatwg.org/#the-getallresponseheaders()-method
fn GetAllResponseHeaders(&self) -> ByteString {
- ByteString::new(self.filter_response_headers().to_string().into_bytes())
+ let headers = self.filter_response_headers();
+ let keys = headers.keys();
+ let v = keys.fold(Vec::new(), |mut vec, k| {
+ let values = headers.get_all(k);
+ vec.extend(k.as_str().as_bytes());
+ vec.extend(": ".as_bytes());
+ let mut first = true;
+ for value in values {
+ if !first {
+ vec.extend(", ".as_bytes());
+ first = false;
+ }
+ vec.extend(value.as_bytes());
+ }
+ vec.extend("\r\n".as_bytes());
+ vec
+ });
+
+ ByteString::new(v)
}
// https://xhr.spec.whatwg.org/#the-overridemimetype()-method
@@ -751,12 +797,20 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// Step 2
let override_mime = mime.parse::<Mime>().map_err(|_| Error::Syntax)?;
// Step 3
- let mime_no_params = Mime(override_mime.clone().0, override_mime.clone().1, vec![]);
+ let mime_str = override_mime.as_ref();
+ let mime_parts: Vec<&str> = mime_str.split(";").collect();
+ let mime_no_params = if mime_parts.len() > 1 {
+ mime_parts[0].parse().unwrap()
+ } else {
+ override_mime.clone()
+ };
+
*self.override_mime_type.borrow_mut() = Some(mime_no_params);
// Step 4
- let value = override_mime.get_param(mime::Attr::Charset);
- *self.override_charset.borrow_mut() =
- value.and_then(|value| Encoding::for_label(value.as_bytes()));
+ let value = override_mime.get_param(mime::CHARSET);
+ *self.override_charset.borrow_mut() = value.and_then(|value| {
+ Encoding::for_label(value.as_ref().as_bytes())
+ });
Ok(())
}
@@ -1077,20 +1131,17 @@ impl XMLHttpRequest {
fn dispatch_progress_event(&self, upload: bool, type_: Atom, loaded: u64, total: Option<u64>) {
let (total_length, length_computable) =
- if self.response_headers.borrow().has::<ContentEncoding>() {
+ if self.response_headers.borrow().contains_key(header::CONTENT_ENCODING) {
(0, false)
} else {
(total.unwrap_or(0), total.is_some())
};
- let progressevent = ProgressEvent::new(
- &self.global(),
- type_,
- EventBubbles::DoesNotBubble,
- EventCancelable::NotCancelable,
- length_computable,
- loaded,
- total_length,
- );
+ let progressevent = ProgressEvent::new(&self.global(),
+ type_,
+ EventBubbles::DoesNotBubble,
+ EventCancelable::NotCancelable,
+ length_computable, loaded,
+ total_length);
let target = if upload {
self.upload.upcast()
} else {
@@ -1108,13 +1159,10 @@ impl XMLHttpRequest {
fn dispatch_response_progress_event(&self, type_: Atom) {
let len = self.response.borrow().len() as u64;
- let total = self
- .response_headers
- .borrow()
- .get::<ContentLength>()
- .map(|x| **x as u64);
+ let total = self.response_headers.borrow().typed_get::<ContentLength>().map(|v| v.0);
self.dispatch_progress_event(false, type_, len, total);
}
+
fn set_timeout(&self, duration_ms: u32) {
// Sets up the object to timeout in a given number of milliseconds
// This will cancel all previous timeouts
@@ -1154,11 +1202,7 @@ impl XMLHttpRequest {
return response;
}
// Step 2
- let mime = self
- .final_mime_type()
- .as_ref()
- .map(Mime::to_string)
- .unwrap_or("".to_owned());
+ let mime = self.final_mime_type().as_ref().map(|m| m.to_string()).unwrap_or("".to_owned());
// Step 3, 4
let bytes = self.response.borrow().to_vec();
@@ -1200,7 +1244,7 @@ impl XMLHttpRequest {
let charset = self.final_charset().unwrap_or(UTF_8);
let temp_doc: DomRoot<Document>;
match mime_type {
- Some(Mime(mime::TopLevel::Text, mime::SubLevel::Html, _)) => {
+ Some(ref mime) if mime.type_() == mime::TEXT && mime.subtype() == mime::HTML => {
// Step 5
if self.response_type.get() == XMLHttpRequestResponseType::_empty {
return None;
@@ -1210,17 +1254,15 @@ impl XMLHttpRequest {
}
},
// Step 7
- Some(Mime(mime::TopLevel::Text, mime::SubLevel::Xml, _)) |
- Some(Mime(mime::TopLevel::Application, mime::SubLevel::Xml, _)) |
+ Some(ref mime) if (mime.type_() == mime::TEXT && mime.subtype() == mime::XML) ||
+ (mime.type_() == mime::APPLICATION && mime.subtype() == mime::XML) => {
+ temp_doc = self.handle_xml();
+ },
None => {
temp_doc = self.handle_xml();
},
- Some(Mime(_, mime::SubLevel::Ext(sub), _)) => {
- if sub.ends_with("+xml") {
- temp_doc = self.handle_xml();
- } else {
- return None;
- }
+ Some(ref mime) if mime.suffix() == Some(mime::XML) => {
+ temp_doc = self.handle_xml();
},
// Step 4
_ => {
@@ -1336,34 +1378,13 @@ impl XMLHttpRequest {
)
}
- fn filter_response_headers(&self) -> Headers {
+ fn filter_response_headers(&self) -> HeaderMap {
// https://fetch.spec.whatwg.org/#concept-response-header-list
- use hyper::error::Result;
- use hyper::header::{Header, HeaderFormat};
- use hyper::header::SetCookie;
- use std::fmt;
-
- // a dummy header so we can use headers.remove::<SetCookie2>()
- #[derive(Clone, Debug, MallocSizeOf)]
- struct SetCookie2;
- impl Header for SetCookie2 {
- fn header_name() -> &'static str {
- "set-cookie2"
- }
-
- fn parse_header(_: &[Vec<u8>]) -> Result<SetCookie2> {
- unimplemented!()
- }
- }
- impl HeaderFormat for SetCookie2 {
- fn fmt_header(&self, _f: &mut fmt::Formatter) -> fmt::Result {
- unimplemented!()
- }
- }
+ use http::header::{self, HeaderName};
let mut headers = self.response_headers.borrow().clone();
- headers.remove::<SetCookie>();
- headers.remove::<SetCookie2>();
+ headers.remove(header::SET_COOKIE);
+ headers.remove(HeaderName::from_static("set-cookie2"));
// XXXManishearth additional CORS filtering goes here
headers
}
@@ -1416,12 +1437,15 @@ impl XMLHttpRequest {
if self.override_charset.borrow().is_some() {
self.override_charset.borrow().clone()
} else {
- match self.response_headers.borrow().get() {
- Some(&ContentType(ref mime)) => {
- let value = mime.get_param(mime::Attr::Charset);
- value.and_then(|value| Encoding::for_label(value.as_bytes()))
- },
- None => None,
+ match self.response_headers.borrow().typed_get::<ContentType>() {
+ Some(ct) => {
+ let mime: Mime = ct.into();
+ let value = mime.get_param(mime::CHARSET);
+ value.and_then(|value|{
+ Encoding::for_label(value.as_ref().as_bytes())
+ })
+ }
+ None => { None }
}
}
}
@@ -1430,9 +1454,9 @@ impl XMLHttpRequest {
if self.override_mime_type.borrow().is_some() {
self.override_mime_type.borrow().clone()
} else {
- match self.response_headers.borrow().get() {
- Some(&ContentType(ref mime)) => Some(mime.clone()),
- None => None,
+ match self.response_headers.borrow().typed_get::<ContentType>() {
+ Some(ct) => { Some(ct.into()) },
+ None => { None }
}
}
}
diff --git a/components/script/lib.rs b/components/script/lib.rs
index a402bec7cf3..ef0205b68b6 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -45,9 +45,11 @@ extern crate euclid;
extern crate fnv;
extern crate gleam;
extern crate half;
+extern crate headers_core;
+extern crate headers_ext;
#[macro_use]
extern crate html5ever;
-#[macro_use]
+extern crate http;
extern crate hyper;
extern crate hyper_serde;
extern crate image;
@@ -65,7 +67,6 @@ extern crate malloc_size_of;
#[macro_use]
extern crate malloc_size_of_derive;
extern crate metrics;
-#[macro_use]
extern crate mime;
extern crate mime_guess;
extern crate mitochondria;
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 8795a65cd13..e1d9fd4c0e4 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -65,9 +65,9 @@ use dom::workletglobalscope::WorkletGlobalScopeInit;
use embedder_traits::EmbedderMsg;
use euclid::{Point2D, Vector2D, Rect};
use fetch::FetchCanceller;
-use hyper::header::{ContentType, HttpDate, Headers, LastModified};
-use hyper::header::ReferrerPolicy as ReferrerPolicyHeader;
-use hyper::mime::{Mime, SubLevel, TopLevel};
+use headers_core::HeaderMapExt;
+use headers_ext::LastModified;
+use headers_ext::ReferrerPolicy as ReferrerPolicyHeader;
use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcSender};
use js::glue::GetWindowProxyClass;
@@ -76,6 +76,7 @@ use js::jsapi::{JSTracer, SetWindowProxyClass};
use js::jsval::UndefinedValue;
use metrics::{MAX_TASK_NS, PaintTimeMetrics};
use microtask::{MicrotaskQueue, Microtask};
+use mime::{self, Mime};
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId};
use msg::constellation_msg::{PipelineNamespace, TopLevelBrowsingContextId};
use net_traits::{FetchMetadata, FetchResponseListener, FetchResponseMsg};
@@ -115,6 +116,7 @@ use std::rc::Rc;
use std::result::Result;
use std::sync::Arc;
use std::thread;
+use std::time::SystemTime;
use style::thread_state::{self, ThreadState};
use task_queue::{QueuedTask, QueuedTaskConversion, TaskQueue};
use task_source::TaskSourceName;
@@ -127,7 +129,7 @@ use task_source::performance_timeline::PerformanceTimelineTaskSource;
use task_source::remote_event::RemoteEventTaskSource;
use task_source::user_interaction::UserInteractionTaskSource;
use task_source::websocket::WebsocketTaskSource;
-use time::{get_time, precise_time_ns, Tm};
+use time::{at_utc, get_time, precise_time_ns, Timespec};
use url::Position;
use url::percent_encoding::percent_decode;
use webdriver_handlers;
@@ -2611,37 +2613,27 @@ impl ScriptThread {
window.init_window_proxy(&window_proxy);
let last_modified = metadata.headers.as_ref().and_then(|headers| {
- headers
- .get()
- .map(|&LastModified(HttpDate(ref tm))| dom_last_modified(tm))
+ headers.typed_get::<LastModified>()
+ .map(|tm| dom_last_modified(&tm.into()))
});
- let content_type = metadata
- .content_type
- .as_ref()
- .map(|&Serde(ContentType(ref mimetype))| mimetype.clone());
-
let loader = DocumentLoader::new_with_threads(
self.resource_threads.clone(),
Some(final_url.clone()),
);
- let is_html_document = match metadata.content_type {
- Some(Serde(ContentType(Mime(
- TopLevel::Application,
- SubLevel::Ext(ref sub_level),
- _,
- ))))
- if sub_level.ends_with("+xml") =>
- {
- IsHTMLDocument::NonHTMLDocument
- },
+ let content_type: Option<Mime> = metadata.content_type
+ .map(Serde::into_inner)
+ .map(Into::into);
- Some(Serde(ContentType(Mime(TopLevel::Application, SubLevel::Xml, _)))) |
- Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Xml, _)))) => {
- IsHTMLDocument::NonHTMLDocument
- },
+ let is_html_document = match content_type {
+ Some(ref mime) if mime.type_() == mime::APPLICATION &&
+ mime.suffix() == Some(mime::XML) => IsHTMLDocument::NonHTMLDocument,
+ Some(ref mime) if
+ (mime.type_() == mime::TEXT && mime.subtype() == mime::XML) ||
+ (mime.type_() == mime::APPLICATION && mime.subtype() == mime::XML)
+ => IsHTMLDocument::NonHTMLDocument,
_ => IsHTMLDocument::HTMLDocument,
};
@@ -2650,28 +2642,25 @@ impl ScriptThread {
None => None,
};
- let referrer_policy = metadata
- .headers
- .as_ref()
- .map(Serde::deref)
- .and_then(Headers::get::<ReferrerPolicyHeader>)
- .map(ReferrerPolicy::from);
-
- let document = Document::new(
- &window,
- HasBrowsingContext::Yes,
- Some(final_url.clone()),
- incomplete.origin,
- is_html_document,
- content_type,
- last_modified,
- incomplete.activity,
- DocumentSource::FromParser,
- loader,
- referrer,
- referrer_policy,
- incomplete.canceller,
- );
+ let referrer_policy = metadata.headers
+ .as_ref()
+ .map(Serde::deref)
+ .and_then(|h| h.typed_get::<ReferrerPolicyHeader>())
+ .map(ReferrerPolicy::from);
+
+ let document = Document::new(&window,
+ HasBrowsingContext::Yes,
+ Some(final_url.clone()),
+ incomplete.origin,
+ is_html_document,
+ content_type,
+ last_modified,
+ incomplete.activity,
+ DocumentSource::FromParser,
+ loader,
+ referrer,
+ referrer_policy,
+ incomplete.canceller);
document.set_ready_state(DocumentReadyState::Loading);
self.documents
@@ -3112,7 +3101,7 @@ impl ScriptThread {
let mut context = ParserContext::new(id, url.clone());
let mut meta = Metadata::default(url);
- meta.set_content_type(Some(&mime!(Text / Html)));
+ meta.set_content_type(Some(&mime::TEXT_HTML));
// If this page load is the result of a javascript scheme url, map
// the evaluation result into a response.
@@ -3221,7 +3210,10 @@ impl Drop for ScriptThread {
}
}
-fn dom_last_modified(tm: &Tm) -> String {
+fn dom_last_modified(tm: &SystemTime) -> String {
+ let tm = tm.duration_since(SystemTime::UNIX_EPOCH).unwrap();
+ let tm = Timespec::new(tm.as_secs() as i64, 0);
+ let tm = at_utc(tm);
tm.to_local()
.strftime("%m/%d/%Y %H:%M:%S")
.unwrap()
diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs
index 8ae75a6e35b..6562dcf7c2a 100644
--- a/components/script/stylesheet_loader.rs
+++ b/components/script/stylesheet_loader.rs
@@ -14,11 +14,9 @@ use dom::htmlelement::HTMLElement;
use dom::htmllinkelement::{RequestGenerationId, HTMLLinkElement};
use dom::node::{document_from_node, window_from_node};
use encoding_rs::UTF_8;
-use hyper::header::ContentType;
-use hyper::mime::{Mime, TopLevel, SubLevel};
-use hyper_serde::Serde;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
+use mime::{self, Mime};
use net_traits::{FetchResponseListener, FetchMetadata, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy};
use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode};
use network_listener::{NetworkListener, PreInvoke};
@@ -117,18 +115,12 @@ impl FetchResponseListener for StylesheetContext {
Some(meta) => meta,
None => return,
};
- let is_css =
- metadata
- .content_type
- .map_or(false, |Serde(ContentType(Mime(top, sub, _)))| {
- top == TopLevel::Text && sub == SubLevel::Css
- });
-
- let data = if is_css {
- mem::replace(&mut self.data, vec![])
- } else {
- vec![]
- };
+ let is_css = metadata.content_type.map_or(false, |ct| {
+ let mime: Mime = ct.into_inner().into();
+ mime.type_() == mime::TEXT && mime.subtype() == mime::CSS
+ });
+
+ let data = if is_css { mem::replace(&mut self.data, vec![]) } else { vec![] };
// TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
let environment_encoding = UTF_8;
diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs
index 6c3e7deb910..3ac4362f8bd 100644
--- a/components/script/webdriver_handlers.rs
+++ b/components/script/webdriver_handlers.rs
@@ -299,7 +299,11 @@ pub fn handle_add_cookie(
},
};
let url = document.url();
- let method = if cookie.http_only() { HTTP } else { NonHTTP };
+ let method = if cookie.http_only().unwrap_or(false) {
+ HTTP
+ } else {
+ NonHTTP
+ };
let domain = cookie.domain().map(ToOwned::to_owned);
reply
diff --git a/components/script_traits/Cargo.toml b/components/script_traits/Cargo.toml
index 580897fcc58..3656990aafe 100644
--- a/components/script_traits/Cargo.toml
+++ b/components/script_traits/Cargo.toml
@@ -12,13 +12,14 @@ path = "lib.rs"
[dependencies]
bluetooth_traits = {path = "../bluetooth_traits"}
canvas_traits = {path = "../canvas_traits"}
-cookie = "0.10"
+cookie = "0.11"
devtools_traits = {path = "../devtools_traits"}
embedder_traits = {path = "../embedder_traits"}
euclid = "0.19"
gfx_traits = {path = "../gfx_traits"}
-hyper = "0.10"
-hyper_serde = "0.8"
+http = "0.1"
+hyper = "0.12"
+hyper_serde = "0.9"
ipc-channel = "0.11"
keyboard-types = {version = "0.4.2-servo", features = ["serde"]}
libc = "0.2"
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index cc9787d4721..6ac224d0b51 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -16,6 +16,7 @@ extern crate devtools_traits;
extern crate embedder_traits;
extern crate euclid;
extern crate gfx_traits;
+extern crate http;
extern crate hyper;
extern crate hyper_serde;
extern crate ipc_channel;
@@ -47,8 +48,8 @@ use canvas_traits::webgl::WebGLPipeline;
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
use euclid::{Length, Point2D, Vector2D, Rect, TypedSize2D, TypedScale};
use gfx_traits::Epoch;
-use hyper::header::Headers;
-use hyper::method::Method;
+use http::HeaderMap;
+use hyper::Method;
use ipc_channel::{Error as IpcError};
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use keyboard_types::KeyboardEvent;
@@ -148,7 +149,7 @@ pub struct LoadData {
deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize"
)]
- pub headers: Headers,
+ pub headers: HeaderMap,
/// The data.
pub data: Option<Vec<u8>>,
/// The result of evaluating a javascript scheme url.
@@ -180,8 +181,8 @@ impl LoadData {
LoadData {
url: url,
creator_pipeline_id: creator_pipeline_id,
- method: Method::Get,
- headers: Headers::new(),
+ method: Method::GET,
+ headers: HeaderMap::new(),
data: None,
js_eval_result: None,
referrer_policy: referrer_policy,
diff --git a/components/webdriver_server/Cargo.toml b/components/webdriver_server/Cargo.toml
index d5f4c6fd76c..18d13d309df 100644
--- a/components/webdriver_server/Cargo.toml
+++ b/components/webdriver_server/Cargo.toml
@@ -10,10 +10,10 @@ name = "webdriver_server"
path = "lib.rs"
[dependencies]
-base64 = "0.6"
-cookie = "0.10"
+base64 = "0.9"
+cookie = "0.11"
euclid = "0.19"
-hyper = "0.10"
+hyper = "0.12"
image = "0.19"
ipc-channel = "0.11"
keyboard-types = {version = "0.4.2-servo", features = ["serde"]}
@@ -21,11 +21,12 @@ log = "0.4"
msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
regex = "1.0"
-rustc-serialize = "0.3.4"
+serde = "1"
+serde_json = "1"
script_traits = {path = "../script_traits"}
servo_channel = {path = "../channel"}
servo_config = {path = "../config"}
servo_url = {path = "../url"}
url = "1.2"
uuid = {version = "0.6", features = ["v4"]}
-webdriver = "0.35"
+webdriver = "0.37"
diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs
index 300096061d0..6c1bbbf8094 100644
--- a/components/webdriver_server/lib.rs
+++ b/components/webdriver_server/lib.rs
@@ -18,8 +18,10 @@ extern crate log;
extern crate msg;
extern crate net_traits;
extern crate regex;
-extern crate rustc_serialize;
extern crate script_traits;
+#[macro_use]
+extern crate serde;
+extern crate serde_json;
extern crate servo_channel;
extern crate servo_config;
extern crate servo_url;
@@ -29,77 +31,55 @@ extern crate webdriver;
mod keys;
use euclid::TypedSize2D;
-use hyper::method::Method::{self, Post};
+use hyper::Method;
use image::{DynamicImage, ImageFormat, RgbImage};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use keys::keycodes_to_keys;
use msg::constellation_msg::{BrowsingContextId, TopLevelBrowsingContextId, TraversalDirection};
use net_traits::image::base::PixelFormat;
use regex::Captures;
-use rustc_serialize::json::{Json, ToJson};
use script_traits::{ConstellationMsg, LoadData, WebDriverCommandMsg};
use script_traits::webdriver_msg::{LoadStatus, WebDriverCookieError, WebDriverFrameId};
-use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult, WebDriverScriptCommand};
+use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult, WebDriverScriptCommand, WebDriverJSValue};
+use serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
+use serde::ser::{Serialize, Serializer};
+use serde_json::Value;
use servo_channel::Sender;
use servo_config::prefs::{PREFS, PrefValue};
use servo_url::ServoUrl;
use std::borrow::ToOwned;
use std::collections::BTreeMap;
+use std::fmt;
use std::net::{SocketAddr, SocketAddrV4};
use std::thread;
use std::time::Duration;
use uuid::Uuid;
-use webdriver::command::{AddCookieParameters, GetParameters, JavascriptCommandParameters};
-use webdriver::command::{LocatorParameters, Parameters};
+use webdriver::command::{AddCookieParameters, GetParameters, JavascriptCommandParameters, LocatorParameters};
use webdriver::command::{SendKeysParameters, SwitchToFrameParameters, TimeoutsParameters};
-use webdriver::command::{WebDriverCommand, WebDriverExtensionCommand, WebDriverMessage};
-use webdriver::command::WindowRectParameters;
-use webdriver::common::{Date, LocatorStrategy, Nullable, WebElement};
+use webdriver::command::{WebDriverCommand, WebDriverExtensionCommand, WebDriverMessage, WindowRectParameters};
+use webdriver::common::{Cookie, Date, LocatorStrategy, WebElement};
use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult};
use webdriver::httpapi::WebDriverExtensionRoute;
-use webdriver::response::{Cookie, CookieResponse, CookiesResponse};
+use webdriver::response::{CookieResponse, CookiesResponse};
use webdriver::response::{ElementRectResponse, NewSessionResponse, ValueResponse};
use webdriver::response::{WebDriverResponse, WindowRectResponse};
use webdriver::server::{self, Session, WebDriverHandler};
fn extension_routes() -> Vec<(Method, &'static str, ServoExtensionRoute)> {
- return vec![
- (
- Post,
- "/session/{sessionId}/servo/prefs/get",
- ServoExtensionRoute::GetPrefs,
- ),
- (
- Post,
- "/session/{sessionId}/servo/prefs/set",
- ServoExtensionRoute::SetPrefs,
- ),
- (
- Post,
- "/session/{sessionId}/servo/prefs/reset",
- ServoExtensionRoute::ResetPrefs,
- ),
- ];
+ return vec![(Method::POST, "/session/{sessionId}/servo/prefs/get", ServoExtensionRoute::GetPrefs),
+ (Method::POST, "/session/{sessionId}/servo/prefs/set", ServoExtensionRoute::SetPrefs),
+ (Method::POST, "/session/{sessionId}/servo/prefs/reset", ServoExtensionRoute::ResetPrefs)]
}
fn cookie_msg_to_cookie(cookie: cookie_rs::Cookie) -> Cookie {
Cookie {
name: cookie.name().to_owned(),
value: cookie.value().to_owned(),
- path: match cookie.path() {
- Some(path) => Nullable::Value(path.to_string()),
- None => Nullable::Null,
- },
- domain: match cookie.domain() {
- Some(domain) => Nullable::Value(domain.to_string()),
- None => Nullable::Null,
- },
- expiry: match cookie.expires() {
- Some(time) => Nullable::Value(Date::new(time.to_timespec().sec as u64)),
- None => Nullable::Null,
- },
- secure: cookie.secure(),
- httpOnly: cookie.http_only(),
+ path: cookie.path().map(|s| s.to_owned()),
+ domain: cookie.domain().map(|s| s.to_owned()),
+ expiry: cookie.expires().map(|time| Date(time.to_timespec().sec as u64)),
+ secure: cookie.secure().unwrap_or(false),
+ httpOnly: cookie.http_only().unwrap_or(false),
}
}
@@ -167,22 +147,20 @@ enum ServoExtensionRoute {
impl WebDriverExtensionRoute for ServoExtensionRoute {
type Command = ServoExtensionCommand;
- fn command(
- &self,
- _captures: &Captures,
- body_data: &Json,
- ) -> WebDriverResult<WebDriverCommand<ServoExtensionCommand>> {
+ fn command(&self,
+ _captures: &Captures,
+ body_data: &Value) -> WebDriverResult<WebDriverCommand<ServoExtensionCommand>> {
let command = match *self {
ServoExtensionRoute::GetPrefs => {
- let parameters: GetPrefsParameters = Parameters::from_json(&body_data)?;
+ let parameters: GetPrefsParameters = serde_json::from_value(body_data.clone())?;
ServoExtensionCommand::GetPrefs(parameters)
},
ServoExtensionRoute::SetPrefs => {
- let parameters: SetPrefsParameters = Parameters::from_json(&body_data)?;
+ let parameters: SetPrefsParameters = serde_json::from_value(body_data.clone())?;
ServoExtensionCommand::SetPrefs(parameters)
},
ServoExtensionRoute::ResetPrefs => {
- let parameters: GetPrefsParameters = Parameters::from_json(&body_data)?;
+ let parameters: GetPrefsParameters = serde_json::from_value(body_data.clone())?;
ServoExtensionCommand::ResetPrefs(parameters)
},
};
@@ -198,95 +176,148 @@ enum ServoExtensionCommand {
}
impl WebDriverExtensionCommand for ServoExtensionCommand {
- fn parameters_json(&self) -> Option<Json> {
+ fn parameters_json(&self) -> Option<Value> {
match *self {
- ServoExtensionCommand::GetPrefs(ref x) => Some(x.to_json()),
- ServoExtensionCommand::SetPrefs(ref x) => Some(x.to_json()),
- ServoExtensionCommand::ResetPrefs(ref x) => Some(x.to_json()),
+ ServoExtensionCommand::GetPrefs(ref x) => serde_json::to_value(x).ok(),
+ ServoExtensionCommand::SetPrefs(ref x) => serde_json::to_value(x).ok(),
+ ServoExtensionCommand::ResetPrefs(ref x) => serde_json::to_value(x).ok(),
}
}
}
-#[derive(Clone, Debug, PartialEq)]
-struct GetPrefsParameters {
- prefs: Vec<String>,
+struct SendableWebDriverJSValue(pub WebDriverJSValue);
+
+impl Serialize for SendableWebDriverJSValue {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self.0 {
+ WebDriverJSValue::Undefined => serializer.serialize_unit(),
+ WebDriverJSValue::Null => serializer.serialize_unit(),
+ WebDriverJSValue::Boolean(x) => serializer.serialize_bool(x),
+ WebDriverJSValue::Number(x) => serializer.serialize_f64(x),
+ WebDriverJSValue::String(ref x) => serializer.serialize_str(&x),
+ }
+ }
}
-impl Parameters for GetPrefsParameters {
- fn from_json(body: &Json) -> WebDriverResult<GetPrefsParameters> {
- let data = body.as_object().ok_or(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Message body was not an object",
- ))?;
- let prefs_value = data.get("prefs").ok_or(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Missing prefs key",
- ))?;
- let items = prefs_value.as_array().ok_or(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "prefs was not an array",
- ))?;
- let params = items
- .iter()
- .map(|x| {
- x.as_string()
- .map(|y| y.to_owned())
- .ok_or(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Pref is not a string",
- ))
- }).collect::<Result<Vec<_>, _>>()?;
- Ok(GetPrefsParameters { prefs: params })
+#[derive(Clone, Debug, PartialEq)]
+struct WebDriverPrefValue(pub PrefValue);
+
+impl Serialize for WebDriverPrefValue {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self.0 {
+ PrefValue::Boolean(b) => serializer.serialize_bool(b),
+ PrefValue::String(ref s) => serializer.serialize_str(&s),
+ PrefValue::Number(f) => serializer.serialize_f64(f),
+ PrefValue::Missing => serializer.serialize_unit(),
+ }
}
}
-impl ToJson for GetPrefsParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("prefs".to_owned(), self.prefs.to_json());
- Json::Object(data)
+impl<'de> Deserialize<'de> for WebDriverPrefValue {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct Visitor;
+
+
+ impl<'de> ::serde::de::Visitor<'de> for Visitor {
+ type Value = WebDriverPrefValue;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("preference value")
+ }
+
+ fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
+ where
+ E: ::serde::de::Error,
+ {
+ Ok(WebDriverPrefValue(PrefValue::Number(value)))
+ }
+
+ fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+ where
+ E: ::serde::de::Error,
+ {
+ Ok(WebDriverPrefValue(PrefValue::Number(value as f64)))
+ }
+
+ fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: ::serde::de::Error,
+ {
+ Ok(WebDriverPrefValue(PrefValue::Number(value as f64)))
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: ::serde::de::Error,
+ {
+ Ok(WebDriverPrefValue(PrefValue::String(value.to_owned())))
+ }
+
+ fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
+ where
+ E: ::serde::de::Error,
+ {
+ Ok(WebDriverPrefValue(PrefValue::Boolean(value)))
+ }
+ }
+
+ deserializer.deserialize_any(Visitor)
}
}
-#[derive(Clone, Debug, PartialEq)]
+
+#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
+struct GetPrefsParameters {
+ prefs: Vec<String>,
+}
+
+#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
struct SetPrefsParameters {
- prefs: Vec<(String, PrefValue)>,
+ #[serde(deserialize_with = "map_to_vec")]
+ prefs: Vec<(String, WebDriverPrefValue)>,
}
-impl Parameters for SetPrefsParameters {
- fn from_json(body: &Json) -> WebDriverResult<SetPrefsParameters> {
- let data = body.as_object().ok_or(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Message body was not an object",
- ))?;
- let items = data
- .get("prefs")
- .ok_or(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Missing prefs key",
- ))?.as_object()
- .ok_or(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "prefs was not an array",
- ))?;
- let mut params = Vec::with_capacity(items.len());
- for (name, val) in items.iter() {
- let value = PrefValue::from_json(val.clone()).or(Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Pref is not a boolean or string",
- )))?;
- let key = name.to_owned();
- params.push((key, value));
- }
- Ok(SetPrefsParameters { prefs: params })
- }
+fn map_to_vec<'de, D>(de: D) -> Result<Vec<(String, WebDriverPrefValue)>, D::Error>
+ where D: Deserializer<'de> {
+ de.deserialize_map(TupleVecMapVisitor)
}
-impl ToJson for SetPrefsParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("prefs".to_owned(), self.prefs.to_json());
- Json::Object(data)
+struct TupleVecMapVisitor;
+
+impl<'de> Visitor<'de> for TupleVecMapVisitor
+{
+ type Value = Vec<(String, WebDriverPrefValue)>;
+
+ fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<Self::Value, E> {
+ Ok(Vec::new())
+ }
+
+ #[inline]
+ fn visit_map<T>(self, mut access: T) -> Result<Self::Value, T::Error>
+ where
+ T: MapAccess<'de>,
+ {
+ let mut values = Vec::new();
+
+ while let Some((key, value)) = access.next_entry()? {
+ values.push((key, value));
+ }
+
+ Ok(values)
}
}
@@ -349,12 +380,11 @@ impl Handler {
let top_level_browsing_context_id = self.focus_top_level_browsing_context_id()?;
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
let session = WebDriverSession::new(browsing_context_id, top_level_browsing_context_id);
- let mut capabilities = BTreeMap::new();
- capabilities.insert("browserName".to_owned(), "servo".to_json());
- capabilities.insert("browserVersion".to_owned(), "0.0.1".to_json());
- capabilities.insert("acceptInsecureCerts".to_owned(), false.to_json());
- let response =
- NewSessionResponse::new(session.id.to_string(), Json::Object(capabilities));
+ let mut capabilities = serde_json::Map::new();
+ capabilities.insert("browserName".to_owned(), serde_json::to_value("servo")?);
+ capabilities.insert("browserVersion".to_owned(), serde_json::to_value("0.0.1")?);
+ capabilities.insert("acceptInsecureCerts".to_owned(), serde_json::to_value(false)?);
+ let response = NewSessionResponse::new(session.id.to_string(), Value::Object(capabilities));
debug!("new session created {}.", session.id);
self.session = Some(session);
Ok(WebDriverResponse::NewSession(response))
@@ -447,9 +477,7 @@ impl Handler {
let url = receiver.recv().unwrap();
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- url.as_str().to_json(),
- )))
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(url.as_str())?)))
}
fn handle_window_size(&self) -> WebDriverResult<WebDriverResponse> {
@@ -478,12 +506,12 @@ impl Handler {
) -> WebDriverResult<WebDriverResponse> {
let (sender, receiver) = ipc::channel().unwrap();
let width = match params.width {
- Nullable::Value(v) => v,
- Nullable::Null => 0,
+ Some(v) => v,
+ None => 0,
};
let height = match params.height {
- Nullable::Value(v) => v,
- Nullable::Null => 0,
+ Some(v) => v,
+ None => 0,
};
let size = TypedSize2D::new(width as u32, height as u32);
let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id;
@@ -526,13 +554,8 @@ impl Handler {
))?;
match receiver.recv().unwrap() {
- Ok(is_enabled) => Ok(WebDriverResponse::Generic(ValueResponse::new(
- is_enabled.to_json(),
- ))),
- Err(_) => Err(WebDriverError::new(
- ErrorStatus::StaleElementReference,
- "Element not found",
- )),
+ Ok(is_enabled) => Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(is_enabled)?))),
+ Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, "Element not found"))
}
}
@@ -545,13 +568,8 @@ impl Handler {
))?;
match receiver.recv().unwrap() {
- Ok(is_selected) => Ok(WebDriverResponse::Generic(ValueResponse::new(
- is_selected.to_json(),
- ))),
- Err(_) => Err(WebDriverError::new(
- ErrorStatus::StaleElementReference,
- "Element not found",
- )),
+ Ok(is_selected) => Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(is_selected)?))),
+ Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, "Element not found"))
}
}
@@ -590,27 +608,21 @@ impl Handler {
self.top_level_script_command(WebDriverScriptCommand::GetTitle(sender))?;
let value = receiver.recv().unwrap();
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- value.to_json(),
- )))
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(value)?)))
}
fn handle_window_handle(&self) -> WebDriverResult<WebDriverResponse> {
// For now we assume there's only one window so just use the session
// id as the window id
let handle = self.session.as_ref().unwrap().id.to_string();
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- handle.to_json(),
- )))
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(handle)?)))
}
fn handle_window_handles(&self) -> WebDriverResult<WebDriverResponse> {
// For now we assume there's only one window so just use the session
// id as the window id
- let handles = vec![self.session.as_ref().unwrap().id.to_string().to_json()];
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- handles.to_json(),
- )))
+ let handles = vec![serde_json::to_value(self.session.as_ref().unwrap().id.to_string())?];
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(handles)?)))
}
fn handle_find_element(
@@ -631,13 +643,13 @@ impl Handler {
match receiver.recv().unwrap() {
Ok(value) => {
- let value_resp = value.map(|x| WebElement::new(x).to_json()).to_json();
- Ok(WebDriverResponse::Generic(ValueResponse::new(value_resp)))
- },
- Err(_) => Err(WebDriverError::new(
- ErrorStatus::InvalidSelector,
- "Invalid selector",
- )),
+ let value_resp = serde_json::to_value(
+ value.map(|x| serde_json::to_value(WebElement::new(x)).unwrap())
+ )?;
+ Ok(WebDriverResponse::Generic(ValueResponse(value_resp)))
+ }
+ Err(_) => Err(WebDriverError::new(ErrorStatus::InvalidSelector,
+ "Invalid selector"))
}
}
@@ -647,14 +659,14 @@ impl Handler {
) -> WebDriverResult<WebDriverResponse> {
use webdriver::common::FrameId;
let frame_id = match parameters.id {
- FrameId::Null => {
+ None => {
let session = self.session_mut()?;
session.browsing_context_id =
BrowsingContextId::from(session.top_level_browsing_context_id);
return Ok(WebDriverResponse::Void);
},
- FrameId::Short(ref x) => WebDriverFrameId::Short(*x),
- FrameId::Element(ref x) => WebDriverFrameId::Element(x.id.clone()),
+ Some(FrameId::Short(ref x)) => WebDriverFrameId::Short(*x),
+ Some(FrameId::Element(ref x)) => WebDriverFrameId::Element(x.id.clone())
};
self.switch_to_frame(frame_id)
@@ -704,18 +716,12 @@ impl Handler {
self.browsing_context_script_command(cmd)?;
match receiver.recv().unwrap() {
Ok(value) => {
- let resp_value: Vec<Json> = value
- .into_iter()
- .map(|x| WebElement::new(x).to_json())
- .collect();
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- resp_value.to_json(),
- )))
- },
- Err(_) => Err(WebDriverError::new(
- ErrorStatus::InvalidSelector,
- "Invalid selector",
- )),
+ let resp_value: Vec<Value> = value.into_iter().map(
+ |x| serde_json::to_value(WebElement::new(x)).unwrap()).collect();
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(resp_value)?)))
+ }
+ Err(_) => Err(WebDriverError::new(ErrorStatus::InvalidSelector,
+ "Invalid selector"))
}
}
@@ -746,13 +752,9 @@ impl Handler {
let cmd = WebDriverScriptCommand::GetElementText(element.id.clone(), sender);
self.browsing_context_script_command(cmd)?;
match receiver.recv().unwrap() {
- Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(
- value.to_json(),
- ))),
- Err(_) => Err(WebDriverError::new(
- ErrorStatus::StaleElementReference,
- "Unable to find element in document",
- )),
+ Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(value)?))),
+ Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
+ "Unable to find element in document"))
}
}
@@ -760,13 +762,8 @@ impl Handler {
let (sender, receiver) = ipc::channel().unwrap();
let cmd = WebDriverScriptCommand::GetActiveElement(sender);
self.browsing_context_script_command(cmd)?;
- let value = receiver
- .recv()
- .unwrap()
- .map(|x| WebElement::new(x).to_json());
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- value.to_json(),
- )))
+ let value = receiver.recv().unwrap().map(|x| serde_json::to_value(WebElement::new(x)).unwrap());
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(value)?)))
}
fn handle_element_tag_name(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> {
@@ -774,13 +771,9 @@ impl Handler {
let cmd = WebDriverScriptCommand::GetElementTagName(element.id.clone(), sender);
self.browsing_context_script_command(cmd)?;
match receiver.recv().unwrap() {
- Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(
- value.to_json(),
- ))),
- Err(_) => Err(WebDriverError::new(
- ErrorStatus::StaleElementReference,
- "Unable to find element in document",
- )),
+ Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(value)?))),
+ Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
+ "Unable to find element in document"))
}
}
@@ -797,13 +790,9 @@ impl Handler {
);
self.browsing_context_script_command(cmd)?;
match receiver.recv().unwrap() {
- Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(
- value.to_json(),
- ))),
- Err(_) => Err(WebDriverError::new(
- ErrorStatus::StaleElementReference,
- "Unable to find element in document",
- )),
+ Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(value)?))),
+ Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
+ "Unable to find element in document"))
}
}
@@ -817,13 +806,9 @@ impl Handler {
WebDriverScriptCommand::GetElementCSS(element.id.clone(), name.to_owned(), sender);
self.browsing_context_script_command(cmd)?;
match receiver.recv().unwrap() {
- Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(
- value.to_json(),
- ))),
- Err(_) => Err(WebDriverError::new(
- ErrorStatus::StaleElementReference,
- "Unable to find element in document",
- )),
+ Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(value)?))),
+ Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
+ "Unable to find element in document"))
}
}
@@ -832,13 +817,10 @@ impl Handler {
let cmd = WebDriverScriptCommand::GetCookies(sender);
self.browsing_context_script_command(cmd)?;
let cookies = receiver.recv().unwrap();
- let response = cookies
- .into_iter()
- .map(|cookie| cookie_msg_to_cookie(cookie.into_inner()))
- .collect::<Vec<Cookie>>();
- Ok(WebDriverResponse::Cookies(CookiesResponse {
- value: response,
- }))
+ let response = cookies.into_iter().map(|cookie| {
+ cookie_msg_to_cookie(cookie.into_inner())
+ }).collect::<Vec<Cookie>>();
+ Ok(WebDriverResponse::Cookies(CookiesResponse(response)))
}
fn handle_get_cookie(&self, name: &str) -> WebDriverResult<WebDriverResponse> {
@@ -846,14 +828,10 @@ impl Handler {
let cmd = WebDriverScriptCommand::GetCookie(name.to_owned(), sender);
self.browsing_context_script_command(cmd)?;
let cookies = receiver.recv().unwrap();
- let response = cookies
- .into_iter()
- .map(|cookie| cookie_msg_to_cookie(cookie.into_inner()))
- .next()
- .unwrap();
- Ok(WebDriverResponse::Cookie(CookieResponse {
- value: response,
- }))
+ let response = cookies.into_iter().map(|cookie| {
+ cookie_msg_to_cookie(cookie.into_inner())
+ }).next().unwrap();
+ Ok(WebDriverResponse::Cookie(CookieResponse(response)))
}
fn handle_add_cookie(
@@ -866,11 +844,11 @@ impl Handler {
.secure(params.secure)
.http_only(params.httpOnly);
let cookie = match params.domain {
- Nullable::Value(ref domain) => cookie.domain(domain.to_owned()),
+ Some(ref domain) => cookie.domain(domain.to_owned()),
_ => cookie,
};
let cookie = match params.path {
- Nullable::Value(ref path) => cookie.path(path.to_owned()).finish(),
+ Some(ref path) => cookie.path(path.to_owned()).finish(),
_ => cookie.finish(),
};
@@ -958,9 +936,8 @@ impl Handler {
result: WebDriverJSResult,
) -> WebDriverResult<WebDriverResponse> {
match result {
- Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse::new(
- value.to_json(),
- ))),
+ Ok(value) =>
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(SendableWebDriverJSValue(value))?))),
Err(WebDriverJSError::Timeout) => Err(WebDriverError::new(ErrorStatus::Timeout, "")),
Err(WebDriverJSError::UnknownType) => Err(WebDriverError::new(
ErrorStatus::UnsupportedOperation,
@@ -1055,9 +1032,7 @@ impl Handler {
.unwrap();
let encoded = base64::encode(&png_data);
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- encoded.to_json(),
- )))
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(encoded)?)))
}
fn handle_get_prefs(
@@ -1067,12 +1042,10 @@ impl Handler {
let prefs = parameters
.prefs
.iter()
- .map(|item| (item.clone(), PREFS.get(item).to_json()))
+ .map(|item| (item.clone(), serde_json::to_value(PREFS.get(item)).unwrap()))
.collect::<BTreeMap<_, _>>();
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- prefs.to_json(),
- )))
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(prefs)?)))
}
fn handle_set_prefs(
@@ -1080,7 +1053,7 @@ impl Handler {
parameters: &SetPrefsParameters,
) -> WebDriverResult<WebDriverResponse> {
for &(ref key, ref value) in parameters.prefs.iter() {
- PREFS.set(key, value.clone());
+ PREFS.set(key, value.0.clone());
}
Ok(WebDriverResponse::Void)
}
@@ -1096,12 +1069,10 @@ impl Handler {
parameters
.prefs
.iter()
- .map(|item| (item.clone(), PREFS.reset(item).to_json()))
+ .map(|item| (item.clone(), serde_json::to_value(PREFS.reset(item)).unwrap()))
.collect::<BTreeMap<_, _>>()
};
- Ok(WebDriverResponse::Generic(ValueResponse::new(
- prefs.to_json(),
- )))
+ Ok(WebDriverResponse::Generic(ValueResponse(serde_json::to_value(prefs)?)))
}
}
diff --git a/servo-tidy.toml b/servo-tidy.toml
index 06aac102079..addfab8963f 100644
--- a/servo-tidy.toml
+++ b/servo-tidy.toml
@@ -25,6 +25,7 @@ rand = [
"rayon-core",
"servo_rand",
"tempfile",
+ "tokio-threadpool",
"uuid",
"ws",
]
@@ -32,8 +33,8 @@ rand = [
[ignore]
# Ignored packages with duplicated versions
packages = [
- "bitflags",
"core-graphics",
+ "crossbeam-deque",
"crossbeam-epoch",
"crossbeam-utils",
"log",
@@ -42,9 +43,8 @@ packages = [
"proc-macro2",
"quote",
"rand",
- # TODO: remove slab when #21426 lands
- "slab",
"syn",
+ "unicase",
"winapi",
]
# Files that are ignored for all tidy and lint checks.
diff --git a/tests/unit/metrics/paint_time.rs b/tests/unit/metrics/paint_time.rs
index 20c43b28c84..0207324a9c2 100644
--- a/tests/unit/metrics/paint_time.rs
+++ b/tests/unit/metrics/paint_time.rs
@@ -10,7 +10,7 @@ use msg::constellation_msg::TEST_PIPELINE_ID;
use profile_traits::time::{ProfilerChan, TimerMetadata};
use servo_url::ServoUrl;
use time;
-use webrender_api::{AlphaType, ImageDisplayItem, ImageKey, ImageRendering, LayoutSize, ColorF};
+use webrender_api::{AlphaType, ColorF, ImageDisplayItem, ImageKey, ImageRendering, LayoutSize};
struct DummyProfilerMetadataFactory {}
impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
diff --git a/tests/wpt/metadata/cors/access-control-expose-headers-parsing.window.js.ini b/tests/wpt/metadata/cors/access-control-expose-headers-parsing.window.js.ini
index d5d99a12283..efbfad792a9 100644
--- a/tests/wpt/metadata/cors/access-control-expose-headers-parsing.window.js.ini
+++ b/tests/wpt/metadata/cors/access-control-expose-headers-parsing.window.js.ini
@@ -1,5 +1,4 @@
[access-control-expose-headers-parsing.window.html]
- type: testharness
[Access-Control-Expose-Headers parsing: #1]
expected: FAIL
diff --git a/tests/wpt/metadata/cors/allow-headers.htm.ini b/tests/wpt/metadata/cors/allow-headers.htm.ini
index c41fcae641b..6b73e9141ba 100644
--- a/tests/wpt/metadata/cors/allow-headers.htm.ini
+++ b/tests/wpt/metadata/cors/allow-headers.htm.ini
@@ -12,3 +12,18 @@
[Allow origin: [tab\]undefined//undefined]
expected: FAIL
+ [Allow origin: _*__]
+ expected: FAIL
+
+ [Allow origin: _http://web-platform.test:8000___[tab\]_]
+ expected: FAIL
+
+ [Disallow origin: HTTP://web-platform.test:8000]
+ expected: FAIL
+
+ [Disallow origin: http://web-platform.test:8000#]
+ expected: FAIL
+
+ [Disallow origin: http://web-platform.test:8000/]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/cors/origin.htm.ini b/tests/wpt/metadata/cors/origin.htm.ini
new file mode 100644
index 00000000000..224c803a5e6
--- /dev/null
+++ b/tests/wpt/metadata/cors/origin.htm.ini
@@ -0,0 +1,16 @@
+[origin.htm]
+ [Allow origin: _*__]
+ expected: FAIL
+
+ [Allow origin: _http://web-platform.test:8000___[tab\]_]
+ expected: FAIL
+
+ [Disallow origin: HTTP://web-platform.test:8000]
+ expected: FAIL
+
+ [Disallow origin: http://web-platform.test:8000#]
+ expected: FAIL
+
+ [Disallow origin: http://web-platform.test:8000/]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/cors/redirect-origin.htm.ini b/tests/wpt/metadata/cors/redirect-origin.htm.ini
index 02481d435c1..f3be237aea1 100644
--- a/tests/wpt/metadata/cors/redirect-origin.htm.ini
+++ b/tests/wpt/metadata/cors/redirect-origin.htm.ini
@@ -20,12 +20,6 @@
[local (none) to remote (*), expect origin=undefined//undefined]
expected: FAIL
- [remote (*) to local (*), expect origin=null]
- expected: FAIL
-
- [remote (*) to local (null), expect origin=null]
- expected: FAIL
-
[remote (undefined//undefined) to local (*), expect origin=null]
expected: FAIL
@@ -44,27 +38,9 @@
[remote (undefined//undefined) to remote (undefined//undefined), expect origin=undefined//undefined]
expected: FAIL
- [remote (*) to remote2 (*), expect origin=null]
- expected: FAIL
-
- [remote (*) to remote2 (null), expect origin=null]
- expected: FAIL
-
[remote (undefined//undefined) to remote2 (*), expect origin=null]
expected: FAIL
[remote (undefined//undefined) to remote2 (null), expect origin=null]
expected: FAIL
- [remote (http://web-platform.test:8000) to local (*), expect origin=null]
- expected: FAIL
-
- [remote (http://web-platform.test:8000) to local (null), expect origin=null]
- expected: FAIL
-
- [remote (http://web-platform.test:8000) to remote2 (*), expect origin=null]
- expected: FAIL
-
- [remote (http://web-platform.test:8000) to remote2 (null), expect origin=null]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/cors/redirect-userinfo.htm.ini b/tests/wpt/metadata/cors/redirect-userinfo.htm.ini
deleted file mode 100644
index 78a8ba34586..00000000000
--- a/tests/wpt/metadata/cors/redirect-userinfo.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[redirect-userinfo.htm]
- type: testharness
- [Allow redirect without userinfo (:@ is trimmed during URL parsing)]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/cors/request-headers.htm.ini b/tests/wpt/metadata/cors/request-headers.htm.ini
new file mode 100644
index 00000000000..d5a0e025561
--- /dev/null
+++ b/tests/wpt/metadata/cors/request-headers.htm.ini
@@ -0,0 +1,4 @@
+[request-headers.htm]
+ [Strange allowheaders (case insensitive)]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/cors/status-async.htm.ini b/tests/wpt/metadata/cors/status-async.htm.ini
new file mode 100644
index 00000000000..74385e9e7be
--- /dev/null
+++ b/tests/wpt/metadata/cors/status-async.htm.ini
@@ -0,0 +1,37 @@
+[status-async.htm]
+ [Status on POST 500]
+ expected: FAIL
+
+ [Status on HEAD 401]
+ expected: FAIL
+
+ [Status on POST 404]
+ expected: FAIL
+
+ [Status on GET 299]
+ expected: FAIL
+
+ [Status on GET 400]
+ expected: FAIL
+
+ [Status on GET 206]
+ expected: FAIL
+
+ [Status on GET 204]
+ expected: FAIL
+
+ [Status on GET 205]
+ expected: FAIL
+
+ [Status on GET 202]
+ expected: FAIL
+
+ [Status on GET 203]
+ expected: FAIL
+
+ [Status on GET 201]
+ expected: FAIL
+
+ [Status on GET 209]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/cors/status-preflight.htm.ini b/tests/wpt/metadata/cors/status-preflight.htm.ini
new file mode 100644
index 00000000000..cf220f7f4ae
--- /dev/null
+++ b/tests/wpt/metadata/cors/status-preflight.htm.ini
@@ -0,0 +1,7 @@
+[status-preflight.htm]
+ [CORS - status after preflight on HEAD 699]
+ expected: FAIL
+
+ [CORS - status after preflight on PUT 699]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/css/CSS2/backgrounds/background-043.xht.ini b/tests/wpt/metadata/css/CSS2/backgrounds/background-043.xht.ini
index e9b801cb297..5d83aba3f7b 100644
--- a/tests/wpt/metadata/css/CSS2/backgrounds/background-043.xht.ini
+++ b/tests/wpt/metadata/css/CSS2/backgrounds/background-043.xht.ini
@@ -1,3 +1,2 @@
[background-043.xht]
- type: reftest
expected: FAIL
diff --git a/tests/wpt/metadata/css/CSS2/backgrounds/background-048.xht.ini b/tests/wpt/metadata/css/CSS2/backgrounds/background-048.xht.ini
index acf3a0819f6..4f08e157d7a 100644
--- a/tests/wpt/metadata/css/CSS2/backgrounds/background-048.xht.ini
+++ b/tests/wpt/metadata/css/CSS2/backgrounds/background-048.xht.ini
@@ -1,3 +1,5 @@
+[background-043.xht]
+ expected: FAIL
+
[background-048.xht]
- type: reftest
expected: FAIL
diff --git a/tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini b/tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini
index 72b09371038..e38782d8c85 100644
--- a/tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini
+++ b/tests/wpt/metadata/css/cssom-view/elementFromPoint-001.html.ini
@@ -1,3 +1,4 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL
+
diff --git a/tests/wpt/metadata/css/cssom-view/elementFromPoint-dynamic-anon-box.html.ini b/tests/wpt/metadata/css/cssom-view/elementFromPoint-dynamic-anon-box.html.ini
index cf67b5d03dd..4596f046e93 100644
--- a/tests/wpt/metadata/css/cssom-view/elementFromPoint-dynamic-anon-box.html.ini
+++ b/tests/wpt/metadata/css/cssom-view/elementFromPoint-dynamic-anon-box.html.ini
@@ -1,3 +1,4 @@
[elementFromPoint-dynamic-anon-box.html]
[Link should be clickable after hiding a scrollbox with an anonymous table inside]
expected: FAIL
+
diff --git a/tests/wpt/metadata/eventsource/format-mime-trailing-semicolon.htm.ini b/tests/wpt/metadata/eventsource/format-mime-trailing-semicolon.htm.ini
new file mode 100644
index 00000000000..7d8960be496
--- /dev/null
+++ b/tests/wpt/metadata/eventsource/format-mime-trailing-semicolon.htm.ini
@@ -0,0 +1,4 @@
+[format-mime-trailing-semicolon.htm]
+ [EventSource: MIME type with trailing ;]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/api/abort/general.any.js.ini b/tests/wpt/metadata/fetch/api/abort/general.any.js.ini
index f7ffeaa41d2..10e4a5a2ec6 100644
--- a/tests/wpt/metadata/fetch/api/abort/general.any.js.ini
+++ b/tests/wpt/metadata/fetch/api/abort/general.any.js.ini
@@ -100,6 +100,8 @@
[Clone aborts with original controller]
expected: FAIL
+ [TypeError from request constructor takes priority - RequestInit's method is invalid]
+ expected: FAIL
[general.any.html]
type: testharness
@@ -142,6 +144,8 @@
expected: FAIL
[TypeError from request constructor takes priority - Bad redirect init parameter value]
expected: FAIL
+ [TypeError from request constructor takes priority - RequestInit's method is invalid]
+ expected: FAIL
[Request objects have a signal property]
expected: FAIL
[Signal on request object]
diff --git a/tests/wpt/metadata/fetch/api/cors/cors-cookies-redirect.any.js.ini b/tests/wpt/metadata/fetch/api/cors/cors-cookies-redirect.any.js.ini
index a87a4de0332..016ba7b482d 100644
--- a/tests/wpt/metadata/fetch/api/cors/cors-cookies-redirect.any.js.ini
+++ b/tests/wpt/metadata/fetch/api/cors/cors-cookies-redirect.any.js.ini
@@ -24,8 +24,4 @@
[cors-cookies-redirect]
expected: FAIL
- [Testing credentials after cross-origin redirection with CORS and no preflight]
- expected: FAIL
- [Testing credentials after cross-origin redirection with CORS and preflight]
- expected: FAIL
diff --git a/tests/wpt/metadata/fetch/api/cors/cors-redirect.any.js.ini b/tests/wpt/metadata/fetch/api/cors/cors-redirect.any.js.ini
index 40a3372ee88..60b5048cc85 100644
--- a/tests/wpt/metadata/fetch/api/cors/cors-redirect.any.js.ini
+++ b/tests/wpt/metadata/fetch/api/cors/cors-redirect.any.js.ini
@@ -3,93 +3,33 @@
[Redirect 301: cors to same cors]
expected: FAIL
- [Redirect 301: cors to another cors]
- expected: FAIL
-
[Redirect 301: same origin to cors]
expected: FAIL
- [Redirect 301: cors to same origin]
- expected: FAIL
-
[Redirect 302: cors to same cors]
expected: FAIL
- [Redirect 302: cors to another cors]
- expected: FAIL
-
[Redirect 302: same origin to cors]
expected: FAIL
- [Redirect 302: cors to same origin]
- expected: FAIL
-
[Redirect 303: cors to same cors]
expected: FAIL
- [Redirect 303: cors to another cors]
- expected: FAIL
-
[Redirect 303: same origin to cors]
expected: FAIL
- [Redirect 303: cors to same origin]
- expected: FAIL
-
[Redirect 307: cors to same cors]
expected: FAIL
- [Redirect 307: cors to another cors]
- expected: FAIL
-
[Redirect 307: same origin to cors]
expected: FAIL
- [Redirect 307: cors to same origin]
- expected: FAIL
-
[Redirect 308: cors to same cors]
expected: FAIL
- [Redirect 308: cors to another cors]
- expected: FAIL
-
[Redirect 308: same origin to cors]
expected: FAIL
- [Redirect 308: cors to same origin]
- expected: FAIL
-
[cors-redirect.any.html]
type: testharness
- [Redirect 301: cors to another cors]
- expected: FAIL
-
- [Redirect 301: cors to same origin]
- expected: FAIL
-
- [Redirect 302: cors to another cors]
- expected: FAIL
-
- [Redirect 302: cors to same origin]
- expected: FAIL
-
- [Redirect 303: cors to another cors]
- expected: FAIL
-
- [Redirect 303: cors to same origin]
- expected: FAIL
-
- [Redirect 307: cors to another cors]
- expected: FAIL
-
- [Redirect 307: cors to same origin]
- expected: FAIL
-
- [Redirect 308: cors to another cors]
- expected: FAIL
-
- [Redirect 308: cors to same origin]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/fetch/api/redirect/redirect-empty-location.any.js.ini b/tests/wpt/metadata/fetch/api/redirect/redirect-empty-location.any.js.ini
index 32d2e40bec4..f7d8e67b4b3 100644
--- a/tests/wpt/metadata/fetch/api/redirect/redirect-empty-location.any.js.ini
+++ b/tests/wpt/metadata/fetch/api/redirect/redirect-empty-location.any.js.ini
@@ -1,15 +1,9 @@
[redirect-empty-location.any.worker.html]
- [redirect response with empty Location, follow mode]
- expected: FAIL
-
[redirect response with empty Location, manual mode]
expected: FAIL
[redirect-empty-location.any.html]
- [redirect response with empty Location, follow mode]
- expected: FAIL
-
[redirect response with empty Location, manual mode]
expected: FAIL
diff --git a/tests/wpt/metadata/fetch/api/redirect/redirect-origin.any.js.ini b/tests/wpt/metadata/fetch/api/redirect/redirect-origin.any.js.ini
deleted file mode 100644
index 473d1e45206..00000000000
--- a/tests/wpt/metadata/fetch/api/redirect/redirect-origin.any.js.ini
+++ /dev/null
@@ -1,33 +0,0 @@
-[redirect-origin.any.html]
- [Other origin to same origin redirection 301]
- expected: FAIL
-
- [Other origin to same origin redirection 302]
- expected: FAIL
-
- [Other origin to same origin redirection 303]
- expected: FAIL
-
- [Other origin to same origin redirection 307]
- expected: FAIL
-
- [Other origin to same origin redirection 308]
- expected: FAIL
-
-
-[redirect-origin.any.worker.html]
- [Other origin to same origin redirection 301]
- expected: FAIL
-
- [Other origin to same origin redirection 302]
- expected: FAIL
-
- [Other origin to same origin redirection 303]
- expected: FAIL
-
- [Other origin to same origin redirection 307]
- expected: FAIL
-
- [Other origin to same origin redirection 308]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/fetch/api/request/request-error.html.ini b/tests/wpt/metadata/fetch/api/request/request-error.html.ini
index 9deb35c1e9c..1745c4a0aa9 100644
--- a/tests/wpt/metadata/fetch/api/request/request-error.html.ini
+++ b/tests/wpt/metadata/fetch/api/request/request-error.html.ini
@@ -2,5 +2,3 @@
type: testharness
[Request error]
expected: FAIL
- [RequestInit's method is invalid]
- expected: FAIL
diff --git a/tests/wpt/metadata/fetch/api/response/response-consume.html.ini b/tests/wpt/metadata/fetch/api/response/response-consume.html.ini
index 00047323b01..94ca58262d7 100644
--- a/tests/wpt/metadata/fetch/api/response/response-consume.html.ini
+++ b/tests/wpt/metadata/fetch/api/response/response-consume.html.ini
@@ -73,6 +73,3 @@
[Consume response's body: from multipart form data blob to formData]
expected: FAIL
- [Consume response's body: from URLSearchParams to blob]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/fetch/data-urls/processing.any.js.ini b/tests/wpt/metadata/fetch/data-urls/processing.any.js.ini
index 43b62775d0a..fca83c027a5 100644
--- a/tests/wpt/metadata/fetch/data-urls/processing.any.js.ini
+++ b/tests/wpt/metadata/fetch/data-urls/processing.any.js.ini
@@ -17,33 +17,15 @@
["data:text/plain ,X"]
expected: FAIL
- ["data:text/plain%20,X"]
- expected: FAIL
-
- ["data:text/plain\\f,X"]
- expected: FAIL
-
- ["data:text/plain%0C,X"]
- expected: FAIL
-
["data:;x=x;charset=x,X"]
expected: FAIL
["data:;x=x,X"]
expected: FAIL
- ["data:text/plain;charset=windows-1252,%C2%B1"]
- expected: FAIL
-
["data:text/plain;Charset=UTF-8,%C2%B1"]
expected: FAIL
- ["data:IMAGE/gif;hi=x,%C2%B1"]
- expected: FAIL
-
- ["data:IMAGE/gif;CHARSET=x,%C2%B1"]
- expected: FAIL
-
["data: ,%FF"]
expected: FAIL
@@ -71,18 +53,12 @@
["data:†,X"]
expected: FAIL
- ["data:†/†,X"]
- expected: FAIL
-
["data:X,X"]
expected: FAIL
["data:text/plain;a=\\",\\",X"]
expected: FAIL
- ["data:text/plain;a=%2C,X"]
- expected: FAIL
-
["data:;base64;base64,WA"]
expected: FAIL
@@ -137,9 +113,6 @@
["data:%3Bbase64,WA"]
expected: FAIL
- ["data:;charset=x,X"]
- expected: FAIL
-
["data:; charset=x,X"]
expected: FAIL
@@ -161,51 +134,48 @@
["data:;CHARSET=\\"X\\",X"]
expected: FAIL
-
-[processing.any.html]
- ["data://test/,X"]
+ ["data:†,X"]
expected: FAIL
- ["data:,X"]
+ ["data:†,X"]
expected: FAIL
- ["data:,"]
+ ["data:text/plain;,X"]
expected: FAIL
- ["data:,X#X"]
+ ["data:x/x;base64;base64x,WA"]
expected: FAIL
- ["data:,%FF"]
+ ["data:x/x;base64;base64,WA"]
expected: FAIL
- ["data:text/plain ,X"]
- expected: FAIL
- ["data:text/plain%20,X"]
+[processing.any.html]
+ ["data://test/,X"]
expected: FAIL
- ["data:text/plain\\f,X"]
+ ["data:,X"]
expected: FAIL
- ["data:text/plain%0C,X"]
+ ["data:,"]
expected: FAIL
- ["data:;x=x;charset=x,X"]
+ ["data:,X#X"]
expected: FAIL
- ["data:;x=x,X"]
+ ["data:,%FF"]
expected: FAIL
- ["data:text/plain;charset=windows-1252,%C2%B1"]
+ ["data:text/plain ,X"]
expected: FAIL
- ["data:text/plain;Charset=UTF-8,%C2%B1"]
+ ["data:;x=x;charset=x,X"]
expected: FAIL
- ["data:IMAGE/gif;hi=x,%C2%B1"]
+ ["data:;x=x,X"]
expected: FAIL
- ["data:IMAGE/gif;CHARSET=x,%C2%B1"]
+ ["data:text/plain;Charset=UTF-8,%C2%B1"]
expected: FAIL
["data: ,%FF"]
@@ -235,18 +205,12 @@
["data:†,X"]
expected: FAIL
- ["data:†/†,X"]
- expected: FAIL
-
["data:X,X"]
expected: FAIL
["data:text/plain;a=\\",\\",X"]
expected: FAIL
- ["data:text/plain;a=%2C,X"]
- expected: FAIL
-
["data:;base64;base64,WA"]
expected: FAIL
@@ -301,9 +265,6 @@
["data:%3Bbase64,WA"]
expected: FAIL
- ["data:;charset=x,X"]
- expected: FAIL
-
["data:; charset=x,X"]
expected: FAIL
@@ -325,3 +286,18 @@
["data:;CHARSET=\\"X\\",X"]
expected: FAIL
+ ["data:†,X"]
+ expected: FAIL
+
+ ["data:†,X"]
+ expected: FAIL
+
+ ["data:text/plain;,X"]
+ expected: FAIL
+
+ ["data:x/x;base64;base64x,WA"]
+ expected: FAIL
+
+ ["data:x/x;base64;base64,WA"]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/nosniff/importscripts.html.ini b/tests/wpt/metadata/fetch/nosniff/importscripts.html.ini
new file mode 100644
index 00000000000..7b5fc2a3eb0
--- /dev/null
+++ b/tests/wpt/metadata/fetch/nosniff/importscripts.html.ini
@@ -0,0 +1,5 @@
+[importscripts.html]
+ expected: ERROR
+ [Test importScripts()]
+ expected: TIMEOUT
+
diff --git a/tests/wpt/metadata/fetch/nosniff/script.html.ini b/tests/wpt/metadata/fetch/nosniff/script.html.ini
new file mode 100644
index 00000000000..1582de16a3e
--- /dev/null
+++ b/tests/wpt/metadata/fetch/nosniff/script.html.ini
@@ -0,0 +1,4 @@
+[script.html]
+ [URL query: text/ecmascript;blah]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/fetch/nosniff/stylesheet.html.ini b/tests/wpt/metadata/fetch/nosniff/stylesheet.html.ini
index c87f89ee811..70bfecb9fd1 100644
--- a/tests/wpt/metadata/fetch/nosniff/stylesheet.html.ini
+++ b/tests/wpt/metadata/fetch/nosniff/stylesheet.html.ini
@@ -11,3 +11,9 @@
[Revalidated URL query: text/json]
expected: FAIL
+ [Revalidated URL query: text/css;blah]
+ expected: FAIL
+
+ [URL query: text/css;blah]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini
index bcad0d56823..c0bcb73d564 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini
@@ -36,21 +36,6 @@
[video/webm; codecs="vp9.0" (optional)]
expected: FAIL
- [audio/mp4 with and without codecs]
- expected: FAIL
-
- [audio/ogg with and without codecs]
- expected: FAIL
-
- [audio/wav with and without codecs]
- expected: FAIL
-
- [video/mp4 with and without codecs]
- expected: FAIL
-
- [video/ogg with and without codecs]
- expected: FAIL
-
[video/x-new-fictional-format]
expected: FAIL
@@ -78,15 +63,9 @@
[audio/webm with bogus codec]
expected: FAIL
- [audio/webm with and without codecs]
- expected: FAIL
-
[video/3gpp with bogus codec]
expected: FAIL
- [video/3gpp with and without codecs]
- expected: FAIL
-
[video/mp4; codecs="mp4a.40.2" (optional)]
expected: FAIL
@@ -120,9 +99,30 @@
[video/webm with bogus codec]
expected: FAIL
- [video/webm with and without codecs]
+ [fictional formats and codecs not supported]
+ expected: FAIL
+
+ [audio/webm (optional)]
expected: FAIL
- [fictional formats and codecs not supported]
+ [video/mp4 (optional)]
+ expected: FAIL
+
+ [video/webm (optional)]
+ expected: FAIL
+
+ [audio/wav (optional)]
+ expected: FAIL
+
+ [video/ogg (optional)]
+ expected: FAIL
+
+ [audio/mp4 (optional)]
+ expected: FAIL
+
+ [video/3gpp (optional)]
+ expected: FAIL
+
+ [audio/ogg (optional)]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini
index 92a61676381..cf6b9408e6b 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini
@@ -24,3 +24,6 @@
[<picture><source srcset="data:,b" type="image/foobarbaz"><img src="data:,a" data-expect="data:,a"></picture>]
expected: FAIL
+ [<picture><source srcset="data:,b" type="image/gif;encodings"><img src="data:,a" data-expect="data:,b"></picture>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html.ini
new file mode 100644
index 00000000000..d6db2e55af7
--- /dev/null
+++ b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/module/dynamic-import/dynamic-imports-credentials.sub.html.ini
@@ -0,0 +1,4 @@
+[dynamic-imports-credentials.sub.html]
+ [Dynamic imports should be loaded with or without the credentials based on the same-origin-ness and the parent script's crossOrigin attribute]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/url/a-element-origin-xhtml.xhtml.ini b/tests/wpt/metadata/url/a-element-origin-xhtml.xhtml.ini
index 21b2a4a5d2c..cc2702303bc 100644
--- a/tests/wpt/metadata/url/a-element-origin-xhtml.xhtml.ini
+++ b/tests/wpt/metadata/url/a-element-origin-xhtml.xhtml.ini
@@ -1,8 +1,5 @@
[a-element-origin-xhtml.xhtml]
type: testharness
- [Parsing origin: <sc://\x1f!"$&'()*+,-.;<=>^_`{|}~/> against <about:blank>]
- expected: FAIL
-
[Parsing origin: <https://faß.ExAmPlE/> against <about:blank>]
expected: FAIL
diff --git a/tests/wpt/metadata/url/a-element-origin.html.ini b/tests/wpt/metadata/url/a-element-origin.html.ini
index c4f8964312b..467203dcd45 100644
--- a/tests/wpt/metadata/url/a-element-origin.html.ini
+++ b/tests/wpt/metadata/url/a-element-origin.html.ini
@@ -1,8 +1,4 @@
[a-element-origin.html]
type: testharness
- [Parsing origin: <sc://\x1f!"$&'()*+,-.;<=>^_`{|}~/> against <about:blank>]
- expected: FAIL
-
[Parsing origin: <https://faß.ExAmPlE/> against <about:blank>]
expected: FAIL
-
diff --git a/tests/wpt/metadata/url/a-element-xhtml.xhtml.ini b/tests/wpt/metadata/url/a-element-xhtml.xhtml.ini
index 8abf0e96552..c4ca103fea6 100644
--- a/tests/wpt/metadata/url/a-element-xhtml.xhtml.ini
+++ b/tests/wpt/metadata/url/a-element-xhtml.xhtml.ini
@@ -1,56 +1,8 @@
[a-element-xhtml.xhtml]
type: testharness
- [Parsing: <http://10000000000> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <http://4294967296> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <http://0xffffffff1> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <https://test:@test> against <about:blank>]
- expected: FAIL
-
- [Parsing: <https://:@test> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://test:@test/x> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://:@test/x> against <about:blank>]
- expected: FAIL
-
[Parsing: <foo://> against <http://example.org/foo/bar>]
expected: FAIL
- [Parsing: <http://example.com/foo/%2e%2> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://www/foo%2Ehtml> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http:a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http:/a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://ñ.test/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://\x1f!"$&'()*+,-.;<=>^_`{|}~/> against <about:blank>]
- expected: FAIL
-
[Parsing: <sc://@/> against <about:blank>]
expected: FAIL
@@ -63,9 +15,6 @@
[Parsing: <sc://:12/> against <about:blank>]
expected: FAIL
- [Parsing: <x> against <sc://ñ>]
- expected: FAIL
-
[Parsing: <sc://ñ> against <about:blank>]
expected: FAIL
@@ -96,21 +45,6 @@
[Parsing: <https://faß.ExAmPlE/> against <about:blank>]
expected: FAIL
- [Parsing: <sc://faß.ExAmPlE/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://%/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file:#frag> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://%E2%80%A0/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://H%4fSt/path> against <about:blank>]
- expected: FAIL
-
[Parsing: <file:\\\\//> against <about:blank>]
expected: FAIL
@@ -153,18 +87,6 @@
[Parsing: </?chai> against <file://tea/>]
expected: FAIL
- [Parsing: <file://example.net/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file://1.2.3.4/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file://[1::8\]/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <https://0x100000000/test> against <about:blank>]
- expected: FAIL
-
[Parsing: <C|> against <file://host/dir/file>]
expected: FAIL
@@ -213,3 +135,27 @@
[Parsing: <http://host/?'> against <about:blank>]
expected: FAIL
+ [Parsing: <sc://ñ> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <https://faß.ExAmPlE/> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <sc://ñ#x> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <http://www.google.com/foo?bar=baz# »> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <data:test# »> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <sc://ñ?x> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <?x> against <sc://ñ>]
+ expected: FAIL
+
+ [Parsing: <#x> against <sc://ñ>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/url/a-element.html.ini b/tests/wpt/metadata/url/a-element.html.ini
index 43d58c6105b..c970ed63dfd 100644
--- a/tests/wpt/metadata/url/a-element.html.ini
+++ b/tests/wpt/metadata/url/a-element.html.ini
@@ -1,56 +1,8 @@
[a-element.html]
type: testharness
- [Parsing: <http://10000000000> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <http://4294967296> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <http://0xffffffff1> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <https://test:@test> against <about:blank>]
- expected: FAIL
-
- [Parsing: <https://:@test> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://test:@test/x> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://:@test/x> against <about:blank>]
- expected: FAIL
-
[Parsing: <foo://> against <http://example.org/foo/bar>]
expected: FAIL
- [Parsing: <http://example.com/foo/%2e%2> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://www/foo%2Ehtml> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http:a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http:/a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://ñ.test/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://\x1f!"$&'()*+,-.;<=>^_`{|}~/> against <about:blank>]
- expected: FAIL
-
[Parsing: <sc://@/> against <about:blank>]
expected: FAIL
@@ -63,9 +15,6 @@
[Parsing: <sc://:12/> against <about:blank>]
expected: FAIL
- [Parsing: <x> against <sc://ñ>]
- expected: FAIL
-
[Parsing: <sc://ñ> against <about:blank>]
expected: FAIL
@@ -96,21 +45,6 @@
[Parsing: <https://faß.ExAmPlE/> against <about:blank>]
expected: FAIL
- [Parsing: <sc://faß.ExAmPlE/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://%/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file:#frag> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://%E2%80%A0/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://H%4fSt/path> against <about:blank>]
- expected: FAIL
-
[Parsing: <file:\\\\//> against <about:blank>]
expected: FAIL
@@ -153,18 +87,6 @@
[Parsing: </?chai> against <file://tea/>]
expected: FAIL
- [Parsing: <file://example.net/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file://1.2.3.4/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file://[1::8\]/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <https://0x100000000/test> against <about:blank>]
- expected: FAIL
-
[Parsing: <C|> against <file://host/dir/file>]
expected: FAIL
@@ -213,3 +135,27 @@
[Parsing: <http://host/?'> against <about:blank>]
expected: FAIL
+ [Parsing: <sc://ñ> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <https://faß.ExAmPlE/> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <sc://ñ#x> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <http://www.google.com/foo?bar=baz# »> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <data:test# »> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <sc://ñ?x> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <?x> against <sc://ñ>]
+ expected: FAIL
+
+ [Parsing: <#x> against <sc://ñ>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/url/failure.html.ini b/tests/wpt/metadata/url/failure.html.ini
index 45a5d6b2372..631e3e992a0 100644
--- a/tests/wpt/metadata/url/failure.html.ini
+++ b/tests/wpt/metadata/url/failure.html.ini
@@ -5,169 +5,244 @@
[window.open(): file://example:1/ should throw]
expected: FAIL
+
[window.open(): file://example:test/ should throw]
expected: FAIL
+
[window.open(): file://example%/ should throw]
expected: FAIL
- [window.open(): file://\[example\]/ should throw]
+
+ [window.open(): file://[example\]/ should throw]
expected: FAIL
+
[window.open(): http://user:pass@/ should throw]
expected: FAIL
+
[window.open(): http://foo:-80/ should throw]
expected: FAIL
+
[XHR: http:/:@/www.example.com should throw]
expected: FAIL
+
[window.open(): http:/:@/www.example.com should throw]
expected: FAIL
+
[window.open(): http://user@/www.example.com should throw]
expected: FAIL
+
[XHR: http:@/www.example.com should throw]
expected: FAIL
+
[window.open(): http:@/www.example.com should throw]
expected: FAIL
+
[XHR: http:/@/www.example.com should throw]
expected: FAIL
+
[window.open(): http:/@/www.example.com should throw]
expected: FAIL
+
[window.open(): http://@/www.example.com should throw]
expected: FAIL
+
[window.open(): https:@/www.example.com should throw]
expected: FAIL
+
[XHR: http:a:b@/www.example.com should throw]
expected: FAIL
+
[window.open(): http:a:b@/www.example.com should throw]
expected: FAIL
+
[XHR: http:/a:b@/www.example.com should throw]
expected: FAIL
+
[window.open(): http:/a:b@/www.example.com should throw]
expected: FAIL
+
[window.open(): http://a:b@/www.example.com should throw]
expected: FAIL
+
[XHR: http::@/www.example.com should throw]
expected: FAIL
+
[window.open(): http::@/www.example.com should throw]
expected: FAIL
+
[XHR: http:@:www.example.com should throw]
expected: FAIL
+
[window.open(): http:@:www.example.com should throw]
expected: FAIL
+
[XHR: http:/@:www.example.com should throw]
expected: FAIL
+
[window.open(): http:/@:www.example.com should throw]
expected: FAIL
+
[window.open(): http://@:www.example.com should throw]
expected: FAIL
+
[window.open(): https://� should throw]
expected: FAIL
+
[window.open(): https://%EF%BF%BD should throw]
expected: FAIL
+
[window.open(): https://x x:12 should throw]
expected: FAIL
- [window.open(): http://\[www.google.com\]/ should throw]
+
+ [window.open(): http://[www.google.com\]/ should throw]
expected: FAIL
+
[window.open(): sc:/// should throw]
expected: FAIL
+
[window.open(): sc:// / should throw]
expected: FAIL
+
[URL's constructor's base argument: sc://@/ should throw]
expected: FAIL
+
[URL's href: sc://@/ should throw]
expected: FAIL
+
[XHR: sc://@/ should throw]
expected: FAIL
+
[Location's href: sc://@/ should throw]
expected: FAIL
+
[window.open(): sc://@/ should throw]
expected: FAIL
+
[URL's constructor's base argument: sc://te@s:t@/ should throw]
expected: FAIL
+
[URL's href: sc://te@s:t@/ should throw]
expected: FAIL
+
[XHR: sc://te@s:t@/ should throw]
expected: FAIL
+
[Location's href: sc://te@s:t@/ should throw]
expected: FAIL
+
[window.open(): sc://te@s:t@/ should throw]
expected: FAIL
+
[URL's constructor's base argument: sc://:/ should throw]
expected: FAIL
+
[URL's href: sc://:/ should throw]
expected: FAIL
+
[XHR: sc://:/ should throw]
expected: FAIL
+
[Location's href: sc://:/ should throw]
expected: FAIL
+
[window.open(): sc://:/ should throw]
expected: FAIL
+
[URL's constructor's base argument: sc://:12/ should throw]
expected: FAIL
+
[URL's href: sc://:12/ should throw]
expected: FAIL
+
[XHR: sc://:12/ should throw]
expected: FAIL
+
[Location's href: sc://:12/ should throw]
expected: FAIL
+
[window.open(): sc://:12/ should throw]
expected: FAIL
- [window.open(): sc://\[/ should throw]
+
+ [window.open(): sc://[/ should throw]
expected: FAIL
+
[window.open(): sc://\\/ should throw]
expected: FAIL
+
[window.open(): sc://\]/ should throw]
expected: FAIL
+
[window.open(): sc://\x00/ should throw]
expected: FAIL
+
[window.open(): ftp://example.com%80/ should throw]
expected: FAIL
+
[window.open(): ftp://example.com%A0/ should throw]
expected: FAIL
+
[window.open(): https://example.com%80/ should throw]
expected: FAIL
+
[window.open(): https://example.com%A0/ should throw]
expected: FAIL
- [URL's constructor's base argument: https://0x100000000/test should throw]
- expected: FAIL
- [URL's href: https://0x100000000/test should throw]
- expected: FAIL
- [XHR: https://0x100000000/test should throw]
- expected: FAIL
- [Location's href: https://0x100000000/test should throw]
- expected: FAIL
+
[window.open(): https://0x100000000/test should throw]
expected: FAIL
+
[window.open(): https://256.0.0.1/test should throw]
expected: FAIL
- [window.open(): https://\[0::0::0\] should throw]
+
+ [window.open(): https://[0::0::0\] should throw]
expected: FAIL
- [window.open(): https://\[0:.0\] should throw]
+
+ [window.open(): https://[0:.0\] should throw]
expected: FAIL
- [window.open(): https://\[0:0:\] should throw]
+
+ [window.open(): https://[0:0:\] should throw]
expected: FAIL
- [window.open(): https://\[0:1:2:3:4:5:6:7.0.0.0.1\] should throw]
+
+ [window.open(): https://[0:1:2:3:4:5:6:7.0.0.0.1\] should throw]
expected: FAIL
- [window.open(): https://\[0:1.00.0.0.0\] should throw]
+
+ [window.open(): https://[0:1.00.0.0.0\] should throw]
expected: FAIL
- [window.open(): https://\[0:1.290.0.0.0\] should throw]
+
+ [window.open(): https://[0:1.290.0.0.0\] should throw]
expected: FAIL
- [window.open(): https://\[0:1.23.23\] should throw]
+
+ [window.open(): https://[0:1.23.23\] should throw]
expected: FAIL
+
[window.open(): http://? should throw]
expected: FAIL
+
[window.open(): http://# should throw]
expected: FAIL
- [window.open(): non-special://\[:80/ should throw]
+
+ [window.open(): non-special://[:80/ should throw]
expected: FAIL
- [window.open(): http://\[::127.0.0.0.1\] should throw]
+
+ [window.open(): http://[::127.0.0.0.1\] should throw]
expected: FAIL
+
[XHR: a should throw]
expected: FAIL
+
[window.open(): a should throw]
expected: FAIL
+
[XHR: a/ should throw]
expected: FAIL
+
[window.open(): a/ should throw]
expected: FAIL
+
[XHR: a// should throw]
expected: FAIL
+
[window.open(): a// should throw]
expected: FAIL
+
+ [window.open(): https://� should throw]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/url/url-constructor.html.ini b/tests/wpt/metadata/url/url-constructor.html.ini
index e8a51ab3de0..e3ffc72c5ca 100644
--- a/tests/wpt/metadata/url/url-constructor.html.ini
+++ b/tests/wpt/metadata/url/url-constructor.html.ini
@@ -1,56 +1,8 @@
[url-constructor.html]
type: testharness
- [Parsing: <http://10000000000> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <http://4294967296> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <http://0xffffffff1> against <http://other.com/>]
- expected: FAIL
-
- [Parsing: <https://test:@test> against <about:blank>]
- expected: FAIL
-
- [Parsing: <https://:@test> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://test:@test/x> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://:@test/x> against <about:blank>]
- expected: FAIL
-
[Parsing: <foo://> against <http://example.org/foo/bar>]
expected: FAIL
- [Parsing: <http://example.com/foo/%2e%2> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://www/foo%2Ehtml> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http:a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http:/a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://a:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <http://:@www.example.com> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://ñ.test/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://\x1f!"$&'()*+,-.;<=>^_`{|}~/> against <about:blank>]
- expected: FAIL
-
[Parsing: <sc://@/> against <about:blank>]
expected: FAIL
@@ -63,9 +15,6 @@
[Parsing: <sc://:12/> against <about:blank>]
expected: FAIL
- [Parsing: <x> against <sc://ñ>]
- expected: FAIL
-
[Parsing: <sc://ñ> against <about:blank>]
expected: FAIL
@@ -96,21 +45,6 @@
[Parsing: <https://faß.ExAmPlE/> against <about:blank>]
expected: FAIL
- [Parsing: <sc://faß.ExAmPlE/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <sc://%/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file:#frag> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://%E2%80%A0/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <non-special://H%4fSt/path> against <about:blank>]
- expected: FAIL
-
[Parsing: <file:\\\\//> against <about:blank>]
expected: FAIL
@@ -153,18 +87,6 @@
[Parsing: </?chai> against <file://tea/>]
expected: FAIL
- [Parsing: <file://example.net/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file://1.2.3.4/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <file://[1::8\]/C:/> against <about:blank>]
- expected: FAIL
-
- [Parsing: <https://0x100000000/test> against <about:blank>]
- expected: FAIL
-
[Parsing: <C|> against <file://host/dir/file>]
expected: FAIL
@@ -204,3 +126,27 @@
[Parsing: <http://host/?'> against <about:blank>]
expected: FAIL
+ [Parsing: <sc://ñ> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <https://faß.ExAmPlE/> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <sc://ñ#x> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <http://www.google.com/foo?bar=baz# »> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <data:test# »> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <sc://ñ?x> against <about:blank>]
+ expected: FAIL
+
+ [Parsing: <?x> against <sc://ñ>]
+ expected: FAIL
+
+ [Parsing: <#x> against <sc://ñ>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/url/url-origin.html.ini b/tests/wpt/metadata/url/url-origin.html.ini
index 76abb3c7a43..5d0f79285e8 100644
--- a/tests/wpt/metadata/url/url-origin.html.ini
+++ b/tests/wpt/metadata/url/url-origin.html.ini
@@ -1,6 +1,6 @@
[url-origin.html]
type: testharness
- [Origin parsing: <sc://\x1f!"$&'()*+,-.;<=>^_`{|}~/> against <about:blank>]
+ [Origin parsing: <https://faß.ExAmPlE/> against <about:blank>]
expected: FAIL
[Origin parsing: <https://faß.ExAmPlE/> against <about:blank>]
diff --git a/tests/wpt/metadata/url/url-setters.html.ini b/tests/wpt/metadata/url/url-setters.html.ini
index a78f6df7be7..b33b1118516 100644
--- a/tests/wpt/metadata/url/url-setters.html.ini
+++ b/tests/wpt/metadata/url/url-setters.html.ini
@@ -636,18 +636,6 @@
[<area>: Setting <http://example.net/>.hostname = '[::1.\]']
expected: FAIL
- [URL: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\\a\\%2E\\b\\%2e.\\c' \\ is *not* a segment delimiter for non-'special' URLs]
- expected: FAIL
-
- [<a>: Setting <view-source+http://example.net/home?lang=fr#nav>.pathname = '\\a\\%2E\\b\\%2e.\\c' \\ is *not* a segment delimiter for non-'special' URLs]
- expected: FAIL
-
- [URL: Setting <http://example.net>.pathname = '%2e%2E%c3%89té' Bytes already percent-encoded are left as-is, including %2E outside dotted segments.]
- expected: FAIL
-
- [<a>: Setting <http://example.net>.pathname = '%2e%2E%c3%89té' Bytes already percent-encoded are left as-is, including %2E outside dotted segments.]
- expected: FAIL
-
[<area>: Setting <http://example.net>.pathname = '%2e%2E%c3%89té' Bytes already percent-encoded are left as-is, including %2E outside dotted segments.]
expected: FAIL
@@ -660,48 +648,18 @@
[<area>: Setting <sc://example.net>.pathname = '#' # needs to be encoded, non-special scheme]
expected: FAIL
- [URL: Setting <sc:///>.username = 'x']
- expected: FAIL
-
- [<a>: Setting <sc:///>.username = 'x']
- expected: FAIL
-
[<area>: Setting <sc:///>.username = 'x']
expected: FAIL
- [URL: Setting <file://test/>.username = 'test']
- expected: FAIL
-
- [<a>: Setting <file://test/>.username = 'test']
- expected: FAIL
-
[<area>: Setting <file://test/>.username = 'test']
expected: FAIL
- [URL: Setting <sc:///>.password = 'x']
- expected: FAIL
-
- [<a>: Setting <sc:///>.password = 'x']
- expected: FAIL
-
[<area>: Setting <sc:///>.password = 'x']
expected: FAIL
- [URL: Setting <file://test/>.password = 'test']
- expected: FAIL
-
- [<a>: Setting <file://test/>.password = 'test']
- expected: FAIL
-
[<area>: Setting <file://test/>.password = 'test']
expected: FAIL
- [URL: Setting <sc://x/>.host = 'ß']
- expected: FAIL
-
- [<a>: Setting <sc://x/>.host = 'ß']
- expected: FAIL
-
[<area>: Setting <sc://x/>.host = 'ß']
expected: FAIL
@@ -807,12 +765,6 @@
[<area>: Setting <non-base:value>.port = '12']
expected: FAIL
- [URL: Setting <sc:///>.port = '12']
- expected: FAIL
-
- [<a>: Setting <sc:///>.port = '12']
- expected: FAIL
-
[<area>: Setting <sc:///>.port = '12']
expected: FAIL
@@ -981,3 +933,117 @@
[<area>: Setting <http://example.net:8080>.host = 'example.com:80' Port number is removed if new port is scheme default and existing URL has a non-default port]
expected: FAIL
+ [URL: Setting <a:/>.hash = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' Simple percent-encoding; nuls, tabs, and newlines are removed]
+ expected: FAIL
+
+ [<a>: Setting <a:/>.pathname = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.]
+ expected: FAIL
+
+ [<a>: Setting <a:/>.search = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.]
+ expected: FAIL
+
+ [<area>: Setting <https://x/>.host = 'ß' IDNA Nontransitional_Processing]
+ expected: FAIL
+
+ [URL: Setting <a:/>.search = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.]
+ expected: FAIL
+
+ [<area>: Setting <http://example.net>.protocol = 'b' Can’t switch from special scheme to non-special]
+ expected: FAIL
+
+ [<area>: Setting <file://localhost/>.protocol = 'http' Can’t switch from file URL with no host]
+ expected: FAIL
+
+ [<area>: Setting <a://example.net>.protocol = 'bé' Non-ASCII is rejected]
+ expected: FAIL
+
+ [<area>: Setting <http://example.net>.username = '%c3%89té' Bytes already percent-encoded are left as-is.]
+ expected: FAIL
+
+ [<area>: Setting <a:/>.pathname = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.]
+ expected: FAIL
+
+ [<area>: Setting <mailto:me@example.net>.pathname = '/foo' Cannot-be-a-base don’t have a path]
+ expected: FAIL
+
+ [<area>: Setting <a://example.net>.protocol = 'é' Non-ASCII is rejected]
+ expected: FAIL
+
+ [<area>: Setting <http://example.net>.password = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' UTF-8 percent encoding with the userinfo encode set.]
+ expected: FAIL
+
+ [<a>: Setting <https://x/>.host = 'ß' IDNA Nontransitional_Processing]
+ expected: FAIL
+
+ [<a>: Setting <a:/>.hash = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' Simple percent-encoding; nuls, tabs, and newlines are removed]
+ expected: FAIL
+
+ [<a>: Setting <http://example.net>.protocol = 'b' Can’t switch from special scheme to non-special]
+ expected: FAIL
+
+ [<a>: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file]
+ expected: FAIL
+
+ [URL: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special]
+ expected: FAIL
+
+ [<area>: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file]
+ expected: FAIL
+
+ [<area>: Setting <http://example.net>.password = '%c3%89té' Bytes already percent-encoded are left as-is.]
+ expected: FAIL
+
+ [<area>: Setting <mailto:me@example.net>.protocol = 'http' Cannot-be-a-base URL doesn’t have a host, but URL in a special scheme must.]
+ expected: FAIL
+
+ [URL: Setting <http://test@example.net>.protocol = 'file' Can’t switch from URL containing username/password/port to file]
+ expected: FAIL
+
+ [<a>: Setting <a://example.net>.protocol = 'é' Non-ASCII is rejected]
+ expected: FAIL
+
+ [<area>: Setting <sc://x/>.host = 'ß']
+ expected: FAIL
+
+ [URL: Setting <http://example.net>.protocol = 'b' Can’t switch from special scheme to non-special]
+ expected: FAIL
+
+ [<area>: Setting <http://example.net>.username = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' UTF-8 percent encoding with the userinfo encode set.]
+ expected: FAIL
+
+ [URL: Setting <a://example.net>.protocol = 'bé' Non-ASCII is rejected]
+ expected: FAIL
+
+ [<area>: Setting <a:/>.search = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.]
+ expected: FAIL
+
+ [URL: Setting <a:/>.pathname = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.]
+ expected: FAIL
+
+ [<area>: Setting <http://example.net>.pathname = '%2e%2E%c3%89té' Bytes already percent-encoded are left as-is, including %2E outside dotted segments.]
+ expected: FAIL
+
+ [<area>: Setting <http://example.net>.hash = '%c3%89té' Bytes already percent-encoded are left as-is]
+ expected: FAIL
+
+ [<a>: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special]
+ expected: FAIL
+
+ [<area>: Setting <http://example.net>.search = '%c3%89té' Bytes already percent-encoded are left as-is]
+ expected: FAIL
+
+ [URL: Setting <a://example.net>.protocol = 'é' Non-ASCII is rejected]
+ expected: FAIL
+
+ [<area>: Setting <a:/>.hash = '\x00\x01\t\n\r\x1f !"#$%&'()*+,-./09:;<=>?@AZ[\\\]^_`az{|}~€Éé' Simple percent-encoding; nuls, tabs, and newlines are removed]
+ expected: FAIL
+
+ [URL: Setting <https://x/>.host = 'ß' IDNA Nontransitional_Processing]
+ expected: FAIL
+
+ [<area>: Setting <ssh://me@example.net>.protocol = 'http' Can’t switch from non-special scheme to special]
+ expected: FAIL
+
+ [<a>: Setting <a://example.net>.protocol = 'bé' Non-ASCII is rejected]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/websockets/basic-auth.any.js.ini b/tests/wpt/metadata/websockets/basic-auth.any.js.ini
index 82ab5c1ee6a..d6f36dd4c7d 100644
--- a/tests/wpt/metadata/websockets/basic-auth.any.js.ini
+++ b/tests/wpt/metadata/websockets/basic-auth.any.js.ini
@@ -13,20 +13,10 @@
[basic-auth]
expected: FAIL
+
[basic-auth.any.sharedworker.html]
[Untitled]
expected: FAIL
[basic-auth]
expected: FAIL
-
-
-[basic-auth.any.html]
- [HTTP basic authentication should work with WebSockets]
- expected: FAIL
-
-
-[basic-auth.any.worker.html]
- [HTTP basic authentication should work with WebSockets]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/access-control-and-redirects.htm.ini b/tests/wpt/metadata/xhr/access-control-and-redirects.htm.ini
deleted file mode 100644
index 0e557f621cb..00000000000
--- a/tests/wpt/metadata/xhr/access-control-and-redirects.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[access-control-and-redirects.htm]
- type: testharness
- [Remote sync redirect to local origin]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/access-control-basic-allow-access-control-origin-header-data-url.htm.ini b/tests/wpt/metadata/xhr/access-control-basic-allow-access-control-origin-header-data-url.htm.ini
deleted file mode 100644
index 314fe9ed767..00000000000
--- a/tests/wpt/metadata/xhr/access-control-basic-allow-access-control-origin-header-data-url.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[access-control-basic-allow-access-control-origin-header-data-url.htm]
- type: testharness
- [Access granted to null-origin iframe]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/allow-lists-starting-with-comma.htm.ini b/tests/wpt/metadata/xhr/allow-lists-starting-with-comma.htm.ini
new file mode 100644
index 00000000000..0c3fc9aa2c2
--- /dev/null
+++ b/tests/wpt/metadata/xhr/allow-lists-starting-with-comma.htm.ini
@@ -0,0 +1,4 @@
+[allow-lists-starting-with-comma.htm]
+ [Allow lists starting with a comma should be parsed correctly]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/getresponseheader-chunked-trailer.htm.ini b/tests/wpt/metadata/xhr/getresponseheader-chunked-trailer.htm.ini
index 0ee1ddfee54..586a42bd464 100644
--- a/tests/wpt/metadata/xhr/getresponseheader-chunked-trailer.htm.ini
+++ b/tests/wpt/metadata/xhr/getresponseheader-chunked-trailer.htm.ini
@@ -1,5 +1,6 @@
[getresponseheader-chunked-trailer.htm]
type: testharness
+ expected: TIMEOUT
[XMLHttpRequest: getResponseHeader() and HTTP trailer]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/metadata/xhr/headers-normalize-response.htm.ini b/tests/wpt/metadata/xhr/headers-normalize-response.htm.ini
index c5dc615ee07..01ee7293a40 100644
--- a/tests/wpt/metadata/xhr/headers-normalize-response.htm.ini
+++ b/tests/wpt/metadata/xhr/headers-normalize-response.htm.ini
@@ -12,3 +12,9 @@
[Header value: [tab\]hello_world[tab\]]
expected: FAIL
+ [Header value: hello_world__]
+ expected: FAIL
+
+ [Header value: __hello_world__]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/overridemimetype-blob.html.ini b/tests/wpt/metadata/xhr/overridemimetype-blob.html.ini
index a72e097385e..92513ff0e20 100644
--- a/tests/wpt/metadata/xhr/overridemimetype-blob.html.ini
+++ b/tests/wpt/metadata/xhr/overridemimetype-blob.html.ini
@@ -168,3 +168,45 @@
[57) MIME types need to be parsed and serialized: Ā/Ā]
expected: FAIL
+ [7) MIME types need to be parsed and serialized: text/html;charset =gbk]
+ expected: FAIL
+
+ [38) MIME types need to be parsed and serialized: x/x;x="\t !\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"]
+ expected: FAIL
+
+ [44) MIME types need to be parsed and serialized: x/x;test=�;x=x]
+ expected: FAIL
+
+ [43) MIME types need to be parsed and serialized: text/html;test=ÿ;charset=gbk]
+ expected: FAIL
+
+ [42) MIME types need to be parsed and serialized: x/x;x=\t]
+ expected: FAIL
+
+ [54) MIME types need to be parsed and serialized: ÿ/ÿ]
+ expected: FAIL
+
+ [57) MIME types need to be parsed and serialized: Ā/Ā]
+ expected: FAIL
+
+ [38) MIME types need to be parsed and serialized: x/x;x="\t !\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"]
+ expected: FAIL
+
+ [44) MIME types need to be parsed and serialized: x/x;test=�;x=x]
+ expected: FAIL
+
+ [43) MIME types need to be parsed and serialized: text/html;test=ÿ;charset=gbk]
+ expected: FAIL
+
+ [54) MIME types need to be parsed and serialized: ÿ/ÿ]
+ expected: FAIL
+
+ [57) MIME types need to be parsed and serialized: Ā/Ā]
+ expected: FAIL
+
+ [41) MIME types need to be parsed and serialized: x/x;x= ]
+ expected: FAIL
+
+ [39) MIME types need to be parsed and serialized: x/x;test]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/preserve-ua-header-on-redirect.htm.ini b/tests/wpt/metadata/xhr/preserve-ua-header-on-redirect.htm.ini
deleted file mode 100644
index 468b61c3512..00000000000
--- a/tests/wpt/metadata/xhr/preserve-ua-header-on-redirect.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[preserve-ua-header-on-redirect.htm]
- type: testharness
- [XMLHttpRequest: User-Agent header is preserved on redirect 1]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/responsexml-media-type.htm.ini b/tests/wpt/metadata/xhr/responsexml-media-type.htm.ini
new file mode 100644
index 00000000000..956871eb01f
--- /dev/null
+++ b/tests/wpt/metadata/xhr/responsexml-media-type.htm.ini
@@ -0,0 +1,4 @@
+[responsexml-media-type.htm]
+ [XMLHttpRequest: responseXML MIME type tests ('text/plain;+xml', should not parse)]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/send-accept-language.htm.ini b/tests/wpt/metadata/xhr/send-accept-language.htm.ini
deleted file mode 100644
index 32239786ffd..00000000000
--- a/tests/wpt/metadata/xhr/send-accept-language.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[send-accept-language.htm]
- type: testharness
- [XMLHttpRequest: send() - Accept-Language]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/send-content-type-charset.htm.ini b/tests/wpt/metadata/xhr/send-content-type-charset.htm.ini
index c2a07ab0aa7..cbd02923017 100644
--- a/tests/wpt/metadata/xhr/send-content-type-charset.htm.ini
+++ b/tests/wpt/metadata/xhr/send-content-type-charset.htm.ini
@@ -24,9 +24,6 @@
[charset given but wrong, fix it (known MIME, actual charset)]
expected: FAIL
- [If no charset= param is given, implementation should not add one - known MIME, unknown param, two spaces]
- expected: FAIL
-
[Multiple charset parameters deduplicate, bogus parameter dropped]
expected: FAIL
@@ -45,9 +42,6 @@
[unknown parameters need to be preserved]
expected: FAIL
- [charset with space that is UTF-8 does not change]
- expected: FAIL
-
[charset in double quotes with backslashes that is UTF-8 does not change]
expected: FAIL
@@ -57,9 +51,3 @@
[Multiple non-UTF-8 charset parameters deduplicate, bogus parameter dropped]
expected: FAIL
- [If charset= param is UTF-8 (case-insensitive), it should not be changed]
- expected: FAIL
-
- [charset in double quotes that is UTF-8 does not change]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/send-data-unexpected-tostring.htm.ini b/tests/wpt/metadata/xhr/send-data-unexpected-tostring.htm.ini
index 83018dbd05b..8fa623e7c06 100644
--- a/tests/wpt/metadata/xhr/send-data-unexpected-tostring.htm.ini
+++ b/tests/wpt/metadata/xhr/send-data-unexpected-tostring.htm.ini
@@ -3,3 +3,6 @@
[abort() called from data stringification]
expected: FAIL
+ [open() called from data stringification]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/send-redirect-no-location.htm.ini b/tests/wpt/metadata/xhr/send-redirect-no-location.htm.ini
new file mode 100644
index 00000000000..ae569b6da87
--- /dev/null
+++ b/tests/wpt/metadata/xhr/send-redirect-no-location.htm.ini
@@ -0,0 +1,13 @@
+[send-redirect-no-location.htm]
+ [XMLHttpRequest: send() - Redirects (no Location header) (303)]
+ expected: FAIL
+
+ [XMLHttpRequest: send() - Redirects (no Location header) (301)]
+ expected: FAIL
+
+ [XMLHttpRequest: send() - Redirects (no Location header) (307)]
+ expected: FAIL
+
+ [XMLHttpRequest: send() - Redirects (no Location header) (302)]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/setrequestheader-allow-empty-value.htm.ini b/tests/wpt/metadata/xhr/setrequestheader-allow-empty-value.htm.ini
deleted file mode 100644
index 6085cd77216..00000000000
--- a/tests/wpt/metadata/xhr/setrequestheader-allow-empty-value.htm.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[setrequestheader-allow-empty-value.htm]
- type: testharness
- [XMLHttpRequest: setRequestHeader() - empty header ()]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - empty header (null)]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - empty header (undefined)]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/setrequestheader-allow-whitespace-in-value.htm.ini b/tests/wpt/metadata/xhr/setrequestheader-allow-whitespace-in-value.htm.ini
deleted file mode 100644
index 7607e617629..00000000000
--- a/tests/wpt/metadata/xhr/setrequestheader-allow-whitespace-in-value.htm.ini
+++ /dev/null
@@ -1,14 +0,0 @@
-[setrequestheader-allow-whitespace-in-value.htm]
- type: testharness
- [XMLHttpRequest: setRequestHeader() - header value with whitespace ( )]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - header value with whitespace ( t)]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - header value with whitespace (t )]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - header value with whitespace ( t )]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/setrequestheader-case-insensitive.htm.ini b/tests/wpt/metadata/xhr/setrequestheader-case-insensitive.htm.ini
index d8b4df09bc5..fe3deba5902 100644
--- a/tests/wpt/metadata/xhr/setrequestheader-case-insensitive.htm.ini
+++ b/tests/wpt/metadata/xhr/setrequestheader-case-insensitive.htm.ini
@@ -2,3 +2,6 @@
[XMLHttpRequest: setRequestHeader() - headers that differ in case 1]
expected: FAIL
+ [XMLHttpRequest: setRequestHeader() - headers that differ in case]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/setrequestheader-content-type.htm.ini b/tests/wpt/metadata/xhr/setrequestheader-content-type.htm.ini
index 6a6aba997c1..c66121aa9f6 100644
--- a/tests/wpt/metadata/xhr/setrequestheader-content-type.htm.ini
+++ b/tests/wpt/metadata/xhr/setrequestheader-content-type.htm.ini
@@ -1,11 +1,5 @@
[setrequestheader-content-type.htm]
type: testharness
- [ArrayBuffer request keeps setRequestHeader() Content-Type and charset]
- expected: FAIL
-
- [ArrayBufferView request keeps setRequestHeader() Content-Type and charset]
- expected: FAIL
-
[URLSearchParams request keeps setRequestHeader() Content-Type, with charset adjusted to UTF-8]
expected: FAIL
@@ -18,75 +12,15 @@
[ReadableStream request keeps setRequestHeader() Content-Type and charset]
expected: FAIL
- [setRequestHeader("") sends a blank string]
- expected: FAIL
-
- [setRequestHeader(" ") sends the string " "]
- expected: FAIL
-
- [setRequestHeader(null) sends the string "null"]
- expected: FAIL
-
- [setRequestHeader(undefined) sends the string "undefined"]
- expected: FAIL
-
- [String request has correct default Content-Type of "text/plain;charset=UTF-8"]
- expected: FAIL
-
[String request keeps setRequestHeader() Content-Type, with charset adjusted to UTF-8]
expected: FAIL
- [XML Document request respects setRequestHeader("")]
- expected: FAIL
-
- [XML Document request has correct default Content-Type of "application/xml;charset=UTF-8"]
- expected: FAIL
-
[XML Document request keeps setRequestHeader() Content-Type, with charset adjusted to UTF-8]
expected: FAIL
- [HTML Document request respects setRequestHeader("")]
- expected: FAIL
-
- [HTML Document request has correct default Content-Type of "text/html;charset=UTF-8"]
- expected: FAIL
-
[HTML Document request keeps setRequestHeader() Content-Type, with charset adjusted to UTF-8]
expected: FAIL
- [Blob request respects setRequestHeader("") to be specified]
- expected: FAIL
-
- [Blob request with unset type keeps setRequestHeader() Content-Type and charset]
- expected: FAIL
-
- [Blob request with set type uses that it for Content-Type unless setRequestHeader()]
- expected: FAIL
-
- [Blob request with set type keeps setRequestHeader() Content-Type and charset]
- expected: FAIL
-
- [ArrayBuffer request respects setRequestHeader("")]
- expected: FAIL
-
- [ArrayBufferView request respects setRequestHeader("")]
- expected: FAIL
-
- [FormData request respects setRequestHeader("")]
- expected: FAIL
-
[FormData request has correct default Content-Type of "multipart/form-data; boundary=_"]
expected: FAIL
- [FormData request keeps setRequestHeader() Content-Type and charset]
- expected: FAIL
-
- [URLSearchParams respects setRequestHeader("")]
- expected: FAIL
-
- [URLSearchParams request has correct default Content-Type of "application/x-www-form-urlencoded;charset=UTF-8"]
- expected: FAIL
-
- [Blob request with set type respects setRequestHeader("") to be specified]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/setrequestheader-header-allowed.htm.ini b/tests/wpt/metadata/xhr/setrequestheader-header-allowed.htm.ini
index 9a8d9b02b44..3a000edc060 100644
--- a/tests/wpt/metadata/xhr/setrequestheader-header-allowed.htm.ini
+++ b/tests/wpt/metadata/xhr/setrequestheader-header-allowed.htm.ini
@@ -1,29 +1,7 @@
[setrequestheader-header-allowed.htm]
type: testharness
- [XMLHttpRequest: setRequestHeader() - headers that are allowed (Authorization)]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - headers that are allowed (Pragma)]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - headers that are allowed (User-Agent)]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - headers that are allowed (Content-Transfer-Encoding)]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - headers that are allowed (Content-Type)]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - headers that are allowed (Overwrite)]
- expected: FAIL
-
- [XMLHttpRequest: setRequestHeader() - headers that are allowed (If)]
- expected: FAIL
-
+ expected: CRASH
+ bug: https://github.com/hyperium/http/pull/271
[XMLHttpRequest: setRequestHeader() - headers that are allowed (Status-URI)]
expected: FAIL
- [XMLHttpRequest: setRequestHeader() - headers that are allowed (X-Pink-Unicorn)]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/xhr/status-async.htm.ini b/tests/wpt/metadata/xhr/status-async.htm.ini
new file mode 100644
index 00000000000..3a50b76d527
--- /dev/null
+++ b/tests/wpt/metadata/xhr/status-async.htm.ini
@@ -0,0 +1,82 @@
+[status-async.htm]
+ [XMLHttpRequest: status/statusText - various responses 24 (CHICKEN 503)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 8 (HEAD 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 5 (HEAD 401)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 14 (HEAD 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 19 (GET 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 2 (HEAD 204)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 4 (GET 401)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 9 (CHICKEN 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 6 (CHICKEN 401)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 22 (GET 503)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 20 (HEAD 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 10 (GET 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 21 (CHICKEN 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 11 (HEAD 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 1 (GET 204)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 25 (GET 699)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 16 (GET 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 12 (CHICKEN 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 7 (GET 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 27 (CHICKEN 699)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 26 (HEAD 699)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 13 (GET 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 17 (HEAD 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 3 (CHICKEN 204)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 23 (HEAD 503)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 15 (CHICKEN 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 18 (CHICKEN 502)]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/status-basic.htm.ini b/tests/wpt/metadata/xhr/status-basic.htm.ini
new file mode 100644
index 00000000000..6f08c0d29bd
--- /dev/null
+++ b/tests/wpt/metadata/xhr/status-basic.htm.ini
@@ -0,0 +1,82 @@
+[status-basic.htm]
+ [XMLHttpRequest: status/statusText - various responses 24 (CHICKEN 503)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 8 (HEAD 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 5 (HEAD 401)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 14 (HEAD 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 19 (GET 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 2 (HEAD 204)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 4 (GET 401)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 9 (CHICKEN 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 6 (CHICKEN 401)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 22 (GET 503)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 20 (HEAD 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 10 (GET 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 21 (CHICKEN 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 11 (HEAD 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 1 (GET 204)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 25 (GET 699)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 16 (GET 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 12 (CHICKEN 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 7 (GET 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 27 (CHICKEN 699)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 26 (HEAD 699)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 13 (GET 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 17 (HEAD 502)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 3 (CHICKEN 204)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 23 (HEAD 503)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 15 (CHICKEN 402)]
+ expected: FAIL
+
+ [XMLHttpRequest: status/statusText - various responses 18 (CHICKEN 502)]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/xhr/status-error.htm.ini b/tests/wpt/metadata/xhr/status-error.htm.ini
new file mode 100644
index 00000000000..922f4647fe4
--- /dev/null
+++ b/tests/wpt/metadata/xhr/status-error.htm.ini
@@ -0,0 +1,13 @@
+[status-error.htm]
+ [XMLHttpRequest: status error handling GET 699]
+ expected: FAIL
+
+ [XMLHttpRequest: status error handling POST 699]
+ expected: FAIL
+
+ [XMLHttpRequest: status error handling PUT 699]
+ expected: FAIL
+
+ [XMLHttpRequest: status error handling HEAD 699]
+ expected: FAIL
+