WIP: major changes;
* using RwLock instead of Mutex. * Added WebServer for API & http tracker using hyper. * added iterator trait for StackVec<T>. * removed benchmarks since they require nightly rust.
This commit is contained in:
parent
27111c0c83
commit
ca77851b49
514
Cargo.lock
generated
514
Cargo.lock
generated
|
@ -1,3 +1,11 @@
|
|||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.0.0"
|
||||
|
@ -7,11 +15,251 @@ dependencies = [
|
|||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures-cpupool"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"http 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"h2 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"http 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"want 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.6"
|
||||
|
@ -28,6 +276,26 @@ dependencies = [
|
|||
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.66"
|
||||
|
@ -43,6 +311,16 @@ dependencies = [
|
|||
"syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "string"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.14.2"
|
||||
|
@ -53,13 +331,148 @@ dependencies = [
|
|||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-fs 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-udp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-codec"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-executor"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-fs"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-io"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-reactor"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tcp"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-threadpool"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-timer"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-udp"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "udpt-rs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -67,12 +480,113 @@ name = "unicode-xid"
|
|||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ws2_32-sys"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
|
||||
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
|
||||
"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
|
||||
"checksum bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd32989a66957d3f0cba6588f15d4281a733f4e9ffc43fcd2385f57d3bf99ff"
|
||||
"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
|
||||
"checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7"
|
||||
"checksum crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2af0e75710d6181e234c8ecc79f14a97907850a541b13b0be1dd10992f2e4620"
|
||||
"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c"
|
||||
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
||||
"checksum h2 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6229ac66d3392dd83288fe04defd4b353354b15bbe07820d53dda063a736afcc"
|
||||
"checksum http 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6861b042450b6333fa7212b6edffc2d6df22579042817d59d49f4f8afbaaaf74"
|
||||
"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
|
||||
"checksum hyper 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ad39a4f15051ccd4ea6adf44df851e00fd9062c71734391d806246b94e69dc1f"
|
||||
"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220"
|
||||
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
|
||||
"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
|
||||
"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
|
||||
"checksum log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6fddaa003a65722a7fb9e26b0ce95921fe4ba590542ced664d8ce2fa26f9f3ac"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe"
|
||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||
"checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0"
|
||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
||||
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
|
||||
"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95"
|
||||
"checksum serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "0a90213fa7e0f5eac3f7afe2d5ff6b088af515052cc7303bd68c7e3b91a3fb79"
|
||||
"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d"
|
||||
"checksum string 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31f98b200e7caca9efca50fc0aa69cd58a5ec81d5f6e75b2f3ecaad2e998972a"
|
||||
"checksum syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c67da57e61ebc7b7b6fff56bb34440ca3a83db037320b0507af4c10368deda7d"
|
||||
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
|
||||
"checksum tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ee337e5f4e501fc32966fec6fe0ca0cc1c237b0b1b14a335f8bfe3c5f06e286"
|
||||
"checksum tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb"
|
||||
"checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113"
|
||||
"checksum tokio-fs 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc42bae2f6e33865b99069d95bcddfc85c9f0849b4e7e7399eeee71956ef34d7"
|
||||
"checksum tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a5c9635ee806f26d302b8baa1e145689a280d8f5aa8d0552e7344808da54cc21"
|
||||
"checksum tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e00ec63bbec2c97ce1178cb0587b2c438b2f6b09d3ee54a33c45a9cf0d530810"
|
||||
"checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f"
|
||||
"checksum tokio-threadpool 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c3873a6d8d0b636e024e77b9a82eaab6739578a06189ecd0e731c7308fbc5d"
|
||||
"checksum tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "028b94314065b90f026a21826cffd62a4e40a92cda3e5c069cc7b02e5945f5e9"
|
||||
"checksum tokio-udp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43eb534af6e8f37d43ab1b612660df14755c42bd003c5f8d2475ee78cc4600c0"
|
||||
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum want 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2fffe09593e18ed34950d66dbf44c27deb2e03f3905c493f0641f9f99a3f2349"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
|
|
|
@ -11,3 +11,6 @@ lto = true
|
|||
serde = "1.0.66"
|
||||
bincode = "1.0.0"
|
||||
serde_derive = "1.0.66"
|
||||
hyper = "0.12"
|
||||
futures = "0.1.21"
|
||||
tokio = "0.1.7"
|
|
@ -23,3 +23,9 @@ cd udpt
|
|||
git checkout udpt-rs
|
||||
cargo build
|
||||
```
|
||||
|
||||
## Why was this project rewritten in rust?
|
||||
For a few reasons,
|
||||
1. Rust makes it harder to make mistakes than C/C++.
|
||||
2. Rust allows easier cross-platform development with it's powerful standard library.
|
||||
3. Integrated tests and benchmarks.
|
||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -1,15 +1,24 @@
|
|||
extern crate bincode;
|
||||
extern crate serde;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
extern crate hyper;
|
||||
extern crate futures;
|
||||
|
||||
mod server;
|
||||
mod tracker;
|
||||
mod stackvec;
|
||||
mod webserver;
|
||||
|
||||
fn main() {
|
||||
let mut tracker = tracker::TorrentTracker::new();
|
||||
let tracker = std::sync::Arc::new(tracker::TorrentTracker::new());
|
||||
|
||||
let addr = "0.0.0.0:1212";
|
||||
let mut s = server::UDPTracker::new(addr, &mut tracker).unwrap();
|
||||
let s = std::sync::Arc::new(server::UDPTracker::new(addr, tracker.clone()).unwrap());
|
||||
|
||||
use std::str::FromStr;
|
||||
let sa = std::net::SocketAddrV4::from_str("0.0.0.0:1213").unwrap();
|
||||
webserver::start_server(std::net::SocketAddr::from(sa), tracker.clone(), "myt0k3n");
|
||||
|
||||
loop {
|
||||
match s.accept_packet() {
|
||||
Err(e) => {
|
||||
|
|
122
src/server.rs
122
src/server.rs
|
@ -35,7 +35,7 @@ fn pack<T: Serialize>(data: &T) -> Option<Vec<u8>> {
|
|||
bo.big_endian();
|
||||
|
||||
match bo.serialize(data) {
|
||||
Ok(bytes) => Some(bytes),
|
||||
Ok(v) => Some(v),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
@ -94,13 +94,13 @@ struct UDPAnnounceResponse {
|
|||
seeders: u32,
|
||||
}
|
||||
|
||||
pub struct UDPTracker<'a> {
|
||||
pub struct UDPTracker {
|
||||
server: std::net::UdpSocket,
|
||||
tracker: &'a mut tracker::TorrentTracker,
|
||||
tracker: std::sync::Arc<tracker::TorrentTracker>,
|
||||
}
|
||||
|
||||
impl<'a> UDPTracker<'a> {
|
||||
pub fn new<T: std::net::ToSocketAddrs>(bind_address: T, tracker: &mut tracker::TorrentTracker) -> Result<UDPTracker, std::io::Error> {
|
||||
impl UDPTracker {
|
||||
pub fn new<T: std::net::ToSocketAddrs>(bind_address: T, tracker: std::sync::Arc<tracker::TorrentTracker>) -> Result<UDPTracker, std::io::Error> {
|
||||
let server = match UdpSocket::bind(bind_address) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
|
@ -114,7 +114,7 @@ impl<'a> UDPTracker<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
fn handle_packet(&mut self, remote_address: &SocketAddr, payload: &[u8]) {
|
||||
fn handle_packet(&self, remote_address: &SocketAddr, payload: &[u8]) {
|
||||
let header : UDPRequestHeader = match unpack(payload) {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
|
@ -154,7 +154,7 @@ impl<'a> UDPTracker<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_announce(&mut self, remote_addr: &SocketAddr, header: &UDPRequestHeader, payload: &[u8]) {
|
||||
fn handle_announce(&self, remote_addr: &SocketAddr, header: &UDPRequestHeader, payload: &[u8]) {
|
||||
if header.connection_id != self.get_connection_id(remote_addr) {
|
||||
return;
|
||||
}
|
||||
|
@ -182,23 +182,31 @@ impl<'a> UDPTracker<'a> {
|
|||
}
|
||||
|
||||
let client_addr = SocketAddr::new(remote_addr.ip(), packet.port);
|
||||
match self.tracker.get_torrent(&packet.info_hash, |torrent: &mut tracker::TorrentEntry | -> Result<Vec<u8>, &str> {
|
||||
if torrent.is_flagged() {
|
||||
return Err("Torrent has been flagged.");
|
||||
}
|
||||
torrent.update_peer(&packet.peer_id, &client_addr, packet.uploaded, packet.downloaded, packet.left, packet.event);
|
||||
|
||||
let stats = torrent.get_stats();
|
||||
let peers = torrent.get_peers(&client_addr);
|
||||
if let Some(mut payload) = pack(&UDPAnnounceResponse {
|
||||
header: UDPResponseHeader {
|
||||
action: Actions::Announce,
|
||||
transaction_id: packet.header.transaction_id,
|
||||
},
|
||||
seeders: stats.0 as u32,
|
||||
interval: 20,
|
||||
leechers: stats.2 as u32,
|
||||
}) {
|
||||
match self.tracker.update_torrent_and_get_stats(&packet.info_hash, &packet.peer_id, &client_addr, packet.uploaded, packet.downloaded, packet.left, packet.event) {
|
||||
tracker::TorrentStats::Stats {leechers, complete, seeders} => {
|
||||
let peers = match self.tracker.get_torrent_peers(&packet.info_hash, &client_addr) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut payload = match pack(&UDPAnnounceResponse {
|
||||
header: UDPResponseHeader {
|
||||
action: Actions::Announce,
|
||||
transaction_id: packet.header.transaction_id,
|
||||
},
|
||||
seeders,
|
||||
interval: 20,
|
||||
leechers,
|
||||
}) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
for peer in peers {
|
||||
match peer {
|
||||
SocketAddr::V4(ipv4) => {
|
||||
|
@ -211,70 +219,22 @@ impl<'a> UDPTracker<'a> {
|
|||
|
||||
let port_hton = client_addr.port().to_be();
|
||||
payload.extend(&[(port_hton & 0xff) as u8, ((port_hton >> 8) & 0xff) as u8]);
|
||||
}
|
||||
|
||||
return Ok(payload);
|
||||
}
|
||||
}
|
||||
return Err("");
|
||||
}) {
|
||||
Some(error_message) => {
|
||||
match error_message {
|
||||
Err(err) => {
|
||||
if err.len() > 0 {
|
||||
self.send_error(remote_addr, header, err);
|
||||
}
|
||||
},
|
||||
Ok(payload) => {
|
||||
// send packet...
|
||||
let _ = self.send_packet(remote_addr, payload.as_slice());
|
||||
}
|
||||
}
|
||||
let _ = self.send_packet(&client_addr, payload.as_slice());
|
||||
},
|
||||
None => {
|
||||
self.send_error(remote_addr, header, "Unregistered torrent");
|
||||
tracker::TorrentStats::TorrentFlagged => {
|
||||
self.send_error(&client_addr, &packet.header, "torrent flagged.");
|
||||
return;
|
||||
},
|
||||
tracker::TorrentStats::TorrentNotRegistered => {
|
||||
self.send_error(&client_addr, &packet.header, "torrent not registered.");
|
||||
return;
|
||||
}
|
||||
};
|
||||
/*
|
||||
if torrent.is_flagged() {
|
||||
error = Some("Torrent was flagged");
|
||||
} else {
|
||||
torrent.update_peer(&packet.peer_id, &client_addr, packet.uploaded, packet.downloaded, packet.left, packet.event);
|
||||
|
||||
let stats = torrent.get_stats();
|
||||
let peers = torrent.get_peers(&client_addr);
|
||||
|
||||
if let Some(mut payload) = pack(&UDPAnnounceResponse {
|
||||
header: UDPResponseHeader {
|
||||
action: Actions::Announce,
|
||||
transaction_id: packet.header.transaction_id,
|
||||
},
|
||||
seeders: stats.0 as u32,
|
||||
interval: 20,
|
||||
leechers: stats.2 as u32,
|
||||
}) {
|
||||
for peer in peers {
|
||||
match peer {
|
||||
SocketAddr::V4(ipv4) => {
|
||||
payload.extend(&ipv4.ip().octets());
|
||||
},
|
||||
SocketAddr::V6(ipv6) => {
|
||||
payload.extend(&ipv6.ip().octets());
|
||||
}
|
||||
};
|
||||
|
||||
let port_hton = client_addr.port().to_be();
|
||||
payload.extend(&[(port_hton & 0xff) as u8, ((port_hton >> 8) & 0xff) as u8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(error_message) = error {
|
||||
self.send_error(remote_addr, &packet.header, error_message);
|
||||
}*/
|
||||
}
|
||||
|
||||
fn handle_scrape(&self, remote_addr: &SocketAddr, header: &UDPRequestHeader, payload: &[u8]) {
|
||||
fn handle_scrape(&self, remote_addr: &SocketAddr, header: &UDPRequestHeader, _payload: &[u8]) {
|
||||
if header.connection_id != self.get_connection_id(remote_addr) {
|
||||
return;
|
||||
}
|
||||
|
@ -309,7 +269,7 @@ impl<'a> UDPTracker<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn accept_packet(&mut self) -> Result<(), std::io::Error> {
|
||||
pub fn accept_packet(&self) -> Result<(), std::io::Error> {
|
||||
let mut packet = [0u8; MAX_PACKET_SIZE];
|
||||
match self.server.recv_from(&mut packet) {
|
||||
Ok((size, remote_address)) => {
|
||||
|
|
|
@ -12,12 +12,23 @@ impl<'a, T> StackVec<'a, T> {
|
|||
length: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> StackVec<'a, T> {
|
||||
pub fn len(&self) -> usize {
|
||||
self.length
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
&self.data[0..self.length]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Extend<T> for StackVec<'a, T> {
|
||||
fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
|
||||
for item in iter {
|
||||
self.data[self.length] = item;
|
||||
self.length += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> io::Write for StackVec<'a, u8> {
|
||||
|
@ -26,7 +37,7 @@ impl<'a> io::Write for StackVec<'a, u8> {
|
|||
// not enough space on buffer.
|
||||
return Err(io::Error::from(io::ErrorKind::WriteZero));
|
||||
}
|
||||
let mut writable = &mut self.data[self.length..][0..buf.len()];
|
||||
let writable = &mut self.data[self.length..][0..buf.len()];
|
||||
writable.copy_from_slice(buf);
|
||||
self.length += buf.len();
|
||||
Ok(buf.len())
|
||||
|
@ -52,40 +63,4 @@ mod tests {
|
|||
}
|
||||
assert_eq!(buf[1] as char, 'e');
|
||||
}
|
||||
|
||||
fn add_values<T: io::Write>(vec: &mut T) {
|
||||
for i in 0..BUF_LEN {
|
||||
assert!(vec.write(&[((i % 256) & 0xff) as u8]).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
const BUF_LEN : usize = 1024 * 1024 * 1; // 10MB
|
||||
|
||||
#[bench]
|
||||
fn vec_stack(bencher: &mut Bencher) {
|
||||
bencher.iter(|| {
|
||||
let mut buff = [0u8; BUF_LEN];
|
||||
let mut v = StackVec::from(&mut buff);
|
||||
add_values(&mut v);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn vec_heap(bencher: &mut Bencher) {
|
||||
bencher.iter(|| {
|
||||
let mut v = Vec::new();
|
||||
|
||||
add_values(&mut v);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn vec_heap_cap(bencher: &mut Bencher) {
|
||||
bencher.iter(|| {
|
||||
let mut v = Vec::with_capacity(BUF_LEN);
|
||||
add_values(&mut v);
|
||||
});
|
||||
}
|
||||
}
|
222
src/tracker.rs
222
src/tracker.rs
|
@ -23,8 +23,66 @@ struct TorrentPeer {
|
|||
updated: std::time::SystemTime,
|
||||
}
|
||||
|
||||
type PeerId = [u8; 20];
|
||||
type InfoHash = [u8; 20];
|
||||
pub type PeerId = [u8; 20];
|
||||
pub type InfoHash = [u8; 20];
|
||||
|
||||
pub trait HexConv {
|
||||
fn to_hex(&self) -> String;
|
||||
fn from_hex(hex: &str) -> Option<InfoHash>;
|
||||
}
|
||||
|
||||
impl HexConv for InfoHash {
|
||||
fn to_hex(&self) -> String {
|
||||
const HEX: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
|
||||
let data = self;
|
||||
let mut res = String::with_capacity(data.len() * 2);
|
||||
for b in data {
|
||||
res.push(HEX[((b >> 4) & 0x0fu8) as usize]);
|
||||
res.push(HEX[(b & 0x0fu8) as usize]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
fn from_hex(hex: &str) -> Option<InfoHash> {
|
||||
let mut res : InfoHash = [0u8; 20];
|
||||
if hex.len() != 2 * res.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut tmp = 0;
|
||||
let mut idx = 0;
|
||||
|
||||
for ch in hex.chars() {
|
||||
if idx % 2 == 1 {
|
||||
tmp <<= 4;
|
||||
}
|
||||
|
||||
let mut num = ch as u32;
|
||||
if ch >= '0' && ch <= '9' {
|
||||
num -= '0' as u32;
|
||||
} else if ch >= 'a' && ch <= 'f' {
|
||||
num -= 'a' as u32;
|
||||
num += 10;
|
||||
} else if ch >= 'A' && ch <= 'F' {
|
||||
num -= 'A' as u32;
|
||||
num += 10;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
||||
tmp |= num & 0x0f;
|
||||
|
||||
if idx % 2 == 1 {
|
||||
res[(idx - 1) / 2] = tmp as u8;
|
||||
tmp = 0;
|
||||
}
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
return Some(res);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TorrentEntry {
|
||||
is_flagged: bool,
|
||||
|
@ -35,6 +93,15 @@ pub struct TorrentEntry {
|
|||
}
|
||||
|
||||
impl TorrentEntry {
|
||||
pub fn new() -> TorrentEntry{
|
||||
TorrentEntry{
|
||||
is_flagged: false,
|
||||
peers: std::collections::BTreeMap::new(),
|
||||
completed: 0,
|
||||
seeders: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_flagged(&self) -> bool {
|
||||
self.is_flagged
|
||||
}
|
||||
|
@ -94,7 +161,7 @@ impl TorrentEntry {
|
|||
}
|
||||
|
||||
struct TorrentDatabase {
|
||||
torrent_peers: std::collections::BTreeMap<InfoHash, TorrentEntry>,
|
||||
torrent_peers: std::sync::RwLock<std::collections::BTreeMap<InfoHash, TorrentEntry>>,
|
||||
}
|
||||
|
||||
pub struct TorrentTracker {
|
||||
|
@ -102,45 +169,63 @@ pub struct TorrentTracker {
|
|||
database: TorrentDatabase,
|
||||
}
|
||||
|
||||
pub enum TorrentStats {
|
||||
TorrentFlagged,
|
||||
TorrentNotRegistered,
|
||||
Stats{
|
||||
seeders: u32,
|
||||
leechers: u32,
|
||||
complete: u32,
|
||||
}
|
||||
}
|
||||
|
||||
impl TorrentTracker {
|
||||
pub fn new() -> TorrentTracker {
|
||||
TorrentTracker{
|
||||
mode: TrackerMode::DynamicMode,
|
||||
database: TorrentDatabase{
|
||||
torrent_peers: std::collections::BTreeMap::new(),
|
||||
torrent_peers: std::sync::RwLock::new(std::collections::BTreeMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Adding torrents is not relevant to dynamic trackers.
|
||||
pub fn add_torrent(&mut self, info_hash: &InfoHash) {
|
||||
self.database.torrent_peers.entry(*info_hash).or_insert(TorrentEntry{
|
||||
is_flagged: false,
|
||||
peers: std::collections::BTreeMap::new(),
|
||||
seeders: 0,
|
||||
completed: 0,
|
||||
});
|
||||
pub fn add_torrent(&self, info_hash: &InfoHash) -> Result<(), ()> {
|
||||
let mut write_lock = self.database.torrent_peers.write().unwrap();
|
||||
match write_lock.entry(*info_hash) {
|
||||
std::collections::btree_map::Entry::Vacant(ve) => {
|
||||
ve.insert(TorrentEntry::new());
|
||||
return Ok(());
|
||||
},
|
||||
std::collections::btree_map::Entry::Occupied(entry) => {
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If the torrent is flagged, it will not be removed unless force is set to true.
|
||||
pub fn remove_torrent(&mut self, info_hash: &InfoHash, force: bool) {
|
||||
if !force {
|
||||
if let Some(entry) = self.database.torrent_peers.get(info_hash) {
|
||||
if entry.is_flagged {
|
||||
// torrent is flagged, ignore request.
|
||||
return;
|
||||
pub fn remove_torrent(&self, info_hash: &InfoHash, force: bool) -> Result<(), ()> {
|
||||
use std::collections::btree_map::Entry;
|
||||
let mut entry_lock = self.database.torrent_peers.write().unwrap();
|
||||
let mut torrent_entry = entry_lock.entry(*info_hash);
|
||||
match torrent_entry {
|
||||
Entry::Vacant(_) => {
|
||||
// no entry, nothing to do...
|
||||
return Err(());
|
||||
},
|
||||
Entry::Occupied(entry) => {
|
||||
if force || !entry.get().is_flagged() {
|
||||
entry.remove();
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
// torrent not found, no point looking for it again...
|
||||
return;
|
||||
}
|
||||
return Err(());
|
||||
},
|
||||
}
|
||||
self.database.torrent_peers.remove(info_hash);
|
||||
}
|
||||
|
||||
/// flagged torrents will result in a tracking error. This is to allow enforcement against piracy.
|
||||
pub fn set_torrent_flag(&mut self, info_hash: &InfoHash, is_flagged: bool) {
|
||||
if let Some(mut entry) = self.database.torrent_peers.get_mut(info_hash) {
|
||||
pub fn set_torrent_flag(&self, info_hash: &InfoHash, is_flagged: bool) {
|
||||
if let Some(entry) = self.database.torrent_peers.write().unwrap().get_mut(info_hash) {
|
||||
if is_flagged && !entry.is_flagged {
|
||||
// empty peer list.
|
||||
entry.peers.clear();
|
||||
|
@ -149,23 +234,84 @@ impl TorrentTracker {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_torrent<F, R>(&mut self, info_hash: &InfoHash, action: F) -> Option<R>
|
||||
where F: Fn(&mut TorrentEntry) -> R
|
||||
{
|
||||
if let Some(torrent_entry) = self.database.torrent_peers.get_mut(info_hash) {
|
||||
Some(action(torrent_entry))
|
||||
} else {
|
||||
match self.mode {
|
||||
TrackerMode::StaticMode => None,
|
||||
TrackerMode::PrivateMode => None,
|
||||
TrackerMode::DynamicMode => {
|
||||
None
|
||||
}
|
||||
pub fn get_torrent_peers(&self, info_hash: &InfoHash, remote_addr: &std::net::SocketAddr) -> Option<Vec<std::net::SocketAddr>> {
|
||||
let mut read_lock = self.database.torrent_peers.read().unwrap();
|
||||
match read_lock.get(info_hash) {
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(entry) => {
|
||||
return Some(entry.get_peers(remote_addr));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn cleanup(&mut self) {
|
||||
pub fn update_torrent_and_get_stats(&self, info_hash: &InfoHash, peer_id: &PeerId, remote_address: &std::net::SocketAddr, uploaded: u64, downloaded: u64, left: u64, event: Events) -> TorrentStats {
|
||||
use std::collections::btree_map::Entry;
|
||||
let mut torrent_peers = self.database.torrent_peers.write().unwrap();
|
||||
let mut torrent_entry = match torrent_peers.entry(*info_hash) {
|
||||
Entry::Vacant(vacant) => {
|
||||
match self.mode {
|
||||
TrackerMode::DynamicMode => {
|
||||
vacant.insert(TorrentEntry::new())
|
||||
},
|
||||
_ => {
|
||||
return TorrentStats::TorrentNotRegistered;
|
||||
}
|
||||
}
|
||||
},
|
||||
Entry::Occupied(entry) => {
|
||||
if entry.get().is_flagged() {
|
||||
return TorrentStats::TorrentFlagged;
|
||||
}
|
||||
entry.into_mut()
|
||||
},
|
||||
};
|
||||
|
||||
torrent_entry.update_peer(peer_id, remote_address, uploaded, downloaded, left, event);
|
||||
|
||||
let (seeders, complete, leechers) = torrent_entry.get_stats();
|
||||
|
||||
return TorrentStats::Stats {
|
||||
seeders,
|
||||
leechers,
|
||||
complete,
|
||||
};
|
||||
}
|
||||
|
||||
pub (crate) fn get_database(&self) -> std::sync::RwLockReadGuard<std::collections::BTreeMap<InfoHash, TorrentEntry>>{
|
||||
self.database.torrent_peers.read().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn is_sync<T: Sync>() {}
|
||||
fn is_send<T: Send>() {}
|
||||
|
||||
#[test]
|
||||
fn tracker_send() {
|
||||
is_send::<TorrentTracker>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tracker_sync() {
|
||||
is_sync::<TorrentTracker>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ih2hex() {
|
||||
let ih: InfoHash = [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0xa,
|
||||
0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0xff];
|
||||
assert!(ih.to_hex() == "0102030405060708090a0b0c0d0e0f10111213ff");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex2ih() {
|
||||
let ih = InfoHash::from_hex("0102030405060708090a0b0c0d0e0f10111213ff").unwrap();
|
||||
assert_eq!(ih, [1u8, 2, 3, 4, 5, 6, 7, 8, 9, 0xa,
|
||||
0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0xff]);
|
||||
}
|
||||
}
|
277
src/webserver.rs
Normal file
277
src/webserver.rs
Normal file
|
@ -0,0 +1,277 @@
|
|||
use std;
|
||||
use hyper;
|
||||
use futures::Future;
|
||||
use futures::future::FutureResult;
|
||||
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use tracker;
|
||||
use tracker::TorrentTracker;
|
||||
|
||||
enum APIError {
|
||||
NoSuchMethod,
|
||||
BadAPICall,
|
||||
NotFound,
|
||||
InvalidAccessToken,
|
||||
}
|
||||
|
||||
struct WebApplication {
|
||||
tracker: std::sync::Arc<TorrentTracker>,
|
||||
token: std::sync::Arc<String>,
|
||||
}
|
||||
|
||||
impl std::error::Error for APIError {}
|
||||
|
||||
use std::fmt;
|
||||
impl fmt::Debug for APIError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", "Hello world!")
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for APIError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", "Hello world!")
|
||||
}
|
||||
}
|
||||
|
||||
impl WebApplication {
|
||||
pub fn new(tracker: std::sync::Arc<TorrentTracker>, token: String) -> WebApplication {
|
||||
WebApplication{
|
||||
tracker,
|
||||
token: std::sync::Arc::new(token),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_root(&self, request: &hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, APIError> {
|
||||
Ok(hyper::Response::new(hyper::Body::from("<a href=\"https://naim94a.github.io/udpt\">https://naim94a.github.io/udpt</a>")))
|
||||
}
|
||||
|
||||
fn handle_announce(&self, request: &hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, APIError> {
|
||||
Err(APIError::NoSuchMethod)
|
||||
}
|
||||
|
||||
fn handle_scrape(&self, request: &hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, APIError> {
|
||||
Err(APIError::NoSuchMethod)
|
||||
}
|
||||
|
||||
fn handle_stats(&self, request: &hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, APIError> {
|
||||
Err(APIError::NoSuchMethod)
|
||||
}
|
||||
|
||||
fn parse_query(query: &str) -> std::collections::HashMap<&str, &str> {
|
||||
let mut res = std::collections::HashMap::new();
|
||||
|
||||
let mut pair_start = 0;
|
||||
|
||||
loop {
|
||||
let remaining = &query[pair_start..];
|
||||
let pair_len = match remaining.find("&") {
|
||||
Some(v) => v,
|
||||
None => remaining.len(),
|
||||
};
|
||||
|
||||
let pair_str = &remaining[..pair_len];
|
||||
|
||||
{
|
||||
let key_end = match pair_str.find("=") {
|
||||
Some(v) => v,
|
||||
None => pair_str.len(),
|
||||
};
|
||||
|
||||
let mut val_start = key_end + 1;
|
||||
if val_start > pair_str.len() {
|
||||
val_start = pair_str.len();
|
||||
}
|
||||
|
||||
res.insert(&pair_str[..key_end], &pair_str[val_start..]);
|
||||
}
|
||||
|
||||
pair_start += pair_len + 1;
|
||||
|
||||
if pair_start >= query.len() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
fn handle_api(&self, request: &hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, APIError> {
|
||||
// before processing request, check client's access.
|
||||
let partial = &request.uri().path()[4..]; // slice "/api" out...
|
||||
|
||||
if partial == "/torrents" {
|
||||
if let Some(q) = request.uri().query() {
|
||||
let parsed_query = Self::parse_query(q);
|
||||
match parsed_query.get("token") {
|
||||
Some(&token) => {
|
||||
if token != self.token.as_str() {
|
||||
return Err(APIError::InvalidAccessToken);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(APIError::InvalidAccessToken);
|
||||
}
|
||||
}
|
||||
|
||||
let action = match parsed_query.get("action") {
|
||||
Some(&v) => v,
|
||||
None => {
|
||||
return Err(APIError::BadAPICall);
|
||||
}
|
||||
};
|
||||
if action == "list" {
|
||||
let mut response = String::from("[");
|
||||
let mut idx = 0;
|
||||
|
||||
let db = self.tracker.get_database();
|
||||
for (info_hash, entry) in db.iter() {
|
||||
use tracker::HexConv;
|
||||
|
||||
if idx > 0 {
|
||||
response += ", ";
|
||||
}
|
||||
response += "{\"info_hash\":\"";
|
||||
response += info_hash.to_hex().as_str();
|
||||
response += "\"}";
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
response += "]";
|
||||
|
||||
return Ok(hyper::Response::new(hyper::Body::from(response)));
|
||||
} else if action == "add" {
|
||||
use tracker::HexConv;
|
||||
let info_hash: tracker::InfoHash = match parsed_query.get("info_hash") {
|
||||
Some(&v) => {
|
||||
match tracker::InfoHash::from_hex(v) {
|
||||
Some(ih) => ih,
|
||||
None => {
|
||||
return Err(APIError::BadAPICall);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(APIError::BadAPICall);
|
||||
}
|
||||
};
|
||||
|
||||
match self.tracker.add_torrent(&info_hash) {
|
||||
Ok(_) => {
|
||||
return Ok(hyper::Response::new(hyper::Body::from("{\"ok\": 1}")));
|
||||
},
|
||||
Err(_) => {
|
||||
let mut resp = hyper::Response::new(hyper::Body::from("{\"ok\": 0}"));
|
||||
*resp.status_mut() = hyper::StatusCode::NOT_FOUND;
|
||||
return Ok(resp);
|
||||
}
|
||||
}
|
||||
} else if action == "remove" {
|
||||
use tracker::HexConv;
|
||||
let info_hash: tracker::InfoHash = match parsed_query.get("info_hash") {
|
||||
Some(&v) => {
|
||||
match tracker::InfoHash::from_hex(v) {
|
||||
Some(ih) => ih,
|
||||
None => {
|
||||
return Err(APIError::BadAPICall);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(APIError::BadAPICall);
|
||||
}
|
||||
};
|
||||
|
||||
match self.tracker.remove_torrent(&info_hash, true) {
|
||||
Ok(_) => {
|
||||
return Ok(hyper::Response::new(hyper::Body::from("{\"ok\": 1}")));
|
||||
},
|
||||
Err(_) => {
|
||||
let mut resp = hyper::Response::new(hyper::Body::from("{\"ok\": 0}"));
|
||||
*resp.status_mut() = hyper::StatusCode::NOT_FOUND;
|
||||
return Ok(resp);
|
||||
}
|
||||
};
|
||||
|
||||
} else if action == "info" {
|
||||
|
||||
} else {
|
||||
return Err(APIError::NoSuchMethod);
|
||||
}
|
||||
} else {
|
||||
return Err(APIError::BadAPICall);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Err(APIError::NoSuchMethod);
|
||||
}
|
||||
|
||||
Ok(hyper::Response::new(hyper::Body::from("api")))
|
||||
}
|
||||
|
||||
pub fn handle_request(&mut self, request: &hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, APIError> {
|
||||
if request.uri().path() == "/" {
|
||||
return self.handle_root(request);
|
||||
} else if request.uri().path() == "/announce" {
|
||||
return self.handle_announce(request);
|
||||
} else if request.uri().path() == "/scrape" {
|
||||
return self.handle_scrape(request);
|
||||
} else if request.uri().path() == "/stats" {
|
||||
return self.handle_stats(request);
|
||||
} else if request.uri().path().starts_with("/api") {
|
||||
return self.handle_api(request);
|
||||
} else {
|
||||
Ok(hyper::Response::new(hyper::Body::from("Invalid url")))
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_error(req: &hyper::Request<hyper::Body>, err: &APIError) -> hyper::Response<hyper::Body> {
|
||||
hyper::Response::new(hyper::Body::from("Error report"))
|
||||
}
|
||||
}
|
||||
|
||||
impl hyper::service::Service for WebApplication {
|
||||
type ReqBody = hyper::Body;
|
||||
type ResBody = hyper::Body;
|
||||
type Error = APIError;
|
||||
type Future = FutureResult<hyper::Response<Self::ResBody>, Self::Error>;
|
||||
|
||||
fn call(&mut self, req: hyper::Request<Self::ReqBody>) -> Self::Future {
|
||||
use futures;
|
||||
|
||||
let mut res = match self.handle_request(&req) {
|
||||
Ok(res) => res,
|
||||
Err(err) => Self::handle_error(&req, &err),
|
||||
};
|
||||
|
||||
futures::future::ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl hyper::service::NewService for WebApplication {
|
||||
type ReqBody = hyper::Body;
|
||||
type ResBody = hyper::Body;
|
||||
type Error = APIError;
|
||||
type Service = Self;
|
||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||
type InitError = hyper::Error;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
use futures;
|
||||
|
||||
futures::future::ok(WebApplication{
|
||||
tracker: self.tracker.clone(),
|
||||
token: self.token.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_server(addr: SocketAddr, tracker: std::sync::Arc<TorrentTracker>, token: &str) {
|
||||
let svc = WebApplication::new(tracker, String::from(token));
|
||||
let server = hyper::Server::bind(&addr).serve( svc);
|
||||
|
||||
hyper::rt::run(server.map_err(|_e|{
|
||||
println!("error: {}", _e);
|
||||
}));
|
||||
}
|
Loading…
Reference in a new issue