├── .editorconfig ├── .gitignore ├── .travis.yml ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src ├── application.rs ├── assets ├── LICENSE.md ├── UTF-8-demo.txt ├── angry_ascii.txt ├── forms-post.html ├── images │ ├── jackal.jpg │ ├── pig_icon.png │ ├── svg_logo.svg │ └── wolf_1.webp ├── index.html ├── links.html ├── moby.html └── sample.xml ├── handlers ├── auth.rs ├── cookies.rs ├── dynamic │ ├── bytes.rs │ ├── delay.rs │ ├── drip.rs │ ├── mod.rs │ ├── range.rs │ ├── stream.rs │ └── stream_bytes.rs ├── formats.rs ├── images.rs ├── methods.rs ├── mod.rs ├── redirects.rs ├── request.rs ├── response.rs └── statuses.rs ├── main.rs ├── map.rs ├── middleware.rs ├── response ├── errors.rs ├── formatters │ ├── bytes.rs │ ├── json.rs │ ├── json_value.rs │ ├── mod.rs │ └── response.rs ├── mod.rs └── modifiers │ ├── args.rs │ ├── extra.rs │ ├── headers.rs │ ├── method.rs │ ├── mod.rs │ ├── origin.rs │ ├── url.rs │ └── user_agent.rs └── templates.rs /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | [*] 3 | end_of_line = lf 4 | insert_final_newline = true 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | local_docker.sh 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | - beta 5 | - nightly 6 | matrix: 7 | allow_failures: 8 | - rust: nightly 9 | 10 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "actix" 3 | version = "0.5.6" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | dependencies = [ 6 | "actix_derive 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 8 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "crossbeam-channel 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 11 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 12 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 13 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "skeptic 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 17 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 18 | "tokio-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 19 | "trust-dns-resolver 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 20 | "uuid 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 21 | ] 22 | 23 | [[package]] 24 | name = "actix-httpbin" 25 | version = "0.1.0" 26 | dependencies = [ 27 | "actix-web 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 28 | "actix-web-httpauth 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 29 | "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 30 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 31 | "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", 32 | "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", 33 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 34 | "http 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 35 | "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 36 | "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 37 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 38 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 39 | "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 40 | "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 41 | "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 42 | "tera 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", 43 | "tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 44 | "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 45 | "uuid 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 46 | ] 47 | 48 | [[package]] 49 | name = "actix-web" 50 | version = "0.6.10" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | dependencies = [ 53 | "actix 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", 54 | "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 55 | "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 56 | "brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 57 | "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 58 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 59 | "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 60 | "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 61 | "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 62 | "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 63 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 64 | "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 65 | "h2 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 66 | "http 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 67 | "http-range 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 68 | "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", 69 | "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 70 | "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 71 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 72 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 73 | "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 74 | "mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", 75 | "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 76 | "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 77 | "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 78 | "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 79 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 80 | "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 81 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 82 | "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 83 | "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 84 | "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 85 | "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 86 | "smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 87 | "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", 88 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 89 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 90 | "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 91 | "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 92 | ] 93 | 94 | [[package]] 95 | name = "actix-web-httpauth" 96 | version = "0.0.3" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | dependencies = [ 99 | "actix-web 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", 100 | "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 101 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 102 | ] 103 | 104 | [[package]] 105 | name = "actix_derive" 106 | version = "0.2.0" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | dependencies = [ 109 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 110 | "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", 111 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 112 | "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 113 | ] 114 | 115 | [[package]] 116 | name = "aho-corasick" 117 | version = "0.6.4" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | dependencies = [ 120 | "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 121 | ] 122 | 123 | [[package]] 124 | name = "arrayvec" 125 | version = "0.4.7" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | dependencies = [ 128 | "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 129 | ] 130 | 131 | [[package]] 132 | name = "atty" 133 | version = "0.2.10" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | dependencies = [ 136 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 137 | "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 138 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 139 | ] 140 | 141 | [[package]] 142 | name = "backtrace" 143 | version = "0.2.3" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | dependencies = [ 146 | "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 147 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 148 | "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 149 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 150 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 151 | "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 152 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 153 | ] 154 | 155 | [[package]] 156 | name = "backtrace" 157 | version = "0.3.6" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | dependencies = [ 160 | "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 161 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 162 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 163 | "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 164 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 165 | ] 166 | 167 | [[package]] 168 | name = "backtrace-sys" 169 | version = "0.1.16" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | dependencies = [ 172 | "cc 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", 173 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 174 | ] 175 | 176 | [[package]] 177 | name = "base64" 178 | version = "0.6.0" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | dependencies = [ 181 | "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 182 | "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 183 | ] 184 | 185 | [[package]] 186 | name = "base64" 187 | version = "0.9.1" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | dependencies = [ 190 | "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 191 | "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 192 | ] 193 | 194 | [[package]] 195 | name = "bitflags" 196 | version = "0.9.1" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | 199 | [[package]] 200 | name = "bitflags" 201 | version = "1.0.2" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | 204 | [[package]] 205 | name = "brotli-sys" 206 | version = "0.3.2" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | dependencies = [ 209 | "cc 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", 210 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 211 | ] 212 | 213 | [[package]] 214 | name = "brotli2" 215 | version = "0.3.2" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | dependencies = [ 218 | "brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 219 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 220 | ] 221 | 222 | [[package]] 223 | name = "bytecount" 224 | version = "0.2.0" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | 227 | [[package]] 228 | name = "byteorder" 229 | version = "1.2.2" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | 232 | [[package]] 233 | name = "bytes" 234 | version = "0.4.7" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | dependencies = [ 237 | "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 238 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 239 | ] 240 | 241 | [[package]] 242 | name = "cargo_metadata" 243 | version = "0.3.3" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | dependencies = [ 246 | "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 247 | "semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 248 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 249 | "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 250 | "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 251 | ] 252 | 253 | [[package]] 254 | name = "cc" 255 | version = "1.0.13" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | 258 | [[package]] 259 | name = "cfg-if" 260 | version = "0.1.2" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | 263 | [[package]] 264 | name = "chrono" 265 | version = "0.4.2" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | dependencies = [ 268 | "num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", 269 | "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", 270 | "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", 271 | ] 272 | 273 | [[package]] 274 | name = "clap" 275 | version = "2.31.2" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | dependencies = [ 278 | "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 279 | "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 280 | "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 281 | ] 282 | 283 | [[package]] 284 | name = "cookie" 285 | version = "0.10.1" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | dependencies = [ 288 | "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 289 | "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", 290 | "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", 291 | "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 292 | ] 293 | 294 | [[package]] 295 | name = "crossbeam-channel" 296 | version = "0.1.2" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | dependencies = [ 299 | "crossbeam-epoch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 300 | "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 301 | "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 302 | ] 303 | 304 | [[package]] 305 | name = "crossbeam-deque" 306 | version = "0.2.0" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | dependencies = [ 309 | "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 310 | "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 311 | ] 312 | 313 | [[package]] 314 | name = "crossbeam-deque" 315 | version = "0.3.0" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | dependencies = [ 318 | "crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 319 | "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 320 | ] 321 | 322 | [[package]] 323 | name = "crossbeam-epoch" 324 | version = "0.2.0" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | dependencies = [ 327 | "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 328 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 329 | "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 330 | "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 331 | "memoffset 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 332 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 333 | ] 334 | 335 | [[package]] 336 | name = "crossbeam-epoch" 337 | version = "0.3.1" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | dependencies = [ 340 | "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 341 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 342 | "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 343 | "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 344 | "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 345 | "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 346 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 347 | ] 348 | 349 | [[package]] 350 | name = "crossbeam-epoch" 351 | version = "0.4.1" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | dependencies = [ 354 | "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 355 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 356 | "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 357 | "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 358 | "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 359 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 360 | ] 361 | 362 | [[package]] 363 | name = "crossbeam-utils" 364 | version = "0.2.2" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | dependencies = [ 367 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 368 | ] 369 | 370 | [[package]] 371 | name = "crossbeam-utils" 372 | version = "0.3.2" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | dependencies = [ 375 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 376 | ] 377 | 378 | [[package]] 379 | name = "dbghelp-sys" 380 | version = "0.2.0" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | dependencies = [ 383 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 384 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 385 | ] 386 | 387 | [[package]] 388 | name = "dtoa" 389 | version = "0.4.2" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | 392 | [[package]] 393 | name = "encoding" 394 | version = "0.2.33" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | dependencies = [ 397 | "encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", 398 | "encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", 399 | "encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", 400 | "encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", 401 | "encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", 402 | ] 403 | 404 | [[package]] 405 | name = "encoding-index-japanese" 406 | version = "1.20141219.5" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | dependencies = [ 409 | "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 410 | ] 411 | 412 | [[package]] 413 | name = "encoding-index-korean" 414 | version = "1.20141219.5" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | dependencies = [ 417 | "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 418 | ] 419 | 420 | [[package]] 421 | name = "encoding-index-simpchinese" 422 | version = "1.20141219.5" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | dependencies = [ 425 | "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 426 | ] 427 | 428 | [[package]] 429 | name = "encoding-index-singlebyte" 430 | version = "1.20141219.5" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | dependencies = [ 433 | "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 434 | ] 435 | 436 | [[package]] 437 | name = "encoding-index-tradchinese" 438 | version = "1.20141219.5" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | dependencies = [ 441 | "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 442 | ] 443 | 444 | [[package]] 445 | name = "encoding_index_tests" 446 | version = "0.1.4" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | 449 | [[package]] 450 | name = "env_logger" 451 | version = "0.5.10" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | dependencies = [ 454 | "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 455 | "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 456 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 457 | "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 458 | "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 459 | ] 460 | 461 | [[package]] 462 | name = "error-chain" 463 | version = "0.1.12" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | dependencies = [ 466 | "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 467 | ] 468 | 469 | [[package]] 470 | name = "error-chain" 471 | version = "0.8.1" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | dependencies = [ 474 | "backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 475 | ] 476 | 477 | [[package]] 478 | name = "error-chain" 479 | version = "0.11.0" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | dependencies = [ 482 | "backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 483 | ] 484 | 485 | [[package]] 486 | name = "failure" 487 | version = "0.1.1" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | dependencies = [ 490 | "backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 491 | "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 492 | ] 493 | 494 | [[package]] 495 | name = "failure_derive" 496 | version = "0.1.1" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | dependencies = [ 499 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 500 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 501 | "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 502 | ] 503 | 504 | [[package]] 505 | name = "flate2" 506 | version = "1.0.1" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | dependencies = [ 509 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 510 | "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 511 | ] 512 | 513 | [[package]] 514 | name = "fnv" 515 | version = "1.0.6" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | 518 | [[package]] 519 | name = "fuchsia-zircon" 520 | version = "0.3.3" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | dependencies = [ 523 | "bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 524 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 525 | ] 526 | 527 | [[package]] 528 | name = "fuchsia-zircon-sys" 529 | version = "0.3.3" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | 532 | [[package]] 533 | name = "futures" 534 | version = "0.1.21" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | 537 | [[package]] 538 | name = "futures-cpupool" 539 | version = "0.1.8" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | dependencies = [ 542 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 543 | "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 544 | ] 545 | 546 | [[package]] 547 | name = "gcc" 548 | version = "0.3.54" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | 551 | [[package]] 552 | name = "glob" 553 | version = "0.2.11" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | 556 | [[package]] 557 | name = "h2" 558 | version = "0.1.6" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | dependencies = [ 561 | "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 562 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 563 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 564 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 565 | "http 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 566 | "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 567 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 568 | "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 569 | "string 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 570 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 571 | ] 572 | 573 | [[package]] 574 | name = "hostname" 575 | version = "0.1.4" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | dependencies = [ 578 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 579 | "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 580 | ] 581 | 582 | [[package]] 583 | name = "http" 584 | version = "0.1.5" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | dependencies = [ 587 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 588 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 589 | ] 590 | 591 | [[package]] 592 | name = "http-range" 593 | version = "0.1.1" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | 596 | [[package]] 597 | name = "httparse" 598 | version = "1.2.4" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | 601 | [[package]] 602 | name = "humansize" 603 | version = "1.1.0" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | 606 | [[package]] 607 | name = "humantime" 608 | version = "1.1.1" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | dependencies = [ 611 | "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 612 | ] 613 | 614 | [[package]] 615 | name = "idna" 616 | version = "0.1.4" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | dependencies = [ 619 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 620 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 621 | "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 622 | ] 623 | 624 | [[package]] 625 | name = "indexmap" 626 | version = "1.0.1" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | 629 | [[package]] 630 | name = "iovec" 631 | version = "0.1.2" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | dependencies = [ 634 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 635 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 636 | ] 637 | 638 | [[package]] 639 | name = "ipconfig" 640 | version = "0.1.6" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | dependencies = [ 643 | "error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 644 | "socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 645 | "widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 646 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 647 | "winreg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 648 | ] 649 | 650 | [[package]] 651 | name = "itoa" 652 | version = "0.3.4" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | 655 | [[package]] 656 | name = "itoa" 657 | version = "0.4.1" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | 660 | [[package]] 661 | name = "kernel32-sys" 662 | version = "0.2.2" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | dependencies = [ 665 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 666 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 667 | ] 668 | 669 | [[package]] 670 | name = "language-tags" 671 | version = "0.2.2" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | 674 | [[package]] 675 | name = "lazy_static" 676 | version = "0.2.11" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | 679 | [[package]] 680 | name = "lazy_static" 681 | version = "1.0.0" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | 684 | [[package]] 685 | name = "lazycell" 686 | version = "0.6.0" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | 689 | [[package]] 690 | name = "libc" 691 | version = "0.2.40" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | 694 | [[package]] 695 | name = "linked-hash-map" 696 | version = "0.4.2" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | 699 | [[package]] 700 | name = "linked-hash-map" 701 | version = "0.5.1" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | dependencies = [ 704 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 705 | "serde_test 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 706 | ] 707 | 708 | [[package]] 709 | name = "log" 710 | version = "0.4.1" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | dependencies = [ 713 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 714 | ] 715 | 716 | [[package]] 717 | name = "lru-cache" 718 | version = "0.1.1" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | dependencies = [ 721 | "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 722 | ] 723 | 724 | [[package]] 725 | name = "matches" 726 | version = "0.1.6" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | 729 | [[package]] 730 | name = "memchr" 731 | version = "2.0.1" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | dependencies = [ 734 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 735 | ] 736 | 737 | [[package]] 738 | name = "memoffset" 739 | version = "0.1.0" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | 742 | [[package]] 743 | name = "memoffset" 744 | version = "0.2.1" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | 747 | [[package]] 748 | name = "mime" 749 | version = "0.3.7" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | dependencies = [ 752 | "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 753 | ] 754 | 755 | [[package]] 756 | name = "mime_guess" 757 | version = "2.0.0-alpha.4" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | dependencies = [ 760 | "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 761 | "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 762 | "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 763 | "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 764 | ] 765 | 766 | [[package]] 767 | name = "miniz-sys" 768 | version = "0.1.10" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | dependencies = [ 771 | "cc 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", 772 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 773 | ] 774 | 775 | [[package]] 776 | name = "mio" 777 | version = "0.6.14" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | dependencies = [ 780 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 781 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 782 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 783 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 784 | "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 785 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 786 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 787 | "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 788 | "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 789 | "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 790 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 791 | ] 792 | 793 | [[package]] 794 | name = "mio-uds" 795 | version = "0.6.4" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | dependencies = [ 798 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 799 | "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 800 | ] 801 | 802 | [[package]] 803 | name = "miow" 804 | version = "0.2.1" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | dependencies = [ 807 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 808 | "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", 809 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 810 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 811 | ] 812 | 813 | [[package]] 814 | name = "net2" 815 | version = "0.2.32" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | dependencies = [ 818 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 819 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 820 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 821 | ] 822 | 823 | [[package]] 824 | name = "nodrop" 825 | version = "0.1.12" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | 828 | [[package]] 829 | name = "num-integer" 830 | version = "0.1.38" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | dependencies = [ 833 | "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", 834 | ] 835 | 836 | [[package]] 837 | name = "num-traits" 838 | version = "0.2.4" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | 841 | [[package]] 842 | name = "num_cpus" 843 | version = "1.8.0" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | dependencies = [ 846 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 847 | ] 848 | 849 | [[package]] 850 | name = "owning_ref" 851 | version = "0.3.3" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | dependencies = [ 854 | "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 855 | ] 856 | 857 | [[package]] 858 | name = "parking_lot" 859 | version = "0.4.8" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | dependencies = [ 862 | "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 863 | "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", 864 | ] 865 | 866 | [[package]] 867 | name = "parking_lot_core" 868 | version = "0.2.14" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | dependencies = [ 871 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 872 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 873 | "smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 874 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 875 | ] 876 | 877 | [[package]] 878 | name = "percent-encoding" 879 | version = "1.0.1" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | 882 | [[package]] 883 | name = "pest" 884 | version = "1.0.6" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | 887 | [[package]] 888 | name = "pest_derive" 889 | version = "1.0.7" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | dependencies = [ 892 | "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 893 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 894 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 895 | ] 896 | 897 | [[package]] 898 | name = "phf" 899 | version = "0.7.21" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | dependencies = [ 902 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 903 | ] 904 | 905 | [[package]] 906 | name = "phf_codegen" 907 | version = "0.7.21" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | dependencies = [ 910 | "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 911 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 912 | ] 913 | 914 | [[package]] 915 | name = "phf_generator" 916 | version = "0.7.21" 917 | source = "registry+https://github.com/rust-lang/crates.io-index" 918 | dependencies = [ 919 | "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", 920 | "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", 921 | ] 922 | 923 | [[package]] 924 | name = "phf_shared" 925 | version = "0.7.21" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | dependencies = [ 928 | "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 929 | "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 930 | ] 931 | 932 | [[package]] 933 | name = "proc-macro2" 934 | version = "0.3.7" 935 | source = "registry+https://github.com/rust-lang/crates.io-index" 936 | dependencies = [ 937 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 938 | ] 939 | 940 | [[package]] 941 | name = "pulldown-cmark" 942 | version = "0.1.2" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | dependencies = [ 945 | "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 946 | ] 947 | 948 | [[package]] 949 | name = "quick-error" 950 | version = "1.2.1" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | 953 | [[package]] 954 | name = "quote" 955 | version = "0.3.15" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | 958 | [[package]] 959 | name = "quote" 960 | version = "0.5.2" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | dependencies = [ 963 | "proc-macro2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 964 | ] 965 | 966 | [[package]] 967 | name = "rand" 968 | version = "0.3.22" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | dependencies = [ 971 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 972 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 973 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 974 | ] 975 | 976 | [[package]] 977 | name = "rand" 978 | version = "0.4.2" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | dependencies = [ 981 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 982 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 983 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 984 | ] 985 | 986 | [[package]] 987 | name = "rayon" 988 | version = "0.8.2" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | dependencies = [ 991 | "rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 992 | ] 993 | 994 | [[package]] 995 | name = "rayon-core" 996 | version = "1.4.0" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | dependencies = [ 999 | "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1000 | "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1001 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 1002 | "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1003 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "redox_syscall" 1008 | version = "0.1.37" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | 1011 | [[package]] 1012 | name = "redox_termios" 1013 | version = "0.1.1" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | dependencies = [ 1016 | "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 1017 | ] 1018 | 1019 | [[package]] 1020 | name = "regex" 1021 | version = "0.2.11" 1022 | source = "registry+https://github.com/rust-lang/crates.io-index" 1023 | dependencies = [ 1024 | "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 1025 | "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1026 | "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", 1027 | "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 1028 | "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1029 | ] 1030 | 1031 | [[package]] 1032 | name = "regex" 1033 | version = "1.0.0" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | dependencies = [ 1036 | "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 1037 | "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1038 | "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 1039 | "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 1040 | "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1041 | ] 1042 | 1043 | [[package]] 1044 | name = "regex-syntax" 1045 | version = "0.5.6" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | dependencies = [ 1048 | "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1049 | ] 1050 | 1051 | [[package]] 1052 | name = "regex-syntax" 1053 | version = "0.6.0" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | dependencies = [ 1056 | "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1057 | ] 1058 | 1059 | [[package]] 1060 | name = "remove_dir_all" 1061 | version = "0.5.1" 1062 | source = "registry+https://github.com/rust-lang/crates.io-index" 1063 | dependencies = [ 1064 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "resolv-conf" 1069 | version = "0.6.0" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | dependencies = [ 1072 | "hostname 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1073 | "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "ring" 1078 | version = "0.12.1" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | dependencies = [ 1081 | "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", 1082 | "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1083 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 1084 | "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 1085 | "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1086 | ] 1087 | 1088 | [[package]] 1089 | name = "rustc-demangle" 1090 | version = "0.1.7" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | 1093 | [[package]] 1094 | name = "safemem" 1095 | version = "0.2.0" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | 1098 | [[package]] 1099 | name = "same-file" 1100 | version = "0.1.3" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | dependencies = [ 1103 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1104 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "scoped-tls" 1109 | version = "0.1.1" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | 1112 | [[package]] 1113 | name = "scopeguard" 1114 | version = "0.3.3" 1115 | source = "registry+https://github.com/rust-lang/crates.io-index" 1116 | 1117 | [[package]] 1118 | name = "semver" 1119 | version = "0.8.0" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | dependencies = [ 1122 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1123 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 1124 | ] 1125 | 1126 | [[package]] 1127 | name = "semver-parser" 1128 | version = "0.7.0" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | 1131 | [[package]] 1132 | name = "serde" 1133 | version = "1.0.43" 1134 | source = "registry+https://github.com/rust-lang/crates.io-index" 1135 | 1136 | [[package]] 1137 | name = "serde_derive" 1138 | version = "1.0.43" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | dependencies = [ 1141 | "proc-macro2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 1142 | "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1143 | "serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)", 1144 | "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", 1145 | ] 1146 | 1147 | [[package]] 1148 | name = "serde_derive_internals" 1149 | version = "0.23.1" 1150 | source = "registry+https://github.com/rust-lang/crates.io-index" 1151 | dependencies = [ 1152 | "proc-macro2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 1153 | "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", 1154 | ] 1155 | 1156 | [[package]] 1157 | name = "serde_json" 1158 | version = "1.0.16" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | dependencies = [ 1161 | "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1162 | "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 1163 | "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1164 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "serde_test" 1169 | version = "1.0.43" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | dependencies = [ 1172 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 1173 | ] 1174 | 1175 | [[package]] 1176 | name = "serde_urlencoded" 1177 | version = "0.5.1" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | dependencies = [ 1180 | "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1181 | "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 1182 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 1183 | "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1184 | ] 1185 | 1186 | [[package]] 1187 | name = "sha1" 1188 | version = "0.6.0" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | 1191 | [[package]] 1192 | name = "siphasher" 1193 | version = "0.2.2" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | 1196 | [[package]] 1197 | name = "skeptic" 1198 | version = "0.13.2" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | dependencies = [ 1201 | "bytecount 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1202 | "cargo_metadata 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 1203 | "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 1204 | "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1205 | "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1206 | "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 1207 | "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 1208 | "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "slab" 1213 | version = "0.4.0" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | 1216 | [[package]] 1217 | name = "slug" 1218 | version = "0.1.3" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | dependencies = [ 1221 | "unidecode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1222 | ] 1223 | 1224 | [[package]] 1225 | name = "smallvec" 1226 | version = "0.6.1" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | 1229 | [[package]] 1230 | name = "socket2" 1231 | version = "0.3.5" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | dependencies = [ 1234 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1235 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 1236 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 1237 | ] 1238 | 1239 | [[package]] 1240 | name = "stable_deref_trait" 1241 | version = "1.0.0" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | 1244 | [[package]] 1245 | name = "string" 1246 | version = "0.1.0" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | 1249 | [[package]] 1250 | name = "syn" 1251 | version = "0.11.11" 1252 | source = "registry+https://github.com/rust-lang/crates.io-index" 1253 | dependencies = [ 1254 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 1255 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 1256 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 1257 | ] 1258 | 1259 | [[package]] 1260 | name = "syn" 1261 | version = "0.13.1" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | dependencies = [ 1264 | "proc-macro2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 1265 | "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1266 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1267 | ] 1268 | 1269 | [[package]] 1270 | name = "synom" 1271 | version = "0.11.3" 1272 | source = "registry+https://github.com/rust-lang/crates.io-index" 1273 | dependencies = [ 1274 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 1275 | ] 1276 | 1277 | [[package]] 1278 | name = "synstructure" 1279 | version = "0.6.1" 1280 | source = "registry+https://github.com/rust-lang/crates.io-index" 1281 | dependencies = [ 1282 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 1283 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "tempdir" 1288 | version = "0.3.7" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | dependencies = [ 1291 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1292 | "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1293 | ] 1294 | 1295 | [[package]] 1296 | name = "tera" 1297 | version = "0.11.7" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | dependencies = [ 1300 | "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1301 | "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 1302 | "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1303 | "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1304 | "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1305 | "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1306 | "pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 1307 | "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1308 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 1309 | "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 1310 | "slug 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1311 | "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1312 | ] 1313 | 1314 | [[package]] 1315 | name = "termcolor" 1316 | version = "0.3.6" 1317 | source = "registry+https://github.com/rust-lang/crates.io-index" 1318 | dependencies = [ 1319 | "wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1320 | ] 1321 | 1322 | [[package]] 1323 | name = "termion" 1324 | version = "1.5.1" 1325 | source = "registry+https://github.com/rust-lang/crates.io-index" 1326 | dependencies = [ 1327 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 1328 | "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 1329 | "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1330 | ] 1331 | 1332 | [[package]] 1333 | name = "textwrap" 1334 | version = "0.9.0" 1335 | source = "registry+https://github.com/rust-lang/crates.io-index" 1336 | dependencies = [ 1337 | "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1338 | ] 1339 | 1340 | [[package]] 1341 | name = "thread_local" 1342 | version = "0.3.5" 1343 | source = "registry+https://github.com/rust-lang/crates.io-index" 1344 | dependencies = [ 1345 | "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1346 | "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1347 | ] 1348 | 1349 | [[package]] 1350 | name = "time" 1351 | version = "0.1.39" 1352 | source = "registry+https://github.com/rust-lang/crates.io-index" 1353 | dependencies = [ 1354 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 1355 | "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 1356 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 1357 | ] 1358 | 1359 | [[package]] 1360 | name = "tokio" 1361 | version = "0.1.5" 1362 | source = "registry+https://github.com/rust-lang/crates.io-index" 1363 | dependencies = [ 1364 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1365 | "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 1366 | "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1367 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1368 | "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1369 | "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1370 | "tokio-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1371 | "tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1372 | "tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1373 | ] 1374 | 1375 | [[package]] 1376 | name = "tokio-core" 1377 | version = "0.1.17" 1378 | source = "registry+https://github.com/rust-lang/crates.io-index" 1379 | dependencies = [ 1380 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 1381 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1382 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1383 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 1384 | "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 1385 | "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1386 | "tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1387 | "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1388 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1389 | "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1390 | "tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1391 | ] 1392 | 1393 | [[package]] 1394 | name = "tokio-executor" 1395 | version = "0.1.2" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | dependencies = [ 1398 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1399 | ] 1400 | 1401 | [[package]] 1402 | name = "tokio-io" 1403 | version = "0.1.6" 1404 | source = "registry+https://github.com/rust-lang/crates.io-index" 1405 | dependencies = [ 1406 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 1407 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1408 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 1409 | ] 1410 | 1411 | [[package]] 1412 | name = "tokio-reactor" 1413 | version = "0.1.1" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | dependencies = [ 1416 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1417 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 1418 | "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 1419 | "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1420 | "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1421 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1422 | ] 1423 | 1424 | [[package]] 1425 | name = "tokio-signal" 1426 | version = "0.1.5" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | dependencies = [ 1429 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1430 | "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", 1431 | "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 1432 | "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 1433 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 1434 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1435 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 1436 | ] 1437 | 1438 | [[package]] 1439 | name = "tokio-tcp" 1440 | version = "0.1.0" 1441 | source = "registry+https://github.com/rust-lang/crates.io-index" 1442 | dependencies = [ 1443 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 1444 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1445 | "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1446 | "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 1447 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1448 | "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1449 | ] 1450 | 1451 | [[package]] 1452 | name = "tokio-threadpool" 1453 | version = "0.1.2" 1454 | source = "registry+https://github.com/rust-lang/crates.io-index" 1455 | dependencies = [ 1456 | "crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1457 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1458 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 1459 | "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1460 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1461 | "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "tokio-timer" 1466 | version = "0.2.1" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | dependencies = [ 1469 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1470 | "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1471 | ] 1472 | 1473 | [[package]] 1474 | name = "tokio-udp" 1475 | version = "0.1.0" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | dependencies = [ 1478 | "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 1479 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1480 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 1481 | "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 1482 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1483 | "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1484 | ] 1485 | 1486 | [[package]] 1487 | name = "trust-dns-proto" 1488 | version = "0.3.3" 1489 | source = "registry+https://github.com/rust-lang/crates.io-index" 1490 | dependencies = [ 1491 | "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1492 | "error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 1493 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1494 | "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1495 | "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1496 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 1497 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1498 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 1499 | "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1500 | "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1501 | ] 1502 | 1503 | [[package]] 1504 | name = "trust-dns-resolver" 1505 | version = "0.8.2" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | dependencies = [ 1508 | "error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 1509 | "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1510 | "ipconfig 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1511 | "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1512 | "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 1513 | "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1514 | "resolv-conf 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 1515 | "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 1516 | "trust-dns-proto 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "ucd-util" 1521 | version = "0.1.1" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | 1524 | [[package]] 1525 | name = "unicase" 1526 | version = "1.4.2" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | dependencies = [ 1529 | "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1530 | ] 1531 | 1532 | [[package]] 1533 | name = "unicase" 1534 | version = "2.1.0" 1535 | source = "registry+https://github.com/rust-lang/crates.io-index" 1536 | dependencies = [ 1537 | "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1538 | ] 1539 | 1540 | [[package]] 1541 | name = "unicode-bidi" 1542 | version = "0.3.4" 1543 | source = "registry+https://github.com/rust-lang/crates.io-index" 1544 | dependencies = [ 1545 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1546 | ] 1547 | 1548 | [[package]] 1549 | name = "unicode-normalization" 1550 | version = "0.1.5" 1551 | source = "registry+https://github.com/rust-lang/crates.io-index" 1552 | 1553 | [[package]] 1554 | name = "unicode-width" 1555 | version = "0.1.4" 1556 | source = "registry+https://github.com/rust-lang/crates.io-index" 1557 | 1558 | [[package]] 1559 | name = "unicode-xid" 1560 | version = "0.0.4" 1561 | source = "registry+https://github.com/rust-lang/crates.io-index" 1562 | 1563 | [[package]] 1564 | name = "unicode-xid" 1565 | version = "0.1.0" 1566 | source = "registry+https://github.com/rust-lang/crates.io-index" 1567 | 1568 | [[package]] 1569 | name = "unidecode" 1570 | version = "0.3.0" 1571 | source = "registry+https://github.com/rust-lang/crates.io-index" 1572 | 1573 | [[package]] 1574 | name = "unreachable" 1575 | version = "1.0.0" 1576 | source = "registry+https://github.com/rust-lang/crates.io-index" 1577 | dependencies = [ 1578 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1579 | ] 1580 | 1581 | [[package]] 1582 | name = "untrusted" 1583 | version = "0.5.1" 1584 | source = "registry+https://github.com/rust-lang/crates.io-index" 1585 | 1586 | [[package]] 1587 | name = "url" 1588 | version = "1.7.0" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | dependencies = [ 1591 | "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 1592 | "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1593 | "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1594 | "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1595 | ] 1596 | 1597 | [[package]] 1598 | name = "utf8-ranges" 1599 | version = "1.0.0" 1600 | source = "registry+https://github.com/rust-lang/crates.io-index" 1601 | 1602 | [[package]] 1603 | name = "uuid" 1604 | version = "0.6.3" 1605 | source = "registry+https://github.com/rust-lang/crates.io-index" 1606 | dependencies = [ 1607 | "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1608 | "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1609 | "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "version_check" 1614 | version = "0.1.3" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | 1617 | [[package]] 1618 | name = "void" 1619 | version = "1.0.2" 1620 | source = "registry+https://github.com/rust-lang/crates.io-index" 1621 | 1622 | [[package]] 1623 | name = "walkdir" 1624 | version = "1.0.7" 1625 | source = "registry+https://github.com/rust-lang/crates.io-index" 1626 | dependencies = [ 1627 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1628 | "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1629 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1630 | ] 1631 | 1632 | [[package]] 1633 | name = "widestring" 1634 | version = "0.2.2" 1635 | source = "registry+https://github.com/rust-lang/crates.io-index" 1636 | 1637 | [[package]] 1638 | name = "winapi" 1639 | version = "0.2.8" 1640 | source = "registry+https://github.com/rust-lang/crates.io-index" 1641 | 1642 | [[package]] 1643 | name = "winapi" 1644 | version = "0.3.4" 1645 | source = "registry+https://github.com/rust-lang/crates.io-index" 1646 | dependencies = [ 1647 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1648 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1649 | ] 1650 | 1651 | [[package]] 1652 | name = "winapi-build" 1653 | version = "0.1.1" 1654 | source = "registry+https://github.com/rust-lang/crates.io-index" 1655 | 1656 | [[package]] 1657 | name = "winapi-i686-pc-windows-gnu" 1658 | version = "0.4.0" 1659 | source = "registry+https://github.com/rust-lang/crates.io-index" 1660 | 1661 | [[package]] 1662 | name = "winapi-x86_64-pc-windows-gnu" 1663 | version = "0.4.0" 1664 | source = "registry+https://github.com/rust-lang/crates.io-index" 1665 | 1666 | [[package]] 1667 | name = "wincolor" 1668 | version = "0.1.6" 1669 | source = "registry+https://github.com/rust-lang/crates.io-index" 1670 | dependencies = [ 1671 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 1672 | ] 1673 | 1674 | [[package]] 1675 | name = "winreg" 1676 | version = "0.5.0" 1677 | source = "registry+https://github.com/rust-lang/crates.io-index" 1678 | dependencies = [ 1679 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 1680 | ] 1681 | 1682 | [[package]] 1683 | name = "winutil" 1684 | version = "0.1.1" 1685 | source = "registry+https://github.com/rust-lang/crates.io-index" 1686 | dependencies = [ 1687 | "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 1688 | ] 1689 | 1690 | [[package]] 1691 | name = "ws2_32-sys" 1692 | version = "0.2.1" 1693 | source = "registry+https://github.com/rust-lang/crates.io-index" 1694 | dependencies = [ 1695 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1696 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1697 | ] 1698 | 1699 | [metadata] 1700 | "checksum actix 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e767e3170dc7cdec50fe1b74d22fd9d2f4b78b97b2052a254b5acb07dae68634" 1701 | "checksum actix-web 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "f3e8ee6c135276906d4af0a9a900ea7c230995e9328b44cd1a6d306918db47e4" 1702 | "checksum actix-web-httpauth 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56ddae68b376c7a9295169b75a40fb06efeafef7096516b5c3c82aca437adebf" 1703 | "checksum actix_derive 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b1dc922654b9aca7a8a31eab875fde804fa9fbd67f220f2e457787b23590f2" 1704 | "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" 1705 | "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" 1706 | "checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" 1707 | "checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" 1708 | "checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e" 1709 | "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" 1710 | "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" 1711 | "checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" 1712 | "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" 1713 | "checksum bitflags 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1b2bf7093258c32e0825b635948de528a5949799dcd61bef39534c8aab95870c" 1714 | "checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" 1715 | "checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" 1716 | "checksum bytecount 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af27422163679dea46a1a7239dffff64d3dcdc3ba5fe9c49c789fbfe0eb949de" 1717 | "checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" 1718 | "checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59" 1719 | "checksum cargo_metadata 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f56ec3e469bca7c276f2eea015aa05c5e381356febdbb0683c2580189604537" 1720 | "checksum cc 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "38fb45eeb2c9216a6700cf675b418d6c26ee15b55a3700970112da9fedfb8694" 1721 | "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" 1722 | "checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6" 1723 | "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" 1724 | "checksum cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "746858cae4eae40fff37e1998320068df317bc247dc91a67c6cfa053afdc2abb" 1725 | "checksum crossbeam-channel 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7b07a3084d8718d95338443d5a46aab38ce16d5f991d4027a0906b369f70a3" 1726 | "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" 1727 | "checksum crossbeam-deque 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bdc73742c36f7f35ebcda81dbb33a7e0d33757d03a06d9ddca762712ec5ea2" 1728 | "checksum crossbeam-epoch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9898f21d6d647793e163c804944941fb19aecd1f4a1a4c254bbb0bee15ccdea5" 1729 | "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" 1730 | "checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" 1731 | "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" 1732 | "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" 1733 | "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" 1734 | "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" 1735 | "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" 1736 | "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" 1737 | "checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" 1738 | "checksum encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" 1739 | "checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" 1740 | "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" 1741 | "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" 1742 | "checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" 1743 | "checksum error-chain 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faa976b4fd2e4c2b2f3f486874b19e61944d3de3de8b61c9fcf835d583871bcc" 1744 | "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" 1745 | "checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46" 1746 | "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" 1747 | "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" 1748 | "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909" 1749 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 1750 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 1751 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 1752 | "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" 1753 | "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" 1754 | "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" 1755 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 1756 | "checksum h2 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c91a0ee01fcf961ae004d88f1a77fc47dc5db6164f7d57605cc9f2c93d535686" 1757 | "checksum hostname 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "58fab6e177434b0bb4cd344a4dabaa5bd6d7a8d792b1885aebcae7af1091d1cb" 1758 | "checksum http 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "75df369fd52c60635208a4d3e694777c099569b3dcf4844df8f652dc004644ab" 1759 | "checksum http-range 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2e4003e6fd05ea9109db00415e670b11f511a42e567ff2d5d771cbdfa24e02" 1760 | "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" 1761 | "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" 1762 | "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" 1763 | "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" 1764 | "checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220" 1765 | "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" 1766 | "checksum ipconfig 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec4e18c0a0d4340870c14284293632d8421f419008371422dd327892b88877c" 1767 | "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" 1768 | "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" 1769 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1770 | "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" 1771 | "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" 1772 | "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" 1773 | "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" 1774 | "checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" 1775 | "checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" 1776 | "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" 1777 | "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" 1778 | "checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" 1779 | "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" 1780 | "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" 1781 | "checksum memoffset 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e163e5baece1a039e71e75b074de17a9b4114982aa109921fc20253bdf91a53c" 1782 | "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" 1783 | "checksum mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b28683d0b09bbc20be1c9b3f6f24854efb1356ffcffee08ea3f6e65596e85fa" 1784 | "checksum mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130ea3c9c1b65dba905ab5a4d9ac59234a9585c24d135f264e187fe7336febbd" 1785 | "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" 1786 | "checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" 1787 | "checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673" 1788 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1789 | "checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" 1790 | "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" 1791 | "checksum num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac0ea58d64a89d9d6b7688031b3be9358d6c919badcf7fbb0527ccfd891ee45" 1792 | "checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28" 1793 | "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" 1794 | "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" 1795 | "checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" 1796 | "checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" 1797 | "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1798 | "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" 1799 | "checksum pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ab94faafeb93f4c5e3ce81ca0e5a779529a602ad5d09ae6d21996bfb8b6a52bf" 1800 | "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" 1801 | "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" 1802 | "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" 1803 | "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" 1804 | "checksum proc-macro2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b16749538926f394755373f0dfec0852d79b3bd512a5906ceaeb72ee64a4eaa0" 1805 | "checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" 1806 | "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" 1807 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 1808 | "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" 1809 | "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" 1810 | "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" 1811 | "checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" 1812 | "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" 1813 | "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" 1814 | "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" 1815 | "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" 1816 | "checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3" 1817 | "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" 1818 | "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b" 1819 | "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" 1820 | "checksum resolv-conf 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e1b086bb6a2659d6ba66e4aa21bde8a53ec03587cd5c80b83bdc3a330f35cab" 1821 | "checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" 1822 | "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" 1823 | "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" 1824 | "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" 1825 | "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" 1826 | "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 1827 | "checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b" 1828 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1829 | "checksum serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "0c855d888276f20d140223bd06515e5bf1647fd6d02593cb5792466d9a8ec2d0" 1830 | "checksum serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "aa113e5fc4b008a626ba2bbd41330b56c9987d667f79f7b243e5a2d03d91ed1c" 1831 | "checksum serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d30c4596450fd7bbda79ef15559683f9a79ac0193ea819db90000d7e1cae794" 1832 | "checksum serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6c4e049dc657a99e394bd85c22acbf97356feeec6dbf44150f2dcf79fb3118" 1833 | "checksum serde_test 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b5dbca0b6cbcf8b006de17c7abba271508ce31420d6d7e3621427190bb7f8a" 1834 | "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" 1835 | "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" 1836 | "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" 1837 | "checksum skeptic 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c8431f8fca168e2db4be547bd8329eac70d095dff1444fee4b0fa0fabc7df75a" 1838 | "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" 1839 | "checksum slug 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "797bcb4d24e91239a8615415814f4afb2d8ca400c472de3c73f803a5a7689e11" 1840 | "checksum smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03dab98ab5ded3a8b43b2c80751194608d0b2aa0f1d46cf95d1c35e192844aa7" 1841 | "checksum socket2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ff606e0486e88f5fc6cfeb3966e434fb409abbc7a3ab495238f70a1ca97f789d" 1842 | "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" 1843 | "checksum string 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31f98b200e7caca9efca50fc0aa69cd58a5ec81d5f6e75b2f3ecaad2e998972a" 1844 | "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 1845 | "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" 1846 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 1847 | "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" 1848 | "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" 1849 | "checksum tera 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e815b67d44c26feb06630011fb58b5b243f4e9585aac1ed0592c5795de64cd75" 1850 | "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" 1851 | "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" 1852 | "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" 1853 | "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" 1854 | "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" 1855 | "checksum tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be15ef40f675c9fe66e354d74c73f3ed012ca1aa14d65846a33ee48f1ae8d922" 1856 | "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" 1857 | "checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" 1858 | "checksum tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af9eb326f64b2d6b68438e1953341e00ab3cf54de7e35d92bfc73af8555313a" 1859 | "checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" 1860 | "checksum tokio-signal 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f46863230f9a05cf52d173721ec391b9c5782a2465f593029922b8782b9ffe" 1861 | "checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" 1862 | "checksum tokio-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3d05cdd6a78005e535d2b27c21521bdf91fbb321027a62d8e178929d18966d" 1863 | "checksum tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29a89e4ad0c8f1e4c9860e605c38c69bfdad3cccd4ea446e58ff588c1c07a397" 1864 | "checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" 1865 | "checksum trust-dns-proto 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cbbddb93547eeee847367d8f59b68002294a7b4df31c143fbee4109ce0c61a04" 1866 | "checksum trust-dns-resolver 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9b0a0c9d4f8dd56481209c5ae1a8965ed022461d352c81fb92466ec9d846929e" 1867 | "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" 1868 | "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" 1869 | "checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" 1870 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1871 | "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" 1872 | "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" 1873 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 1874 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 1875 | "checksum unidecode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc" 1876 | "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 1877 | "checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" 1878 | "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" 1879 | "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" 1880 | "checksum uuid 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8630752f979f1b6b87c49830a5e3784082545de63920d59fbaac252474319447" 1881 | "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" 1882 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1883 | "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" 1884 | "checksum widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7157704c2e12e3d2189c507b7482c52820a16dfa4465ba91add92f266667cadb" 1885 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1886 | "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" 1887 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1888 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1889 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1890 | "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" 1891 | "checksum winreg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9338067aba07889a38beaad4dbb77fa2e62e87c423b770824b3bdf412874bd2c" 1892 | "checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e" 1893 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 1894 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "actix-httpbin" 3 | version = "0.1.0" 4 | authors = ["svartalf "] 5 | description = "httpbin.org clone with actix-web" 6 | homepage = "https://github.com/svartalf/actix-httpbin" 7 | repository = "https://github.com/svartalf/actix-httpbin" 8 | keywords = ["http", "web", "server", "testing", "tokio"] 9 | categories = ["asynchronous", "web-programming::http-server"] 10 | license = "Apache-2.0 OR MIT" 11 | readme = "README.md" 12 | 13 | [dependencies] 14 | actix-web = "0.6.10" 15 | serde = "1.0" 16 | serde_derive = "1.0" 17 | serde_json = { version = "1.0", features = ["preserve_order"] } 18 | serde_urlencoded = "0.5.1" 19 | linked-hash-map = { version = "0.5", features = ["serde_impl"] } 20 | uuid = { version = "0.6.3", features = ["serde"] } 21 | http = "0.1.5" 22 | url = "1.7.0" 23 | mime = "0.3.7" 24 | base64 = "0.9" 25 | env_logger = "0.5.10" 26 | futures = "0.1" 27 | bytes = "0.4" 28 | clap = { version = "2.31", default-features = false } 29 | tera = "0.11.7" 30 | tokio-timer = "0.2.1" 31 | rand = "0.4.2" 32 | actix-web-httpauth = "0.0.3" 33 | 34 | [features] 35 | default = [] 36 | nightly = [] 37 | 38 | [badges] 39 | travis-ci = { repository = "svartalf/actix-httpbin", branch = "master" } 40 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2018 svartalf 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 svartalf 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # actix-httpbin 2 | 3 | [httpbin.org](https://httpbin.org) clone with an [actix-web](https://actix.rs) under the hood. 4 | 5 | ![Build Status](https://travis-ci.org/svartalf/actix-httpbin.svg?branch=master) 6 | ![Crates.io](https://img.shields.io/crates/v/actix-httpbin.svg) 7 | 8 | ## Advantages 9 | 10 | 1. [Rust](https://rust-lang.org) is cool 11 | 2. All images, templates and other files are bundled into one binary, so you can just run it; 12 | there is no need in python anymore. 13 | 3. Amazingly fast, low CPU and memory footprint 14 | 15 | ## API 16 | 17 | Till `1.0.0` version it will follow the `httpbin(1)` API, 18 | so any requests for changes that are not present at the `https://httpbin.org` 19 | will be closed or postponed. 20 | 21 | After the `1.0.0` I might consider to go separately, but let's just reach the first milestone, are'nt we? 22 | 23 | Any way, if you need to get list of all available endpoints, 24 | run and open it in your browser. 25 | 26 | ### Differences 27 | 28 | There are few known (and maybe some unknown) differences from the `httpbin(1)` right now. 29 | 30 | 1. `"headers"` object keys in the `/get`, `/post` and other similar endpoints are lower-cased, 31 | it comes from the `http` crate in that way and I'm not sure if I should force some Camel-Dashed-Case on them 32 | 2. Many methods may respond not only to `GET` method, it is not intended. 33 | If you think that this behaviour is wrong, do not hesitate to create an issue. 34 | 3. Not all methods are implemented for now, 35 | you can find them by searching for `TODO` comment in the `src/application.rs` file 36 | 37 | ## How to run? 38 | 39 | ### Via Docker 40 | 41 | $ docker run -p 80:80 svartalf/actix-httpbin 42 | 43 | ### Install with `cargo` 44 | 45 | $ cargo install actix-httpbin 46 | 47 | ### From sources 48 | 49 | $ git clone https://github.com/svartalf/actix-httpbin.git 50 | $ cargo run --release 51 | -------------------------------------------------------------------------------- /src/application.rs: -------------------------------------------------------------------------------- 1 | use actix_web::App; 2 | use actix_web::http::Method; 3 | use actix_web::middleware::Logger; 4 | use tera::Tera; 5 | 6 | use middleware; 7 | use handlers; 8 | use templates; 9 | 10 | pub struct State { 11 | pub template: Tera, 12 | } 13 | 14 | pub fn app() -> App { 15 | let state = State{ 16 | template: templates::create_tera().expect("Templates are not bundled"), 17 | }; 18 | 19 | App::with_state(state) 20 | .middleware(Logger::default()) 21 | .middleware(middleware::Headers) 22 | .resource("/", |r| r.with(handlers::index)) 23 | 24 | // HTTP methods 25 | .resource("/get", |r| r.method(Method::GET).with(handlers::methods::get)) 26 | // TODO: /post 27 | // TODO: /patch 28 | // TODO: /put 29 | // TODO: /delete 30 | 31 | // Auth 32 | .resource("/basic-auth/{user}/{passwd}", |r| r.with(handlers::auth::basic_auth)) 33 | .resource("/bearer", |r| r.with(handlers::auth::bearer_auth)) 34 | // TODO: /digest-auth/{qop}/{user}{passwd} 35 | // TODO: /digest-auth/{qop}/{user}{passwd}/{algorithm} 36 | // TODO: /digest-auth/{qop}/{user}{passwd}/{algorithm}/{stale_after} 37 | // TODO: /digest-auth/{qop}/{user}{passwd} 38 | .resource("/hidden-basic-auth/{user}/{passwd}", |r| r.with(handlers::auth::hidden_basic_auth)) 39 | 40 | // Status codes 41 | .resource("/status/{code}", |r| r.with(handlers::statuses::status)) 42 | 43 | // Request inspection 44 | .resource("/ip", |r| r.f(handlers::request::origin)) 45 | .resource("/headers", |r| r.with(handlers::request::headers)) 46 | .resource("/user-agent", |r| r.f(handlers::request::user_agent)) 47 | 48 | // Response inspection 49 | .resource("/cache", |r| r.with(handlers::response::cache)) 50 | .resource("/cache/{n}", |r| r.with(handlers::response::cache_control)) 51 | .resource("/etag/{etag}", |r| r.with(handlers::response::etag)) 52 | .resource("/response-headers", |r| r.with(handlers::response::headers)) 53 | // TODO: /response-headers 54 | 55 | // Response formats 56 | .resource("/gzip", |r| r.with(handlers::formats::gzip)) 57 | .resource("/deflate", |r| r.with(handlers::formats::deflate)) 58 | .resource("/brotli", |r| r.with(handlers::formats::brotli)) 59 | .resource("/encoding/utf8", |r| r.with(handlers::formats::encoding_utf8)) 60 | .resource("/html", |r| r.with(handlers::formats::html)) 61 | .resource("/robots.txt", |r| r.with(handlers::formats::robots_txt)) 62 | .resource("/deny", |r| r.with(handlers::formats::deny)) 63 | .resource("/json", |r| r.with(handlers::formats::json)) 64 | .resource("/xml", |r| r.with(handlers::formats::xml)) 65 | .resource("/forms/post", |r| r.with(handlers::formats::form)) 66 | 67 | // Dynamic data 68 | .resource("/uuid", |r| r.with(handlers::dynamic::uuid)) 69 | .resource("/base64/{value}", |r| r.with(handlers::dynamic::base64)) 70 | .resource("/stream/{n}", |r| r.with(handlers::dynamic::stream)) 71 | .resource("/delay/{n}", |r| r.with(handlers::dynamic::delay)) 72 | .resource("/bytes/{n}", |r| r.with(handlers::dynamic::bytes)) 73 | .resource("/stream-bytes/{n}", |r| r.with(handlers::dynamic::stream_bytes)) 74 | .resource("/drip", |r| r.with(handlers::dynamic::drip)) 75 | // TODO: /range/1024 76 | .resource("/links/{total}/{current}", |r| r.with(handlers::dynamic::links)) 77 | 78 | // Cookies 79 | .resource("/cookies", |r| r.with(handlers::cookies::cookies)) 80 | .resource("/cookies/set", |r| r.with(handlers::cookies::cookies_set)) 81 | .resource("/cookies/set/{name}/{value}", |r| r.with(handlers::cookies::cookie_set)) 82 | .resource("/cookies/delete", |r| r.with(handlers::cookies::cookies_delete)) 83 | 84 | // Images 85 | .resource("/image", |r| r.with(handlers::images::image)) 86 | .resource("/image/png", |r| r.with(handlers::images::image_png)) 87 | .resource("/image/jpeg", |r| r.with(handlers::images::image_jpeg)) 88 | .resource("/image/webp", |r| r.with(handlers::images::image_webp)) 89 | .resource("/image/svg", |r| r.with(handlers::images::image_svg)) 90 | 91 | // Redirects 92 | .resource("/absolute-redirect/{n}", |r| r.with(handlers::redirects::absolute_redirect_n)) 93 | .resource("/redirect-to", |r| r.with(handlers::redirects::redirect_to)) 94 | .resource("/redirect/{n}", |r| r.with(handlers::redirects::redirect_n)) 95 | .resource("/relative-redirect/{n}", |r| r.with(handlers::redirects::relative_redirect_n)) 96 | 97 | // Anything 98 | .resource("/anything", |r| r.with(handlers::methods::anything)) 99 | // TODO: /anything/{anything} 100 | 101 | 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/assets/LICENSE.md: -------------------------------------------------------------------------------- 1 | # Disclaimer 2 | 3 | Files in the `actix-httpbin/src/assets` were copied from the `httpbin` project 4 | and therefore `httpbin` license is applied to them: 5 | https://github.com/requests/httpbin/blob/master/LICENSE 6 | 7 | # httpbin license copy 8 | 9 | ISC License 10 | 11 | Copyright (c) 2017 Kenneth Reitz. 12 | 13 | Permission to use, copy, modify, and/or distribute this software for any 14 | purpose with or without fee is hereby granted, provided that the above 15 | copyright notice and this permission notice appear in all copies. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 18 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 19 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 20 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 22 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 23 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/assets/UTF-8-demo.txt: -------------------------------------------------------------------------------- 1 |

Unicode Demo

2 | 3 |

Taken from http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt

5 | 6 |
  7 | 
  8 | UTF-8 encoded sample plain-text file
  9 | ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
 10 | 
 11 | Markus Kuhn [ˈmaʳkʊs kuːn]  — 2002-07-25
 12 | 
 13 | 
 14 | The ASCII compatible UTF-8 encoding used in this plain-text file
 15 | is defined in Unicode, ISO 10646-1, and RFC 2279.
 16 | 
 17 | 
 18 | Using Unicode/UTF-8, you can write in emails and source code things such as
 19 | 
 20 | Mathematics and sciences:
 21 | 
 22 |   ∮ E⋅da = Q,  n → ∞, ∑ f(i) = ∏ g(i),      ⎧⎡⎛┌─────┐⎞⎤⎫
 23 |                                             ⎪⎢⎜│a²+b³ ⎟⎥⎪
 24 |   ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β),    ⎪⎢⎜│───── ⎟⎥⎪
 25 |                                             ⎪⎢⎜⎷ c₈   ⎟⎥⎪
 26 |   ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ,                   ⎨⎢⎜       ⎟⎥⎬
 27 |                                             ⎪⎢⎜ ∞     ⎟⎥⎪
 28 |   ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫),      ⎪⎢⎜ ⎲     ⎟⎥⎪
 29 |                                             ⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪
 30 |   2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm     ⎩⎣⎝i=1    ⎠⎦⎭
 31 | 
 32 | Linguistics and dictionaries:
 33 | 
 34 |   ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
 35 |   Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
 36 | 
 37 | APL:
 38 | 
 39 |   ((V⍳V)=⍳⍴V)/V←,V    ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
 40 | 
 41 | Nicer typography in plain text files:
 42 | 
 43 |   ╔══════════════════════════════════════════╗
 44 |   ║                                          ║
 45 |   ║   • ‘single’ and “double” quotes         ║
 46 |   ║                                          ║
 47 |   ║   • Curly apostrophes: “We’ve been here” ║
 48 |   ║                                          ║
 49 |   ║   • Latin-1 apostrophe and accents: '´`  ║
 50 |   ║                                          ║
 51 |   ║   • ‚deutsche‘ „Anführungszeichen“       ║
 52 |   ║                                          ║
 53 |   ║   • †, ‡, ‰, •, 3–4, —, −5/+5, ™, …      ║
 54 |   ║                                          ║
 55 |   ║   • ASCII safety test: 1lI|, 0OD, 8B     ║
 56 |   ║                      ╭─────────╮         ║
 57 |   ║   • the euro symbol: │ 14.95 € │         ║
 58 |   ║                      ╰─────────╯         ║
 59 |   ╚══════════════════════════════════════════╝
 60 | 
 61 | Combining characters:
 62 | 
 63 |   STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑
 64 | 
 65 | Greek (in Polytonic):
 66 | 
 67 |   The Greek anthem:
 68 | 
 69 |   Σὲ γνωρίζω ἀπὸ τὴν κόψη
 70 |   τοῦ σπαθιοῦ τὴν τρομερή,
 71 |   σὲ γνωρίζω ἀπὸ τὴν ὄψη
 72 |   ποὺ μὲ βία μετράει τὴ γῆ.
 73 | 
 74 |   ᾿Απ᾿ τὰ κόκκαλα βγαλμένη
 75 |   τῶν ῾Ελλήνων τὰ ἱερά
 76 |   καὶ σὰν πρῶτα ἀνδρειωμένη
 77 |   χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
 78 | 
 79 |   From a speech of Demosthenes in the 4th century BC:
 80 | 
 81 |   Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
 82 |   ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
 83 |   λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
 84 |   τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
 85 |   εἰς τοῦτο προήκοντα,  ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
 86 |   πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
 87 |   οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
 88 |   οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
 89 |   ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
 90 |   τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
 91 |   γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
 92 |   προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
 93 |   σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
 94 |   τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
 95 |   τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
 96 |   τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
 97 | 
 98 |   Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
 99 | 
