mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
net: Replace ws-rs with async-tungstenite.
This commit is contained in:
parent
e0e22a3399
commit
76198e40a8
8 changed files with 765 additions and 324 deletions
358
Cargo.lock
generated
358
Cargo.lock
generated
|
@ -171,6 +171,22 @@ dependencies = [
|
||||||
"libloading 0.6.1",
|
"libloading 0.6.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-tungstenite"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2760f968801f873112e651c5a9c3b60c11ae6d66e7ca3f2d51aafbfcef9495fa"
|
||||||
|
dependencies = [
|
||||||
|
"futures-io",
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"openssl",
|
||||||
|
"pin-project",
|
||||||
|
"tokio 0.2.21",
|
||||||
|
"tokio-openssl 0.4.0",
|
||||||
|
"tungstenite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atom"
|
name = "atom"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -474,6 +490,15 @@ dependencies = [
|
||||||
"iovec",
|
"iovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "0.5.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b"
|
||||||
|
dependencies = [
|
||||||
|
"loom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bzip2"
|
name = "bzip2"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -815,7 +840,7 @@ dependencies = [
|
||||||
"gaol",
|
"gaol",
|
||||||
"gfx",
|
"gfx",
|
||||||
"gfx_traits",
|
"gfx_traits",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
"keyboard-types",
|
"keyboard-types",
|
||||||
"layout_traits",
|
"layout_traits",
|
||||||
|
@ -1204,7 +1229,7 @@ dependencies = [
|
||||||
"devtools_traits",
|
"devtools_traits",
|
||||||
"embedder_traits",
|
"embedder_traits",
|
||||||
"headers",
|
"headers",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"hyper",
|
"hyper",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1222,7 +1247,7 @@ name = "devtools_traits"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
"malloc_size_of",
|
"malloc_size_of",
|
||||||
"malloc_size_of_derive",
|
"malloc_size_of_derive",
|
||||||
|
@ -1592,6 +1617,21 @@ version = "0.1.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869"
|
checksum = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -1599,6 +1639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
|
checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1613,7 +1654,7 @@ version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1628,6 +1669,12 @@ dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -1661,9 +1708,13 @@ version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
|
checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
"futures-macro",
|
"futures-macro",
|
||||||
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
|
@ -1690,6 +1741,19 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generator"
|
||||||
|
version = "0.6.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"rustc_version",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
@ -2327,10 +2391,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
|
checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"fnv",
|
"fnv",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"log",
|
"log",
|
||||||
"slab",
|
"slab",
|
||||||
|
@ -2374,9 +2438,9 @@ checksum = "882ca7d8722f33ce2c2db44f95425d6267ed59ca96ce02acbe58320054ceb642"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.10.1",
|
"base64 0.10.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"headers-core",
|
"headers-core",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"mime",
|
"mime",
|
||||||
"sha-1",
|
"sha-1",
|
||||||
"time",
|
"time",
|
||||||
|
@ -2388,8 +2452,8 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "967131279aaa9f7c20c7205b45a391638a83ab118e6509b2d0ccbe08de044237"
|
checksum = "967131279aaa9f7c20c7205b45a391638a83ab118e6509b2d0ccbe08de044237"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2451,7 +2515,18 @@ version = "0.1.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0"
|
checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
|
"fnv",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.5.5",
|
||||||
"fnv",
|
"fnv",
|
||||||
"itoa",
|
"itoa",
|
||||||
]
|
]
|
||||||
|
@ -2462,9 +2537,9 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
|
checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"tokio-buf",
|
"tokio-buf",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2489,11 +2564,11 @@ version = "0.12.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6"
|
checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"futures-cpupool",
|
"futures-cpupool",
|
||||||
"h2",
|
"h2",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
"iovec",
|
"iovec",
|
||||||
|
@ -2502,7 +2577,7 @@ dependencies = [
|
||||||
"net2",
|
"net2",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio 0.1.22",
|
||||||
"tokio-buf",
|
"tokio-buf",
|
||||||
"tokio-executor",
|
"tokio-executor",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
|
@ -2520,15 +2595,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f52657b5cdb2a8067efd29a02e011b7cf656b473ec8a5c34e86645e85d763006"
|
checksum = "f52657b5cdb2a8067efd29a02e011b7cf656b473ec8a5c34e86645e85d763006"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"antidote",
|
"antidote",
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"hyper",
|
"hyper",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"linked_hash_set",
|
"linked_hash_set",
|
||||||
"openssl",
|
"openssl",
|
||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
"tokio-openssl",
|
"tokio-openssl 0.3.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2539,7 +2614,7 @@ checksum = "3bf0fc731a638339172253834b4ba8d60a9ecbeb4c031fcfcacd25b3cdf6e6c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cookie",
|
"cookie",
|
||||||
"headers",
|
"headers",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"hyper",
|
"hyper",
|
||||||
"mime",
|
"mime",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -2611,6 +2686,15 @@ dependencies = [
|
||||||
"adler32",
|
"adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "input_buffer"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.5.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-surface"
|
name = "io-surface"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
@ -3134,6 +3218,17 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "loom"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"generator",
|
||||||
|
"scoped-tls 0.1.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lyon_geom"
|
name = "lyon_geom"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
|
@ -3387,9 +3482,10 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.18"
|
version = "0.6.22"
|
||||||
source = "git+https://github.com/servo/mio.git?branch=servo#846242c05bacacda9a67033551eb33027f2648fc"
|
source = "git+https://github.com/servo/mio.git?branch=servo-mio-0.6.22#f640fd662db03026ca2a1b21ac1e161ec6f8150b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
"fuchsia-zircon",
|
"fuchsia-zircon",
|
||||||
"fuchsia-zircon-sys",
|
"fuchsia-zircon-sys",
|
||||||
"iovec",
|
"iovec",
|
||||||
|
@ -3527,13 +3623,32 @@ dependencies = [
|
||||||
"spirv_headers",
|
"spirv_headers",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native-tls"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"openssl",
|
||||||
|
"openssl-probe",
|
||||||
|
"openssl-sys",
|
||||||
|
"schannel",
|
||||||
|
"security-framework",
|
||||||
|
"security-framework-sys",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "net"
|
name = "net"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-tungstenite",
|
||||||
"base64 0.10.1",
|
"base64 0.10.1",
|
||||||
"brotli",
|
"brotli",
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"content-security-policy",
|
"content-security-policy",
|
||||||
"cookie",
|
"cookie",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
|
@ -3541,9 +3656,10 @@ dependencies = [
|
||||||
"devtools_traits",
|
"devtools_traits",
|
||||||
"embedder_traits",
|
"embedder_traits",
|
||||||
"flate2",
|
"flate2",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
|
"futures 0.3.5",
|
||||||
"headers",
|
"headers",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-openssl",
|
"hyper-openssl",
|
||||||
"hyper_serde",
|
"hyper_serde",
|
||||||
|
@ -3572,12 +3688,13 @@ dependencies = [
|
||||||
"servo_url",
|
"servo_url",
|
||||||
"std_test_override",
|
"std_test_override",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio 0.1.22",
|
||||||
"tokio-openssl",
|
"tokio 0.2.21",
|
||||||
|
"tokio-openssl 0.3.0",
|
||||||
|
"tungstenite",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
"webrender_api",
|
"webrender_api",
|
||||||
"ws",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3599,7 +3716,7 @@ dependencies = [
|
||||||
"cookie",
|
"cookie",
|
||||||
"embedder_traits",
|
"embedder_traits",
|
||||||
"headers",
|
"headers",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper_serde",
|
"hyper_serde",
|
||||||
"image",
|
"image",
|
||||||
|
@ -3802,6 +3919,12 @@ dependencies = [
|
||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-probe"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.58"
|
version = "0.9.58"
|
||||||
|
@ -4067,6 +4190,12 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-utils"
|
name = "pin-utils"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -4506,6 +4635,22 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "schannel"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped-tls"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scoped-tls"
|
name = "scoped-tls"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -4553,7 +4698,7 @@ dependencies = [
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"headers",
|
"headers",
|
||||||
"html5ever",
|
"html5ever",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper_serde",
|
"hyper_serde",
|
||||||
"image",
|
"image",
|
||||||
|
@ -4688,7 +4833,7 @@ dependencies = [
|
||||||
"embedder_traits",
|
"embedder_traits",
|
||||||
"euclid",
|
"euclid",
|
||||||
"gfx_traits",
|
"gfx_traits",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper_serde",
|
"hyper_serde",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
|
@ -4715,6 +4860,29 @@ dependencies = [
|
||||||
"webxr-api",
|
"webxr-api",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "security-framework"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"core-foundation 0.7.0",
|
||||||
|
"core-foundation-sys 0.7.0",
|
||||||
|
"libc",
|
||||||
|
"security-framework-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "security-framework-sys"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys 0.7.0",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "selectors"
|
name = "selectors"
|
||||||
version = "0.22.0"
|
version = "0.22.0"
|
||||||
|
@ -5406,7 +5574,7 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
|
checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5794,8 +5962,8 @@ version = "0.1.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
|
checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"tokio-codec",
|
"tokio-codec",
|
||||||
|
@ -5812,15 +5980,31 @@ dependencies = [
|
||||||
"tokio-uds",
|
"tokio-uds",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.5.5",
|
||||||
|
"fnv",
|
||||||
|
"iovec",
|
||||||
|
"lazy_static",
|
||||||
|
"mio",
|
||||||
|
"num_cpus",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio-macros",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-buf"
|
name = "tokio-buf"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
|
checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"either",
|
"either",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5829,8 +6013,8 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b"
|
checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -5840,7 +6024,7 @@ version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e"
|
checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"tokio-executor",
|
"tokio-executor",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -5851,7 +6035,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671"
|
checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5860,7 +6044,7 @@ version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4"
|
checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
"tokio-threadpool",
|
"tokio-threadpool",
|
||||||
]
|
]
|
||||||
|
@ -5871,22 +6055,43 @@ version = "0.1.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674"
|
checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.17",
|
||||||
|
"quote 1.0.2",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-openssl"
|
name = "tokio-openssl"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "771d6246b170ae108d67d9963c23f31a579016c016d73bd4bd7d6ef0252afda7"
|
checksum = "771d6246b170ae108d67d9963c23f31a579016c016d73bd4bd7d6ef0252afda7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"openssl",
|
"openssl",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-openssl"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594"
|
||||||
|
dependencies = [
|
||||||
|
"openssl",
|
||||||
|
"tokio 0.2.21",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-reactor"
|
name = "tokio-reactor"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -5894,7 +6099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351"
|
checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"mio",
|
"mio",
|
||||||
|
@ -5913,7 +6118,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee"
|
checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fnv",
|
"fnv",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5922,8 +6127,8 @@ version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72"
|
checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"iovec",
|
"iovec",
|
||||||
"mio",
|
"mio",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
|
@ -5939,7 +6144,7 @@ dependencies = [
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
@ -5954,7 +6159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296"
|
checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio-executor",
|
"tokio-executor",
|
||||||
]
|
]
|
||||||
|
@ -5965,8 +6170,8 @@ version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82"
|
checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"log",
|
"log",
|
||||||
"mio",
|
"mio",
|
||||||
"tokio-codec",
|
"tokio-codec",
|
||||||
|
@ -5980,8 +6185,8 @@ version = "0.2.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0"
|
checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"iovec",
|
"iovec",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
@ -6038,6 +6243,26 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tungstenite"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a5c7d464221cb0b538a1cd12f6d9127ed1e6bb7f3ffca98fb3cd4c6e3af8175c"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.12.0",
|
||||||
|
"byteorder",
|
||||||
|
"bytes 0.5.5",
|
||||||
|
"http 0.2.1",
|
||||||
|
"httparse",
|
||||||
|
"input_buffer",
|
||||||
|
"log",
|
||||||
|
"native-tls",
|
||||||
|
"rand",
|
||||||
|
"sha-1",
|
||||||
|
"url",
|
||||||
|
"utf-8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typed-arena"
|
name = "typed-arena"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
|
@ -6220,7 +6445,7 @@ version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230"
|
checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"log",
|
"log",
|
||||||
"try-lock",
|
"try-lock",
|
||||||
]
|
]
|
||||||
|
@ -6231,19 +6456,19 @@ version = "0.1.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99b53196ba54e91e31ba1e90309a31053218cc1d4697f6e48f7c7e3d255e64fc"
|
checksum = "99b53196ba54e91e31ba1e90309a31053218cc1d4697f6e48f7c7e3d255e64fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"futures",
|
"futures 0.1.28",
|
||||||
"headers",
|
"headers",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"hyper",
|
"hyper",
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"scoped-tls",
|
"scoped-tls 1.0.0",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio",
|
"tokio 0.1.22",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
"tokio-threadpool",
|
"tokio-threadpool",
|
||||||
"urlencoding",
|
"urlencoding",
|
||||||
|
@ -6386,14 +6611,14 @@ checksum = "ad517a7e5bb5228bee491b97f5c471b31606a42e89fda90a966d8245a4308e31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.10.1",
|
"base64 0.10.1",
|
||||||
"cookie",
|
"cookie",
|
||||||
"http",
|
"http 0.1.21",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio 0.1.22",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"url",
|
"url",
|
||||||
"warp",
|
"warp",
|
||||||
|
@ -6706,12 +6931,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94"
|
checksum = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes 0.4.12",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"mio",
|
"mio",
|
||||||
"mio-extras",
|
"mio-extras",
|
||||||
"openssl",
|
|
||||||
"rand",
|
"rand",
|
||||||
"sha-1",
|
"sha-1",
|
||||||
"slab",
|
"slab",
|
||||||
|
|
|
@ -27,7 +27,7 @@ opt-level = 3
|
||||||
# <crate> = { path = "/path/to/local/checkout" }
|
# <crate> = { path = "/path/to/local/checkout" }
|
||||||
|
|
||||||
# This is here to dedupe winapi since mio 0.6 is still using winapi 0.2.
|
# This is here to dedupe winapi since mio 0.6 is still using winapi 0.2.
|
||||||
mio = { git = "https://github.com/servo/mio.git", branch = "servo" }
|
mio = { git = "https://github.com/servo/mio.git", branch = "servo-mio-0.6.22" }
|
||||||
|
|
||||||
# https://github.com/servo/servo/issues/27039#issuecomment-654400150
|
# https://github.com/servo/servo/issues/27039#issuecomment-654400150
|
||||||
[patch."https://github.com/servo/webrender"]
|
[patch."https://github.com/servo/webrender"]
|
||||||
|
|
|
@ -15,6 +15,7 @@ test = false
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-tungstenite = { version = "0.7.1", features = ["tokio-openssl"] }
|
||||||
base64 = "0.10.1"
|
base64 = "0.10.1"
|
||||||
brotli = "3"
|
brotli = "3"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
|
@ -26,6 +27,7 @@ devtools_traits = { path = "../devtools_traits" }
|
||||||
embedder_traits = { path = "../embedder_traits" }
|
embedder_traits = { path = "../embedder_traits" }
|
||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
|
futures03 = { version = "0.3", package = "futures" }
|
||||||
headers = "0.2"
|
headers = "0.2"
|
||||||
http = "0.1"
|
http = "0.1"
|
||||||
hyper = "0.12"
|
hyper = "0.12"
|
||||||
|
@ -56,10 +58,11 @@ servo_config = { path = "../config" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
time = "0.1.17"
|
time = "0.1.17"
|
||||||
tokio = "0.1"
|
tokio = "0.1"
|
||||||
|
tokio2 = { version = "0.2", package = "tokio", features = ["sync", "macros", "rt-threaded"] }
|
||||||
|
tungstenite = "0.11"
|
||||||
url = "2.0"
|
url = "2.0"
|
||||||
uuid = { version = "0.8", features = ["v4"] }
|
uuid = { version = "0.8", features = ["v4"] }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { git = "https://github.com/servo/webrender" }
|
||||||
ws = { version = "0.9", features = ["ssl"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::hsts::HstsList;
|
||||||
use crate::http_cache::HttpCache;
|
use crate::http_cache::HttpCache;
|
||||||
use crate::http_loader::{http_redirect_fetch, HttpState, HANDLE};
|
use crate::http_loader::{http_redirect_fetch, HttpState, HANDLE};
|
||||||
use crate::storage_thread::StorageThreadFactory;
|
use crate::storage_thread::StorageThreadFactory;
|
||||||
use crate::websocket_loader;
|
use crate::websocket_loader::{self, HANDLE as WS_HANDLE};
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
use devtools_traits::DevtoolsControlMsg;
|
use devtools_traits::DevtoolsControlMsg;
|
||||||
use embedder_traits::resources::{self, Resource};
|
use embedder_traits::resources::{self, Resource};
|
||||||
|
@ -616,6 +616,9 @@ impl CoreResourceManager {
|
||||||
// Shut-down the async runtime used by fetch workers.
|
// Shut-down the async runtime used by fetch workers.
|
||||||
drop(HANDLE.lock().unwrap().take());
|
drop(HANDLE.lock().unwrap().take());
|
||||||
|
|
||||||
|
// Shut-down the async runtime used by websocket workers.
|
||||||
|
drop(WS_HANDLE.lock().unwrap().take());
|
||||||
|
|
||||||
debug!("Exited CoreResourceManager");
|
debug!("Exited CoreResourceManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,8 +730,6 @@ impl CoreResourceManager {
|
||||||
action_receiver,
|
action_receiver,
|
||||||
http_state.clone(),
|
http_state.clone(),
|
||||||
self.certificate_path.clone(),
|
self.certificate_path.clone(),
|
||||||
http_state.extra_certs.clone(),
|
|
||||||
http_state.connection_certs.clone(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,297 +2,491 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::connector::{create_tls_config, ConnectionCerts, ExtraCerts, ALPN_H1};
|
//! The websocket handler has three main responsibilities:
|
||||||
|
//! 1) initiate the initial HTTP connection and process the response
|
||||||
|
//! 2) ensure any DOM requests for sending/closing are propagated to the network
|
||||||
|
//! 3) transmit any incoming messages/closing to the DOM
|
||||||
|
//!
|
||||||
|
//! In order to accomplish this, the handler uses a long-running loop that selects
|
||||||
|
//! over events from the network and events from the DOM, using async/await to avoid
|
||||||
|
//! the need for a dedicated thread per websocket.
|
||||||
|
|
||||||
|
use crate::connector::{create_tls_config, ALPN_H1};
|
||||||
use crate::cookie::Cookie;
|
use crate::cookie::Cookie;
|
||||||
use crate::fetch::methods::should_be_blocked_due_to_bad_port;
|
use crate::fetch::methods::should_be_blocked_due_to_bad_port;
|
||||||
use crate::hosts::replace_host;
|
use crate::hosts::replace_host;
|
||||||
use crate::http_loader::HttpState;
|
use crate::http_loader::HttpState;
|
||||||
|
use async_tungstenite::tokio::{client_async_tls_with_connector_and_config, ConnectStream};
|
||||||
|
use async_tungstenite::WebSocketStream;
|
||||||
use embedder_traits::resources::{self, Resource};
|
use embedder_traits::resources::{self, Resource};
|
||||||
use http::header::{self, HeaderMap, HeaderName, HeaderValue};
|
use futures03::future::TryFutureExt;
|
||||||
|
use futures03::sink::SinkExt;
|
||||||
|
use futures03::stream::StreamExt;
|
||||||
|
use headers::Host;
|
||||||
|
use http::header::{HeaderMap, HeaderName, HeaderValue};
|
||||||
|
use http::uri::Authority;
|
||||||
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use net_traits::request::{RequestBuilder, RequestMode};
|
use net_traits::request::{RequestBuilder, RequestMode};
|
||||||
use net_traits::{CookieSource, MessageData};
|
use net_traits::{CookieSource, MessageData};
|
||||||
use net_traits::{WebSocketDomAction, WebSocketNetworkEvent};
|
use net_traits::{WebSocketDomAction, WebSocketNetworkEvent};
|
||||||
use openssl::ssl::SslStream;
|
use openssl::ssl::ConnectConfiguration;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use tokio2::net::TcpStream;
|
||||||
|
use tokio2::runtime::Runtime;
|
||||||
|
use tokio2::select;
|
||||||
|
use tokio2::sync::mpsc::{unbounded_channel, UnboundedReceiver};
|
||||||
|
use tungstenite::error::Error;
|
||||||
|
use tungstenite::error::Result as WebSocketResult;
|
||||||
|
use tungstenite::handshake::client::{Request, Response};
|
||||||
|
use tungstenite::http::header::{self as WSHeader, HeaderValue as WSHeaderValue};
|
||||||
|
use tungstenite::protocol::CloseFrame;
|
||||||
|
use tungstenite::Message;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use ws::util::TcpStream;
|
|
||||||
use ws::{
|
|
||||||
CloseCode, Factory, Handler, Handshake, Message, Request, Response as WsResponse, Sender,
|
|
||||||
WebSocket,
|
|
||||||
};
|
|
||||||
use ws::{Error as WebSocketError, ErrorKind as WebSocketErrorKind, Result as WebSocketResult};
|
|
||||||
|
|
||||||
/// A client for connecting to a websocket server
|
// Websockets get their own tokio runtime that's independent of the one used for
|
||||||
#[derive(Clone)]
|
// HTTP connections, otherwise a large number of websockets could occupy all workers
|
||||||
struct Client<'a> {
|
// and starve other network traffic.
|
||||||
origin: &'a str,
|
lazy_static! {
|
||||||
protocols: &'a [String],
|
pub static ref HANDLE: Mutex<Option<Runtime>> = Mutex::new(Some(Runtime::new().unwrap()));
|
||||||
http_state: &'a Arc<HttpState>,
|
|
||||||
resource_url: &'a ServoUrl,
|
|
||||||
event_sender: &'a IpcSender<WebSocketNetworkEvent>,
|
|
||||||
protocol_in_use: Option<String>,
|
|
||||||
certificate_path: Option<String>,
|
|
||||||
extra_certs: ExtraCerts,
|
|
||||||
connection_certs: ConnectionCerts,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Factory for Client<'a> {
|
/// Create a tungstenite Request object for the initial HTTP request.
|
||||||
type Handler = Self;
|
/// This request contains `Origin`, `Sec-WebSocket-Protocol`, `Authorization`,
|
||||||
|
/// `Cookie`, and `Host` headers as appropriate.
|
||||||
|
/// Returns an error if any header values are invalid or tungstenite cannot create
|
||||||
|
/// the desired request.
|
||||||
|
fn create_request(
|
||||||
|
resource_url: &ServoUrl,
|
||||||
|
origin: &str,
|
||||||
|
protocols: &[String],
|
||||||
|
host: &Host,
|
||||||
|
http_state: &HttpState,
|
||||||
|
) -> WebSocketResult<Request> {
|
||||||
|
let mut builder = Request::get(resource_url.as_str());
|
||||||
|
let headers = builder.headers_mut().unwrap();
|
||||||
|
headers.insert("Origin", WSHeaderValue::from_str(origin)?);
|
||||||
|
|
||||||
fn connection_made(&mut self, _: Sender) -> Self::Handler {
|
if !protocols.is_empty() {
|
||||||
self.clone()
|
let protocols = protocols.join(",");
|
||||||
|
headers.insert(
|
||||||
|
"Sec-WebSocket-Protocol",
|
||||||
|
WSHeaderValue::from_str(&protocols)?,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connection_lost(&mut self, _: Self::Handler) {
|
headers.insert("Host", WSHeaderValue::from_str(&host.to_string())?);
|
||||||
let _ = self.event_sender.send(WebSocketNetworkEvent::Fail);
|
|
||||||
|
let mut cookie_jar = http_state.cookie_jar.write().unwrap();
|
||||||
|
cookie_jar.remove_expired_cookies_for_url(resource_url);
|
||||||
|
if let Some(cookie_list) = cookie_jar.cookies_for_url(resource_url, CookieSource::HTTP) {
|
||||||
|
headers.insert("Cookie", WSHeaderValue::from_str(&cookie_list)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resource_url.password().is_some() || resource_url.username() != "" {
|
||||||
|
let basic = base64::encode(&format!(
|
||||||
|
"{}:{}",
|
||||||
|
resource_url.username(),
|
||||||
|
resource_url.password().unwrap_or("")
|
||||||
|
));
|
||||||
|
headers.insert(
|
||||||
|
"Authorization",
|
||||||
|
WSHeaderValue::from_str(&format!("Basic {}", basic))?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = builder.body(())?;
|
||||||
|
Ok(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Handler for Client<'a> {
|
/// Process an HTTP response resulting from a WS handshake.
|
||||||
fn build_request(&mut self, url: &Url) -> WebSocketResult<Request> {
|
/// This ensures that any `Cookie` or HSTS headers are recognized.
|
||||||
let mut req = Request::from_url(url)?;
|
/// Returns an error if the protocol selected by the handshake doesn't
|
||||||
req.headers_mut()
|
/// match the list of provided protocols in the original request.
|
||||||
.push(("Origin".to_string(), self.origin.as_bytes().to_owned()));
|
fn process_ws_response(
|
||||||
|
http_state: &HttpState,
|
||||||
for protocol in self.protocols {
|
response: &Response,
|
||||||
req.add_protocol(protocol);
|
resource_url: &ServoUrl,
|
||||||
|
protocols: &[String],
|
||||||
|
) -> Result<Option<String>, Error> {
|
||||||
|
trace!("processing websocket http response for {}", resource_url);
|
||||||
|
let mut protocol_in_use = None;
|
||||||
|
if let Some(protocol_name) = response.headers().get("Sec-WebSocket-Protocol") {
|
||||||
|
let protocol_name = protocol_name.to_str().unwrap();
|
||||||
|
if !protocols.is_empty() && !protocols.iter().any(|p| protocol_name == (*p)) {
|
||||||
|
return Err(Error::Protocol(
|
||||||
|
"Protocol in use not in client-supplied protocol list".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
protocol_in_use = Some(protocol_name.to_string());
|
||||||
let mut cookie_jar = self.http_state.cookie_jar.write().unwrap();
|
|
||||||
cookie_jar.remove_expired_cookies_for_url(self.resource_url);
|
|
||||||
if let Some(cookie_list) = cookie_jar.cookies_for_url(self.resource_url, CookieSource::HTTP)
|
|
||||||
{
|
|
||||||
req.headers_mut()
|
|
||||||
.push(("Cookie".into(), cookie_list.as_bytes().to_owned()))
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(req)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_open(&mut self, shake: Handshake) -> WebSocketResult<()> {
|
let mut jar = http_state.cookie_jar.write().unwrap();
|
||||||
let mut headers = HeaderMap::new();
|
// TODO(eijebong): Replace thise once typed headers settled on a cookie impl
|
||||||
for &(ref name, ref value) in shake.response.headers().iter() {
|
for cookie in response.headers().get_all(WSHeader::SET_COOKIE) {
|
||||||
let name = HeaderName::from_bytes(name.as_bytes()).unwrap();
|
if let Ok(s) = std::str::from_utf8(cookie.as_bytes()) {
|
||||||
let value = HeaderValue::from_bytes(&value).unwrap();
|
if let Some(cookie) =
|
||||||
|
Cookie::from_cookie_string(s.into(), resource_url, CookieSource::HTTP)
|
||||||
headers.insert(name, value);
|
{
|
||||||
|
jar.push(cookie, resource_url, CookieSource::HTTP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut jar = self.http_state.cookie_jar.write().unwrap();
|
// We need to make a new header map here because tungstenite depends on
|
||||||
// TODO(eijebong): Replace thise once typed headers settled on a cookie impl
|
// a more recent version of http than the rest of the network stack, so the
|
||||||
for cookie in headers.get_all(header::SET_COOKIE) {
|
// HeaderMap types are incompatible.
|
||||||
if let Ok(s) = std::str::from_utf8(cookie.as_bytes()) {
|
let mut headers = HeaderMap::new();
|
||||||
if let Some(cookie) =
|
for (key, value) in response.headers().iter() {
|
||||||
Cookie::from_cookie_string(s.into(), self.resource_url, CookieSource::HTTP)
|
if let (Ok(key), Ok(value)) = (
|
||||||
{
|
HeaderName::from_bytes(key.as_ref()),
|
||||||
jar.push(cookie, self.resource_url, CookieSource::HTTP);
|
HeaderValue::from_bytes(value.as_ref()),
|
||||||
|
) {
|
||||||
|
headers.insert(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http_state
|
||||||
|
.hsts_list
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.update_hsts_list_from_response(resource_url, &headers);
|
||||||
|
|
||||||
|
Ok(protocol_in_use)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum DomMsg {
|
||||||
|
Send(Message),
|
||||||
|
Close(Option<(u16, String)>),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialize a listener for DOM actions. These are routed from the IPC channel
|
||||||
|
/// to a tokio channel that the main WS client task uses to receive them.
|
||||||
|
fn setup_dom_listener(
|
||||||
|
dom_action_receiver: IpcReceiver<WebSocketDomAction>,
|
||||||
|
initiated_close: Arc<AtomicBool>,
|
||||||
|
) -> UnboundedReceiver<DomMsg> {
|
||||||
|
let (sender, receiver) = unbounded_channel();
|
||||||
|
|
||||||
|
ROUTER.add_route(
|
||||||
|
dom_action_receiver.to_opaque(),
|
||||||
|
Box::new(move |message| {
|
||||||
|
let dom_action = message.to().expect("Ws dom_action message to deserialize");
|
||||||
|
trace!("handling WS DOM action: {:?}", dom_action);
|
||||||
|
match dom_action {
|
||||||
|
WebSocketDomAction::SendMessage(MessageData::Text(data)) => {
|
||||||
|
if let Err(e) = sender.send(DomMsg::Send(Message::Text(data))) {
|
||||||
|
warn!("Error sending websocket message: {:?}", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
WebSocketDomAction::SendMessage(MessageData::Binary(data)) => {
|
||||||
|
if let Err(e) = sender.send(DomMsg::Send(Message::Binary(data))) {
|
||||||
|
warn!("Error sending websocket message: {:?}", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
WebSocketDomAction::Close(code, reason) => {
|
||||||
|
if initiated_close.fetch_or(true, Ordering::SeqCst) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let frame = code.map(move |c| (c, reason.unwrap_or_default()));
|
||||||
|
if let Err(e) = sender.send(DomMsg::Close(frame)) {
|
||||||
|
warn!("Error closing websocket: {:?}", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
receiver
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Listen for WS events from the DOM and the network until one side
|
||||||
|
/// closes the connection or an error occurs. Since this is an async
|
||||||
|
/// function that uses the select operation, it will run as a task
|
||||||
|
/// on the WS tokio runtime.
|
||||||
|
async fn run_ws_loop(
|
||||||
|
mut dom_receiver: UnboundedReceiver<DomMsg>,
|
||||||
|
resource_event_sender: IpcSender<WebSocketNetworkEvent>,
|
||||||
|
mut stream: WebSocketStream<ConnectStream>,
|
||||||
|
) {
|
||||||
|
loop {
|
||||||
|
select! {
|
||||||
|
dom_msg = dom_receiver.recv() => {
|
||||||
|
trace!("processing dom msg: {:?}", dom_msg);
|
||||||
|
let dom_msg = match dom_msg {
|
||||||
|
Some(msg) => msg,
|
||||||
|
None => break,
|
||||||
|
};
|
||||||
|
match dom_msg {
|
||||||
|
DomMsg::Send(m) => {
|
||||||
|
if let Err(e) = stream.send(m).await {
|
||||||
|
warn!("error sending websocket message: {:?}", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DomMsg::Close(frame) => {
|
||||||
|
if let Err(e) = stream.close(frame.map(|(code, reason)| {
|
||||||
|
CloseFrame {
|
||||||
|
code: code.into(),
|
||||||
|
reason: reason.into(),
|
||||||
|
}
|
||||||
|
})).await {
|
||||||
|
warn!("error closing websocket: {:?}", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws_msg = stream.next() => {
|
||||||
|
trace!("processing WS stream: {:?}", ws_msg);
|
||||||
|
let msg = match ws_msg {
|
||||||
|
Some(Ok(msg)) => msg,
|
||||||
|
Some(Err(e)) => {
|
||||||
|
warn!("Error in WebSocket communication: {:?}", e);
|
||||||
|
let _ = resource_event_sender.send(WebSocketNetworkEvent::Fail);
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
warn!("Error in WebSocket communication");
|
||||||
|
let _ = resource_event_sender.send(WebSocketNetworkEvent::Fail);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match msg {
|
||||||
|
Message::Text(s) => {
|
||||||
|
let message = MessageData::Text(s);
|
||||||
|
if let Err(e) = resource_event_sender
|
||||||
|
.send(WebSocketNetworkEvent::MessageReceived(message))
|
||||||
|
{
|
||||||
|
warn!("Error sending websocket notification: {:?}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Message::Binary(v) => {
|
||||||
|
let message = MessageData::Binary(v);
|
||||||
|
if let Err(e) = resource_event_sender
|
||||||
|
.send(WebSocketNetworkEvent::MessageReceived(message))
|
||||||
|
{
|
||||||
|
warn!("Error sending websocket notification: {:?}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Message::Ping(_) | Message::Pong(_) => {}
|
||||||
|
|
||||||
|
Message::Close(frame) => {
|
||||||
|
let (reason, code) = match frame {
|
||||||
|
Some(frame) => (frame.reason, Some(frame.code.into())),
|
||||||
|
None => ("".into(), None),
|
||||||
|
};
|
||||||
|
debug!("Websocket connection closing due to ({:?}) {}", code, reason);
|
||||||
|
let _ = resource_event_sender.send(WebSocketNetworkEvent::Close(
|
||||||
|
code,
|
||||||
|
reason.to_string(),
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.http_state
|
|
||||||
.hsts_list
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.update_hsts_list_from_response(self.resource_url, &headers);
|
|
||||||
|
|
||||||
let _ = self
|
|
||||||
.event_sender
|
|
||||||
.send(WebSocketNetworkEvent::ConnectionEstablished {
|
|
||||||
protocol_in_use: self.protocol_in_use.clone(),
|
|
||||||
});
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_message(&mut self, message: Message) -> WebSocketResult<()> {
|
|
||||||
let message = match message {
|
|
||||||
Message::Text(message) => MessageData::Text(message),
|
|
||||||
Message::Binary(message) => MessageData::Binary(message),
|
|
||||||
};
|
|
||||||
let _ = self
|
|
||||||
.event_sender
|
|
||||||
.send(WebSocketNetworkEvent::MessageReceived(message));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_error(&mut self, err: WebSocketError) {
|
|
||||||
debug!("Error in WebSocket communication: {:?}", err);
|
|
||||||
let _ = self.event_sender.send(WebSocketNetworkEvent::Fail);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_response(&mut self, res: &WsResponse) -> WebSocketResult<()> {
|
|
||||||
let protocol_in_use = res.protocol()?;
|
|
||||||
|
|
||||||
if let Some(protocol_name) = protocol_in_use {
|
|
||||||
if !self.protocols.is_empty() && !self.protocols.iter().any(|p| protocol_name == (*p)) {
|
|
||||||
let error = WebSocketError::new(
|
|
||||||
WebSocketErrorKind::Protocol,
|
|
||||||
"Protocol in Use not in client-supplied protocol list",
|
|
||||||
);
|
|
||||||
return Err(error);
|
|
||||||
}
|
|
||||||
self.protocol_in_use = Some(protocol_name.into());
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_close(&mut self, code: CloseCode, reason: &str) {
|
|
||||||
debug!("Connection closing due to ({:?}) {}", code, reason);
|
|
||||||
let _ = self.event_sender.send(WebSocketNetworkEvent::Close(
|
|
||||||
Some(code.into()),
|
|
||||||
reason.to_owned(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn upgrade_ssl_client(
|
|
||||||
&mut self,
|
|
||||||
stream: TcpStream,
|
|
||||||
url: &Url,
|
|
||||||
) -> WebSocketResult<SslStream<TcpStream>> {
|
|
||||||
let certs = match self.certificate_path {
|
|
||||||
Some(ref path) => fs::read_to_string(path).expect("Couldn't not find certificate file"),
|
|
||||||
None => resources::read_string(Resource::SSLCertificates),
|
|
||||||
};
|
|
||||||
|
|
||||||
let domain = self
|
|
||||||
.resource_url
|
|
||||||
.as_url()
|
|
||||||
.domain()
|
|
||||||
.ok_or(WebSocketError::new(
|
|
||||||
WebSocketErrorKind::Protocol,
|
|
||||||
format!("Unable to parse domain from {}. Needed for SSL.", url),
|
|
||||||
))?;
|
|
||||||
let tls_config = create_tls_config(
|
|
||||||
&certs,
|
|
||||||
ALPN_H1,
|
|
||||||
self.extra_certs.clone(),
|
|
||||||
self.connection_certs.clone(),
|
|
||||||
);
|
|
||||||
tls_config
|
|
||||||
.build()
|
|
||||||
.connect(domain, stream)
|
|
||||||
.map_err(WebSocketError::from)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initiate a new async WS connection. Returns an error if the connection fails
|
||||||
|
/// for any reason, or if the response isn't valid. Otherwise, the endless WS
|
||||||
|
/// listening loop will be started.
|
||||||
|
async fn start_websocket(
|
||||||
|
http_state: Arc<HttpState>,
|
||||||
|
url: ServoUrl,
|
||||||
|
resource_event_sender: IpcSender<WebSocketNetworkEvent>,
|
||||||
|
protocols: Vec<String>,
|
||||||
|
client: Request,
|
||||||
|
tls_config: ConnectConfiguration,
|
||||||
|
dom_action_receiver: IpcReceiver<WebSocketDomAction>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
trace!("starting WS connection to {}", url);
|
||||||
|
|
||||||
|
let initiated_close = Arc::new(AtomicBool::new(false));
|
||||||
|
let dom_receiver = setup_dom_listener(dom_action_receiver, initiated_close.clone());
|
||||||
|
|
||||||
|
let host_str = client
|
||||||
|
.uri()
|
||||||
|
.host()
|
||||||
|
.ok_or_else(|| Error::Url("No host string".into()))?;
|
||||||
|
let host = replace_host(host_str);
|
||||||
|
let mut net_url =
|
||||||
|
Url::parse(&client.uri().to_string()).map_err(|e| Error::Url(e.to_string().into()))?;
|
||||||
|
net_url
|
||||||
|
.set_host(Some(&host))
|
||||||
|
.map_err(|e| Error::Url(e.to_string().into()))?;
|
||||||
|
|
||||||
|
let domain = net_url
|
||||||
|
.host()
|
||||||
|
.ok_or_else(|| Error::Url("No host string".into()))?;
|
||||||
|
let port = net_url
|
||||||
|
.port_or_known_default()
|
||||||
|
.ok_or_else(|| Error::Url("Unknown port".into()))?;
|
||||||
|
|
||||||
|
let try_socket = TcpStream::connect((&*domain.to_string(), port)).await;
|
||||||
|
let socket = try_socket.map_err(Error::Io)?;
|
||||||
|
let (stream, response) =
|
||||||
|
client_async_tls_with_connector_and_config(client, socket, Some(tls_config), None).await?;
|
||||||
|
|
||||||
|
let protocol_in_use = process_ws_response(&http_state, &response, &url, &protocols)?;
|
||||||
|
|
||||||
|
if !initiated_close.load(Ordering::SeqCst) {
|
||||||
|
if resource_event_sender
|
||||||
|
.send(WebSocketNetworkEvent::ConnectionEstablished { protocol_in_use })
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("about to start ws loop for {}", url);
|
||||||
|
run_ws_loop(dom_receiver, resource_event_sender, stream).await;
|
||||||
|
} else {
|
||||||
|
trace!("client closed connection for {}, not running loop", url);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new websocket connection for the given request.
|
||||||
|
fn connect(
|
||||||
|
mut req_builder: RequestBuilder,
|
||||||
|
resource_event_sender: IpcSender<WebSocketNetworkEvent>,
|
||||||
|
dom_action_receiver: IpcReceiver<WebSocketDomAction>,
|
||||||
|
http_state: Arc<HttpState>,
|
||||||
|
certificate_path: Option<String>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let protocols = match req_builder.mode {
|
||||||
|
RequestMode::WebSocket { protocols } => protocols,
|
||||||
|
_ => {
|
||||||
|
return Err(
|
||||||
|
"Received a RequestBuilder with a non-websocket mode in websocket_loader"
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://fetch.spec.whatwg.org/#websocket-opening-handshake
|
||||||
|
// By standard, we should work with an http(s):// URL (req_url),
|
||||||
|
// but as ws-rs expects to be called with a ws(s):// URL (net_url)
|
||||||
|
// we upgrade ws to wss, so we don't have to convert http(s) back to ws(s).
|
||||||
|
http_state
|
||||||
|
.hsts_list
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.apply_hsts_rules(&mut req_builder.url);
|
||||||
|
|
||||||
|
let scheme = req_builder.url.scheme();
|
||||||
|
let mut req_url = req_builder.url.clone();
|
||||||
|
match scheme {
|
||||||
|
"ws" => {
|
||||||
|
req_url
|
||||||
|
.as_mut_url()
|
||||||
|
.set_scheme("http")
|
||||||
|
.map_err(|()| "couldn't replace scheme".to_string())?;
|
||||||
|
},
|
||||||
|
"wss" => {
|
||||||
|
req_url
|
||||||
|
.as_mut_url()
|
||||||
|
.set_scheme("https")
|
||||||
|
.map_err(|()| "couldn't replace scheme".to_string())?;
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
if should_be_blocked_due_to_bad_port(&req_url) {
|
||||||
|
return Err("Port blocked".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let host_str = req_builder
|
||||||
|
.url
|
||||||
|
.host_str()
|
||||||
|
.ok_or_else(|| "No host string".to_string())?;
|
||||||
|
|
||||||
|
let host = Host::from(
|
||||||
|
format!(
|
||||||
|
"{}{}",
|
||||||
|
host_str,
|
||||||
|
req_builder
|
||||||
|
.url
|
||||||
|
.port_or_known_default()
|
||||||
|
.map(|v| format!(":{}", v))
|
||||||
|
.unwrap_or("".into())
|
||||||
|
)
|
||||||
|
.parse::<Authority>()
|
||||||
|
.map_err(|e| e.to_string())?,
|
||||||
|
);
|
||||||
|
|
||||||
|
let certs = match certificate_path {
|
||||||
|
Some(ref path) => fs::read_to_string(path).map_err(|e| e.to_string())?,
|
||||||
|
None => resources::read_string(Resource::SSLCertificates),
|
||||||
|
};
|
||||||
|
|
||||||
|
let client = match create_request(
|
||||||
|
&req_builder.url,
|
||||||
|
&req_builder.origin.ascii_serialization(),
|
||||||
|
&protocols,
|
||||||
|
&host,
|
||||||
|
&*http_state,
|
||||||
|
) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => return Err(e.to_string()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let tls_config = create_tls_config(
|
||||||
|
&certs,
|
||||||
|
ALPN_H1,
|
||||||
|
http_state.extra_certs.clone(),
|
||||||
|
http_state.connection_certs.clone(),
|
||||||
|
);
|
||||||
|
let tls_config = match tls_config.build().configure() {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => return Err(e.to_string()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let resource_event_sender2 = resource_event_sender.clone();
|
||||||
|
match HANDLE.lock().unwrap().as_mut() {
|
||||||
|
Some(handle) => handle.spawn(
|
||||||
|
start_websocket(
|
||||||
|
http_state,
|
||||||
|
req_builder.url.clone(),
|
||||||
|
resource_event_sender,
|
||||||
|
protocols,
|
||||||
|
client,
|
||||||
|
tls_config,
|
||||||
|
dom_action_receiver,
|
||||||
|
)
|
||||||
|
.map_err(move |e| {
|
||||||
|
warn!("Failed to establish a WebSocket connection: {:?}", e);
|
||||||
|
let _ = resource_event_sender2.send(WebSocketNetworkEvent::Fail);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
None => return Err("No runtime available".to_string()),
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new websocket connection for the given request.
|
||||||
pub fn init(
|
pub fn init(
|
||||||
req_builder: RequestBuilder,
|
req_builder: RequestBuilder,
|
||||||
resource_event_sender: IpcSender<WebSocketNetworkEvent>,
|
resource_event_sender: IpcSender<WebSocketNetworkEvent>,
|
||||||
dom_action_receiver: IpcReceiver<WebSocketDomAction>,
|
dom_action_receiver: IpcReceiver<WebSocketDomAction>,
|
||||||
http_state: Arc<HttpState>,
|
http_state: Arc<HttpState>,
|
||||||
certificate_path: Option<String>,
|
certificate_path: Option<String>,
|
||||||
extra_certs: ExtraCerts,
|
|
||||||
connection_certs: ConnectionCerts,
|
|
||||||
) {
|
) {
|
||||||
thread::Builder::new()
|
let resource_event_sender2 = resource_event_sender.clone();
|
||||||
.name(format!("WebSocket connection to {}", req_builder.url))
|
if let Err(e) = connect(
|
||||||
.spawn(move || {
|
req_builder,
|
||||||
let mut req_builder = req_builder;
|
resource_event_sender,
|
||||||
let protocols = match req_builder.mode {
|
dom_action_receiver,
|
||||||
RequestMode::WebSocket { protocols } => protocols,
|
http_state,
|
||||||
_ => panic!(
|
certificate_path,
|
||||||
"Received a RequestBuilder with a non-websocket mode in websocket_loader"
|
) {
|
||||||
),
|
warn!("Error starting websocket: {}", e);
|
||||||
};
|
let _ = resource_event_sender2.send(WebSocketNetworkEvent::Fail);
|
||||||
|
}
|
||||||
// https://fetch.spec.whatwg.org/#websocket-opening-handshake
|
|
||||||
// By standard, we should work with an http(s):// URL (req_url),
|
|
||||||
// but as ws-rs expects to be called with a ws(s):// URL (net_url)
|
|
||||||
// we upgrade ws to wss, so we don't have to convert http(s) back to ws(s).
|
|
||||||
http_state
|
|
||||||
.hsts_list
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.apply_hsts_rules(&mut req_builder.url);
|
|
||||||
|
|
||||||
let scheme = req_builder.url.scheme();
|
|
||||||
let mut req_url = req_builder.url.clone();
|
|
||||||
if scheme == "ws" {
|
|
||||||
req_url.as_mut_url().set_scheme("http").unwrap();
|
|
||||||
} else if scheme == "wss" {
|
|
||||||
req_url.as_mut_url().set_scheme("https").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if should_be_blocked_due_to_bad_port(&req_url) {
|
|
||||||
debug!("Failed to establish a WebSocket connection: port blocked");
|
|
||||||
let _ = resource_event_sender.send(WebSocketNetworkEvent::Fail);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let host = replace_host(req_builder.url.host_str().unwrap());
|
|
||||||
let mut net_url = req_builder.url.clone().into_url();
|
|
||||||
net_url.set_host(Some(&host)).unwrap();
|
|
||||||
|
|
||||||
let client = Client {
|
|
||||||
origin: &req_builder.origin.ascii_serialization(),
|
|
||||||
protocols: &protocols,
|
|
||||||
http_state: &http_state,
|
|
||||||
resource_url: &req_builder.url,
|
|
||||||
event_sender: &resource_event_sender,
|
|
||||||
protocol_in_use: None,
|
|
||||||
certificate_path,
|
|
||||||
extra_certs,
|
|
||||||
connection_certs,
|
|
||||||
};
|
|
||||||
let mut ws = WebSocket::new(client).unwrap();
|
|
||||||
|
|
||||||
if let Err(e) = ws.connect(net_url) {
|
|
||||||
debug!("Failed to establish a WebSocket connection: {:?}", e);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let ws_sender = ws.broadcaster();
|
|
||||||
let initiated_close = Arc::new(AtomicBool::new(false));
|
|
||||||
|
|
||||||
ROUTER.add_route(
|
|
||||||
dom_action_receiver.to_opaque(),
|
|
||||||
Box::new(move |message| {
|
|
||||||
let dom_action = message.to().expect("Ws dom_action message to deserialize");
|
|
||||||
match dom_action {
|
|
||||||
WebSocketDomAction::SendMessage(MessageData::Text(data)) => {
|
|
||||||
if let Err(e) = ws_sender.send(Message::text(data)) {
|
|
||||||
warn!("Error sending websocket message: {:?}", e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
WebSocketDomAction::SendMessage(MessageData::Binary(data)) => {
|
|
||||||
if let Err(e) = ws_sender.send(Message::binary(data)) {
|
|
||||||
warn!("Error sending websocket message: {:?}", e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
WebSocketDomAction::Close(code, reason) => {
|
|
||||||
if !initiated_close.fetch_or(true, Ordering::SeqCst) {
|
|
||||||
match code {
|
|
||||||
Some(code) => {
|
|
||||||
if let Err(e) = ws_sender.close_with_reason(
|
|
||||||
code.into(),
|
|
||||||
reason.unwrap_or("".to_owned()),
|
|
||||||
) {
|
|
||||||
warn!("Error closing websocket: {:?}", e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
if let Err(e) = ws_sender.close(CloseCode::Status) {
|
|
||||||
warn!("Error closing websocket: {:?}", e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Err(e) = ws.run() {
|
|
||||||
debug!("Failed to run WebSocket: {:?}", e);
|
|
||||||
let _ = resource_event_sender.send(WebSocketNetworkEvent::Fail);
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.expect("Thread spawning failed");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ rand = [
|
||||||
"servo_rand",
|
"servo_rand",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
"tungstenite",
|
||||||
"ws",
|
"ws",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -36,6 +37,14 @@ packages = [
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"parking_lot_core",
|
"parking_lot_core",
|
||||||
|
|
||||||
|
# https://github.com/servo/servo/issues/26933
|
||||||
|
"futures",
|
||||||
|
"tokio-openssl",
|
||||||
|
"tokio",
|
||||||
|
"http",
|
||||||
|
"scoped-tls",
|
||||||
|
"bytes",
|
||||||
|
|
||||||
# https://github.com/servo/servo/pull/23288#issuecomment-494687746
|
# https://github.com/servo/servo/pull/23288#issuecomment-494687746
|
||||||
"gl_generator",
|
"gl_generator",
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
[third-party-cookie-accepted.https.html]
|
||||||
|
[Test that third-party cookies are accepted for WebSockets.]
|
||||||
|
expected: FAIL
|
|
@ -0,0 +1,7 @@
|
||||||
|
[close-connecting.html]
|
||||||
|
[WebSockets: close() when connecting]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[close-connecting.html?wss]
|
||||||
|
[WebSockets: close() when connecting]
|
||||||
|
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue