summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock393
-rw-r--r--Cargo.toml11
-rw-r--r--page.html4
-rw-r--r--src/conn.rs133
-rw-r--r--src/main.rs145
-rw-r--r--src/types.rs15
6 files changed, 375 insertions, 326 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 00bb05a..1f200e3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,12 +3,6 @@
version = 3
[[package]]
-name = "anyhow"
-version = "1.0.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
-
-[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -28,6 +22,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "block-buffer"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
@@ -36,6 +39,16 @@ dependencies = [
]
[[package]]
+name = "buf_redux"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
+dependencies = [
+ "memchr",
+ "safemem",
+]
+
+[[package]]
name = "bumpalo"
version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -86,15 +99,33 @@ dependencies = [
[[package]]
name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "digest"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
dependencies = [
- "block-buffer",
+ "block-buffer 0.10.2",
"crypto-common",
]
[[package]]
+name = "fastrand"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
+dependencies = [
+ "instant",
+]
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -111,41 +142,6 @@ dependencies = [
]
[[package]]
-name = "format-bytes"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48942366ef93975da38e175ac9e10068c6fc08ca9e85930d4f098f4d5b14c2fd"
-dependencies = [
- "format-bytes-macros",
-]
-
-[[package]]
-name = "format-bytes-macros"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "203aadebefcc73d12038296c228eabf830f99cba991b0032adf20e9fa6ce7e4f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "futures"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
name = "futures-channel"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -162,23 +158,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
[[package]]
-name = "futures-executor"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
-
-[[package]]
name = "futures-macro"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -207,13 +186,10 @@ version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
dependencies = [
- "futures-channel",
"futures-core",
- "futures-io",
"futures-macro",
"futures-sink",
"futures-task",
- "memchr",
"pin-project-lite",
"pin-utils",
"slab",
@@ -255,7 +231,7 @@ dependencies = [
"indexmap",
"slab",
"tokio",
- "tokio-util",
+ "tokio-util 0.7.1",
"tracing",
]
@@ -266,6 +242,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
+name = "headers"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d"
+dependencies = [
+ "base64",
+ "bitflags",
+ "bytes",
+ "headers-core",
+ "http",
+ "httpdate",
+ "mime",
+ "sha-1 0.10.0",
+]
+
+[[package]]
+name = "headers-core"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
+dependencies = [
+ "http",
+]
+
+[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -333,19 +334,6 @@ dependencies = [
]
[[package]]
-name = "hyper-tungstenite"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0ea2c1b59596d6b1302fe616266257a58b079f68fee329d6d111f79241cb7fd"
-dependencies = [
- "hyper",
- "pin-project",
- "tokio",
- "tokio-tungstenite",
- "tungstenite",
-]
-
-[[package]]
name = "idna"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -367,6 +355,15 @@ dependencies = [
]
[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
name = "itoa"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -425,6 +422,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "mime_guess"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
+dependencies = [
+ "mime",
+ "unicase",
+]
+
+[[package]]
name = "mio"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -448,6 +461,24 @@ dependencies = [
]
[[package]]
+name = "multipart"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182"
+dependencies = [
+ "buf_redux",
+ "httparse",
+ "log",
+ "mime",
+ "mime_guess",
+ "quick-error",
+ "rand",
+ "safemem",
+ "tempfile",
+ "twoway",
+]
+
+[[package]]
name = "ntapi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -473,6 +504,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
name = "parking_lot"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -549,6 +586,12 @@ dependencies = [
]
[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
+[[package]]
name = "quote"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -597,6 +640,15 @@ dependencies = [
]
[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -613,10 +665,11 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.20.4"
+version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921"
+checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
dependencies = [
+ "base64",
"log",
"ring",
"sct",
@@ -624,13 +677,22 @@ dependencies = [
]
[[package]]
-name = "rustls-pemfile"
+name = "ryu"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
+
+[[package]]
+name = "safemem"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
+
+[[package]]
+name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9"
-dependencies = [
- "base64",
-]
+checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "scopeguard"
@@ -640,15 +702,57 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sct"
-version = "0.7.0"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
+checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
dependencies = [
"ring",
"untrusted",
]
[[package]]
+name = "serde"
+version = "1.0.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
+
+[[package]]
+name = "serde_json"
+version = "1.0.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha-1"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
+dependencies = [
+ "block-buffer 0.9.0",
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.9.0",
+ "opaque-debug",
+]
+
+[[package]]
name = "sha-1"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -656,7 +760,7 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
dependencies = [
"cfg-if",
"cpufeatures",
- "digest",
+ "digest 0.10.3",
]
[[package]]
@@ -708,6 +812,20 @@ dependencies = [
]
[[package]]
+name = "tempfile"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "libc",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi",
+]
+
+[[package]]
name = "thiserror"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -775,9 +893,9 @@ dependencies = [
[[package]]
name = "tokio-rustls"
-version = "0.23.4"
+version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
+checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
dependencies = [
"rustls",
"tokio",
@@ -785,19 +903,45 @@ dependencies = [
]
[[package]]
+name = "tokio-stream"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
name = "tokio-tungstenite"
-version = "0.17.1"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06cda1232a49558c46f8a504d5b93101d42c0bf7f911f12a105ba48168f821ae"
+checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8"
dependencies = [
"futures-util",
"log",
+ "pin-project",
"tokio",
"tungstenite",
]
[[package]]
name = "tokio-util"
+version = "0.6.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764"
@@ -823,6 +967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
dependencies = [
"cfg-if",
+ "log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@@ -856,9 +1001,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "tungstenite"
-version = "0.17.2"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5"
+checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5"
dependencies = [
"base64",
"byteorder",
@@ -867,19 +1012,37 @@ dependencies = [
"httparse",
"log",
"rand",
- "sha-1",
+ "sha-1 0.9.8",
"thiserror",
"url",
"utf-8",
]
[[package]]
+name = "twoway"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "typenum"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
+name = "unicase"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
name = "unicode-bidi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -941,6 +1104,37 @@ dependencies = [
]
[[package]]
+name = "warp"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "headers",
+ "http",
+ "hyper",
+ "log",
+ "mime",
+ "mime_guess",
+ "multipart",
+ "percent-encoding",
+ "pin-project",
+ "scoped-tls",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio",
+ "tokio-rustls",
+ "tokio-stream",
+ "tokio-tungstenite",
+ "tokio-util 0.6.9",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1018,9 +1212,9 @@ dependencies = [
[[package]]
name = "webpki"
-version = "0.22.0"
+version = "0.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
+checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
dependencies = [
"ring",
"untrusted",
@@ -1030,17 +1224,10 @@ dependencies = [
name = "websweeper"
version = "1.0.0"
dependencies = [
- "anyhow",
- "format-bytes",
- "futures",
- "futures-channel",
"futures-util",
- "hyper",
- "hyper-tungstenite",
"rand",
- "rustls-pemfile",
"tokio",
- "tokio-rustls",
+ "warp",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index d54c86d..1cfddc5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,14 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["full"] }
-tokio-rustls = "0.23"
-rustls-pemfile = "1"
-hyper-tungstenite = "0.8"
+warp = { version = "0.3", features = ["tls", "websocket"] }
rand = "0.8"
-futures = "0.3"
-futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
-futures-channel = "0.3"
-format-bytes = "0.3"
-anyhow = "1.0"
+futures-util = "0.3"
diff --git a/page.html b/page.html
index e2aec9b..78df322 100644
--- a/page.html
+++ b/page.html
@@ -11,11 +11,11 @@
src: url("font.ttf");
}
#board-container {
- font-family: vt323, monospace;
font-size: 28pt;
line-height: 0.6em;
}
body {
+ font-family: vt323, monospace;
background-color: black;
color: white;
}
@@ -46,7 +46,7 @@
<script>
window.id = NaN;
let wsproto = (window.location.protocol == "https:")? "wss:": "ws:";
- let s = new WebSocket(`${wsproto}//${window.location.hostname}:${window.location.port}`);
+ let s = new WebSocket(`${wsproto}//${window.location.hostname}:${window.location.port}/ws`);
let info_elem = document.getElementById("miscinfo");
let board_elem = document.getElementById("board");
let name = "deadbeef";
diff --git a/src/conn.rs b/src/conn.rs
index 6d08942..fda3a2b 100644
--- a/src/conn.rs
+++ b/src/conn.rs
@@ -1,106 +1,19 @@
use crate::types::*;
-use std::{
- net::SocketAddr,
- convert::Infallible,
- pin::Pin,
- task::Poll,
-};
-use hyper::{ Request, Response, Body, service::Service };
-use hyper_tungstenite::{
- HyperWebsocket,
- tungstenite::Message,
-};
-use futures::{
- Future,
- SinkExt,
- StreamExt,
- TryStreamExt,
- TryFuture,
- TryFutureExt,
- channel::mpsc::unbounded,
- pin_mut,
-};
+use futures_util::{SinkExt, StreamExt, TryStreamExt};
+use warp::ws::Message;
-const FONT_FILE: &[u8] = include_bytes!("./VT323-Regular.ttf");
-
-#[derive(Clone)]
-pub struct PerConnHandler {
- pub state: State,
- pub local_addr: SocketAddr,
- pub remote_addr: SocketAddr,
- pub game_cmd_tx: MovReqTx,
- pub page: String,
-}
-
-impl PerConnHandler {
- async fn handle_req(self, req: Request<Body>)
- -> std::result::Result<Response<Body>, Infallible>
- {
- if hyper_tungstenite::is_upgrade_request(&req) {
- let (resp, wsocket) = hyper_tungstenite::upgrade(req, None).expect("couldn't upgrade to websocket");
- tokio::spawn(async move {
- peer_connection(self, wsocket).await;
- });
- return Ok(resp);
- }
-
- //let page = tokio::fs::read_to_string(self.page).await.map_err(errpage)?;
- let mut uri_path = req.uri().path().split('/').skip(1);
- let actual_path = uri_path.next();
-
- use hyper::{ Method, StatusCode };
- match (req.method(), actual_path) {
- (&Method::GET, None | Some("")) => {
- Ok(Response::builder()
- .status(StatusCode::OK)
- .body(Body::from(self.page))
- .unwrap())
- },
- (&Method::GET, Some("font.ttf")) => {
- Ok(Response::builder()
- .status(StatusCode::OK)
- .body(Body::from(FONT_FILE))
- .unwrap())
- },
- _ => {
- Ok(Response::builder()
- .status(StatusCode::NOT_FOUND)
- .body(Body::empty())
- .unwrap())
- }
- }
- }
-}
-
-impl Service<Request<Body>> for PerConnHandler
-{
- type Response = Response<Body>;
- type Error = Infallible;
- type Future = Pin<Box<dyn Future<Output = std::result::Result<Self::Response,Self::Error>> + Send>>;
-
- fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
- Poll::Ready(Ok(()))
- }
-
- fn call(&mut self, req: Request<Body>) -> Self::Future {
- let cloned_self = self.clone();
- Box::pin(cloned_self.handle_req(req))
- }
-}
-
-pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
- let socket = socket.await.expect("couldn't finish websocket connection");
- let addr = conn.remote_addr;
- let peers = &conn.state.peers;
- let mut cmd_tx = &conn.game_cmd_tx;
- println!("Incoming TCP connection from: {addr}");
+pub async fn peer_connection(socket: warp::ws::WebSocket, conndata: ConnData) {
+ let addr = conndata.remote_addr;
+ let peers = &conndata.peers;
+ let cmd_tx = conndata.cmd_tx.clone();
+ println!("Incoming TCP connection from: {}", conndata.remote_addr);
let mut peer_name = "unknown".to_string();
// for game -> conn comms
- let (tx, rx) = unbounded();
+ let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel();
// for server -> client comms
- let (outgoing, mut incoming) = socket.split();
+ let (mut outgoing, mut incoming) = socket.split();
let process_incoming = async {
while let Ok(cmd) = incoming.try_next().await {
@@ -112,7 +25,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
peers.remove(&addr);
}
for (paddr, p) in peers.iter() {
- if let Err(e) = tx.unbounded_send(Message::text("logoff {p.seqid} {p.name}")) {
+ if let Err(e) = tx.send(Message::text("logoff {p.seqid} {p.name}")) {
println!("couldn't deliver logoff info to \"{}\"@{}: {}", p.name, paddr, e);
}
}
@@ -120,7 +33,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
}
// if it ain't text we can't handle it
if !cmd.is_text() { continue; }
- let cmd = cmd.to_text().unwrap();
+ let cmd = cmd.to_str().to_owned().unwrap();
let mut fields = cmd.split(" ");
let parse_pos = |mut fields: std::str::Split<&str>| -> Option<(usize, usize)> {
@@ -144,7 +57,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
{
let peers = peers.read().await;
for peer_tx in peers.iter().filter(|(s, _)| **s != addr).map(|(_,p)| &p.tx) {
- let r = peer_tx.unbounded_send(Message::text(format!("pos {id} {sanitized_name} {} {}", pos.0, pos.1)));
+ let r = peer_tx.send(Message::text(format!("pos {id} {sanitized_name} {} {}", pos.0, pos.1)));
if let Err(e) = r {
println!("error sending pos update: {e}");
}
@@ -160,7 +73,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
match parse_pos(fields) {
Some(pos) => {
println!("{cmd} from \"{peer_name}\"@{addr}");
- if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::Reveal, pos }, addr)).await {
+ if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::Reveal, pos }, addr)) {
println!("couldn't process \"{peer_name}\"'s reveal command: {e}");
};
},
@@ -173,7 +86,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
match parse_pos(fields) {
Some(pos) => {
println!("{cmd} from \"{peer_name}\"@{addr}");
- if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::ToggleFlag, pos }, addr)).await {
+ if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::ToggleFlag, pos }, addr)) {
println!("couldn't process \"{peer_name}\"'s flag command: {e}");
};
},
@@ -184,7 +97,7 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
},
"reset" => {
println!("{cmd} from \"{peer_name}\"@{addr}");
- if let Err(e) = cmd_tx.send(MetaMove::Reset).await {
+ if let Err(e) = cmd_tx.send(MetaMove::Reset) {
println!("couldn't send game dump to \"{peer_name}\"@{addr}: {e}");
}
},
@@ -206,8 +119,8 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
position: (0,0)
});
}
- tx.unbounded_send(Message::text(format!("id {id}"))).unwrap();
- if let Err(e) = cmd_tx.send(MetaMove::Dump).await {
+ tx.send(Message::text(format!("id {id}"))).unwrap();
+ if let Err(e) = cmd_tx.send(MetaMove::Dump) {
println!("couldn't send game dump to \"{peer_name}\"@{addr}: {e}");
}
},
@@ -217,10 +130,16 @@ pub async fn peer_connection(conn: PerConnHandler, socket: HyperWebsocket) {
}
}
};
- let send_to_browser = rx.map(Ok).forward(outgoing);
+ let send_to_client = async move {
+ while let Some(m) = rx.recv().await {
+ if let Err(e) = outgoing.send(m).await {
+ println!("something went bad lol: {e}");
+ };
+ }
+ };
- pin_mut!(process_incoming, send_to_browser);
- futures_util::future::select(process_incoming, send_to_browser).await;
+ futures_util::pin_mut!(process_incoming, send_to_client);
+ futures_util::future::select(process_incoming, send_to_client).await;
println!("{addr} disconnected");
peers.write().await.remove(&addr);
diff --git a/src/main.rs b/src/main.rs
index cafc9d4..b3c3cf9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,33 +1,21 @@
-#[macro_use] extern crate anyhow;
-
-pub use anyhow::{ Result, Error };
-
use std::{
convert::Infallible,
collections::HashMap,
+ error::Error,
net::SocketAddr,
- sync::Arc,
};
+use warp::Filter;
mod types;
mod conn;
mod minesweeper;
use types::*;
-use hyper::{ Body, Request, Server };
-use hyper::server::conn::{ AddrStream, AddrIncoming };
-use hyper::service::{make_service_fn, service_fn, Service};
use tokio::sync::RwLock;
-use std::fs;
-
-use futures_util::{future, pin_mut, ready, stream::TryStreamExt, StreamExt, sink::SinkExt, TryFutureExt};
-use hyper_tungstenite::{ tungstenite::protocol::Message, HyperWebsocket };
-use tokio_rustls::{ rustls, Accept, server::TlsStream, TlsAcceptor };
-use rustls::{ServerConnection, SupportedCipherSuite, ProtocolVersion, ServerConfig,
- Certificate, PrivateKey};
+const FONT_FILE: &[u8] = include_bytes!("./VT323-Regular.ttf");
-fn main() -> Result<()> {
+fn main() -> Result<(), Box<dyn Error>> {
let conf = Config {
cert_path: "./cert.pem".to_owned(),
pkey_path: "./cert.rsa".to_owned(),
@@ -40,91 +28,59 @@ fn main() -> Result<()> {
peers: PeerMap::new(RwLock::new(HashMap::new())),
};
- let cert_pem = fs::read(&state.conf.cert_path)?;
- let pkey_pem = fs::read(&state.conf.pkey_path)?;
+ tokio_main(state)
+}
- // Build TLS configuration.
- let tls_cfg = {
- let certs: Vec<Certificate> = rustls_pemfile::certs(&mut &*cert_pem)
- .map(|mut certs| certs.drain(..).map(Certificate).collect())?;
- if certs.len() < 1 {
- return Err(anyhow!("No certificates found"));
- }
- let mut keys: Vec<PrivateKey> = rustls_pemfile::rsa_private_keys(&mut &*pkey_pem)
- .map(|mut keys| keys.drain(..).map(PrivateKey).collect())?;
- if keys.len() < 1 {
- return Err(anyhow!("No private keys found"));
- }
+#[tokio::main]
+async fn tokio_main(state: State) -> Result<(), Box<dyn Error>> {
+ // Start the temporary single lobby
+ let (cmd_tx, cmd_rx) = tokio::sync::mpsc::unbounded_channel();
+ let _game_t = tokio::spawn(gameloop(cmd_rx, state.peers.clone()));
- let mut tls_cfg = ServerConfig::builder()
- .with_safe_defaults()
- .with_no_client_auth()
- .with_single_cert(certs, keys.remove(0))?;
+ let cmd_filter = warp::any().map(move || cmd_tx.clone());
- // Configure ALPN to accept HTTP/2, HTTP/1.1 in that order.
- tls_cfg.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
- tls_cfg
+ let page_route = {
+ use warp::*;
+ get()
+ .and(path("font.ttf"))
+ .map(|| FONT_FILE)
+ .or(fs::file(state.conf.page_path.clone()))
};
- tokio_main(state, tls_cfg)
-}
+ let websocket_route = {
+ let state = state.clone();
+ use warp::*;
+ path("ws")
+ .and(ws())
+ .and(addr::remote())
+ .and(cmd_filter)
+ .map(move |ws: warp::ws::Ws, saddr: Option<SocketAddr>, cmd_tx: CmdTx| {
+ let state = state.clone();
+ println!("conn from {saddr:?}");
+ ws.on_upgrade(move |socket| {
+ let conn_data = types::ConnData { remote_addr: saddr.unwrap(), cmd_tx: cmd_tx.clone(), peers: state.peers.clone() };
+ conn::peer_connection(socket, conn_data)
+ })
+ })
+ };
+ let routes = websocket_route.or(page_route);
-#[tokio::main]
-async fn tokio_main(state: State, tls_conf: ServerConfig) -> Result<()> {
- let server = main_server(state.clone(), tls_conf);
+ let server = warp::serve(routes)
+ .tls()
+ .cert_path(state.conf.cert_path)
+ .key_path(state.conf.pkey_path)
+ .run(state.conf.socket_addr);
println!("Serving on {}", state.conf.socket_addr);
- server.await?;
+ server.await;
Ok(())
}
-async fn main_server(state: State, tls_conf: ServerConfig) -> Result<()> {
- // Create a TCP listener, that uses TLS
- let listener = tokio::net::TcpListener::bind(&state.conf.socket_addr).await?;
- let local_addr = listener.local_addr()?;
- let acceptor = tokio_rustls::TlsAcceptor::from(Arc::new(tls_conf));
- let http = hyper::server::conn::Http::new();
-
- // Start the temporary single lobby
- let (cmd_tx, cmd_rx) = futures::channel::mpsc::unbounded();
- let game_t = tokio::spawn(gameloop(cmd_rx, state.peers.clone()));
-
- loop {
- let (conn, remote_addr) = listener.accept().await?;
- let acceptor = acceptor.clone();
- let http = http.clone();
- let cloned_state = state.clone();
- let cmd_tx = cmd_tx.clone();
- let fut = async move {
- match acceptor.accept(conn).await {
- Ok(stream) => {
- let page = tokio::fs::read_to_string(&cloned_state.conf.page_path).await;
- if let Err(e) = page { return Err(anyhow!("couldn't read page file: {e}")); }
-
- let handler = conn::PerConnHandler {
- state: cloned_state,
- local_addr,
- remote_addr,
- game_cmd_tx: cmd_tx,
- page: page.unwrap(),
- };
- if let Err(e) = http.serve_connection(stream, handler).await {
- eprintln!("hyper error for {remote_addr}: {e}");
- }
- },
- Err(e) => eprintln!("TLS error for {remote_addr}: {e}"),
- }
- Ok(())
- };
- tokio::spawn(fut);
- }
-}
-
// If a move is made, broadcast new board, else just send current board
-async fn gameloop(mut move_rx: futures::channel::mpsc::UnboundedReceiver<MetaMove>, peers: PeerMap) {
+async fn gameloop(mut move_rx: tokio::sync::mpsc::UnboundedReceiver<MetaMove>, peers: PeerMap) {
use minesweeper::*;
let mut game = Game::new(Board::new(75,35), (75*35)/8);
let mut latest_player_name = None;
- while let Some(req) = move_rx.next().await {
+ while let Some(req) = move_rx.recv().await {
let done = game.phase == Phase::Die || game.phase == Phase::Win;
match req {
MetaMove::Move(m, o) => if !done {
@@ -137,6 +93,7 @@ async fn gameloop(mut move_rx: futures::channel::mpsc::UnboundedReceiver<MetaMov
MetaMove::Dump => (),
MetaMove::Reset => { game = Game::new(Board::new(75,35), (75*35)/8); },
}
+ use warp::ws::Message;
let mut reply = vec![Message::binary(game.board.render())];
let lpname = latest_player_name.as_ref().map(|s| s.as_str()).unwrap_or("unknown player");
match game.phase {
@@ -148,21 +105,11 @@ async fn gameloop(mut move_rx: futures::channel::mpsc::UnboundedReceiver<MetaMov
let peers = peers.read().await;
for (addr, p) in peers.iter() {
for r in reply.iter() {
- if let Err(e) = p.tx.unbounded_send(r.clone()) {
- println!("couldn't send game update {r} to {addr}: {e}");
+ if let Err(e) = p.tx.send(r.clone()) {
+ println!("couldn't send game update {r:?} to {addr}: {e}");
}
}
}
}
}
}
-
-fn error(err: String) -> std::io::Error {
- std::io::Error::new(std::io::ErrorKind::Other, err)
-}
-
-async fn shutdown_signal() {
- tokio::signal::ctrl_c()
- .await
- .expect("failed to install CTRL+C signal handler");
-}
diff --git a/src/types.rs b/src/types.rs
index eed69dd..73d51b8 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -3,10 +3,8 @@ use std::{
net::SocketAddr,
sync::Arc,
};
+use warp::ws::Message;
use tokio::sync::RwLock;
-use hyper_tungstenite::tungstenite::Message;
-use hyper::{ Response, Body };
-use futures::channel::mpsc::UnboundedSender;
use crate::minesweeper;
#[derive(Debug, Clone)]
@@ -32,12 +30,17 @@ pub enum MetaMove {
#[derive(Debug)]
pub struct Peer {
- pub tx: UnboundedSender<Message>,
+ pub tx: tokio::sync::mpsc::UnboundedSender<Message>,
pub seq_id: usize,
pub name: String,
pub position: (usize, usize),
}
-pub type HtmlResult = Result<Response<Body>, Response<Body>>;
-pub type MovReqTx = futures::channel::mpsc::UnboundedSender<MetaMove>;
+pub struct ConnData {
+ pub cmd_tx: CmdTx,
+ pub remote_addr: SocketAddr,
+ pub peers: PeerMap,
+}
+
+pub type CmdTx = tokio::sync::mpsc::UnboundedSender<MetaMove>;
pub type PeerMap = Arc<RwLock<HashMap<SocketAddr, Peer>>>;