100 | Georgian:
101 | 
102 |   From a Unicode conference invitation:
103 | 
104 |   გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
105 |   კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
106 |   ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
107 |   ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
108 |   ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
109 |   ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
110 |   ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
111 | 
112 | Russian:
113 | 
114 |   From a Unicode conference invitation:
115 | 
116 |   Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
117 |   Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
118 |   Конференция соберет широкий круг экспертов по  вопросам глобального
119 |   Интернета и Unicode, локализации и интернационализации, воплощению и
120 |   применению Unicode в различных операционных системах и программных
121 |   приложениях, шрифтах, верстке и многоязычных компьютерных системах.
122 | 
123 | Thai (UCS Level 2):
124 | 
125 |   Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
126 |   classic 'San Gua'):
127 | 
128 |   [----------------------------|------------------------]
129 |     ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช  พระปกเกศกองบู๊กู้ขึ้นใหม่
130 |   สิบสองกษัตริย์ก่อนหน้าแลถัดไป       สององค์ไซร้โง่เขลาเบาปัญญา
131 |     ทรงนับถือขันทีเป็นที่พึ่ง           บ้านเมืองจึงวิปริตเป็นนักหนา
132 |   โฮจิ๋นเรียกทัพทั่วหัวเมืองมา         หมายจะฆ่ามดชั่วตัวสำคัญ
133 |     เหมือนขับไสไล่เสือจากเคหา      รับหมาป่าเข้ามาเลยอาสัญ
134 |   ฝ่ายอ้องอุ้นยุแยกให้แตกกัน          ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
135 |     พลันลิฉุยกุยกีกลับก่อเหตุ          ช่างอาเพศจริงหนาฟ้าร้องไห้
136 |   ต้องรบราฆ่าฟันจนบรรลัย           ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
137 | 
138 |   (The above is a two-column text. If combining characters are handled
139 |   correctly, the lines of the second column should be aligned with the
140 |   | character above.)
141 | 
142 | Ethiopian:
143 | 
144 |   Proverbs in the Amharic language:
145 | 
146 |   ሰማይ አይታረስ ንጉሥ አይከሰስ።
147 |   ብላ ካለኝ እንደአባቴ በቆመጠኝ።
148 |   ጌጥ ያለቤቱ ቁምጥና ነው።
149 |   ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
150 |   የአፍ ወለምታ በቅቤ አይታሽም።
151 |   አይጥ በበላ ዳዋ ተመታ።
152 |   ሲተረጉሙ ይደረግሙ።
153 |   ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
154 |   ድር ቢያብር አንበሳ ያስር።
155 |   ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
156 |   እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
157 |   የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
158 |   ሥራ ከመፍታት ልጄን ላፋታት።
159 |   ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
160 |   የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
161 |   ተንጋሎ ቢተፉ ተመልሶ ባፉ።
162 |   ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
163 |   እግርህን በፍራሽህ ልክ ዘርጋ።
164 | 
165 | Runes:
166 | 
167 |   ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
168 | 
169 |   (Old English, which transcribed into Latin reads 'He cwaeth that he
170 |   bude thaem lande northweardum with tha Westsae.' and means 'He said
171 |   that he lived in the northern land near the Western Sea.')
172 | 
173 | Braille:
174 | 
175 |   ⡌⠁⠧⠑ ⠼⠁⠒  ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
176 | 
177 |   ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
178 |   ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
179 |   ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
180 |   ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
181 |   ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
182 |   ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
183 | 
184 |   ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
185 | 
186 |   ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
187 |   ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
188 |   ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
189 |   ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
190 |   ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
191 |   ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
192 |   ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
193 |   ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
194 |   ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
195 | 
196 |   (The first couple of paragraphs of "A Christmas Carol" by Dickens)
197 | 
198 | Compact font selection example text:
199 | 
200 |   ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
201 |   abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
202 |   –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
203 |   ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა
204 | 
205 | Greetings in various languages:
206 | 
207 |   Hello world, Καλημέρα κόσμε, コンニチハ
208 | 
209 | Box drawing alignment tests:                                          █
210 |                                                                       ▉
211 |   ╔══╦══╗  ┌──┬──┐  ╭──┬──╮  ╭──┬──╮  ┏━━┳━━┓  ┎┒┏┑   ╷  ╻ ┏┯┓ ┌┰┐    ▊ ╱╲╱╲╳╳╳
212 |   ║┌─╨─┐║  │╔═╧═╗│  │╒═╪═╕│  │╓─╁─╖│  ┃┌─╂─┐┃  ┗╃╄┙  ╶┼╴╺╋╸┠┼┨ ┝╋┥    ▋ ╲╱╲╱╳╳╳
213 |   ║│╲ ╱│║  │║   ║│  ││ │ ││  │║ ┃ ║│  ┃│ ╿ │┃  ┍╅╆┓   ╵  ╹ ┗┷┛ └┸┘    ▌ ╱╲╱╲╳╳╳
214 |   ╠╡ ╳ ╞╣  ├╢   ╟┤  ├┼─┼─┼┤  ├╫─╂─╫┤  ┣┿╾┼╼┿┫  ┕┛┖┚     ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
215 |   ║│╱ ╲│║  │║   ║│  ││ │ ││  │║ ┃ ║│  ┃│ ╽ │┃  ░░▒▒▓▓██ ┊  ┆ ╎ ╏  ┇ ┋ ▎
216 |   ║└─╥─┘║  │╚═╤═╝│  │╘═╪═╛│  │╙─╀─╜│  ┃└─╂─┘┃  ░░▒▒▓▓██ ┊  ┆ ╎ ╏  ┇ ┋ ▏
217 |   ╚══╩══╝  └──┴──┘  ╰──┴──╯  ╰──┴──╯  ┗━━┻━━┛  ▗▄▖▛▀▜   └╌╌┘ ╎ ┗╍╍┛ ┋  ▁▂▃▄▅▆▇█
218 |                                                ▝▀▘▙▄▟
219 | 
220 | 
221 | -------------------------------------------------------------------------------- /src/assets/angry_ascii.txt: -------------------------------------------------------------------------------- 1 | 2 | .-''''''-. 3 | .' _ _ '. 4 | / O O \\ 5 | : : 6 | | | 7 | : __ : 8 | \ .-"` `"-. / 9 | '. .' 10 | '-......-' 11 | YOU SHOULDN'T BE HERE 12 | -------------------------------------------------------------------------------- /src/assets/forms-post.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

9 |

10 |

11 |
12 | Pizza Size 13 |

14 |

15 |

16 |
17 |
18 | Pizza Toppings 19 |

20 |

21 |

22 |

23 |
24 |

25 |

26 |

27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /src/assets/images/jackal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svartalf/actix-httpbin/c7118111931ff1559fb1312fc2685d11d5151bd5/src/assets/images/jackal.jpg -------------------------------------------------------------------------------- /src/assets/images/pig_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svartalf/actix-httpbin/c7118111931ff1559fb1312fc2685d11d5151bd5/src/assets/images/pig_icon.png -------------------------------------------------------------------------------- /src/assets/images/svg_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | SVG Logo 4 | 5 | 7 | 8 | 15 | 16 | 23 | 24 | 33 | 34 | 35 | 40 | 41 | 46 | 47 | 52 | 53 | 58 | 59 | 64 | 65 | 70 | 71 | 76 | 77 | 82 | 83 | 84 | 85 | 104 | 105 | 157 | 158 | 159 | 160 | 169 | 170 | 181 | 182 | 183 | SVG 184 | 215 | 227 | 228 | 256 | 257 | 258 | 259 | 260 | -------------------------------------------------------------------------------- /src/assets/images/wolf_1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svartalf/actix-httpbin/c7118111931ff1559fb1312fc2685d11d5151bd5/src/assets/images/wolf_1.webp -------------------------------------------------------------------------------- /src/assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | actix-httpbin: HTTP Client Testing Service 5 | 6 | 7 | 94 | 95 | 96 |
97 |

actix-httpbin

98 | 99 |
100 |

HTTP methods

101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 |
/getGET data
/postPOST data
/patchPATCH data
/putPUT data
/deleteDELETE data
125 | 126 |
127 | 128 |
129 |

Auth

130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 |
/basic-auth/{user}/{passwd}Challenges HTTP Basic Auth
/bearerChallenges HTTP Bearer Auth
/hidden-basic-auth/{user}/{passwd}404'd HTTP Basic Auth
/digest-auth/{qop}/{user}/{passwd}/{algorithm}Challenges HTTP Digest Auth
150 |
151 | 152 |
153 |

Status codes

154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 |
/status/{code}Given HTTP status code
162 |
163 | 164 |
165 |

Request inspection

166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 |
/ipRequester IP address
/headersHTTP headers
/user-agentUser-Agent header
182 |
183 | 184 |
185 |

Response inspection

186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 |
/cacheReturns a HTTP 304 if an If-Modified-Since or If-None-Match is present
/cache/{value}Sets a Cache-Control header for value seconds
/etag/{etag}Assumes the resource has the given etag and responds to If-None-Match and If-Match headers appropriately
/response-headers?key=valGiven response headers
207 |
208 | 209 |
210 |

Response formats

211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 |
/encoding/utf8Page containing UTF-8 data
/gzipGzip-encoded data
/deflateDeflate-encoded data
/brotliBrotli-encoded data
/jsonJSON document
/forms/postHTML form that posts to /post
239 |
240 | 241 |
242 |

Dynamic data

243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 |
/uuidUUID4
/base64/{value}Decodes base64url-encoded string
/stream/{n}Stream n JSON responses
/delay/{n}Returns a response delayed to {n} seconds
/bytes/{n}?seed={seed}Returns {n} random bytes generated with optional {seed}
/stream-bytes/{n}?seed={seed}&chunk_size={size}Streams {n} random bytes generated with optional {seed}, at given chunk size per packet.
/links/{total}/{current}Generate a page containing {total} links to other pages which do the same.
275 |
276 | 277 |
278 |

Redirects

279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 |
/redirect/{n}302 redirects {n} times
/redirect-to?url=foo302 redirects to the foo URL
/redirect-to?url=foo&status_code=307302 redirects to the foo URL with optional status_code
/relative-redirect/{n}302 relative redirects {n} times
/absolute-redirect/{n}302 absolute redirects {n} times
303 |
304 | 305 |
306 |

Cookies

307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 |
/cookiesCookie data
/cookies/set?name=valueSet one or more simple cookies
/cookies/set/{name}/{value}Set one simple cookie with name {name} and value {value}
/cookies/delete?nameDelete one or more simple cookies
327 |
328 | 329 |
330 |

Anything

331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 |
/anythingRequest data, including method used
/anything/{path}Request data, including method and URL used
343 | 344 |
345 |
346 | 347 | 389 | 390 | 391 | -------------------------------------------------------------------------------- /src/assets/links.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Links 6 | 7 | 8 | {% for link in links %} 9 | {% if link == current %} 10 | {{ link }} 11 | {% else %} 12 | {{ link }} 13 | {% endif %} 14 | {% endfor %} 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/assets/moby.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

Herman Melville - Moby-Dick

7 | 8 |
9 |

10 | Availing himself of the mild, summer-cool weather that now reigned in these latitudes, and in preparation for the peculiarly active pursuits shortly to be anticipated, Perth, the begrimed, blistered old blacksmith, had not removed his portable forge to the hold again, after concluding his contributory work for Ahab's leg, but still retained it on deck, fast lashed to ringbolts by the foremast; being now almost incessantly invoked by the headsmen, and harpooneers, and bowsmen to do some little job for them; altering, or repairing, or new shaping their various weapons and boat furniture. Often he would be surrounded by an eager circle, all waiting to be served; holding boat-spades, pike-heads, harpoons, and lances, and jealously watching his every sooty movement, as he toiled. Nevertheless, this old man's was a patient hammer wielded by a patient arm. No murmur, no impatience, no petulance did come from him. Silent, slow, and solemn; bowing over still further his chronically broken back, he toiled away, as if toil were life itself, and the heavy beating of his hammer the heavy beating of his heart. And so it was.—Most miserable! A peculiar walk in this old man, a certain slight but painful appearing yawing in his gait, had at an early period of the voyage excited the curiosity of the mariners. And to the importunity of their persisted questionings he had finally given in; and so it came to pass that every one now knew the shameful story of his wretched fate. Belated, and not innocently, one bitter winter's midnight, on the road running between two country towns, the blacksmith half-stupidly felt the deadly numbness stealing over him, and sought refuge in a leaning, dilapidated barn. The issue was, the loss of the extremities of both feet. Out of this revelation, part by part, at last came out the four acts of the gladness, and the one long, and as yet uncatastrophied fifth act of the grief of his life's drama. He was an old man, who, at the age of nearly sixty, had postponedly encountered that thing in sorrow's technicals called ruin. He had been an artisan of famed excellence, and with plenty to do; owned a house and garden; embraced a youthful, daughter-like, loving wife, and three blithe, ruddy children; every Sunday went to a cheerful-looking church, planted in a grove. But one night, under cover of darkness, and further concealed in a most cunning disguisement, a desperate burglar slid into his happy home, and robbed them all of everything. And darker yet to tell, the blacksmith himself did ignorantly conduct this burglar into his family's heart. It was the Bottle Conjuror! Upon the opening of that fatal cork, forth flew the fiend, and shrivelled up his home. Now, for prudent, most wise, and economic reasons, the blacksmith's shop was in the basement of his dwelling, but with a separate entrance to it; so that always had the young and loving healthy wife listened with no unhappy nervousness, but with vigorous pleasure, to the stout ringing of her young-armed old husband's hammer; whose reverberations, muffled by passing through the floors and walls, came up to her, not unsweetly, in her nursery; and so, to stout Labor's iron lullaby, the blacksmith's infants were rocked to slumber. Oh, woe on woe! Oh, Death, why canst thou not sometimes be timely? Hadst thou taken this old blacksmith to thyself ere his full ruin came upon him, then had the young widow had a delicious grief, and her orphans a truly venerable, legendary sire to dream of in their after years; and all of them a care-killing competency. 11 |

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | Wake up to WonderWidgets! 14 | 15 | 16 | 17 | 18 | Overview 19 | Why WonderWidgets are great 20 | 21 | Who buys WonderWidgets 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/handlers/auth.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{HttpRequest, HttpResponse, Path, Result, FromRequest, http}; 2 | use actix_web_httpauth::extractors::{AuthenticationError, basic, bearer}; 3 | 4 | use application::State; 5 | 6 | #[derive(Deserialize)] 7 | pub struct Credentials { 8 | user: String, 9 | passwd: String, 10 | } 11 | 12 | /// Prompts the user for authorization using HTTP Basic Auth. 13 | pub fn basic_auth((req, path, auth): (HttpRequest, Path, basic::BasicAuth)) -> Result { 14 | if path.user == auth.username() && Some(path.passwd.as_str()) == auth.password() { 15 | let body = json!({ 16 | "authenticated": true, 17 | "user": auth.username(), 18 | }); 19 | let resp = req.build_response(http::StatusCode::OK) 20 | .json(body); 21 | Ok(resp) 22 | } else { 23 | Err(AuthenticationError::from(basic::Config::default()).into()) 24 | } 25 | } 26 | 27 | /// Prompts the user for authorization using HTTP Basic Auth, 28 | /// but returns `HTTP 404` instead of `HTTP 401` 29 | pub fn hidden_basic_auth((req, path): (HttpRequest, Path)) -> HttpResponse { 30 | if let Ok(auth) = basic::BasicAuth::extract(&req) { 31 | if path.user == auth.username() && Some(path.passwd.as_str()) == auth.password() { 32 | let body = json!({ 33 | "authenticated": true, 34 | "user": auth.username(), 35 | }); 36 | 37 | return req.build_response(http::StatusCode::OK) 38 | .json(body); 39 | } 40 | } 41 | 42 | req.build_response(http::StatusCode::NOT_FOUND) 43 | .finish() 44 | 45 | } 46 | 47 | /// Checks for HTTP Bearer auth 48 | pub fn bearer_auth((req, auth): (HttpRequest, bearer::BearerAuth)) -> HttpResponse { 49 | let body = json!({ 50 | "authenticated": true, 51 | "token": auth.token(), 52 | }); 53 | 54 | req.build_response(http::StatusCode::OK) 55 | .json(body) 56 | } 57 | -------------------------------------------------------------------------------- /src/handlers/cookies.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use serde_json::Value; 4 | use actix_web::{HttpRequest, HttpResponse, Path, Json, Result}; 5 | use actix_web::http::{header, StatusCode, Cookie}; 6 | 7 | use application::State; 8 | 9 | #[derive(Deserialize)] 10 | pub struct CookieInfo { 11 | name: String, 12 | value: String, 13 | } 14 | 15 | /// Returns cookie data. 16 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 17 | pub fn cookies(req: HttpRequest) -> Result> { 18 | let cookies = req.cookies()?.iter().map(|cookie| { 19 | (cookie.name(), cookie.value()) 20 | }).collect::>(); 21 | 22 | let body = json!({ 23 | "cookies": cookies, 24 | }); 25 | 26 | Ok(Json(body)) 27 | } 28 | 29 | /// Set cookie based on the path params. 30 | pub fn cookie_set((req, info): (HttpRequest, Path)) -> Result { 31 | let is_secure = req.connection_info().scheme() == "https"; 32 | let mut cookie = Cookie::new(info.name.clone(), info.value.clone()); 33 | cookie.set_secure(is_secure); 34 | cookie.set_path("/"); 35 | 36 | let resp = req.build_response(StatusCode::FOUND) 37 | .cookie(cookie) 38 | // TODO: Use `req.url_for()` here 39 | .header(header::LOCATION, "/cookies") 40 | .finish(); 41 | Ok(resp) 42 | } 43 | 44 | 45 | /// Set cookies based on the query string params. 46 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 47 | pub fn cookies_set(req: HttpRequest) -> Result { 48 | let is_secure = req.connection_info().scheme() == "https"; 49 | let mut resp = req.build_response(StatusCode::FOUND); 50 | 51 | for &(ref name, ref value) in req.query().iter() { 52 | let mut cookie = Cookie::new(name.to_string(), value.to_string()); 53 | cookie.set_secure(is_secure); 54 | cookie.set_path("/"); 55 | resp.cookie(cookie); 56 | } 57 | 58 | // TODO: Use `req.url_for()` here 59 | Ok(resp.header(header::LOCATION, "/cookies").finish()) 60 | } 61 | 62 | 63 | /// Delete cookies based on the query string params. 64 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 65 | pub fn cookies_delete(req: HttpRequest) -> Result { 66 | let mut resp = req.build_response(StatusCode::FOUND); 67 | 68 | for &(ref name, _) in req.query().iter() { 69 | let cookie = Cookie::named(name.to_string()); 70 | resp.del_cookie(&cookie); 71 | } 72 | 73 | // TODO: Use `req.url_for()` here 74 | Ok(resp.header(header::LOCATION, "/cookies").finish()) 75 | } 76 | -------------------------------------------------------------------------------- /src/handlers/dynamic/bytes.rs: -------------------------------------------------------------------------------- 1 | use std::cmp; 2 | use std::mem; 3 | 4 | use actix_web::{HttpRequest, HttpResponse, Path, Query}; 5 | use actix_web::http::StatusCode; 6 | use rand::{self, XorShiftRng, Rng, SeedableRng}; 7 | 8 | use application::State; 9 | 10 | #[derive(Deserialize)] 11 | pub struct BytesQuery { 12 | seed: Option, 13 | } 14 | 15 | /// Returns `n` random bytes generated with given seed. 16 | pub fn bytes((req, path, query): (HttpRequest, Path, Query)) -> HttpResponse { 17 | let n = cmp::min(*path, 100 * 1024); 18 | 19 | let seed = if let Some(seed) = (*query).seed { 20 | unsafe { mem::transmute(u128::from(seed)) } 21 | } else { 22 | [rand::random(), rand::random(), rand::random(), rand::random()] 23 | }; 24 | 25 | let mut rng = XorShiftRng::from_seed(seed); 26 | let mut body = vec![0u8; n as usize]; 27 | rng.fill_bytes(&mut body); 28 | 29 | req.build_response(StatusCode::OK) 30 | .content_type("application/octet-stream") 31 | .body(body) 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/handlers/dynamic/delay.rs: -------------------------------------------------------------------------------- 1 | use std::cmp; 2 | use std::time::{Duration, Instant}; 3 | 4 | use actix_web::{HttpResponse, Path, error}; 5 | use actix_web::http::StatusCode; 6 | use futures::Future; 7 | use tokio_timer; 8 | 9 | /// Returns a delayed response (max of 10 seconds). 10 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 11 | pub fn delay(info: Path) -> Box>> { 12 | let n = cmp::min(*info, 10); 13 | let when = Instant::now() + Duration::new(n, 0); 14 | let future = tokio_timer::Delay::new(when) 15 | .and_then(|_| Ok(HttpResponse::build(StatusCode::OK).finish())) 16 | .map_err(|e| error::InternalError::new(e, StatusCode::INTERNAL_SERVER_ERROR)); 17 | 18 | Box::new(future) 19 | } 20 | -------------------------------------------------------------------------------- /src/handlers/dynamic/drip.rs: -------------------------------------------------------------------------------- 1 | use std::cmp; 2 | use std::time::{Instant, Duration}; 3 | 4 | use bytes::Bytes; 5 | use tokio_timer::Interval; 6 | use actix_web::{self, HttpRequest, HttpResponse, Query, error}; 7 | use actix_web::http::StatusCode; 8 | use futures::Stream; 9 | // `actix-web` is not re-exporting this and probably it should 10 | // Create an issue about it. 11 | use http::status::InvalidStatusCode; 12 | 13 | use application::State; 14 | 15 | 16 | #[derive(Debug, Deserialize)] 17 | pub struct DripQuery { 18 | duration: Option, // TODO: duration should be a float 19 | numbytes: Option, 20 | code: Option, 21 | delay: Option, // TODO: delay should be a float 22 | } 23 | 24 | impl DripQuery { 25 | fn duration(&self) -> Duration { 26 | let seconds = match self.duration { 27 | None => 2, 28 | Some(seconds) => u64::from(seconds) 29 | }; 30 | 31 | Duration::from_secs(seconds) 32 | } 33 | 34 | fn num_bytes(&self) -> u32 { 35 | match self.numbytes { 36 | None => 10, 37 | Some(bytes) => cmp::min(bytes, 10 * 1024 * 1024), 38 | } 39 | } 40 | 41 | fn delay(&self) -> Duration { 42 | let seconds = match self.delay { 43 | None => 0, 44 | Some(seconds) => u64::from(seconds), 45 | }; 46 | 47 | Duration::from_secs(seconds) 48 | } 49 | 50 | fn status_code(&self) -> Result { 51 | StatusCode::from_u16(self.code.unwrap_or(200)) 52 | } 53 | } 54 | 55 | /// Drips data over a duration after an optional initial delay. 56 | pub fn drip((req, query): (HttpRequest, Query)) -> actix_web::Result { 57 | let duration = query.duration(); 58 | let num_bytes = query.num_bytes(); 59 | let code = query.status_code().map_err(error::ErrorBadRequest)?; 60 | let interval = duration / num_bytes; 61 | 62 | let stream = Interval::new(Instant::now() + query.delay(), interval) 63 | .map(|_| Bytes::from_static(b"*")) 64 | .map_err(error::ErrorInternalServerError) 65 | .take(num_bytes.into()); 66 | 67 | let resp = req.build_response(code) 68 | .content_type("application/octet-stream") 69 | .content_length(num_bytes.into()) 70 | .streaming(stream); 71 | Ok(resp) 72 | } 73 | -------------------------------------------------------------------------------- /src/handlers/dynamic/mod.rs: -------------------------------------------------------------------------------- 1 | use uuid; 2 | use base64; 3 | use actix_web::{Json, HttpRequest, HttpResponse, Path, Result, error}; 4 | 5 | use application::State; 6 | use templates::{Context, render}; 7 | 8 | mod drip; 9 | mod bytes; 10 | mod delay; 11 | mod stream; 12 | mod stream_bytes; 13 | 14 | pub use self::bytes::bytes; 15 | pub use self::delay::delay; 16 | pub use self::stream::stream; 17 | pub use self::stream_bytes::stream_bytes; 18 | pub use self::drip::drip; 19 | 20 | #[derive(Serialize)] 21 | pub struct UUID { 22 | uuid: uuid::Uuid, 23 | } 24 | 25 | /// Returns a generated `UUID4`. 26 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 27 | pub fn uuid(_req: HttpRequest) -> Json { 28 | Json(UUID{ 29 | uuid: uuid::Uuid::new_v4(), 30 | }) 31 | } 32 | 33 | /// Returns base64url-encoded string. 34 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 35 | pub fn base64(info: Path) -> Result { 36 | base64::decode_config(&*info, base64::URL_SAFE) 37 | .map_err(error::ErrorBadRequest) 38 | .map(String::from_utf8)? 39 | .map_err(error::ErrorBadRequest) 40 | } 41 | 42 | 43 | pub fn links((req, info): (HttpRequest, Path<(u8, u8)>)) -> Result { 44 | let (total, current) = *info; 45 | let mut context = Context::new(); 46 | context.add("links", &(0..total).collect::>()); 47 | context.add("total", &total); 48 | context.add("current", ¤t); 49 | 50 | render(req, "links.html", &context) 51 | } 52 | -------------------------------------------------------------------------------- /src/handlers/dynamic/range.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{HttpRequest, HttpResponse, Result, Query}; 2 | use actix_web::http::header::ContentRange; 3 | use actix_web::http::StatusCode; 4 | 5 | 6 | #[derive(Debug, Deserialize)] 7 | pub struct RangeQuery { 8 | chunk_size: Option, 9 | duration: Option, 10 | } 11 | 12 | 13 | pub fn range((req, info, query): (HttpRequest, Path, Query)) -> Result { 14 | let num_bytes = *info; 15 | 16 | Ok(req.build_response(StatusCode::OK) 17 | .finish()) 18 | } 19 | -------------------------------------------------------------------------------- /src/handlers/dynamic/stream.rs: -------------------------------------------------------------------------------- 1 | use bytes::Bytes; 2 | use serde_json::{self, Value}; 3 | use actix_web::{HttpRequest, HttpResponse, Path}; 4 | use actix_web::http::StatusCode; 5 | use futures::{Future, Stream, Poll, Async}; 6 | 7 | use application::State; 8 | use response::{Body, Builder, Error}; 9 | 10 | #[derive(Serialize)] 11 | struct StreamLine<'l> { 12 | #[serde(flatten)] 13 | value: &'l Value, 14 | id: usize, 15 | } 16 | 17 | /// In order not to generate `Body` instance each time, we are going to await it's completion 18 | /// and then just yield a `StreamLine` instance few times with a reference to a generated body. 19 | struct BodyStream { 20 | future: F, 21 | value: Option, 22 | iteration: usize, 23 | limit: usize, 24 | } 25 | 26 | impl BodyStream where F: Future { 27 | pub fn new(f: F, limit: u8) -> BodyStream { 28 | BodyStream { 29 | future: f, 30 | value: None, 31 | iteration: 0, 32 | limit: limit as usize, 33 | } 34 | } 35 | } 36 | 37 | impl Stream for BodyStream where F: Future { 38 | type Item = Bytes; 39 | type Error = Error; 40 | 41 | fn poll(&mut self) -> Poll, Error> { 42 | if self.value.is_none() { 43 | // Awaiting until body future resolves at first 44 | match self.future.poll() { 45 | Err(e) => return Err(e), 46 | Ok(Async::NotReady) => return Ok(Async::NotReady), 47 | Ok(Async::Ready(value)) => { 48 | self.value = Some(value) 49 | } 50 | } 51 | } 52 | 53 | if self.iteration >= self.limit { 54 | Ok(Async::Ready(None)) 55 | } else { 56 | let line = StreamLine { 57 | value: self.value.as_ref().expect("Iteration started before inner future resolved"), 58 | id: self.iteration, 59 | }; 60 | let mut bytes = serde_json::to_vec(&line)?; 61 | bytes.push(b'\n'); 62 | self.iteration += 1; 63 | 64 | Ok(Async::Ready(Some(Bytes::from(bytes)))) 65 | } 66 | } 67 | } 68 | 69 | /// Stream `n` JSON responses. 70 | pub fn stream((req, path): (HttpRequest, Path)) -> HttpResponse { 71 | let body = Body::new(req) 72 | .with_url() 73 | .with_args() 74 | .with_headers() 75 | .with_origin() 76 | .into_json_value(); 77 | 78 | HttpResponse::build(StatusCode::OK) 79 | .streaming(BodyStream::new(body, *path)) 80 | } 81 | -------------------------------------------------------------------------------- /src/handlers/dynamic/stream_bytes.rs: -------------------------------------------------------------------------------- 1 | use std::cmp; 2 | use std::mem; 3 | 4 | use rand::{self, XorShiftRng, Rng, SeedableRng}; 5 | use bytes::Bytes; 6 | use actix_web::{HttpRequest, HttpResponse, Path, Query}; 7 | use actix_web::http::StatusCode; 8 | use futures::{Stream, Poll, Async}; 9 | 10 | use application::State; 11 | use response:: Error; 12 | 13 | 14 | #[derive(Deserialize)] 15 | pub struct StreamBytesQuery { 16 | seed: Option, 17 | chunk_size: Option, 18 | } 19 | 20 | impl StreamBytesQuery { 21 | fn seed(&self) -> [u32; 4] { 22 | if let Some(seed) = self.seed { 23 | unsafe { mem::transmute(u128::from(seed)) } 24 | } else { 25 | [rand::random(), rand::random(), rand::random(), rand::random()] 26 | } 27 | } 28 | 29 | fn chunk_size(&self) -> usize { 30 | if let Some(size) = self.chunk_size { 31 | cmp::max(1, size) as usize 32 | } else { 33 | 10 * 1024 34 | } 35 | } 36 | } 37 | 38 | pub struct StreamBytes { 39 | limit: usize, 40 | sent: usize, 41 | chunk_size: usize, 42 | rng: XorShiftRng, 43 | } 44 | 45 | impl StreamBytes { 46 | pub fn new(limit: usize, seed: [u32; 4], chunk_size: usize) -> StreamBytes { 47 | StreamBytes { 48 | sent: 0, 49 | limit: limit, 50 | rng: XorShiftRng::from_seed(seed), 51 | chunk_size: chunk_size, 52 | } 53 | } 54 | } 55 | 56 | impl Stream for StreamBytes { 57 | type Item = Bytes; 58 | type Error = Error; 59 | 60 | fn poll(&mut self) -> Poll, Error> { 61 | if self.sent >= self.limit { 62 | return Ok(Async::Ready(None)) 63 | } 64 | 65 | let size = cmp::min(self.chunk_size, self.limit - self.sent); 66 | let mut buffer = vec![0; size]; 67 | self.rng.fill_bytes(&mut buffer); 68 | self.sent += size; 69 | 70 | Ok(Async::Ready(Some(Bytes::from(buffer)))) 71 | } 72 | } 73 | 74 | /// Streams `n` random bytes generated with given seed, at given chuck size per packet. 75 | pub fn stream_bytes((req, path, query): (HttpRequest, Path, Query)) -> HttpResponse { 76 | let stream = StreamBytes::new( 77 | usize::from(*path), 78 | query.seed(), 79 | query.chunk_size()); 80 | 81 | req.build_response(StatusCode::OK) 82 | .content_type("application/octet-stream") 83 | .streaming(stream) 84 | } 85 | -------------------------------------------------------------------------------- /src/handlers/formats.rs: -------------------------------------------------------------------------------- 1 | use futures::Future; 2 | use actix_web::{HttpRequest, HttpResponse, Json, Result}; 3 | use actix_web::http::{StatusCode, ContentEncoding}; 4 | use serde_json::Value; 5 | 6 | use application::State; 7 | use response::{Body, Builder, ResponseFuture}; 8 | use templates::{Context, render}; 9 | 10 | static ENCODING_UTF8: &'static str = include_str!("../assets/UTF-8-demo.txt"); 11 | static HTML: &'static str = include_str!("../assets/moby.html"); 12 | static XML: &'static str = include_str!("../assets/sample.xml"); 13 | static ROBOTS_TXT: &'static str = "User-agent: *\nDisallow: /deny\n"; 14 | static ANGRY_ASCII: &'static str = include_str!("../assets/angry_ascii.txt"); 15 | 16 | fn compress(req: HttpRequest, extra_key: &'static str, encoding: ContentEncoding) -> Box { 17 | let resp = Body::new(req) 18 | .with_url() 19 | .with_headers() 20 | .with_origin() 21 | .with_args() 22 | .with_extra(extra_key, true) 23 | .into_response() 24 | .map(move |mut response| { 25 | response.set_content_encoding(encoding); 26 | response 27 | }); 28 | 29 | Box::new(resp) 30 | } 31 | 32 | /// Returns Gzip-encoded data. 33 | pub fn gzip(req: HttpRequest) -> Box { 34 | compress(req, "gzipped", ContentEncoding::Gzip) 35 | } 36 | 37 | /// Returns Deflate-encoded data. 38 | pub fn deflate(req: HttpRequest) -> Box { 39 | compress(req, "deflated", ContentEncoding::Deflate) 40 | } 41 | 42 | /// Returns Brotli-encoded data. 43 | pub fn brotli(req: HttpRequest) -> Box { 44 | compress(req, "brotli", ContentEncoding::Br) 45 | } 46 | 47 | /// Returns an UTF-8 encoded HTML page. 48 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 49 | pub fn encoding_utf8(req: HttpRequest) -> HttpResponse { 50 | req.build_response(StatusCode::OK) 51 | .content_type("text/html; charset=utf8") 52 | .body(ENCODING_UTF8) 53 | } 54 | 55 | /// Returns a simple XML document. 56 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 57 | pub fn xml(req: HttpRequest) -> HttpResponse { 58 | req.build_response(StatusCode::OK) 59 | .content_type("application/xml") 60 | .body(XML) 61 | } 62 | 63 | /// Returns a simple HTML document. 64 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 65 | pub fn html(req: HttpRequest) -> HttpResponse { 66 | req.build_response(StatusCode::OK) 67 | .content_type("text/html; charset=utf8") 68 | .body(HTML) 69 | } 70 | 71 | /// Returns a simple JSON document. 72 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 73 | pub fn json(_req: HttpRequest) -> Json { 74 | let body = json!({ 75 | "slideshow": { 76 | "title": "Sample Slide Show", 77 | "date": "date of publication", 78 | "author": "Yours Truly", 79 | "slides": [ 80 | { 81 | "type": "all", 82 | "title": "Wake up to WonderWidgets!", 83 | }, 84 | { 85 | "type": "all", 86 | "title": "Overview", 87 | "items": [ 88 | "Why WonderWidgets are great", 89 | "Who buys WonderWidgets", 90 | ] 91 | } 92 | ], 93 | } 94 | }); 95 | 96 | Json(body) 97 | } 98 | 99 | /// Returns some `robots.txt` rules 100 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 101 | pub fn robots_txt(req: HttpRequest) -> HttpResponse { 102 | req.build_response(StatusCode::OK) 103 | .content_type("text/plain; charset=utf8") 104 | .body(ROBOTS_TXT) 105 | } 106 | 107 | /// Returns page denied by `robots.txt` rules. 108 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 109 | pub fn deny(req: HttpRequest) -> HttpResponse { 110 | req.build_response(StatusCode::OK) 111 | .content_type("text/plain; charset=utf8") 112 | .body(ANGRY_ASCII) 113 | } 114 | 115 | /// HTML form that posts to `/post` URL 116 | pub fn form(req: HttpRequest) -> Result { 117 | render(req, "forms-post.html", &Context::default()) 118 | } 119 | -------------------------------------------------------------------------------- /src/handlers/images.rs: -------------------------------------------------------------------------------- 1 | use mime; 2 | use actix_web::{HttpRequest, HttpResponse}; 3 | use actix_web::http::StatusCode; 4 | use actix_web::http::header::{self, Header}; 5 | 6 | use application::State; 7 | 8 | static IMAGE_PNG: &'static [u8] = include_bytes!("../assets/images/pig_icon.png"); 9 | static IMAGE_JPEG: &'static [u8] = include_bytes!("../assets/images/jackal.jpg"); 10 | static IMAGE_WEBP: &'static [u8] = include_bytes!("../assets/images/wolf_1.webp"); 11 | static IMAGE_SVG: &'static [u8] = include_bytes!("../assets/images/svg_logo.svg"); 12 | 13 | 14 | /// Returns a simple image of the type suggested by the `Accept` header. 15 | pub fn image(req: HttpRequest) -> HttpResponse { 16 | if let Ok(accept) = header::Accept::parse(&req) { 17 | for qi in accept.0 { 18 | match () { 19 | () if qi.item == mime::IMAGE_PNG => return image_png(req), 20 | () if qi.item == mime::IMAGE_JPEG => return image_jpeg(req), 21 | () if qi.item == "image/webp" => return image_webp(req), 22 | () if qi.item == "image/svg+xml" => return image_svg(req), 23 | _ => continue, 24 | } 25 | } 26 | } 27 | 28 | image_png(req) 29 | } 30 | 31 | /// Returns a PNG image. 32 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 33 | pub fn image_png(req: HttpRequest) -> HttpResponse { 34 | req.build_response(StatusCode::OK) 35 | .content_type("image/png") 36 | .body(IMAGE_PNG) 37 | } 38 | 39 | /// Returns a JPG image. 40 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 41 | pub fn image_jpeg(req: HttpRequest) -> HttpResponse { 42 | req.build_response(StatusCode::OK) 43 | .content_type("image/jpeg") 44 | .body(IMAGE_JPEG) 45 | } 46 | 47 | /// Returns a WEBP image. 48 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 49 | pub fn image_webp(req: HttpRequest) -> HttpResponse { 50 | req.build_response(StatusCode::OK) 51 | .content_type("image/webp") 52 | .body(IMAGE_WEBP) 53 | } 54 | 55 | /// Returns a SVG image. 56 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 57 | pub fn image_svg(req: HttpRequest) -> HttpResponse { 58 | req.build_response(StatusCode::OK) 59 | .content_type("image/svg+xml") 60 | .body(IMAGE_SVG) 61 | } 62 | -------------------------------------------------------------------------------- /src/handlers/methods.rs: -------------------------------------------------------------------------------- 1 | use actix_web::HttpRequest; 2 | 3 | use application::State; 4 | use response::{Body, Builder, JsonFuture}; 5 | 6 | /// The request's query parameters. 7 | pub fn get(req: HttpRequest) -> Box> { 8 | Box::new(Body::new(req) 9 | .with_url() 10 | .with_headers() 11 | .with_origin() 12 | .with_args() 13 | .into_json()) 14 | } 15 | 16 | /// Returns anything passed in request data. 17 | pub fn anything(req: HttpRequest) -> Box> { 18 | Box::new(Body::new(req) 19 | .with_method() 20 | .with_url() 21 | .with_headers() 22 | .with_origin() 23 | .with_args() 24 | .into_json()) 25 | } 26 | -------------------------------------------------------------------------------- /src/handlers/mod.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{HttpRequest, HttpResponse, Result}; 2 | use tera::Context; 3 | 4 | pub mod methods; 5 | pub mod auth; 6 | pub mod statuses; 7 | pub mod request; 8 | pub mod response; 9 | pub mod formats; 10 | pub mod dynamic; 11 | pub mod cookies; 12 | pub mod images; 13 | pub mod redirects; 14 | 15 | use application::State; 16 | use templates; 17 | 18 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 19 | pub fn index(req: HttpRequest) -> Result { 20 | templates::render(req, "index.html", &Context::new()) 21 | } 22 | -------------------------------------------------------------------------------- /src/handlers/redirects.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{HttpRequest, HttpResponse, Path, Query, Result, http}; 2 | 3 | use application::State; 4 | 5 | 6 | #[derive(Debug, Deserialize)] 7 | pub struct RedirectQuery { 8 | absolute: Option, 9 | } 10 | 11 | pub fn redirect_n((req, path, query): (HttpRequest, Path, Query)) -> HttpResponse { 12 | if query.absolute.unwrap_or(false) { 13 | absolute_redirect_n((req, path)) 14 | } else { 15 | relative_redirect_n((req, path)) 16 | } 17 | } 18 | 19 | 20 | /// `HTTP 302` redirects `n` times with an absolute URL. 21 | pub fn absolute_redirect_n((req, path): (HttpRequest, Path)) -> HttpResponse { 22 | // TODO: Use `req.url_for()` here 23 | let info = req.connection_info(); 24 | let url = if *path == 1 { 25 | format!("{}://{}/get", info.scheme(), info.host()) 26 | } else { 27 | format!("{}://{}/absolute-redirect/{}", info.scheme(), info.host(), (*path - 1)) 28 | }; 29 | 30 | req.build_response(http::StatusCode::FOUND) 31 | .header("Location", url) 32 | .finish() 33 | } 34 | 35 | #[derive(Debug, Deserialize)] 36 | pub struct RedirectTo { 37 | url: String, 38 | status_code: Option, 39 | } 40 | 41 | impl RedirectTo { 42 | fn parts(self) -> (String, http::StatusCode) { 43 | let code = match self.status_code { 44 | Some(code) if code >= 300 && code < 400 => http::StatusCode::from_u16(code).expect("Unexpected"), 45 | _ => http::StatusCode::FOUND, 46 | }; 47 | 48 | (self.url, code) 49 | } 50 | } 51 | 52 | pub fn redirect_to((req, query): (HttpRequest, Query)) -> Result { 53 | let (url, code) = query.into_inner().parts(); 54 | let resp = req.build_response(code) 55 | .header(http::header::LOCATION, url) 56 | .finish(); 57 | Ok(resp) 58 | } 59 | 60 | 61 | /// `HTTP 302` redirects `n` times with a relative URL. 62 | pub fn relative_redirect_n((req, path): (HttpRequest, Path)) -> HttpResponse { 63 | // TODO: Use `req.url_for()` here 64 | let url = if *path == 1 { 65 | "/get".to_string() 66 | } else { 67 | format!("/relative-redirect/{}", (*path - 1)) 68 | }; 69 | 70 | req.build_response(http::StatusCode::FOUND) 71 | .header("Location", url) 72 | .finish() 73 | } 74 | -------------------------------------------------------------------------------- /src/handlers/request.rs: -------------------------------------------------------------------------------- 1 | use actix_web::HttpRequest; 2 | 3 | use application::State; 4 | use response::{Body, Builder, JsonFuture}; 5 | 6 | 7 | /// Return the requester IP address. 8 | pub fn origin(req: HttpRequest) -> Box> { 9 | Box::new(Body::new(req) 10 | .with_origin() 11 | .into_json()) 12 | } 13 | 14 | /// Return the request' `User-Agent` header. 15 | pub fn user_agent(req: HttpRequest) -> Box> { 16 | Box::new(Body::new(req) 17 | .with_user_agent() 18 | .into_json()) 19 | } 20 | 21 | /// Return the request' HTTP headers. 22 | pub fn headers(req: HttpRequest) -> Box> { 23 | Box::new(Body::new(req) 24 | .with_headers() 25 | .into_json()) 26 | } 27 | -------------------------------------------------------------------------------- /src/handlers/response.rs: -------------------------------------------------------------------------------- 1 | use std::borrow::Borrow; 2 | use std::time::SystemTime; 3 | 4 | use uuid; 5 | use actix_web::{HttpRequest, HttpResponse, HttpMessage, Result, Path}; 6 | use actix_web::http::{StatusCode, header}; 7 | use actix_web::http::header::Header; 8 | use futures::{future, Future}; 9 | 10 | use application::State; 11 | use response::{Body, Builder, ResponseFuture}; 12 | 13 | 14 | /// Returns a `HTTP 304` if an `If-Modified-Since` or `If-None-Match` header is present. 15 | /// 16 | /// Otherwise, returns the same content as `/get` endpoint. 17 | pub fn cache(req: HttpRequest) -> Box { 18 | let is_conditional = req.headers().contains_key(header::IF_MODIFIED_SINCE) || 19 | req.headers().contains_key(header::IF_NONE_MATCH); 20 | 21 | if is_conditional { 22 | let resp = req.build_response(StatusCode::NOT_MODIFIED) 23 | .finish(); 24 | Box::new(future::ok(resp)) 25 | } else { 26 | let future = Body::new(req) 27 | .with_url() 28 | .with_headers() 29 | .with_origin() 30 | .with_args() 31 | .and_then(|body| { 32 | let uuid = uuid::Uuid::new_v4().hyphenated().to_string(); 33 | let resp = HttpResponse::build(StatusCode::OK) 34 | .set(header::LastModified(SystemTime::now().into())) 35 | .set(header::ETag(header::EntityTag::new(false, uuid))) 36 | .json(body); 37 | 38 | Ok(resp) 39 | }); 40 | 41 | Box::new(future) 42 | } 43 | } 44 | 45 | /// Sets a `Cache-Control` header for `n` seconds. 46 | pub fn cache_control((req, info): (HttpRequest, Path)) -> Box { 47 | let future = Body::new(req) 48 | .with_url() 49 | .with_headers() 50 | .with_origin() 51 | .with_args() 52 | .and_then(move |body| { 53 | let resp = HttpResponse::build(StatusCode::OK) 54 | .set(header::CacheControl(vec![ 55 | header::CacheDirective::Public, 56 | header::CacheDirective::MaxAge(*info), 57 | ])) 58 | .json(body); 59 | 60 | Ok(resp) 61 | }); 62 | 63 | Box::new(future) 64 | } 65 | 66 | /// Assumes the resource has the given `etag` and responds to `If-None-Match` and `If-Match` headers appropriately. 67 | pub fn etag((req, info): (HttpRequest, Path)) -> Box { 68 | if let Ok(if_none_match) = header::IfNoneMatch::parse(&req) { 69 | let matches = match if_none_match { 70 | header::IfNoneMatch::Any => true, 71 | header::IfNoneMatch::Items(tags) => tags.iter().any(|entity| entity.tag() == *info) 72 | }; 73 | 74 | if matches { 75 | let resp = req.build_response(StatusCode::NOT_MODIFIED) 76 | .set(header::ETag(header::EntityTag::new(false, (*info).to_string()))) 77 | .finish(); 78 | 79 | return Box::new(future::ok(resp)); 80 | } 81 | } 82 | 83 | if let Ok(if_match) = header::IfMatch::parse(&req) { 84 | let matches = match if_match { 85 | header::IfMatch::Any => true, 86 | header::IfMatch::Items(tags) => tags.iter().any(|entity| entity.tag() == *info) 87 | }; 88 | 89 | if !matches { 90 | return Box::new(future::ok(HttpResponse::PreconditionFailed().finish())) 91 | } 92 | } 93 | 94 | let future = Body::new(req) 95 | .with_url() 96 | .with_headers() 97 | .with_origin() 98 | .with_args() 99 | .and_then(move |body| { 100 | let resp = HttpResponse::build(StatusCode::OK) 101 | .json(body); 102 | 103 | Ok(resp) 104 | }); 105 | 106 | Box::new(future) 107 | } 108 | 109 | 110 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 111 | pub fn headers(req: HttpRequest) -> Result { 112 | let mut resp = req.build_response(StatusCode::OK); 113 | for (key, value) in req.query().iter() { 114 | resp.header::<&str, &str>(key.borrow(), value.borrow()); 115 | } 116 | 117 | Ok(resp.finish()) 118 | } 119 | -------------------------------------------------------------------------------- /src/handlers/statuses.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{HttpResponse, Path, Result, error}; 2 | use actix_web::http::StatusCode; 3 | 4 | /// Return given status code. 5 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 6 | pub fn status(info: Path) -> Result { 7 | let code = StatusCode::from_u16(*info) 8 | .map_err(error::ErrorBadRequest)?; 9 | 10 | Ok(HttpResponse::new(code)) 11 | } 12 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(feature = "nightly", feature(test))] 2 | 3 | #[cfg(feature = "nightly")] extern crate test; 4 | extern crate url; 5 | extern crate http; 6 | extern crate uuid; 7 | extern crate base64; 8 | extern crate mime; 9 | extern crate actix_web; 10 | extern crate actix_web_httpauth; 11 | extern crate serde; 12 | #[macro_use] extern crate serde_json; 13 | extern crate serde_urlencoded; 14 | #[macro_use] extern crate serde_derive; 15 | extern crate linked_hash_map; 16 | extern crate env_logger; 17 | extern crate clap; 18 | extern crate futures; 19 | extern crate bytes; 20 | extern crate rand; 21 | extern crate tokio_timer; 22 | extern crate tera; 23 | 24 | use actix_web::server; 25 | use clap::{Arg, App}; 26 | 27 | mod application; 28 | mod middleware; 29 | mod response; 30 | mod handlers; 31 | mod templates; 32 | mod map; 33 | 34 | fn main() { 35 | ::std::env::set_var("RUST_LOG", "actix_web=info"); 36 | env_logger::init(); 37 | 38 | let matches = App::new("actix-httpbin") 39 | .version(env!("CARGO_PKG_VERSION")) 40 | .about("httpbin.org clone with Rust and actix-web") 41 | .arg(Arg::with_name("bind") 42 | .short("b") 43 | .long("bind") 44 | .takes_value(true) 45 | ) 46 | .get_matches(); 47 | 48 | let bind = matches.value_of("bind") 49 | .unwrap_or("127.0.0.1:8080"); 50 | 51 | server::new(application::app) 52 | .backlog(8192) 53 | .bind(bind).expect(&format!("Unable to bind to {}", bind)) 54 | .run(); 55 | } 56 | -------------------------------------------------------------------------------- /src/map.rs: -------------------------------------------------------------------------------- 1 | use std::iter::FromIterator; 2 | use std::collections::HashMap; 3 | use std::collections::hash_map::Entry; 4 | 5 | use serde::{Serialize, Serializer}; 6 | use serde::ser::SerializeMap; 7 | 8 | /// Wrapper for `HashMap` with additional serialization features: 9 | /// * keys are sorted alphabetically 10 | /// * if value vec have only one element, it will be serialized as an element, not a `vec![element]` 11 | #[derive(Debug, Clone)] 12 | pub struct PickyHashMap(HashMap); 13 | 14 | impl PickyHashMap { 15 | pub fn new() -> PickyHashMap { 16 | PickyHashMap( 17 | HashMap::new() 18 | ) 19 | } 20 | 21 | pub fn entry(&mut self, key: String) -> Entry { 22 | self.0.entry(key) 23 | } 24 | 25 | } 26 | 27 | impl FromIterator<(String, V)> for PickyHashMap { 28 | fn from_iter>(iter: T) -> PickyHashMap { 29 | let mut map = HashMap::with_hasher(Default::default()); 30 | map.extend(iter); 31 | 32 | PickyHashMap(map) 33 | } 34 | } 35 | 36 | 37 | impl Serialize for PickyHashMap> { 38 | fn serialize(&self, serializer: S) -> Result where S: Serializer { 39 | let mut entries = self.0.iter().collect::>(); 40 | entries.sort_unstable_by(|(key1, _), (key2, _)| key1.cmp(key2)); 41 | 42 | let mut map = serializer.serialize_map(Some(self.0.len()))?; 43 | for (key, value) in entries { 44 | if value.len() == 1 { 45 | map.serialize_entry(key, &value[0])?; 46 | } else { 47 | map.serialize_entry(key, value)?; 48 | } 49 | } 50 | map.end() 51 | } 52 | } 53 | 54 | impl Serialize for PickyHashMap { 55 | fn serialize(&self, serializer: S) -> Result where S: Serializer { 56 | let mut entries = self.0.iter().collect::>(); 57 | entries.sort_unstable_by(|(key1, _), (key2, _)| key1.cmp(key2)); 58 | 59 | let mut map = serializer.serialize_map(Some(self.0.len()))?; 60 | for (key, value) in entries { 61 | map.serialize_entry(key, value)?; 62 | } 63 | map.end() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/middleware.rs: -------------------------------------------------------------------------------- 1 | use actix_web::http::header::HeaderValue; 2 | use actix_web::{HttpRequest, HttpResponse, HttpMessage, Result}; 3 | use actix_web::middleware::{Middleware, Response}; 4 | use actix_web::http::header; 5 | 6 | pub struct Headers; 7 | 8 | impl Middleware for Headers { 9 | 10 | fn response(&self, req: &mut HttpRequest, mut resp: HttpResponse) -> Result { 11 | let origin = req.headers().get(header::ORIGIN) 12 | .and_then(|value| Some(value.clone())) 13 | .unwrap_or_else(|| HeaderValue::from_static("*")); 14 | 15 | { 16 | let headers = resp.headers_mut(); 17 | 18 | headers.insert(header::ACCESS_CONTROL_ALLOW_CREDENTIALS, HeaderValue::from_static("'true'")); 19 | headers.insert(header::ACCESS_CONTROL_ALLOW_ORIGIN, origin); 20 | headers.insert("X-Powered-By", HeaderValue::from_static("actix-httpbin")); 21 | } 22 | 23 | Ok(Response::Done(resp)) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/response/errors.rs: -------------------------------------------------------------------------------- 1 | use std::convert::{From, Into}; 2 | 3 | use actix_web; 4 | use serde_json; 5 | 6 | pub enum Error { 7 | Empty, 8 | Serde(serde_json::Error), 9 | } 10 | 11 | impl From<()> for Error { 12 | fn from(_: ()) -> Self { 13 | Error::Empty 14 | } 15 | } 16 | 17 | impl From for Error { 18 | fn from(e: serde_json::Error) -> Self { 19 | Error::Serde(e) 20 | } 21 | } 22 | 23 | impl Into for Error { 24 | fn into(self) -> actix_web::Error { 25 | unimplemented!() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/response/formatters/bytes.rs: -------------------------------------------------------------------------------- 1 | use std::convert::From; 2 | 3 | use serde_json; 4 | use bytes::Bytes; 5 | use futures::{Future, Poll, Async}; 6 | 7 | use response::{Body, Error}; 8 | 9 | pub type BytesFuture = Future; 10 | 11 | 12 | pub struct BytesFormatter(F); 13 | 14 | impl BytesFormatter { 15 | pub fn new(f: F) -> BytesFormatter { 16 | BytesFormatter(f) 17 | } 18 | } 19 | 20 | impl<'r, F> Future for BytesFormatter where F: Future { 21 | type Item = Bytes; 22 | type Error = Error; 23 | 24 | fn poll(&mut self) -> Poll<::Item, ::Error> { 25 | match self.0.poll() { 26 | Ok(Async::NotReady) => Ok(Async::NotReady), 27 | Ok(Async::Ready(body)) => { 28 | match serde_json::to_vec(&body) { 29 | Ok(bytes) => Ok(Async::Ready(Bytes::from(bytes))), 30 | Err(e) => Err(From::from(e)), 31 | } 32 | }, 33 | Err(e) => Err(e), 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/response/formatters/json.rs: -------------------------------------------------------------------------------- 1 | use actix_web::Json; 2 | use futures::{Future, Poll, Async}; 3 | 4 | use response::{Body, Error}; 5 | 6 | pub type JsonFuture = Future>, Error=Error>; 7 | 8 | 9 | pub struct JsonFormatter(F); 10 | 11 | impl JsonFormatter { 12 | pub fn new(f: F) -> JsonFormatter { 13 | JsonFormatter(f) 14 | } 15 | } 16 | 17 | impl<'r, F, S> Future for JsonFormatter where F: Future, Error=Error> { 18 | type Item = Json>; 19 | type Error = Error; 20 | 21 | fn poll(&mut self) -> Poll<::Item, ::Error> { 22 | match self.0.poll() { 23 | Ok(Async::NotReady) => Ok(Async::NotReady), 24 | Ok(Async::Ready(body)) => Ok(Async::Ready(Json(body))), 25 | Err(e) => Err(e), 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/response/formatters/json_value.rs: -------------------------------------------------------------------------------- 1 | use std::convert::From; 2 | 3 | use futures::{Future, Poll, Async}; 4 | use serde_json; 5 | 6 | use response::{Body, Error}; 7 | 8 | pub type JsonValueFuture = Future; 9 | 10 | 11 | #[derive(Debug)] 12 | pub struct JsonValueFormatter(F); 13 | 14 | impl JsonValueFormatter { 15 | pub fn new(f: F) -> JsonValueFormatter { 16 | JsonValueFormatter(f) 17 | } 18 | } 19 | 20 | impl Future for JsonValueFormatter where F: Future, Error=Error> { 21 | type Item = serde_json::Value; 22 | type Error = Error; 23 | 24 | fn poll(&mut self) -> Poll<::Item, ::Error> { 25 | match self.0.poll() { 26 | Ok(Async::NotReady) => Ok(Async::NotReady), 27 | Ok(Async::Ready(body)) => { 28 | match serde_json::to_value(&body) { 29 | Ok(value) => Ok(Async::Ready(value)), 30 | Err(e) => Err(From::from(e)), 31 | } 32 | }, 33 | Err(e) => Err(e), 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/response/formatters/mod.rs: -------------------------------------------------------------------------------- 1 | mod json; 2 | //mod bytes; 3 | mod response; 4 | mod json_value; 5 | 6 | pub use self::json::{JsonFormatter, JsonFuture}; 7 | //pub use self::bytes::{BytesFormatter, BytesFuture}; 8 | pub use self::response::{ResponseFormatter, ResponseFuture}; 9 | pub use self::json_value::{JsonValueFormatter, JsonValueFuture}; 10 | -------------------------------------------------------------------------------- /src/response/formatters/response.rs: -------------------------------------------------------------------------------- 1 | use actix_web::HttpResponse; 2 | use actix_web::http::StatusCode; 3 | use futures::{Future, Poll, Async}; 4 | use serde_json; 5 | 6 | use response::{Body, Error}; 7 | 8 | pub type ResponseFuture = Future; 9 | 10 | 11 | pub struct ResponseFormatter(F); 12 | 13 | impl ResponseFormatter { 14 | pub fn new(f: F) -> ResponseFormatter { 15 | ResponseFormatter(f) 16 | } 17 | } 18 | 19 | impl<'r, F, S> Future for ResponseFormatter where F: Future, Error=Error> { 20 | type Item = HttpResponse; 21 | type Error = Error; 22 | 23 | fn poll(&mut self) -> Poll<::Item, ::Error> { 24 | match self.0.poll() { 25 | Ok(Async::NotReady) => Ok(Async::NotReady), 26 | Ok(Async::Ready(body)) => { 27 | let resp = HttpResponse::build(StatusCode::OK) 28 | .content_type("application/json") 29 | .body(serde_json::to_string(&body)?); 30 | 31 | Ok(Async::Ready(resp)) 32 | }, 33 | Err(e) => Err(e), 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/response/mod.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use actix_web::HttpRequest; 4 | use futures::{Future, Poll, Async}; 5 | use serde::Serialize; 6 | use serde_json::Value; 7 | 8 | mod modifiers; 9 | mod formatters; 10 | mod errors; 11 | 12 | pub use self::formatters::{JsonFuture, JsonValueFuture, ResponseFuture}; 13 | pub use self::errors::Error; 14 | use map::PickyHashMap; 15 | 16 | #[derive(Debug, Clone, Serialize)] 17 | pub struct Body { 18 | #[serde(skip)] 19 | request: HttpRequest, 20 | 21 | #[serde(skip_serializing_if = "Option::is_none")] 22 | method: Option, 23 | 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | url: Option, 26 | 27 | #[serde(skip_serializing_if = "Option::is_none")] 28 | origin: Option, 29 | 30 | #[serde(skip_serializing_if = "Option::is_none")] 31 | args: Option>>, 32 | 33 | #[serde(skip_serializing_if = "Option::is_none")] 34 | headers: Option>, 35 | 36 | #[serde(skip_serializing_if = "Option::is_none")] 37 | user_agent: Option, 38 | 39 | #[serde(flatten)] 40 | extra: HashMap<&'static str, Value>, 41 | } 42 | 43 | impl Body { 44 | #[cfg_attr(feature = "cargo-clippy", allow(new_ret_no_self))] 45 | pub fn new(req: HttpRequest) -> New { 46 | New(Some(Body{ 47 | request: req, 48 | method: None, 49 | url: None, 50 | origin: None, 51 | args: None, 52 | headers: None, 53 | user_agent: None, 54 | extra: HashMap::new(), 55 | })) 56 | } 57 | } 58 | 59 | 60 | pub trait Builder: Future> + Sized { 61 | fn with_method(self) -> modifiers::Method { 62 | modifiers::Method::new(self) 63 | } 64 | 65 | fn with_url(self) -> modifiers::Url { 66 | modifiers::Url::new(self) 67 | } 68 | 69 | fn with_args(self) -> modifiers::Args { 70 | modifiers::Args::new(self) 71 | } 72 | 73 | fn with_headers(self) -> modifiers::Headers { 74 | modifiers::Headers::new(self) 75 | } 76 | 77 | fn with_origin(self) -> modifiers::Origin { 78 | modifiers::Origin::new(self) 79 | } 80 | 81 | fn with_user_agent(self) -> modifiers::UserAgent { 82 | modifiers::UserAgent::new(self) 83 | } 84 | 85 | fn with_extra(self, key: &'static str, value: V) -> modifiers::Extra { 86 | modifiers::Extra::new(self, key, value) 87 | } 88 | 89 | fn into_json(self) -> formatters::JsonFormatter { 90 | formatters::JsonFormatter::new(self) 91 | } 92 | 93 | fn into_json_value(self) -> formatters::JsonValueFormatter { 94 | formatters::JsonValueFormatter::new(self) 95 | } 96 | 97 | // fn into_bytes(self) -> formatters::BytesFormatter { 98 | // formatters::BytesFormatter::new(self) 99 | // } 100 | 101 | fn into_response(self) -> formatters::ResponseFormatter { 102 | formatters::ResponseFormatter::new(self) 103 | } 104 | } 105 | 106 | 107 | /// Future that will be resolved into a `Body` instance. 108 | #[derive(Debug, Clone)] 109 | pub struct New(Option>); 110 | 111 | impl Future for New { 112 | type Item = Body; 113 | type Error = Error; 114 | 115 | fn poll(&mut self) -> Poll<::Item, ::Error> { 116 | Ok(Async::Ready(self.0.take().expect("Can't poll twice"))) 117 | } 118 | } 119 | 120 | impl Builder for New {} 121 | -------------------------------------------------------------------------------- /src/response/modifiers/args.rs: -------------------------------------------------------------------------------- 1 | use url::form_urlencoded; 2 | use futures::{Future, Poll, Async}; 3 | 4 | use response::{Body, Builder, Error}; 5 | use map::PickyHashMap; 6 | 7 | 8 | /// Attach query arguments to `Body`. 9 | #[derive(Debug, Clone)] 10 | pub struct Args(F); 11 | 12 | impl Args { 13 | pub fn new(f: F) -> Args { 14 | Args(f) 15 | } 16 | } 17 | 18 | impl Future for Args where F: Future, Error=Error> { 19 | type Item = Body; 20 | type Error = Error; 21 | 22 | fn poll(&mut self) -> Poll<::Item, ::Error> { 23 | let e = match self.0.poll() { 24 | Ok(Async::NotReady) => return Ok(Async::NotReady), 25 | Ok(Async::Ready(body)) => Ok(body), 26 | Err(e) => Err(e), 27 | }; 28 | 29 | e.map(|mut body| { 30 | let mut args = PickyHashMap::new(); 31 | for (key, value) in form_urlencoded::parse(body.request.query_string().as_ref()) { 32 | let mut entry = args.entry(key.into_owned()).or_insert_with(|| { 33 | Vec::with_capacity(1) 34 | }); 35 | 36 | (*entry).push(value.into_owned()); 37 | } 38 | body.args = Some(args); 39 | 40 | body 41 | }).map(Async::Ready) 42 | } 43 | } 44 | 45 | impl Builder for Args where F: Future, Error=Error> {} 46 | -------------------------------------------------------------------------------- /src/response/modifiers/extra.rs: -------------------------------------------------------------------------------- 1 | use std::convert::From; 2 | 3 | use futures::{Future, Poll, Async}; 4 | use serde::Serialize; 5 | use serde_json; 6 | use response::{Body, Builder, Error}; 7 | 8 | 9 | pub struct Extra where V: Serialize { 10 | inner: F, 11 | key: &'static str, 12 | value: V, 13 | } 14 | 15 | impl Extra where V: Serialize { 16 | pub fn new(f: F, key: &'static str, value: V) -> Extra { 17 | Extra{ 18 | inner: f, 19 | key, 20 | value 21 | } 22 | } 23 | } 24 | 25 | impl Future for Extra where F: Future, Error=Error>, V: Serialize { 26 | type Item = Body; 27 | type Error = Error; 28 | 29 | fn poll(&mut self) -> Poll<::Item, ::Error> { 30 | match self.inner.poll() { 31 | Ok(Async::NotReady) => Ok(Async::NotReady), 32 | Ok(Async::Ready(mut body)) => { 33 | match serde_json::to_value(&self.value) { 34 | Ok(serialized) => { 35 | body.extra.insert(self.key, serialized); 36 | Ok(Async::Ready(body)) 37 | }, 38 | Err(e) => Err(From::from(e)), 39 | } 40 | }, 41 | Err(e) => Err(e), 42 | } 43 | } 44 | } 45 | 46 | impl Builder for Extra where F: Future, Error=Error>, V: Serialize {} 47 | -------------------------------------------------------------------------------- /src/response/modifiers/headers.rs: -------------------------------------------------------------------------------- 1 | use futures::{Future, Poll, Async}; 2 | use actix_web::HttpMessage; 3 | 4 | use response::{Body, Builder, Error}; 5 | use map::PickyHashMap; 6 | 7 | 8 | /// Attach headers map to `Body`. 9 | #[derive(Debug, Clone)] 10 | pub struct Headers(F); 11 | 12 | impl Headers { 13 | pub fn new(f: F) -> Headers { 14 | Headers(f) 15 | } 16 | } 17 | 18 | impl Future for Headers where F: Future, Error=Error> { 19 | type Item = Body; 20 | type Error = Error; 21 | 22 | fn poll(&mut self) -> Poll<::Item, ::Error> { 23 | let e = match self.0.poll() { 24 | Ok(Async::NotReady) => return Ok(Async::NotReady), 25 | Ok(Async::Ready(body)) => Ok(body), 26 | Err(e) => Err(e), 27 | }; 28 | 29 | e.map(|mut body| { 30 | let headers: PickyHashMap<_> = body.request.headers().iter().map(|(key, value)| { 31 | // TODO: Handle `.unwrap()` 32 | (key.as_str().to_string(), value.to_str().unwrap().to_string()) 33 | }).collect(); 34 | body.headers = Some(headers); 35 | 36 | body 37 | }).map(Async::Ready) 38 | } 39 | } 40 | 41 | impl Builder for Headers where F: Future, Error=Error> {} 42 | -------------------------------------------------------------------------------- /src/response/modifiers/method.rs: -------------------------------------------------------------------------------- 1 | use futures::{Future, Poll, Async}; 2 | 3 | use response::{Body, Builder, Error}; 4 | 5 | 6 | #[derive(Debug, Clone)] 7 | pub struct Method(F); 8 | 9 | impl Method { 10 | pub fn new(f: F) -> Method { 11 | Method(f) 12 | } 13 | } 14 | 15 | impl Future for Method where F: Future, Error=Error> { 16 | type Item = Body; 17 | type Error = Error; 18 | 19 | fn poll(&mut self) -> Poll<::Item, ::Error> { 20 | let e = match self.0.poll() { 21 | Ok(Async::NotReady) => return Ok(Async::NotReady), 22 | Ok(Async::Ready(body)) => Ok(body), 23 | Err(e) => Err(e), 24 | }; 25 | 26 | e.map(|mut body: Body| { 27 | body.method = Some(body.request.method().as_str().to_string()); 28 | body 29 | }).map(Async::Ready) 30 | } 31 | } 32 | 33 | impl Builder for Method where F: Future, Error=Error> {} 34 | -------------------------------------------------------------------------------- /src/response/modifiers/mod.rs: -------------------------------------------------------------------------------- 1 | mod args; 2 | mod headers; 3 | mod origin; 4 | mod user_agent; 5 | mod method; 6 | mod url; 7 | mod extra; 8 | 9 | pub use self::args::Args; 10 | pub use self::headers::Headers; 11 | pub use self::origin::Origin; 12 | pub use self::user_agent::UserAgent; 13 | pub use self::method::Method; 14 | pub use self::url::Url; 15 | pub use self::extra::Extra; 16 | -------------------------------------------------------------------------------- /src/response/modifiers/origin.rs: -------------------------------------------------------------------------------- 1 | use futures::{Future, Poll, Async}; 2 | 3 | use response::{Body, Builder, Error}; 4 | 5 | /// Attach origin IP to `Body`. 6 | #[derive(Debug, Clone)] 7 | pub struct Origin(F); 8 | 9 | impl Origin { 10 | pub fn new(f: F) -> Origin { 11 | Origin(f) 12 | } 13 | } 14 | 15 | impl Future for Origin where F: Future, Error=Error> { 16 | type Item = Body; 17 | type Error = Error; 18 | 19 | fn poll(&mut self) -> Poll<::Item, ::Error> { 20 | let e = match self.0.poll() { 21 | Ok(Async::NotReady) => return Ok(Async::NotReady), 22 | Ok(Async::Ready(body)) => Ok(body), 23 | Err(e) => Err(e), 24 | }; 25 | 26 | e.map(|mut body: Body| { 27 | let origin = match body.request.connection_info().remote() { 28 | Some(remote) => remote.split(':').next().unwrap_or("").to_string(), 29 | None => "".to_string() 30 | }; 31 | 32 | body.origin = Some(origin); 33 | 34 | body 35 | }).map(Async::Ready) 36 | } 37 | } 38 | 39 | impl<'r, F, S> Builder for Origin where F: Future, Error=Error> {} 40 | -------------------------------------------------------------------------------- /src/response/modifiers/url.rs: -------------------------------------------------------------------------------- 1 | use futures::{Future, Poll, Async}; 2 | 3 | use response::{Body, Builder, Error}; 4 | 5 | 6 | #[derive(Debug, Clone)] 7 | pub struct Url(F); 8 | 9 | impl Url { 10 | pub fn new(f: F) -> Url { 11 | Url(f) 12 | } 13 | } 14 | 15 | impl Future for Url where F: Future, Error=Error> { 16 | type Item = Body; 17 | type Error = Error; 18 | 19 | fn poll(&mut self) -> Poll<::Item, ::Error> { 20 | let e = match self.0.poll() { 21 | Ok(Async::NotReady) => return Ok(Async::NotReady), 22 | Ok(Async::Ready(body)) => Ok(body), 23 | Err(e) => Err(e), 24 | }; 25 | 26 | e.map(|mut body: Body| { 27 | { 28 | let conn = body.request.connection_info(); 29 | body.url = Some(format!("{}://{}{}", conn.scheme(), conn.host(), body.request.path())); 30 | } 31 | 32 | body 33 | }).map(Async::Ready) 34 | } 35 | } 36 | 37 | impl Builder for Url where F: Future, Error=Error> {} 38 | -------------------------------------------------------------------------------- /src/response/modifiers/user_agent.rs: -------------------------------------------------------------------------------- 1 | use futures::{Future, Poll, Async}; 2 | use actix_web::http::header::USER_AGENT; 3 | use actix_web::HttpMessage; 4 | 5 | use response::{Body, Builder, Error}; 6 | 7 | 8 | /// Attach query arguments to `Body`. 9 | #[derive(Debug, Clone)] 10 | pub struct UserAgent(F); 11 | 12 | impl UserAgent { 13 | pub fn new(f: F) -> UserAgent { 14 | UserAgent(f) 15 | } 16 | } 17 | 18 | impl Future for UserAgent where F: Future, Error=Error> { 19 | type Item = Body; 20 | type Error = Error; 21 | 22 | fn poll(&mut self) -> Poll<::Item, ::Error> { 23 | let e = match self.0.poll() { 24 | Ok(Async::NotReady) => return Ok(Async::NotReady), 25 | Ok(Async::Ready(body)) => Ok(body), 26 | Err(e) => Err(e), 27 | }; 28 | 29 | e.map(|mut body| { 30 | if let Some(header) = body.request.headers().get(USER_AGENT) { 31 | // TODO: Handle error 32 | body.user_agent = Some(header.to_str().unwrap_or("").to_string()) 33 | } 34 | 35 | body 36 | }).map(Async::Ready) 37 | } 38 | } 39 | 40 | impl Builder for UserAgent where F: Future, Error=Error> {} 41 | -------------------------------------------------------------------------------- /src/templates.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{HttpRequest, HttpResponse, Result, http, error}; 2 | use tera::{self, Tera}; 3 | pub use tera::Context; 4 | 5 | use application::State; 6 | 7 | // Since all assets are bundled into an application, 8 | // we need to create tera with a bundled templates too. 9 | pub fn create_tera() -> tera::Result { 10 | let mut tera = Tera::default(); 11 | tera.add_raw_templates(vec![ 12 | ("index.html", include_str!("./assets/index.html")), 13 | ("links.html", include_str!("./assets/links.html")), 14 | ("forms-post.html", include_str!("./assets/forms-post.html")) 15 | ])?; 16 | 17 | Ok(tera) 18 | } 19 | 20 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 21 | pub fn render(req: HttpRequest, template: &'static str, context: &Context) -> Result { 22 | let body = req.state().template 23 | .render(template, context) 24 | .map_err(|e| { 25 | error::ErrorInternalServerError(format!("{:#?}", e)) 26 | })?; 27 | 28 | Ok(req.build_response(http::StatusCode::OK) 29 | .content_type("text/html") 30 | .body(body)) 31 | } 32 | --------------------------------------------------------------------------------