├── .cargo ├── audit.toml └── config.toml ├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── appveyor.yml ├── assets ├── adjust_tz.js ├── directory_listing.html ├── directory_listing_mobile.html ├── encoding_blacklist ├── error.html ├── favicon.ico ├── favicon.png ├── icons │ ├── LICENSE │ ├── back_arrow.gif │ ├── confirm.gif │ ├── delete_file.png │ ├── directory.gif │ ├── file.gif │ ├── file_binary.gif │ ├── file_image.gif │ ├── file_text.gif │ ├── new_directory.gif │ ├── new_directory.psd │ └── rename.gif ├── manage.js ├── manage_desktop.js ├── manage_mobile.js ├── upload.css └── upload.js ├── build-ioctl.c ├── build.rs ├── http-manifest.rc ├── http.md ├── install.nsi ├── install.sh ├── rustfmt.toml ├── src ├── main.rs ├── ops │ ├── bandwidth.rs │ ├── mod.rs │ ├── prune.rs │ └── webdav.rs ├── options.rs └── util │ ├── content_encoding.rs │ ├── mod.rs │ ├── os │ ├── mod.rs │ ├── non_windows.rs │ ├── non_windows_non_macos.rs │ ├── windows.rs │ └── windows_macos.rs │ └── webdav.rs └── vendor ├── hyper-0.10.16 ├── .cargo_vcs_info.json ├── Cargo.toml ├── Cargo.toml.orig ├── LICENSE └── src │ ├── buffer.rs │ ├── error.rs │ ├── header │ ├── common │ │ ├── accept.rs │ │ ├── accept_charset.rs │ │ ├── accept_encoding.rs │ │ ├── accept_ranges.rs │ │ ├── access_control_allow_credentials.rs │ │ ├── access_control_allow_headers.rs │ │ ├── access_control_allow_methods.rs │ │ ├── access_control_allow_origin.rs │ │ ├── access_control_expose_headers.rs │ │ ├── access_control_max_age.rs │ │ ├── access_control_request_headers.rs │ │ ├── access_control_request_method.rs │ │ ├── allow.rs │ │ ├── authorization.rs │ │ ├── cache_control.rs │ │ ├── connection.rs │ │ ├── content_encoding.rs │ │ ├── content_length.rs │ │ ├── content_range.rs │ │ ├── content_type.rs │ │ ├── cookie.rs │ │ ├── date.rs │ │ ├── etag.rs │ │ ├── expect.rs │ │ ├── expires.rs │ │ ├── from.rs │ │ ├── host.rs │ │ ├── if_match.rs │ │ ├── if_modified_since.rs │ │ ├── if_none_match.rs │ │ ├── if_range.rs │ │ ├── if_unmodified_since.rs │ │ ├── last-event-id.rs │ │ ├── last_modified.rs │ │ ├── link.rs │ │ ├── location.rs │ │ ├── mod.rs │ │ ├── origin.rs │ │ ├── pragma.rs │ │ ├── prefer.rs │ │ ├── preference_applied.rs │ │ ├── range.rs │ │ ├── referer.rs │ │ ├── referrer_policy.rs │ │ ├── server.rs │ │ ├── set_cookie.rs │ │ ├── strict_transport_security.rs │ │ ├── transfer_encoding.rs │ │ ├── upgrade.rs │ │ ├── user_agent.rs │ │ └── vary.rs │ ├── internals │ │ ├── cell.rs │ │ ├── item.rs │ │ ├── mod.rs │ │ └── vec_map.rs │ ├── mod.rs │ ├── parsing.rs │ └── shared │ │ ├── charset.rs │ │ ├── encoding.rs │ │ ├── entity.rs │ │ ├── httpdate.rs │ │ ├── mod.rs │ │ └── quality_item.rs │ ├── http │ ├── h1.rs │ └── mod.rs │ ├── lib.rs │ ├── method.rs │ ├── net.rs │ ├── server │ ├── listener.rs │ ├── mod.rs │ ├── request.rs │ └── response.rs │ ├── status.rs │ ├── uri.rs │ └── version.rs ├── iron-0.6.1 ├── .cargo_vcs_info.json ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── Cargo.toml ├── Cargo.toml.orig ├── LICENSE ├── README.md ├── circle.yml ├── examples │ ├── 404.rs │ ├── around.rs │ ├── content_type.rs │ ├── echo.rs │ ├── error.rs │ ├── error_recovery.rs │ ├── get_set_headers.rs │ ├── hello.rs │ ├── hello_custom_config.rs │ ├── helper_macros.rs │ ├── https.rs │ ├── redirect.rs │ ├── simple_routing.rs │ └── time.rs └── src │ ├── error.rs │ ├── iron.rs │ ├── lib.rs │ ├── macros.rs │ ├── middleware │ ├── mod.rs │ └── test.rs │ ├── modifiers.rs │ ├── request │ ├── mod.rs │ └── url.rs │ └── response.rs └── rfsapi-0.2.0 ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE ├── README.md ├── gh_rsa.enc ├── rfsapi-rs.sublime-project ├── rustfmt.toml ├── src ├── lib.rs └── util.rs └── tests ├── data ├── mod.rs ├── raw_file_data.rs └── raw_fs_api_header.rs ├── lib.rs └── util ├── mod.rs └── parse_rfc3339.rs /.cargo/audit.toml: -------------------------------------------------------------------------------- 1 | # https://github.com/thecoshman/http/issues/140 2 | [advisories] 3 | ignore = ["RUSTSEC-2021-0078", "RUSTSEC-2021-0079", "RUSTSEC-2020-0071", "RUSTSEC-2021-0139", "RUSTSEC-2023-0081", "RUSTSEC-2021-0144", "RUSTSEC-2021-0145", "RUSTSEC-2020-0027", "RUSTSEC-2022-0022"] 4 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # Needed for st_dev/st_ino on windows ("windows_by_handle") 2 | # available since 2019 in 1.38: https://github.com/rust-lang/rust/commit/c69f367bafb3a2f90d44fe54fc20d57996fa294a 3 | [env] 4 | RUSTC_BOOTSTRAP = "1" 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !appveyor.yml 4 | !LICENSE 5 | !Cargo.toml 6 | !rustfmt.toml 7 | !build.rs 8 | !build-ioctl.c 9 | !http-manifest.rc 10 | !install.* 11 | !*.md 12 | !.cargo 13 | !.cargo/** 14 | !src 15 | !src/** 16 | !assets 17 | !assets/** 18 | !vendor 19 | !vendor/** 20 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | # "http" was taken, "https" (with 's' apparently standing for "server") is free 3 | name = "https" 4 | description = "Host These Things Please - a basic http server for hosting a folder fast and simply" 5 | repository = "https://github.com/thecoshman/http" 6 | readme = "README.md" 7 | keywords = ["http", "server", "https", "webdav", "directory"] 8 | categories = ["network-programming", "web-programming::http-server"] 9 | license = "MIT" 10 | build = "build.rs" 11 | # Remember to also update in appveyor.yml and the http-crates.io branch 12 | version = "2.2.1" 13 | # Remember to also update in http.md 14 | authors = ["thecoshman ", 15 | "nabijaczleweli ", 16 | "pheki", 17 | "Adrian Herath ", 18 | "cyqsimon", 19 | "jim4067", 20 | "Orhun Parmaksız ", 21 | "Kian-Meng Ang ", 22 | "Theodore Ni", 23 | "Thorbjørn Lindeijer ", 24 | "ideless ", 25 | "Sympatron GmbH"] 26 | 27 | [dependencies] 28 | hyper-native-tls = "0.3" 29 | percent-encoding = "2.1" 30 | serde_json = "1.0" 31 | mime_guess = "1.8" 32 | tabwriter = "1.1" 33 | arrayvec = "0.7" 34 | walkdir = "2.2" 35 | blake3 = "1.3" 36 | flate2 = "1.0" 37 | xml-rs = "0.8" 38 | ctrlc = "3.1" 39 | serde = "1.0" 40 | clap = "2.33" 41 | libc = "0.2" 42 | time = "0.1" 43 | 44 | [dependencies.trivial_colours] 45 | version = "0.3" 46 | default-features = false 47 | 48 | [dependencies.rfsapi] 49 | path = "vendor/rfsapi-0.2.0" 50 | 51 | [dependencies.cidr] 52 | version = "0.1" 53 | default-features = false 54 | 55 | [dependencies.brotli] 56 | version = "6.0" 57 | features = ["simd"] 58 | 59 | [dependencies.iron] 60 | path = "vendor/iron-0.6.1" 61 | features = ["hyper-native-tls"] 62 | 63 | [patch.crates-io.hyper] 64 | path = "vendor/hyper-0.10.16" 65 | 66 | [target.'cfg(target_os = "windows")'.dependencies.winapi] 67 | version = "0.3" 68 | features = ["fileapi"] 69 | 70 | 71 | [build-dependencies] 72 | embed-resource = "1.3" 73 | base64 = "0.10" 74 | 75 | [target.'cfg(not(any(target_os = "windows", target_os = "macos")))'.build-dependencies.cc] 76 | version = "1.0" 77 | 78 | 79 | [[bin]] 80 | name = "http" 81 | path = "src/main.rs" 82 | test = false 83 | doc = false 84 | 85 | [[bin]] 86 | name = "httplz" 87 | path = "src/main.rs" 88 | test = false 89 | doc = false 90 | 91 | 92 | [package.metadata.deb] 93 | name = "http" 94 | maintainer = "nabijaczleweli " 95 | section = "web" 96 | 97 | [profile.release] 98 | lto = true 99 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 thecoshman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: 2 | - Visual Studio 2022 3 | 4 | version: 2.2.1-{build} 5 | 6 | skip_tags: false 7 | 8 | platform: x64 9 | configuration: Release 10 | 11 | clone_folder: C:\http 12 | 13 | install: 14 | - set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%;C:\Users\appveyor\.cargo\bin 15 | # Double upgrade required here 16 | - bash -lc "pacman --noconfirm -Syyu" 17 | - bash -lc "pacman --noconfirm -Syyu" 18 | - bash -lc "pacman --noconfirm -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-nsis unzip" 19 | - 20 | - curl -SL https://win.rustup.rs/ -oC:\rustup-init.exe 21 | - C:\rustup-init.exe -y --default-host="x86_64-pc-windows-gnu" 22 | - 23 | - curl -SOL https://gistcdn.githack.com/nabijaczleweli/880a4b42368c610dc5de041d73bbea58/raw/7f3a23efe680d06934e6c0d7c9fbe92216da0682/EnVar_plugin.zip 24 | - unzip -j EnVar_plugin.zip Plugins/amd64-unicode/EnVar.dll -d C:\msys64\mingw64\share\nsis\Plugins\unicode 25 | 26 | build: off 27 | build_script: 28 | - git submodule update --init --recursive 29 | - cargo build --verbose --release 30 | - cp target\release\http.exe http-v2.2.1.exe 31 | - strip --strip-all --remove-section=.comment --remove-section=.note http-v2.2.1.exe 32 | - makensis -DHTTP_VERSION=v2.2.1 install.nsi 33 | 34 | test: off 35 | test_script: 36 | - cargo test --verbose --release 37 | 38 | artifacts: 39 | - path: http-v2.2.1.exe 40 | - path: http v2.2.1 installer.exe 41 | 42 | deploy: 43 | provider: GitHub 44 | artifact: /http.*v2.2.1.*\.exe/ 45 | auth_token: 46 | secure: ZTXvCrv9y01s7Hd60w8W7NaouPnPoaw9YJt9WhWQ2Pep8HLvCikt9Exjkz8SGP9P 47 | on: 48 | appveyor_repo_tag: true 49 | 50 | notifications: 51 | - provider: Email 52 | to: 53 | - nabijaczleweli@gmail.com 54 | on_build_status_changed: true 55 | on_build_success: false 56 | -------------------------------------------------------------------------------- /assets/adjust_tz.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | window.addEventListener("DOMContentLoaded", function() { 4 | let modtime_h = document.getElementsByTagName("th")[2]; 5 | if(modtime_h) 6 | modtime_h.innerText = modtime_h.innerText.replace(" (UTC)", ""); 7 | 8 | let timestamps = document.getElementsByTagName("time"); 9 | for(let r of timestamps) { 10 | let dt = new Date(parseInt(r.getAttribute("ms"))); 11 | dt.setMinutes(dt.getMinutes() - dt.getTimezoneOffset()) 12 | r.innerText = dt.toISOString().slice(0, 19).replace("T", " "); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /assets/directory_listing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {1}{2}{3} 11 | Directory listing — {0} 12 | 115 | 116 | 117 |

The requested directory {0} contains the following files:

118 | 119 | {7} 120 | {4} 121 | {8} 122 | {5} 123 |
Name Last modified (UTC) Size
124 |

125 | {6} 126 |
127 |

128 | Host These Things Please — a basic HTTP server for hosting a folder fast and simply 129 |

130 | 131 | 132 | -------------------------------------------------------------------------------- /assets/directory_listing_mobile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {1}{2}{3} 12 | Directory listing — {0} 13 | 105 | 106 | 107 | {0} 108 | {4} 109 | {7} 110 | {5} 111 | {6} 112 | Host These Things Please — a basic HTTP server for hosting a folder fast and simply 113 | 114 | 115 | -------------------------------------------------------------------------------- /assets/encoding_blacklist: -------------------------------------------------------------------------------- 1 | ## Stolen from https://en.wikipedia.org/wiki/List_of_archive_formats 2 | # Compression-only files 3 | br 4 | bz2 5 | gz 6 | lz 7 | lz4 8 | lzma 9 | lzo 10 | rz 11 | sfark 12 | sz 13 | xz 14 | z 15 | zst 16 | 17 | # Compression and archiving 18 | 7z 19 | aar 20 | ace 21 | afa 22 | alz 23 | apk 24 | arc 25 | arc 26 | arj 27 | ark 28 | b1 29 | b6z 30 | ba 31 | bh 32 | cab 33 | car 34 | cdx 35 | cfs 36 | cpt 37 | dar 38 | dd 39 | deb 40 | dgc 41 | dmg 42 | ear 43 | gca 44 | genozip 45 | ha 46 | hki 47 | ice 48 | jar 49 | kgb 50 | lha 51 | lzh 52 | lzx 53 | pak 54 | paq6 55 | paq7 56 | paq8 57 | partimg 58 | pea 59 | phar 60 | pim 61 | pit 62 | qda 63 | rar 64 | rk 65 | s7z 66 | sda 67 | sea 68 | sen 69 | sfx 70 | shk 71 | sit 72 | sitx 73 | sqx 74 | tbz2 75 | tgz 76 | tlz 77 | txz 78 | uc 79 | uc0 80 | uc2 81 | uca 82 | ucn 83 | ue2 84 | uha 85 | ur2 86 | war 87 | wim 88 | xar 89 | xp3 90 | yz1 91 | zip 92 | zipx 93 | zoo 94 | zpaq 95 | zz 96 | 97 | 98 | ## Stolen from https://en.wikipedia.org/wiki/Video_file_format 99 | # Compressed videos 100 | 3g2 101 | 3gp 102 | amv 103 | asf 104 | avi 105 | drc 106 | f4a 107 | f4b 108 | f4p 109 | f4v 110 | flv 111 | gif 112 | gifv 113 | m2ts 114 | m2v 115 | m4p 116 | m4v 117 | mkv 118 | mng 119 | mov 120 | mp2 121 | mp4 122 | mpe 123 | mpeg 124 | mpg 125 | mpv 126 | mts 127 | mxf 128 | nsv 129 | ogg 130 | ogv 131 | qt 132 | rm 133 | rmvb 134 | roq 135 | svi 136 | viv 137 | vob 138 | webm 139 | wmv 140 | yuv 141 | 142 | 143 | ## Stolen from https://en.wikipedia.org/wiki/Audio_file_format 144 | # Compressed audio 145 | aac 146 | aax 147 | amr 148 | ape 149 | awb 150 | dct 151 | dss 152 | dvf 153 | flac 154 | gsm 155 | iklax 156 | ivs 157 | m4a 158 | m4b 159 | mmf 160 | mogg 161 | mp3 162 | mpc 163 | msv 164 | oga 165 | opus 166 | ra 167 | sln 168 | tta 169 | vox 170 | wma 171 | wv 172 | 173 | 174 | ## Stolen from https://en.wikipedia.org/wiki/Image_file_format 175 | # Compressed images 176 | avif 177 | avifs 178 | bpg 179 | gif 180 | heic 181 | jfif 182 | jpeg 183 | jpeg2000 184 | jpg 185 | pcx 186 | png 187 | tif 188 | tiff 189 | webp 190 | -------------------------------------------------------------------------------- /assets/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {0} 11 | 12 | 13 |

14 | {1} 15 |

16 | {2} 17 |
18 |

19 | Host These Things Please — a basic HTTP server for hosting a folder fast and simply 20 |

21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/favicon.ico -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/favicon.png -------------------------------------------------------------------------------- /assets/icons/LICENSE: -------------------------------------------------------------------------------- 1 | Unless otherwise specified, all files in this directory come from the Apache Public Domain Icons repository as seen under https://web.archive.org/web/20160303193836/http://www.apache.org/icons/ 2 | 3 | delete_file.png based on https://commons.wikimedia.org/wiki/File:Ballot_x_no_small.png by Mankash licensed under CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0/) 4 | new_directory.gif and new_directory.psd based on dir.png and small/burst.png from the Apache Public Domain Icons repository and released into the public domain 5 | confirm.gif derived from the public-domain https://commons.wikimedia.org/wiki/File:Green_check.png 6 | -------------------------------------------------------------------------------- /assets/icons/back_arrow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/back_arrow.gif -------------------------------------------------------------------------------- /assets/icons/confirm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/confirm.gif -------------------------------------------------------------------------------- /assets/icons/delete_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/delete_file.png -------------------------------------------------------------------------------- /assets/icons/directory.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/directory.gif -------------------------------------------------------------------------------- /assets/icons/file.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/file.gif -------------------------------------------------------------------------------- /assets/icons/file_binary.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/file_binary.gif -------------------------------------------------------------------------------- /assets/icons/file_image.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/file_image.gif -------------------------------------------------------------------------------- /assets/icons/file_text.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/file_text.gif -------------------------------------------------------------------------------- /assets/icons/new_directory.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/new_directory.gif -------------------------------------------------------------------------------- /assets/icons/new_directory.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/new_directory.psd -------------------------------------------------------------------------------- /assets/icons/rename.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/assets/icons/rename.gif -------------------------------------------------------------------------------- /assets/manage.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | function delete_onclick(ev) { 4 | ev.preventDefault(); 5 | 6 | let link = ev.target; 7 | let line = link.parentElement.parentElement; 8 | make_request("DELETE", get_href_for_line(line), link); 9 | } 10 | 11 | 12 | function rename_onclick(ev) { 13 | ev.preventDefault(); 14 | 15 | let link = ev.target; 16 | let line = link.parentElement.parentElement; 17 | let filename_cell = get_filename_cell_for_line(line); 18 | let original_name = filename_cell.innerText; 19 | 20 | let submit_callback = function() { 21 | rename(original_name, new_name_input.value, link); 22 | }; 23 | let new_name_input = make_filename_input(filename_cell, original_name, submit_callback); 24 | 25 | make_confirm_icon(link, submit_callback); 26 | } 27 | 28 | function make_confirm_icon(element, callback) { 29 | element.classList.add("confirm_icon"); 30 | element.innerText = "Confirm"; 31 | element.onclick = function(ev) { 32 | ev.preventDefault(); 33 | ev.stopImmediatePropagation(); 34 | callback(); 35 | }; 36 | } 37 | 38 | 39 | function rename(fname_from, fname_to, status_out) { 40 | let root_url = window.location.origin + window.location.pathname; 41 | if(!root_url.endsWith("/")) 42 | root_url += "/"; 43 | 44 | if(fname_from.endsWith("/")) 45 | fname_from = fname_from.substr(0, fname_from.length - 1); 46 | if(fname_to.endsWith("/")) 47 | fname_to = fname_to.substr(0, fname_to.length - 1); 48 | 49 | if(fname_from == fname_to) // 403 Forbidden nominally 50 | window.location.reload(); 51 | else 52 | make_request("MOVE", root_url + encodeURI(fname_from), status_out, function(request) { 53 | request.setRequestHeader("Destination", root_url + encodeURI(fname_to)); 54 | }); 55 | } 56 | 57 | 58 | function make_filename_input(input_container, initial, callback) { 59 | input_container.innerHTML = ""; 60 | let input_elem = input_container.children[0]; 61 | input_elem.value = initial.endsWith('/') ? initial.slice(0, -1) : initial; 62 | 63 | input_elem.addEventListener("keypress", function(ev) { 64 | if(ev.keyCode === 13) { // Enter 65 | ev.preventDefault(); 66 | callback(); 67 | } 68 | }); 69 | input_container.addEventListener("click", function(ev) { 70 | ev.preventDefault(); 71 | }); 72 | 73 | input_elem.focus(); 74 | return input_elem; 75 | } 76 | 77 | function create_new_directory(fname, status_out) { 78 | let req_url = window.location.origin + window.location.pathname; 79 | if(!req_url.endsWith("/")) 80 | req_url += "/"; 81 | req_url += encodeURI(fname); 82 | 83 | make_request("MKCOL", req_url, status_out); 84 | } 85 | 86 | let make_request_error = false; 87 | function make_request(verb, url, status_out, request_modifier) { 88 | let request = new XMLHttpRequest(); 89 | request.addEventListener("loadend", function() { 90 | if(request.status >= 200 && request.status < 300) 91 | window.location.reload(); 92 | else { 93 | status_out.innerHTML = request.status + " " + request.statusText + (request.response ? " — " : "") + request.response; 94 | status_out.classList.add("has-log"); 95 | make_request_error = true; 96 | } 97 | }); 98 | request.open(verb, url); 99 | if(request_modifier) 100 | request_modifier(request); 101 | request.send(); 102 | } 103 | -------------------------------------------------------------------------------- /assets/manage_desktop.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | window.addEventListener("DOMContentLoaded", function() { 4 | let new_directory = document.getElementById('new"directory'); 5 | if(!new_directory) 6 | return; 7 | 8 | let new_directory_filename_cell = new_directory.children[1]; 9 | let new_directory_status_output = new_directory.children[2].children[0]; 10 | let new_directory_filename_input = null; 11 | 12 | new_directory.addEventListener("click", function(ev) { 13 | if(new_directory_filename_input === null) 14 | ev.preventDefault(); 15 | else if(ev.target === new_directory_status_output) 16 | ; 17 | else if(ev.target !== new_directory_filename_input) { 18 | ev.preventDefault(); 19 | new_directory_filename_input.focus(); 20 | } 21 | 22 | if(new_directory_filename_input === null) { 23 | let submit_callback = function() { 24 | create_new_directory(new_directory_filename_input.value, new_directory_status_output); 25 | }; 26 | 27 | ev.stopImmediatePropagation(); 28 | new_directory_filename_input = make_filename_input(new_directory_filename_cell, "", submit_callback); 29 | make_confirm_icon(new_directory_status_output, submit_callback); 30 | } 31 | }, true); 32 | }); 33 | 34 | 35 | function get_href_for_line(line) { 36 | return line.children[0].children[0].href; 37 | } 38 | 39 | function get_filename_cell_for_line(line) { 40 | return line.children[1]; 41 | } 42 | -------------------------------------------------------------------------------- /assets/manage_mobile.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | window.addEventListener("DOMContentLoaded", function() { 4 | let new_directory = document.getElementById('new"directory'); 5 | if(!new_directory) 6 | return; 7 | 8 | let first_onclick = true, input; 9 | let submit_callback = function() { 10 | if(make_request_error) { 11 | first_onclick = true; 12 | make_request_error = false; 13 | } 14 | if(first_onclick) { 15 | first_onclick = false; 16 | create_new_directory(input.value, new_directory.firstChild); 17 | } 18 | }; 19 | 20 | new_directory.onclick = function(ev) { 21 | ev.preventDefault(); 22 | 23 | if(!input) { 24 | make_confirm_icon(new_directory.firstChild, submit_callback); 25 | let c = document.createElement("span"); 26 | new_directory.appendChild(c); 27 | input = make_filename_input(c, "", submit_callback); 28 | } else 29 | input.focus(); 30 | }; 31 | }); 32 | 33 | 34 | function get_href_for_line(line) { 35 | return line.parentElement.href; 36 | } 37 | 38 | function get_filename_cell_for_line(line) { 39 | return line.firstChild; 40 | } 41 | -------------------------------------------------------------------------------- /assets/upload.css: -------------------------------------------------------------------------------- 1 | dd span { 2 | text-align: right; 3 | display: inline-block; 4 | } 5 | 6 | dd label span { 7 | width: 11em; 8 | } 9 | 10 | dd > span:nth-child(n + 2) { 11 | width: 6em; 12 | } 13 | -------------------------------------------------------------------------------- /build-ioctl.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: 0BSD 2 | // Derived from https://git.sr.ht/~nabijaczleweli/voreutils/tree/02bcd701febb555147b67e0fa7fdc1504fe3cca2/item/cmd/wc.cpp#L155-177 3 | 4 | #include 5 | #include 6 | #include 7 | #if __linux__ 8 | #include 9 | #elif __OpenBSD__ 10 | #include 11 | #include 12 | #elif __has_include() // NetBSD, FreeBSD 13 | #include 14 | #include 15 | #include 16 | #elif __has_include() // illumos 17 | #include 18 | #include 19 | #include 20 | #endif 21 | 22 | 23 | extern uint64_t http_blkgetsize(int fd); 24 | uint64_t http_blkgetsize(int fd) { 25 | int ret = -1; 26 | 27 | #ifdef BLKGETSIZE64 // Linux 28 | uint64_t sz; 29 | ret = ioctl(fd, BLKGETSIZE64, &sz); 30 | #elif defined(DIOCGMEDIASIZE) // NetBSD disk(9), FreeBSD disk(4) 31 | off_t sz; 32 | ret = ioctl(fd, DIOCGMEDIASIZE, &sz); 33 | #elif defined(DIOCGDINFO) // OpenBSD 34 | struct disklabel dl; 35 | ret = ioctl(fd, DIOCGDINFO, &dl); 36 | uint64_t sz = DL_GETDSIZE(&dl); 37 | if(__builtin_mul_overflow(sz, dl.d_secsize, &sz)) 38 | ret = -1; 39 | #elif defined(DKIOCGMEDIAINFO) // illumos 40 | struct dk_minfo mi; 41 | ret = ioctl(fd, DKIOCGMEDIAINFO, &mi); 42 | uint64_t sz = mi.dki_capacity; 43 | if(__builtin_mul_overflow(sz, mi.dki_lbsize, &sz)) 44 | ret = -1; 45 | #endif 46 | 47 | if(ret == -1) 48 | return -1; 49 | else 50 | return sz; 51 | } 52 | -------------------------------------------------------------------------------- /http-manifest.rc: -------------------------------------------------------------------------------- 1 | #define RT_MANIFEST 24 2 | 1 ICON "assets/favicon.ico" 3 | -------------------------------------------------------------------------------- /install.nsi: -------------------------------------------------------------------------------- 1 | Name "http ${HTTP_VERSION}" 2 | OutFile "http ${HTTP_VERSION} installer.exe" 3 | LicenseData "LICENSE" 4 | Icon "assets\favicon.ico" 5 | ShowInstDetails show 6 | InstallDir "$PROGRAMFILES\http" 7 | 8 | Section 9 | SetOutPath $INSTDIR 10 | File /oname=http.exe "http-${HTTP_VERSION}.exe" 11 | WriteUninstaller "$INSTDIR\uninstall http ${HTTP_VERSION}.exe" 12 | SectionEnd 13 | 14 | Section "Update PATH" 15 | EnVar::SetHKLM 16 | EnVar::AddValue "PATH" "$PROGRAMFILES\http" 17 | Pop $0 18 | DetailPrint "Adding $PROGRAMFILES\http to %PATH%: $0" 19 | SectionEnd 20 | 21 | Section "Uninstall" 22 | Delete "$INSTDIR\uninstall http ${HTTP_VERSION}.exe" 23 | Delete "$INSTDIR\http.exe" 24 | Delete "$INSTDIR" 25 | 26 | EnVar::SetHKLM 27 | EnVar::DeleteValue "PATH" "$PROGRAMFILES\http" 28 | Pop $0 29 | DetailPrint "deleting $PROGRAMFILES\http from %PATH%: $0" 30 | SectionEnd 31 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | if [ -z "${PREFIX+marker}" ]; then 5 | prefix_overriden=false; 6 | else 7 | prefix_overriden=true; 8 | fi 9 | 10 | case "$(uname -s)" in 11 | CYGWIN*|MINGW32*|MSYS*) 12 | exe_suffix=.exe 13 | ;; 14 | 15 | *) 16 | exe_suffix= 17 | ;; 18 | esac 19 | 20 | PREFIX="${PREFIX:-"/usr/bin"}" 21 | tag_name=$(curl -SsL "https://api.github.com/repos/thecoshman/http/releases/latest" | grep "tag_name" | head -1 | sed -e 's/.*": "//' -e 's/",//') 22 | 23 | 24 | echo "Installing http $tag_name to $PREFIX..." 25 | if [ "$prefix_overriden" = false ]; then 26 | echo "Set \$PREFIX environment variable to override installation directory."; 27 | fi 28 | 29 | mkdir -p "$PREFIX" 30 | curl -SL "https://github.com/thecoshman/http/releases/download/$tag_name/http-$tag_name$exe_suffix" -o "$PREFIX/http$exe_suffix" 31 | 32 | case "$(uname -s)" in 33 | CYGWIN*|MINGW32*|MSYS*) 34 | ;; 35 | 36 | *) 37 | chmod +x "$PREFIX/http$exe_suffix" 38 | ;; 39 | esac 40 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 160 2 | ideal_width = 128 3 | fn_call_width = 96 4 | fn_args_paren_newline = false 5 | fn_args_density = "Compressed" 6 | struct_trailing_comma = "Always" 7 | wrap_comments = true 8 | -------------------------------------------------------------------------------- /src/ops/bandwidth.rs: -------------------------------------------------------------------------------- 1 | use iron::{AfterMiddleware, IronResult, Response, Handler, Request}; 2 | use std::num::{NonZeroUsize, NonZeroU64}; 3 | use std::io::{Result as IoResult, Write}; 4 | use iron::response::WriteBody; 5 | use std::time::Duration; 6 | use std::thread; 7 | 8 | 9 | pub const DEFAULT_SLEEP: Duration = Duration::from_millis(1); 10 | 11 | 12 | #[derive(Hash, PartialEq, Eq, PartialOrd, Ord)] 13 | pub struct SimpleChain 14 | where &'static H: Handler 15 | { 16 | pub handler: H, 17 | pub after: Option, 18 | } 19 | 20 | impl Handler for &'static SimpleChain 21 | where &'static H: Handler 22 | { 23 | fn handle(&self, req: &mut Request) -> IronResult { 24 | let resp = (&self.handler).handle(req)?; 25 | match self.after.as_ref() { 26 | Some(am) => am.after(req, resp), 27 | None => Ok(resp), 28 | } 29 | } 30 | } 31 | 32 | 33 | 34 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] 35 | pub struct LimitBandwidthMiddleware { 36 | pub bandwidth: NonZeroU64, 37 | } 38 | 39 | impl LimitBandwidthMiddleware { 40 | pub fn new(bandwidth: NonZeroU64) -> LimitBandwidthMiddleware { 41 | LimitBandwidthMiddleware { bandwidth: bandwidth } 42 | } 43 | } 44 | 45 | impl AfterMiddleware for LimitBandwidthMiddleware { 46 | fn after(&self, _: &mut Request, res: Response) -> IronResult { 47 | Ok(Response { 48 | body: res.body.map(|body| { 49 | Box::new(LimitBandwidthWriteBody { 50 | bandwidth: self.bandwidth, 51 | underlying: body, 52 | }) as Box 53 | }), 54 | ..res 55 | }) 56 | } 57 | } 58 | 59 | 60 | struct LimitBandwidthWriteBody { 61 | bandwidth: NonZeroU64, 62 | underlying: Box, 63 | } 64 | 65 | impl WriteBody for LimitBandwidthWriteBody { 66 | fn write_body(&mut self, res: &mut dyn Write) -> IoResult<()> { 67 | self.underlying.write_body(&mut LimitBandwidthWriter::new(self.bandwidth, res)) 68 | } 69 | } 70 | 71 | 72 | struct LimitBandwidthWriter<'o> { 73 | chunk_len: NonZeroUsize, 74 | output: &'o mut dyn Write, 75 | } 76 | 77 | impl<'o> LimitBandwidthWriter<'o> { 78 | fn new(bandwidth: NonZeroU64, output: &'o mut dyn Write) -> LimitBandwidthWriter<'o> { 79 | LimitBandwidthWriter { 80 | // bandwidth / (1000 / DEFAULT_SLEEP_MS) 81 | chunk_len: NonZeroUsize::new(bandwidth.get() as usize * DEFAULT_SLEEP.as_millis() as usize / 1000).unwrap_or(NonZeroUsize::new(1).unwrap()), 82 | output: output, 83 | } 84 | } 85 | } 86 | 87 | impl<'o> Write for LimitBandwidthWriter<'o> { 88 | fn write(&mut self, buf: &[u8]) -> IoResult { 89 | self.write_all(buf)?; 90 | Ok(buf.len()) 91 | } 92 | 93 | fn flush(&mut self) -> IoResult<()> { 94 | self.output.flush() 95 | } 96 | 97 | fn write_all(&mut self, buf: &[u8]) -> IoResult<()> { 98 | for chunk in buf.chunks(self.chunk_len.get()) { 99 | self.output.write_all(chunk)?; 100 | self.output.flush()?; 101 | thread::sleep(DEFAULT_SLEEP); 102 | } 103 | 104 | Ok(()) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/util/os/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(target_os = "windows")] 2 | mod windows; 3 | #[cfg(not(target_os = "windows"))] 4 | mod non_windows; 5 | #[cfg(any(target_os = "windows", target_os = "macos"))] 6 | mod windows_macos; 7 | #[cfg(not(any(target_os = "windows", target_os = "macos")))] 8 | mod non_windows_non_macos; 9 | 10 | #[cfg(target_os = "windows")] 11 | pub use self::windows::*; 12 | #[cfg(not(target_os = "windows"))] 13 | pub use self::non_windows::*; 14 | #[cfg(any(target_os = "windows", target_os = "macos"))] 15 | pub use self::windows_macos::*; 16 | #[cfg(not(any(target_os = "windows", target_os = "macos")))] 17 | pub use self::non_windows_non_macos::*; 18 | -------------------------------------------------------------------------------- /src/util/os/non_windows.rs: -------------------------------------------------------------------------------- 1 | use libc::{AT_SYMLINK_NOFOLLOW, UTIME_OMIT, AT_FDCWD, mode_t, futimens, utimensat, timespec, umask}; 2 | use std::os::unix::fs::{PermissionsExt, MetadataExt}; 3 | use self::super::super::is_actually_file; 4 | use std::fs::{self, Metadata, File}; 5 | use std::os::unix::ffi::OsStrExt; 6 | use std::os::fd::AsRawFd; 7 | use std::path::Path; 8 | 9 | 10 | const FILE_ATTRIBUTE_READONLY: u32 = 0x01; 11 | const FILE_ATTRIBUTE_HIDDEN: u32 = 0x02; 12 | const FILE_ATTRIBUTE_DIRECTORY: u32 = 0x10; 13 | const FILE_ATTRIBUTE_ARCHIVE: u32 = 0x20; 14 | 15 | 16 | /// Get windows-style attributes for the specified file 17 | /// 18 | /// https://docs.microsoft.com/en-gb/windows/win32/fileio/file-attribute-constants 19 | pub fn win32_file_attributes(meta: &Metadata, path: &Path) -> u32 { 20 | let mut attr = 0; 21 | 22 | if meta.permissions().readonly() { 23 | attr |= FILE_ATTRIBUTE_READONLY; 24 | } 25 | 26 | if path.file_name().map(|n| n.as_bytes().starts_with(b".")).unwrap_or(false) { 27 | attr |= FILE_ATTRIBUTE_HIDDEN; 28 | } 29 | 30 | if !is_actually_file(&meta.file_type(), &path) { 31 | attr |= FILE_ATTRIBUTE_DIRECTORY; 32 | } else { 33 | // this is the 'Archive' bit, which is set by 34 | // default on _all_ files on creation and on 35 | // modification. 36 | attr |= FILE_ATTRIBUTE_ARCHIVE; 37 | } 38 | 39 | attr 40 | } 41 | 42 | 43 | /// `st_dev`-`st_ino`-`st_mtime` 44 | pub fn file_etag(m: &Metadata) -> String { 45 | format!("{:x}-{}-{}.{}", m.dev(), m.ino(), m.mtime(), m.mtime_nsec()) 46 | } 47 | 48 | 49 | /// Check if file is marked executable 50 | pub fn file_executable(meta: &Metadata) -> bool { 51 | (meta.permissions().mode() & 0o111) != 0 52 | } 53 | 54 | 55 | static mut UMASK: u32 = 0; 56 | 57 | // as seen in https://docs.rs/ctor/latest/ctor/attr.ctor.html 58 | #[used] 59 | #[cfg_attr(any(target_os = "linux", target_os = "android"), link_section = ".init_array")] 60 | #[cfg_attr(target_os = "freebsd", link_section = ".init_array")] 61 | #[cfg_attr(target_os = "netbsd", link_section = ".init_array")] 62 | #[cfg_attr(target_os = "openbsd", link_section = ".init_array")] 63 | #[cfg_attr(target_os = "illumos", link_section = ".init_array")] 64 | #[cfg_attr(any(target_os = "macos", target_os = "ios", target_os = "tvos"), link_section = "__DATA_CONST,__mod_init_func")] 65 | #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")] 66 | static LOAD_UMASK: unsafe extern "C" fn() = { 67 | #[cfg_attr(any(target_os = "linux", target_os = "android"), link_section = ".text.startup")] 68 | unsafe extern "C" fn load_umask() { 69 | UMASK = umask(0o777) as u32; 70 | umask(UMASK as mode_t); 71 | } 72 | load_umask 73 | }; 74 | 75 | pub fn set_executable(f: &Path, ex: bool) { 76 | let mut perm = match fs::metadata(f) { 77 | Ok(meta) => meta.permissions(), 78 | Err(_) => return, 79 | }; 80 | if ex { 81 | perm.set_mode(perm.mode() | (0o111 & unsafe { !UMASK })); 82 | } else { 83 | perm.set_mode(perm.mode() & !0o111); 84 | } 85 | let _ = fs::set_permissions(f, perm); 86 | } 87 | 88 | 89 | const NO_TIMESPEC: timespec = timespec { 90 | tv_sec: 0, 91 | tv_nsec: UTIME_OMIT, 92 | }; 93 | 94 | pub fn set_mtime_f(f: &File, ms: u64) { 95 | set_times_f(f, Some(ms), None, None) 96 | } 97 | 98 | pub fn set_times_f(f: &File, mtime_ms: Option, atime_ms: Option, _: Option) { 99 | if mtime_ms.is_some() || atime_ms.is_some() { 100 | unsafe { 101 | futimens(f.as_raw_fd(), 102 | [atime_ms.map(ms_to_timespec).unwrap_or(NO_TIMESPEC), mtime_ms.map(ms_to_timespec).unwrap_or(NO_TIMESPEC)].as_ptr()); 103 | } 104 | } 105 | } 106 | 107 | pub fn set_mtime(f: &Path, ms: u64) { 108 | set_times(f, Some(ms), None, None) 109 | } 110 | 111 | pub fn set_times(f: &Path, mtime_ms: Option, atime_ms: Option, _: Option) { 112 | if mtime_ms.is_some() || atime_ms.is_some() { 113 | unsafe { 114 | utimensat(AT_FDCWD, 115 | f.as_os_str().as_bytes().as_ptr() as *const _, 116 | [atime_ms.map(ms_to_timespec).unwrap_or(NO_TIMESPEC), mtime_ms.map(ms_to_timespec).unwrap_or(NO_TIMESPEC)].as_ptr(), 117 | AT_SYMLINK_NOFOLLOW); 118 | } 119 | } 120 | } 121 | 122 | fn ms_to_timespec(ms: u64) -> timespec { 123 | timespec { 124 | tv_sec: (ms / 1000) as _, 125 | tv_nsec: ((ms % 1000) * 1000_000) as _, 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/util/os/non_windows_non_macos.rs: -------------------------------------------------------------------------------- 1 | use std::os::unix::fs::{OpenOptionsExt, FileTypeExt}; 2 | use std::fs::{FileType, Metadata}; 3 | use std::os::fd::AsRawFd; 4 | use std::os::raw::c_int; 5 | use libc::O_NONBLOCK; 6 | use std::path::Path; 7 | use std::fs::OpenOptions; 8 | 9 | 10 | extern "C" { 11 | fn http_blkgetsize(fd: c_int) -> u64; 12 | } 13 | 14 | 15 | /// OS-specific check for fileness 16 | pub fn is_device(tp: &FileType) -> bool { 17 | tp.is_block_device() || tp.is_char_device() || tp.is_fifo() || tp.is_socket() 18 | } 19 | 20 | /// Check file length responsibly 21 | #[inline(always)] 22 | pub fn file_length>(meta: &Metadata, path: &P) -> u64 { 23 | file_length_impl(meta, path.as_ref()) 24 | } 25 | 26 | fn file_length_impl(meta: &Metadata, path: &Path) -> u64 { 27 | if meta.file_type().is_block_device() || meta.file_type().is_char_device() { 28 | if let Ok(f) = OpenOptions::new().read(true).custom_flags(O_NONBLOCK).open(path) { 29 | let size = unsafe { http_blkgetsize(f.as_raw_fd()) }; 30 | if size != u64::MAX { 31 | return size; 32 | } 33 | } 34 | } 35 | 36 | meta.len() 37 | } 38 | -------------------------------------------------------------------------------- /src/util/os/windows.rs: -------------------------------------------------------------------------------- 1 | use winapi::um::fileapi::{GetFileAttributesW, SetFileTime}; 2 | use winapi::shared::minwindef::FILETIME; 3 | use std::os::windows::io::AsRawHandle; 4 | use std::os::windows::fs::MetadataExt; 5 | use std::os::windows::ffi::OsStrExt; 6 | use std::fs::{Metadata, File}; 7 | use std::path::Path; 8 | 9 | 10 | /// Get windows-style attributes for the specified file 11 | /// 12 | /// https://docs.microsoft.com/en-gb/windows/win32/fileio/file-attribute-constants 13 | pub fn win32_file_attributes(_: &Metadata, path: &Path) -> u32 { 14 | let mut buf: Vec<_> = path.as_os_str().encode_wide().collect(); 15 | buf.push(0); 16 | 17 | unsafe { GetFileAttributesW(buf.as_ptr()) } 18 | } 19 | 20 | 21 | /// `st_dev`-`st_ino`-`st_mtim` 22 | pub fn file_etag(m: &Metadata) -> String { 23 | format!("{:x}-{}-{}", 24 | m.volume_serial_number().unwrap_or(0), 25 | m.file_index().unwrap_or(0), 26 | m.last_write_time()) 27 | } 28 | 29 | 30 | /// Check if file is marked executable 31 | #[inline(always)] 32 | pub fn file_executable(_: &Metadata) -> bool { 33 | true 34 | } 35 | 36 | #[inline(always)] 37 | pub fn set_executable(_: &Path, _: bool) {} 38 | 39 | 40 | pub fn set_mtime(f: &Path, ms: u64) { 41 | set_times(f, Some(ms), None, None) 42 | } 43 | 44 | pub fn set_mtime_f(f: &File, ms: u64) { 45 | set_times_f(f, Some(ms), None, None) 46 | } 47 | 48 | 49 | const NO_FILETIME: FILETIME = FILETIME { 50 | dwLowDateTime: 0, 51 | dwHighDateTime: 0, 52 | }; 53 | 54 | pub fn set_times_f(f: &File, mtime_ms: Option, atime_ms: Option, ctime_ms: Option) { 55 | if mtime_ms.is_some() || atime_ms.is_some() || ctime_ms.is_some() { 56 | unsafe { 57 | SetFileTime(f.as_raw_handle(), 58 | &ctime_ms.map(ms_to_FILETIME).unwrap_or(NO_FILETIME), 59 | &atime_ms.map(ms_to_FILETIME).unwrap_or(NO_FILETIME), 60 | &mtime_ms.map(ms_to_FILETIME).unwrap_or(NO_FILETIME)); 61 | } 62 | } 63 | } 64 | 65 | pub fn set_times(f: &Path, mtime_ms: Option, atime_ms: Option, ctime_ms: Option) { 66 | if mtime_ms.is_some() || atime_ms.is_some() || ctime_ms.is_some() { 67 | if let Ok(f) = File::options().write(true).open(f) { 68 | set_times_f(&f, mtime_ms, atime_ms, ctime_ms); 69 | } 70 | } 71 | } 72 | 73 | /// FILETIME is in increments of 100ns, and in the Win32 epoch 74 | #[allow(non_snake_case)] 75 | fn ms_to_FILETIME(ms: u64) -> FILETIME { 76 | let ft = (ms * 1000_0) + 116444736000000000; 77 | FILETIME { 78 | dwLowDateTime: (ft & 0xFFFFFFFF) as u32, 79 | dwHighDateTime: (ft >> 32) as u32, 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/util/os/windows_macos.rs: -------------------------------------------------------------------------------- 1 | use std::fs::{FileType, Metadata}; 2 | use std::path::Path; 3 | 4 | 5 | /// OS-specific check for fileness 6 | #[inline(always)] 7 | pub fn is_device(_: &FileType) -> bool { 8 | false 9 | } 10 | 11 | /// Check file length responsibly 12 | #[inline(always)] 13 | pub fn file_length>(meta: &Metadata, _: &P) -> u64 { 14 | meta.len() 15 | } 16 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/.cargo_vcs_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "sha1": "39a4bd063c1fc7d4b93661dba7d76fef2d8c5c9d" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/Cargo.toml: -------------------------------------------------------------------------------- 1 | # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO 2 | # 3 | # When uploading crates to the registry Cargo will automatically 4 | # "normalize" Cargo.toml files for maximal compatibility 5 | # with all versions of Cargo and also rewrite `path` dependencies 6 | # to registry (e.g., crates.io) dependencies 7 | # 8 | # If you believe there's an error in this file please file an 9 | # issue against the rust-lang/cargo repository. If you're 10 | # editing this file be aware that the upstream Cargo.toml 11 | # will likely look very different (and much more reasonable) 12 | 13 | [package] 14 | name = "hyper" 15 | version = "0.10.16" 16 | authors = ["Sean McArthur ", "Jonathan Reem "] 17 | include = ["Cargo.toml", "LICENSE", "src/**/*"] 18 | description = "A modern HTTP library." 19 | homepage = "http://hyper.rs" 20 | documentation = "https://docs.rs/hyper" 21 | readme = "README.md" 22 | keywords = ["http", "hyper", "hyperium"] 23 | categories = ["web-programming::http-client", "web-programming::http-server"] 24 | license = "MIT" 25 | repository = "https://github.com/hyperium/hyper" 26 | [dependencies.base64] 27 | version = "0.9.0" 28 | 29 | [dependencies.httparse] 30 | version = "1.0" 31 | 32 | [dependencies.mime] 33 | version = "0.2" 34 | 35 | [dependencies.num_cpus] 36 | version = "1.0" 37 | 38 | [dependencies.time] 39 | version = "0.1" 40 | 41 | [dependencies.traitobject] 42 | version = "0.1.1" 43 | 44 | [dependencies.typeable] 45 | version = "0.1" 46 | 47 | [dependencies.unicase] 48 | version = "1.0" 49 | 50 | [dependencies.url] 51 | version = "1.0" 52 | 53 | [dependencies] 54 | crossbeam-channel = "0.5" 55 | [dependencies.smallvec] 56 | version = "1.13" 57 | features = ["union"] 58 | 59 | [features] 60 | nightly = [] 61 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/Cargo.toml.orig: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "hyper" 4 | version = "0.10.16" # remember to update html_root_url 5 | description = "A modern HTTP library." 6 | readme = "README.md" 7 | homepage = "http://hyper.rs" 8 | documentation = "https://docs.rs/hyper" 9 | repository = "https://github.com/hyperium/hyper" 10 | license = "MIT" 11 | authors = ["Sean McArthur ", 12 | "Jonathan Reem "] 13 | keywords = ["http", "hyper", "hyperium"] 14 | categories = ["web-programming::http-client", "web-programming::http-server"] 15 | 16 | include = [ 17 | "Cargo.toml", 18 | "LICENSE", 19 | "src/**/*" 20 | ] 21 | 22 | [dependencies] 23 | base64 = "0.9.0" 24 | httparse = "1.0" 25 | language-tags = "0.2" 26 | log = "0.3" 27 | mime = "0.2" 28 | num_cpus = "1.0" 29 | time = "0.1" 30 | traitobject = "0.1" 31 | typeable = "0.1" 32 | unicase = "1.0" 33 | url = "1.0" 34 | 35 | [dev-dependencies] 36 | env_logger = "0.4" 37 | 38 | [features] 39 | nightly = [] 40 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Sean McArthur 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/accept_charset.rs: -------------------------------------------------------------------------------- 1 | use header::{Charset, QualityItem}; 2 | 3 | header! { 4 | /// `Accept-Charset` header, defined in 5 | /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.3) 6 | /// 7 | /// The `Accept-Charset` header field can be sent by a user agent to 8 | /// indicate what charsets are acceptable in textual response content. 9 | /// This field allows user agents capable of understanding more 10 | /// comprehensive or special-purpose charsets to signal that capability 11 | /// to an origin server that is capable of representing information in 12 | /// those charsets. 13 | /// 14 | /// # ABNF 15 | /// ```plain 16 | /// Accept-Charset = 1#( ( charset / "*" ) [ weight ] ) 17 | /// ``` 18 | /// 19 | /// # Example values 20 | /// * `iso-8859-5, unicode-1-1;q=0.8` 21 | /// 22 | /// # Examples 23 | /// ``` 24 | /// use hyper::header::{Headers, AcceptCharset, Charset, qitem}; 25 | /// 26 | /// let mut headers = Headers::new(); 27 | /// headers.set( 28 | /// AcceptCharset(vec![qitem(Charset::Us_Ascii)]) 29 | /// ); 30 | /// ``` 31 | /// ``` 32 | /// use hyper::header::{Headers, AcceptCharset, Charset, Quality, QualityItem}; 33 | /// 34 | /// let mut headers = Headers::new(); 35 | /// headers.set( 36 | /// AcceptCharset(vec![ 37 | /// QualityItem::new(Charset::Us_Ascii, Quality(900)), 38 | /// QualityItem::new(Charset::Iso_8859_10, Quality(200)), 39 | /// ]) 40 | /// ); 41 | /// ``` 42 | /// ``` 43 | /// use hyper::header::{Headers, AcceptCharset, Charset, qitem}; 44 | /// 45 | /// let mut headers = Headers::new(); 46 | /// headers.set( 47 | /// AcceptCharset(vec![qitem(Charset::Ext("utf-8".to_owned()))]) 48 | /// ); 49 | /// ``` 50 | (AcceptCharset, "Accept-Charset") => (QualityItem)+ 51 | 52 | test_accept_charset { 53 | /// Testcase from RFC 54 | test_header!(test1, vec![b"iso-8859-5, unicode-1-1;q=0.8"]); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/accept_encoding.rs: -------------------------------------------------------------------------------- 1 | use header::{Encoding, QualityItem}; 2 | 3 | header! { 4 | /// `Accept-Encoding` header, defined in 5 | /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.4) 6 | /// 7 | /// The `Accept-Encoding` header field can be used by user agents to 8 | /// indicate what response content-codings are 9 | /// acceptable in the response. An `identity` token is used as a synonym 10 | /// for "no encoding" in order to communicate when no encoding is 11 | /// preferred. 12 | /// 13 | /// # ABNF 14 | /// ```plain 15 | /// Accept-Encoding = #( codings [ weight ] ) 16 | /// codings = content-coding / "identity" / "*" 17 | /// ``` 18 | /// 19 | /// # Example values 20 | /// * `compress, gzip` 21 | /// * `` 22 | /// * `*` 23 | /// * `compress;q=0.5, gzip;q=1` 24 | /// * `gzip;q=1.0, identity; q=0.5, *;q=0` 25 | /// 26 | /// # Examples 27 | /// ``` 28 | /// use hyper::header::{Headers, AcceptEncoding, Encoding, qitem}; 29 | /// 30 | /// let mut headers = Headers::new(); 31 | /// headers.set( 32 | /// AcceptEncoding(vec![qitem(Encoding::Chunked)]) 33 | /// ); 34 | /// ``` 35 | /// ``` 36 | /// use hyper::header::{Headers, AcceptEncoding, Encoding, qitem}; 37 | /// 38 | /// let mut headers = Headers::new(); 39 | /// headers.set( 40 | /// AcceptEncoding(vec![ 41 | /// qitem(Encoding::Chunked), 42 | /// qitem(Encoding::Gzip), 43 | /// qitem(Encoding::Deflate), 44 | /// ]) 45 | /// ); 46 | /// ``` 47 | /// ``` 48 | /// use hyper::header::{Headers, AcceptEncoding, Encoding, QualityItem, Quality, qitem}; 49 | /// 50 | /// let mut headers = Headers::new(); 51 | /// headers.set( 52 | /// AcceptEncoding(vec![ 53 | /// qitem(Encoding::Chunked), 54 | /// QualityItem::new(Encoding::Gzip, Quality(600)), 55 | /// QualityItem::new(Encoding::EncodingExt("*".to_owned()), Quality(0)), 56 | /// ]) 57 | /// ); 58 | /// ``` 59 | (AcceptEncoding, "Accept-Encoding") => (QualityItem)* 60 | 61 | test_accept_encoding { 62 | // From the RFC 63 | test_header!(test1, vec![b"compress, gzip"]); 64 | test_header!(test2, vec![b""], Some(AcceptEncoding(vec![]))); 65 | test_header!(test3, vec![b"*"]); 66 | // Note: Removed quality 1 from gzip 67 | test_header!(test4, vec![b"compress;q=0.5, gzip"]); 68 | // Note: Removed quality 1 from gzip 69 | test_header!(test5, vec![b"gzip, identity; q=0.5, *;q=0"]); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/accept_ranges.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{self, Display}; 2 | use std::str::FromStr; 3 | 4 | header! { 5 | /// `Accept-Ranges` header, defined in 6 | /// [RFC7233](http://tools.ietf.org/html/rfc7233#section-2.3) 7 | /// 8 | /// The `Accept-Ranges` header field allows a server to indicate that it 9 | /// supports range requests for the target resource. 10 | /// 11 | /// # ABNF 12 | /// ```plain 13 | /// Accept-Ranges = acceptable-ranges 14 | /// acceptable-ranges = 1#range-unit / \"none\" 15 | /// 16 | /// # Example values 17 | /// * `bytes` 18 | /// * `none` 19 | /// * `unknown-unit` 20 | /// ``` 21 | /// 22 | /// # Examples 23 | /// ``` 24 | /// use hyper::header::{Headers, AcceptRanges, RangeUnit}; 25 | /// 26 | /// let mut headers = Headers::new(); 27 | /// headers.set(AcceptRanges(vec![RangeUnit::Bytes])); 28 | /// ``` 29 | /// ``` 30 | /// use hyper::header::{Headers, AcceptRanges, RangeUnit}; 31 | /// 32 | /// let mut headers = Headers::new(); 33 | /// headers.set(AcceptRanges(vec![RangeUnit::None])); 34 | /// ``` 35 | /// ``` 36 | /// use hyper::header::{Headers, AcceptRanges, RangeUnit}; 37 | /// 38 | /// let mut headers = Headers::new(); 39 | /// headers.set( 40 | /// AcceptRanges(vec![ 41 | /// RangeUnit::Unregistered("nibbles".to_owned()), 42 | /// RangeUnit::Bytes, 43 | /// RangeUnit::Unregistered("doublets".to_owned()), 44 | /// RangeUnit::Unregistered("quadlets".to_owned()), 45 | /// ]) 46 | /// ); 47 | /// ``` 48 | (AcceptRanges, "Accept-Ranges") => [RangeUnit] 49 | 50 | test_acccept_ranges { 51 | test_header!(test1, vec![b"bytes"]); 52 | test_header!(test2, vec![b"none"]); 53 | } 54 | } 55 | 56 | /// Range Units, described in [RFC7233](http://tools.ietf.org/html/rfc7233#section-2) 57 | /// 58 | /// A representation can be partitioned into subranges according to 59 | /// various structural units, depending on the structure inherent in the 60 | /// representation's media type. 61 | /// 62 | /// # ABNF 63 | /// ```plain 64 | /// range-unit = bytes-unit / other-range-unit 65 | /// bytes-unit = "bytes" 66 | /// other-range-unit = token 67 | /// ``` 68 | #[derive(Clone, Debug, Eq, PartialEq)] 69 | pub enum RangeUnit { 70 | /// Indicating byte-range requests are supported. 71 | Bytes, 72 | /// Reserved as keyword, indicating no ranges are supported. 73 | None, 74 | } 75 | 76 | 77 | impl FromStr for RangeUnit { 78 | type Err = ::Error; 79 | fn from_str(s: &str) -> ::Result { 80 | match s { 81 | "bytes" => Ok(RangeUnit::Bytes), 82 | "none" => Ok(RangeUnit::None), 83 | // FIXME: Check if s is really a Token 84 | _ => Err(::Error::Method), 85 | } 86 | } 87 | } 88 | 89 | impl Display for RangeUnit { 90 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 91 | match *self { 92 | RangeUnit::Bytes => f.write_str("bytes"), 93 | RangeUnit::None => f.write_str("none"), 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/access_control_allow_credentials.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{self, Display}; 2 | use std::str; 3 | use unicase::UniCase; 4 | use header::{Header, HeaderFormat}; 5 | 6 | /// `Access-Control-Allow-Credentials` header, part of 7 | /// [CORS](http://www.w3.org/TR/cors/#access-control-allow-headers-response-header) 8 | /// 9 | /// > The Access-Control-Allow-Credentials HTTP response header indicates whether the 10 | /// > response to request can be exposed when the credentials flag is true. When part 11 | /// > of the response to an preflight request it indicates that the actual request can 12 | /// > be made with credentials. The Access-Control-Allow-Credentials HTTP header must 13 | /// > match the following ABNF: 14 | /// 15 | /// # ABNF 16 | /// ```plain 17 | /// Access-Control-Allow-Credentials: "Access-Control-Allow-Credentials" ":" "true" 18 | /// ``` 19 | /// 20 | /// Since there is only one acceptable field value, the header struct does not accept 21 | /// any values at all. Setting an empty `AccessControlAllowCredentials` header is 22 | /// sufficient. See the examples below. 23 | /// 24 | /// # Example values 25 | /// * "true" 26 | /// 27 | /// # Examples 28 | /// ``` 29 | /// # extern crate hyper; 30 | /// # fn main() { 31 | /// 32 | /// use hyper::header::{Headers, AccessControlAllowCredentials}; 33 | /// 34 | /// let mut headers = Headers::new(); 35 | /// headers.set(AccessControlAllowCredentials); 36 | /// # } 37 | /// ``` 38 | #[derive(Clone, PartialEq, Debug)] 39 | pub struct AccessControlAllowCredentials; 40 | 41 | const ACCESS_CONTROL_ALLOW_CREDENTIALS_TRUE: UniCase<&'static str> = UniCase("true"); 42 | 43 | impl Header for AccessControlAllowCredentials { 44 | fn header_name() -> &'static str { 45 | "Access-Control-Allow-Credentials" 46 | } 47 | 48 | fn parse_header>(raw: &[T]) -> ::Result { 49 | if raw.len() == 1 { 50 | let text = unsafe { 51 | // safe because: 52 | // 1. we just checked raw.len == 1 53 | // 2. we don't actually care if it's utf8, we just want to 54 | // compare the bytes with the "case" normalized. If it's not 55 | // utf8, then the byte comparison will fail, and we'll return 56 | // None. No big deal. 57 | str::from_utf8_unchecked(raw.get_unchecked(0).as_ref()) 58 | }; 59 | if UniCase(text) == ACCESS_CONTROL_ALLOW_CREDENTIALS_TRUE { 60 | return Ok(AccessControlAllowCredentials); 61 | } 62 | } 63 | Err(::Error::Header) 64 | } 65 | } 66 | 67 | impl HeaderFormat for AccessControlAllowCredentials { 68 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 69 | f.write_str("true") 70 | } 71 | } 72 | 73 | impl Display for AccessControlAllowCredentials { 74 | fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 75 | self.fmt_header(f) 76 | } 77 | } 78 | 79 | #[cfg(test)] 80 | mod test_access_control_allow_credentials { 81 | use std::str; 82 | use header::*; 83 | use super::AccessControlAllowCredentials as HeaderField; 84 | test_header!(works, vec![b"true"], Some(HeaderField)); 85 | test_header!(ignores_case, vec![b"True"]); 86 | test_header!(not_bool, vec![b"false"], None); 87 | test_header!(only_single, vec![b"true", b"true"], None); 88 | test_header!(no_gibberish, vec!["\u{645}\u{631}\u{62d}\u{628}\u{627}".as_bytes()], None); 89 | } 90 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/access_control_allow_headers.rs: -------------------------------------------------------------------------------- 1 | use unicase::UniCase; 2 | 3 | header! { 4 | /// `Access-Control-Allow-Headers` header, part of 5 | /// [CORS](http://www.w3.org/TR/cors/#access-control-allow-headers-response-header) 6 | /// 7 | /// The `Access-Control-Allow-Headers` header indicates, as part of the 8 | /// response to a preflight request, which header field names can be used 9 | /// during the actual request. 10 | /// 11 | /// # ABNF 12 | /// ```plain 13 | /// Access-Control-Allow-Headers: "Access-Control-Allow-Headers" ":" #field-name 14 | /// ``` 15 | /// 16 | /// # Example values 17 | /// * `accept-language, date` 18 | /// 19 | /// # Examples 20 | /// ``` 21 | /// # extern crate hyper; 22 | /// # extern crate unicase; 23 | /// # fn main() { 24 | /// // extern crate unicase; 25 | /// 26 | /// use hyper::header::{Headers, AccessControlAllowHeaders}; 27 | /// use unicase::UniCase; 28 | /// 29 | /// let mut headers = Headers::new(); 30 | /// headers.set( 31 | /// AccessControlAllowHeaders(vec![UniCase("date".to_owned())]) 32 | /// ); 33 | /// # } 34 | /// ``` 35 | /// ``` 36 | /// # extern crate hyper; 37 | /// # extern crate unicase; 38 | /// # fn main() { 39 | /// // extern crate unicase; 40 | /// 41 | /// use hyper::header::{Headers, AccessControlAllowHeaders}; 42 | /// use unicase::UniCase; 43 | /// 44 | /// let mut headers = Headers::new(); 45 | /// headers.set( 46 | /// AccessControlAllowHeaders(vec![ 47 | /// UniCase("accept-language".to_owned()), 48 | /// UniCase("date".to_owned()), 49 | /// ]) 50 | /// ); 51 | /// # } 52 | /// ``` 53 | (AccessControlAllowHeaders, "Access-Control-Allow-Headers") => (UniCase)* 54 | 55 | test_access_control_allow_headers { 56 | test_header!(test1, vec![b"accept-language, date"]); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/access_control_allow_methods.rs: -------------------------------------------------------------------------------- 1 | use method::Method; 2 | 3 | header! { 4 | /// `Access-Control-Allow-Methods` header, part of 5 | /// [CORS](http://www.w3.org/TR/cors/#access-control-allow-methods-response-header) 6 | /// 7 | /// The `Access-Control-Allow-Methods` header indicates, as part of the 8 | /// response to a preflight request, which methods can be used during the 9 | /// actual request. 10 | /// 11 | /// # ABNF 12 | /// ```plain 13 | /// Access-Control-Allow-Methods: "Access-Control-Allow-Methods" ":" #Method 14 | /// ``` 15 | /// 16 | /// # Example values 17 | /// * `PUT, DELETE, XMODIFY` 18 | /// 19 | /// # Examples 20 | /// ``` 21 | /// use hyper::header::{Headers, AccessControlAllowMethods}; 22 | /// use hyper::method::Method; 23 | /// 24 | /// let mut headers = Headers::new(); 25 | /// headers.set( 26 | /// AccessControlAllowMethods(vec![Method::Get]) 27 | /// ); 28 | /// ``` 29 | /// ``` 30 | /// use hyper::header::{Headers, AccessControlAllowMethods}; 31 | /// use hyper::method::Method; 32 | /// 33 | /// let mut headers = Headers::new(); 34 | /// headers.set( 35 | /// AccessControlAllowMethods(vec![ 36 | /// Method::Get, 37 | /// Method::Post, 38 | /// Method::Patch, 39 | /// Method::Extension("COPY".to_owned()), 40 | /// ]) 41 | /// ); 42 | /// ``` 43 | (AccessControlAllowMethods, "Access-Control-Allow-Methods") => (Method)* 44 | 45 | test_access_control_allow_methods { 46 | test_header!(test1, vec![b"PUT, DELETE, XMODIFY"]); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/access_control_allow_origin.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{self, Display}; 2 | 3 | use header::{Header, HeaderFormat}; 4 | 5 | /// The `Access-Control-Allow-Origin` response header, 6 | /// part of [CORS](http://www.w3.org/TR/cors/#access-control-allow-origin-response-header) 7 | /// 8 | /// The `Access-Control-Allow-Origin` header indicates whether a resource 9 | /// can be shared based by returning the value of the Origin request header, 10 | /// "*", or "null" in the response. 11 | /// 12 | /// # ABNF 13 | /// ```plain 14 | /// Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | "*" 15 | /// ``` 16 | /// 17 | /// # Example values 18 | /// * `null` 19 | /// * `*` 20 | /// * `http://google.com/` 21 | /// 22 | /// # Examples 23 | /// ``` 24 | /// use hyper::header::{Headers, AccessControlAllowOrigin}; 25 | /// 26 | /// let mut headers = Headers::new(); 27 | /// headers.set( 28 | /// AccessControlAllowOrigin::Any 29 | /// ); 30 | /// ``` 31 | /// ``` 32 | /// use hyper::header::{Headers, AccessControlAllowOrigin}; 33 | /// 34 | /// let mut headers = Headers::new(); 35 | /// headers.set( 36 | /// AccessControlAllowOrigin::Null, 37 | /// ); 38 | /// ``` 39 | /// ``` 40 | /// use hyper::header::{Headers, AccessControlAllowOrigin}; 41 | /// 42 | /// let mut headers = Headers::new(); 43 | /// headers.set( 44 | /// AccessControlAllowOrigin::Value("http://hyper.rs".to_owned()) 45 | /// ); 46 | /// ``` 47 | #[derive(Clone, PartialEq, Debug)] 48 | pub enum AccessControlAllowOrigin { 49 | /// Allow all origins 50 | Any, 51 | /// A hidden origin 52 | Null, 53 | /// Allow one particular origin 54 | Value(String), 55 | } 56 | 57 | impl Header for AccessControlAllowOrigin { 58 | fn header_name() -> &'static str { 59 | "Access-Control-Allow-Origin" 60 | } 61 | 62 | fn parse_header>(raw: &[T]) -> ::Result { 63 | if raw.len() != 1 { 64 | return Err(::Error::Header) 65 | } 66 | let value = unsafe { raw.get_unchecked(0) }.as_ref(); 67 | Ok(match value { 68 | b"*" => AccessControlAllowOrigin::Any, 69 | b"null" => AccessControlAllowOrigin::Null, 70 | _ => AccessControlAllowOrigin::Value(try!(String::from_utf8(value.to_owned()))) 71 | }) 72 | } 73 | } 74 | 75 | impl HeaderFormat for AccessControlAllowOrigin { 76 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 77 | match *self { 78 | AccessControlAllowOrigin::Any => f.write_str("*"), 79 | AccessControlAllowOrigin::Null => f.write_str("null"), 80 | AccessControlAllowOrigin::Value(ref url) => Display::fmt(url, f), 81 | } 82 | } 83 | } 84 | 85 | impl Display for AccessControlAllowOrigin { 86 | fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 87 | self.fmt_header(f) 88 | } 89 | } 90 | 91 | #[cfg(test)] 92 | mod test_access_control_allow_orgin { 93 | use header::*; 94 | use super::AccessControlAllowOrigin as HeaderField; 95 | test_header!(test1, vec![b"null"]); 96 | test_header!(test2, vec![b"*"]); 97 | test_header!(test3, vec![b"http://google.com/"]); 98 | } 99 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/access_control_expose_headers.rs: -------------------------------------------------------------------------------- 1 | use unicase::UniCase; 2 | 3 | header! { 4 | /// `Access-Control-Expose-Headers` header, part of 5 | /// [CORS](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header) 6 | /// 7 | /// The Access-Control-Expose-Headers header indicates which headers are safe to expose to the 8 | /// API of a CORS API specification. 9 | /// 10 | /// # ABNF 11 | /// ```plain 12 | /// Access-Control-Expose-Headers = "Access-Control-Expose-Headers" ":" #field-name 13 | /// ``` 14 | /// 15 | /// # Example values 16 | /// * `ETag, Content-Length` 17 | /// 18 | /// # Examples 19 | /// ``` 20 | /// # extern crate hyper; 21 | /// # extern crate unicase; 22 | /// # fn main() { 23 | /// // extern crate unicase; 24 | /// 25 | /// use hyper::header::{Headers, AccessControlExposeHeaders}; 26 | /// use unicase::UniCase; 27 | /// 28 | /// let mut headers = Headers::new(); 29 | /// headers.set( 30 | /// AccessControlExposeHeaders(vec![ 31 | /// UniCase("etag".to_owned()), 32 | /// UniCase("content-length".to_owned()) 33 | /// ]) 34 | /// ); 35 | /// # } 36 | /// ``` 37 | /// ``` 38 | /// # extern crate hyper; 39 | /// # extern crate unicase; 40 | /// # fn main() { 41 | /// // extern crate unicase; 42 | /// 43 | /// use hyper::header::{Headers, AccessControlExposeHeaders}; 44 | /// use unicase::UniCase; 45 | /// 46 | /// let mut headers = Headers::new(); 47 | /// headers.set( 48 | /// AccessControlExposeHeaders(vec![ 49 | /// UniCase("etag".to_owned()), 50 | /// UniCase("content-length".to_owned()) 51 | /// ]) 52 | /// ); 53 | /// # } 54 | /// ``` 55 | (AccessControlExposeHeaders, "Access-Control-Expose-Headers") => (UniCase)* 56 | 57 | test_access_control_expose_headers { 58 | test_header!(test1, vec![b"etag, content-length"]); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/access_control_max_age.rs: -------------------------------------------------------------------------------- 1 | header! { 2 | /// `Access-Control-Max-Age` header, part of 3 | /// [CORS](http://www.w3.org/TR/cors/#access-control-max-age-response-header) 4 | /// 5 | /// The `Access-Control-Max-Age` header indicates how long the results of a 6 | /// preflight request can be cached in a preflight result cache. 7 | /// 8 | /// # ABNF 9 | /// ```plain 10 | /// Access-Control-Max-Age = \"Access-Control-Max-Age\" \":\" delta-seconds 11 | /// ``` 12 | /// 13 | /// # Example values 14 | /// * `531` 15 | /// 16 | /// # Examples 17 | /// ``` 18 | /// use hyper::header::{Headers, AccessControlMaxAge}; 19 | /// 20 | /// let mut headers = Headers::new(); 21 | /// headers.set(AccessControlMaxAge(1728000u32)); 22 | /// ``` 23 | (AccessControlMaxAge, "Access-Control-Max-Age") => [u32] 24 | 25 | test_access_control_max_age { 26 | test_header!(test1, vec![b"531"]); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/access_control_request_headers.rs: -------------------------------------------------------------------------------- 1 | use unicase::UniCase; 2 | 3 | header! { 4 | /// `Access-Control-Request-Headers` header, part of 5 | /// [CORS](http://www.w3.org/TR/cors/#access-control-request-headers-request-header) 6 | /// 7 | /// The `Access-Control-Request-Headers` header indicates which headers will 8 | /// be used in the actual request as part of the preflight request. 9 | /// during the actual request. 10 | /// 11 | /// # ABNF 12 | /// ```plain 13 | /// Access-Control-Allow-Headers: "Access-Control-Allow-Headers" ":" #field-name 14 | /// ``` 15 | /// 16 | /// # Example values 17 | /// * `accept-language, date` 18 | /// 19 | /// # Examples 20 | /// ``` 21 | /// # extern crate hyper; 22 | /// # extern crate unicase; 23 | /// # fn main() { 24 | /// // extern crate unicase; 25 | /// 26 | /// use hyper::header::{Headers, AccessControlRequestHeaders}; 27 | /// use unicase::UniCase; 28 | /// 29 | /// let mut headers = Headers::new(); 30 | /// headers.set( 31 | /// AccessControlRequestHeaders(vec![UniCase("date".to_owned())]) 32 | /// ); 33 | /// # } 34 | /// ``` 35 | /// ``` 36 | /// # extern crate hyper; 37 | /// # extern crate unicase; 38 | /// # fn main() { 39 | /// // extern crate unicase; 40 | /// 41 | /// use hyper::header::{Headers, AccessControlRequestHeaders}; 42 | /// use unicase::UniCase; 43 | /// 44 | /// let mut headers = Headers::new(); 45 | /// headers.set( 46 | /// AccessControlRequestHeaders(vec![ 47 | /// UniCase("accept-language".to_owned()), 48 | /// UniCase("date".to_owned()), 49 | /// ]) 50 | /// ); 51 | /// # } 52 | /// ``` 53 | (AccessControlRequestHeaders, "Access-Control-Request-Headers") => (UniCase)* 54 | 55 | test_access_control_request_headers { 56 | test_header!(test1, vec![b"accept-language, date"]); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/access_control_request_method.rs: -------------------------------------------------------------------------------- 1 | use method::Method; 2 | 3 | header! { 4 | /// `Access-Control-Request-Method` header, part of 5 | /// [CORS](http://www.w3.org/TR/cors/#access-control-request-method-request-header) 6 | /// 7 | /// The `Access-Control-Request-Method` header indicates which method will be 8 | /// used in the actual request as part of the preflight request. 9 | /// # ABNF 10 | /// ```plain 11 | /// Access-Control-Request-Method: \"Access-Control-Request-Method\" \":\" Method 12 | /// ``` 13 | /// 14 | /// # Example values 15 | /// * `GET` 16 | /// 17 | /// # Examples 18 | /// ``` 19 | /// use hyper::header::{Headers, AccessControlRequestMethod}; 20 | /// use hyper::method::Method; 21 | /// 22 | /// let mut headers = Headers::new(); 23 | /// headers.set(AccessControlRequestMethod(Method::Get)); 24 | /// ``` 25 | (AccessControlRequestMethod, "Access-Control-Request-Method") => [Method] 26 | 27 | test_access_control_request_method { 28 | test_header!(test1, vec![b"GET"]); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/allow.rs: -------------------------------------------------------------------------------- 1 | use method::Method; 2 | 3 | /// `Allow` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.4.1) 4 | /// 5 | /// The `Allow` header field lists the set of methods advertised as 6 | /// supported by the target resource. The purpose of this field is 7 | /// strictly to inform the recipient of valid request methods associated 8 | /// with the resource. 9 | /// 10 | /// # ABNF 11 | /// ```plain 12 | /// Allow = #method 13 | /// ``` 14 | /// 15 | /// # Example values 16 | /// * `GET, HEAD, PUT` 17 | /// * `OPTIONS, GET, PUT, POST, DELETE, HEAD, TRACE, CONNECT, PATCH, fOObAr` 18 | /// * `` 19 | /// 20 | /// # Examples 21 | /// ``` 22 | /// use hyper::header::{Headers, Allow}; 23 | /// use hyper::method::Method; 24 | /// 25 | /// let mut headers = Headers::new(); 26 | /// headers.set( 27 | /// Allow(vec![Method::Get]) 28 | /// ); 29 | /// ``` 30 | /// ``` 31 | /// use hyper::header::{Headers, Allow}; 32 | /// use hyper::method::Method; 33 | /// 34 | /// let mut headers = Headers::new(); 35 | /// headers.set( 36 | /// Allow(vec![ 37 | /// Method::Get, 38 | /// Method::Post, 39 | /// Method::Patch, 40 | /// Method::Extension("TEST".to_owned()), 41 | /// ].into()) 42 | /// ); 43 | /// ``` 44 | #[derive(Clone, Debug, PartialEq)] 45 | pub struct Allow(pub std::borrow::Cow<'static, [Method]>); 46 | __hyper__deref!(Allow => std::borrow::Cow<'static, [Method]>); 47 | impl ::header::Header for Allow { 48 | fn header_name() -> &'static str { 49 | "Allow" 50 | } 51 | fn parse_header>(raw: &[T]) -> ::Result { 52 | ::header::parsing::from_comma_delimited(raw).map(std::borrow::Cow::Owned).map(Allow) 53 | } 54 | } 55 | impl ::header::HeaderFormat for Allow { 56 | fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 57 | ::header::parsing::fmt_comma_delimited(f, &self.0[..]) 58 | } 59 | } 60 | impl ::std::fmt::Display for Allow { 61 | fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 62 | use ::header::HeaderFormat; 63 | self.fmt_header(f) 64 | } 65 | } 66 | 67 | bench_header!(bench, 68 | Allow, { vec![b"OPTIONS,GET,PUT,POST,DELETE,HEAD,TRACE,CONNECT,PATCH,fOObAr".to_vec()] }); 69 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/content_encoding.rs: -------------------------------------------------------------------------------- 1 | use header::Encoding; 2 | 3 | header! { 4 | /// `Content-Encoding` header, defined in 5 | /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.2.2) 6 | /// 7 | /// The `Content-Encoding` header field indicates what content codings 8 | /// have been applied to the representation, beyond those inherent in the 9 | /// media type, and thus what decoding mechanisms have to be applied in 10 | /// order to obtain data in the media type referenced by the Content-Type 11 | /// header field. Content-Encoding is primarily used to allow a 12 | /// representation's data to be compressed without losing the identity of 13 | /// its underlying media type. 14 | /// 15 | /// # ABNF 16 | /// ```plain 17 | /// Content-Encoding = 1#content-coding 18 | /// ``` 19 | /// 20 | /// # Example values 21 | /// * `gzip` 22 | /// 23 | /// # Examples 24 | /// ``` 25 | /// use hyper::header::{Headers, ContentEncoding, Encoding}; 26 | /// 27 | /// let mut headers = Headers::new(); 28 | /// headers.set(ContentEncoding(vec![Encoding::Chunked])); 29 | /// ``` 30 | /// ``` 31 | /// use hyper::header::{Headers, ContentEncoding, Encoding}; 32 | /// 33 | /// let mut headers = Headers::new(); 34 | /// headers.set( 35 | /// ContentEncoding(vec![ 36 | /// Encoding::Gzip, 37 | /// Encoding::Chunked, 38 | /// ]) 39 | /// ); 40 | /// ``` 41 | (ContentEncoding, "Content-Encoding") => [Encoding]+ 42 | 43 | /*test_content_encoding { 44 | /// Testcase from the RFC 45 | test_header!(test1, vec![b"gzip"], Some(ContentEncoding(vec![Encoding::Gzip]))); 46 | }*/ 47 | } 48 | 49 | bench_header!(single, ContentEncoding, { vec![b"gzip".to_vec()] }); 50 | bench_header!(multiple, ContentEncoding, { vec![b"gzip, deflate".to_vec()] }); 51 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/content_length.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use header::{HeaderFormat, Header, parsing}; 4 | 5 | /// `Content-Length` header, defined in 6 | /// [RFC7230](http://tools.ietf.org/html/rfc7230#section-3.3.2) 7 | /// 8 | /// When a message does not have a `Transfer-Encoding` header field, a 9 | /// Content-Length header field can provide the anticipated size, as a 10 | /// decimal number of octets, for a potential payload body. For messages 11 | /// that do include a payload body, the Content-Length field-value 12 | /// provides the framing information necessary for determining where the 13 | /// body (and message) ends. For messages that do not include a payload 14 | /// body, the Content-Length indicates the size of the selected 15 | /// representation. 16 | /// 17 | /// # ABNF 18 | /// ```plain 19 | /// Content-Length = 1*DIGIT 20 | /// ``` 21 | /// 22 | /// # Example values 23 | /// * `3495` 24 | /// 25 | /// # Example 26 | /// ``` 27 | /// use hyper::header::{Headers, ContentLength}; 28 | /// 29 | /// let mut headers = Headers::new(); 30 | /// headers.set(ContentLength(1024u64)); 31 | /// ``` 32 | #[derive(Clone, Copy, Debug, PartialEq)] 33 | pub struct ContentLength(pub u64); 34 | 35 | impl Header for ContentLength { 36 | #[inline] 37 | fn header_name() -> &'static str { 38 | "Content-Length" 39 | } 40 | fn parse_header>(raw: &[T]) -> ::Result { 41 | // If multiple Content-Length headers were sent, everything can still 42 | // be alright if they all contain the same value, and all parse 43 | // correctly. If not, then it's an error. 44 | raw.iter() 45 | .map(|b| b.as_ref()) 46 | .map(|b| if b.iter().all(|b| matches!(b, b'0'..=b'9')) { parsing::from_raw_str(b) } else { Err(::Error::Header) }) 47 | .fold(None, |prev, x| { 48 | match (prev, x) { 49 | (None, x) => Some(x), 50 | (e@Some(Err(_)), _ ) => e, 51 | (Some(Ok(prev)), Ok(x)) if prev == x => Some(Ok(prev)), 52 | _ => Some(Err(::Error::Header)) 53 | } 54 | }) 55 | .unwrap_or(Err(::Error::Header)) 56 | .map(ContentLength) 57 | } 58 | } 59 | 60 | impl HeaderFormat for ContentLength { 61 | #[inline] 62 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 63 | fmt::Display::fmt(&self.0, f) 64 | } 65 | } 66 | 67 | impl fmt::Display for ContentLength { 68 | #[inline] 69 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 70 | fmt::Display::fmt(&self.0, f) 71 | } 72 | } 73 | 74 | __hyper__deref!(ContentLength => u64); 75 | 76 | __hyper__tm!(ContentLength, tests { 77 | // Testcase from RFC 78 | test_header!(test1, vec![b"3495"], Some(HeaderField(3495))); 79 | 80 | test_header!(test_invalid, vec![b"34v95"], None); 81 | 82 | // Can't use the test_header macro because "5, 5" gets cleaned to "5". 83 | #[test] 84 | fn test_duplicates() { 85 | let parsed = HeaderField::parse_header(&[b"5"[..].into(), 86 | b"5"[..].into()]).unwrap(); 87 | assert_eq!(parsed, HeaderField(5)); 88 | assert_eq!(format!("{}", parsed), "5"); 89 | } 90 | 91 | test_header!(test_duplicates_vary, vec![b"5", b"6", b"5"], None); 92 | }); 93 | 94 | bench_header!(bench, ContentLength, { vec![b"42349984".to_vec()] }); 95 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/content_type.rs: -------------------------------------------------------------------------------- 1 | use mime::Mime; 2 | 3 | header! { 4 | /// `Content-Type` header, defined in 5 | /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.1.5) 6 | /// 7 | /// The `Content-Type` header field indicates the media type of the 8 | /// associated representation: either the representation enclosed in the 9 | /// message payload or the selected representation, as determined by the 10 | /// message semantics. The indicated media type defines both the data 11 | /// format and how that data is intended to be processed by a recipient, 12 | /// within the scope of the received message semantics, after any content 13 | /// codings indicated by Content-Encoding are decoded. 14 | /// 15 | /// # ABNF 16 | /// ```plain 17 | /// Content-Type = media-type 18 | /// ``` 19 | /// 20 | /// # Example values 21 | /// * `text/html; charset=ISO-8859-4` 22 | /// 23 | /// # Examples 24 | /// ``` 25 | /// use hyper::header::{Headers, ContentType}; 26 | /// use hyper::mime::{Mime, TopLevel, SubLevel}; 27 | /// 28 | /// let mut headers = Headers::new(); 29 | /// 30 | /// headers.set( 31 | /// ContentType(Mime(TopLevel::Text, SubLevel::Html, vec![])) 32 | /// ); 33 | /// ``` 34 | /// ``` 35 | /// use hyper::header::{Headers, ContentType}; 36 | /// use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value}; 37 | /// 38 | /// let mut headers = Headers::new(); 39 | /// 40 | /// headers.set( 41 | /// ContentType(Mime(TopLevel::Application, SubLevel::Json, 42 | /// vec![(Attr::Charset, Value::Utf8)])) 43 | /// ); 44 | /// ``` 45 | (ContentType, "Content-Type") => [Mime] 46 | 47 | test_content_type { 48 | test_header!( 49 | test1, 50 | // FIXME: Should be b"text/html; charset=ISO-8859-4" but mime crate lowercases 51 | // the whole value so parsing and formatting the value gives a different result 52 | vec![b"text/html; charset=iso-8859-4"], 53 | Some(HeaderField(Mime( 54 | TopLevel::Text, 55 | SubLevel::Html, 56 | vec![(Attr::Charset, Value::Ext("iso-8859-4".to_owned()))])))); 57 | } 58 | } 59 | 60 | impl ContentType { 61 | /// A constructor to easily create a `Content-Type: application/json` header. 62 | #[inline] 63 | pub fn json() -> ContentType { 64 | ContentType(mime!(Application/Json)) 65 | } 66 | 67 | /// A constructor to easily create a `Content-Type: text/plain; charset=utf-8` header. 68 | #[inline] 69 | pub fn plaintext() -> ContentType { 70 | ContentType(mime!(Text/Plain; Charset=Utf8)) 71 | } 72 | 73 | /// A constructor to easily create a `Content-Type: text/html; charset=utf-8` header. 74 | #[inline] 75 | pub fn html() -> ContentType { 76 | ContentType(mime!(Text/Html; Charset=Utf8)) 77 | } 78 | 79 | /// A constructor to easily create a `Content-Type: application/www-form-url-encoded` header. 80 | #[inline] 81 | pub fn form_url_encoded() -> ContentType { 82 | ContentType(mime!(Application/WwwFormUrlEncoded)) 83 | } 84 | /// A constructor to easily create a `Content-Type: image/jpeg` header. 85 | #[inline] 86 | pub fn jpeg() -> ContentType { 87 | ContentType(mime!(Image/Jpeg)) 88 | } 89 | 90 | /// A constructor to easily create a `Content-Type: image/png` header. 91 | #[inline] 92 | pub fn png() -> ContentType { 93 | ContentType(mime!(Image/Png)) 94 | } 95 | } 96 | 97 | bench_header!(bench, ContentType, { vec![b"application/json; charset=utf-8".to_vec()] }); 98 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/cookie.rs: -------------------------------------------------------------------------------- 1 | use header::{Header, HeaderFormat}; 2 | use std::fmt::{self, Display}; 3 | use std::str::from_utf8; 4 | 5 | /// `Cookie` header, defined in [RFC6265](http://tools.ietf.org/html/rfc6265#section-5.4) 6 | /// 7 | /// If the user agent does attach a Cookie header field to an HTTP 8 | /// request, the user agent must send the cookie-string 9 | /// as the value of the header field. 10 | /// 11 | /// When the user agent generates an HTTP request, the user agent MUST NOT 12 | /// attach more than one Cookie header field. 13 | /// 14 | /// # Example values 15 | /// * `SID=31d4d96e407aad42` 16 | /// * `SID=31d4d96e407aad42; lang=en-US` 17 | /// 18 | /// # Example 19 | /// ``` 20 | /// use hyper::header::{Headers, Cookie}; 21 | /// 22 | /// let mut headers = Headers::new(); 23 | /// 24 | /// headers.set( 25 | /// Cookie(vec![ 26 | /// String::from("foo=bar") 27 | /// ]) 28 | /// ); 29 | /// ``` 30 | #[derive(Clone, PartialEq, Debug)] 31 | pub struct Cookie(pub Vec); 32 | 33 | __hyper__deref!(Cookie => Vec); 34 | 35 | impl Header for Cookie { 36 | fn header_name() -> &'static str { 37 | "Cookie" 38 | } 39 | 40 | fn parse_header>(raw: &[T]) -> ::Result { 41 | let mut cookies = Vec::with_capacity(raw.len()); 42 | for cookies_raw in raw.iter() { 43 | let cookies_str = try!(from_utf8(cookies_raw.as_ref())); 44 | for cookie_str in cookies_str.split(';') { 45 | cookies.push(cookie_str.trim().to_owned()) 46 | } 47 | } 48 | 49 | if !cookies.is_empty() { 50 | Ok(Cookie(cookies)) 51 | } else { 52 | Err(::Error::Header) 53 | } 54 | } 55 | } 56 | 57 | impl HeaderFormat for Cookie { 58 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 59 | let cookies = &self.0; 60 | for (i, cookie) in cookies.iter().enumerate() { 61 | if i != 0 { 62 | try!(f.write_str("; ")); 63 | } 64 | try!(Display::fmt(&cookie, f)); 65 | } 66 | Ok(()) 67 | } 68 | } 69 | 70 | bench_header!(bench, Cookie, { vec![b"foo=bar; baz=quux".to_vec()] }); 71 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/date.rs: -------------------------------------------------------------------------------- 1 | use header::HttpDate; 2 | 3 | header! { 4 | /// `Date` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.1.1.2) 5 | /// 6 | /// The `Date` header field represents the date and time at which the 7 | /// message was originated. 8 | /// 9 | /// # ABNF 10 | /// ```plain 11 | /// Date = HTTP-date 12 | /// ``` 13 | /// 14 | /// # Example values 15 | /// * `Tue, 15 Nov 1994 08:12:31 GMT` 16 | /// 17 | /// # Example 18 | /// ``` 19 | /// # extern crate time; 20 | /// # extern crate hyper; 21 | /// # fn main() { 22 | /// // extern crate time; 23 | /// 24 | /// use hyper::header::{Headers, Date, HttpDate}; 25 | /// use time; 26 | /// 27 | /// let mut headers = Headers::new(); 28 | /// headers.set(Date(HttpDate(time::now()))); 29 | /// # } 30 | /// ``` 31 | (Date, "Date") => [HttpDate] 32 | 33 | test_date { 34 | test_header!(test1, vec![b"Tue, 15 Nov 1994 08:12:31 GMT"]); 35 | } 36 | } 37 | 38 | bench_header!(imf_fixdate, Date, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); 39 | bench_header!(rfc_850, Date, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); 40 | bench_header!(asctime, Date, { vec![b"Sun Nov 6 08:49:37 1994".to_vec()] }); 41 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/etag.rs: -------------------------------------------------------------------------------- 1 | use header::EntityTag; 2 | 3 | header! { 4 | /// `ETag` header, defined in [RFC7232](http://tools.ietf.org/html/rfc7232#section-2.3) 5 | /// 6 | /// The `ETag` header field in a response provides the current entity-tag 7 | /// for the selected representation, as determined at the conclusion of 8 | /// handling the request. An entity-tag is an opaque validator for 9 | /// differentiating between multiple representations of the same 10 | /// resource, regardless of whether those multiple representations are 11 | /// due to resource state changes over time, content negotiation 12 | /// resulting in multiple representations being valid at the same time, 13 | /// or both. An entity-tag consists of an opaque quoted string, possibly 14 | /// prefixed by a weakness indicator. 15 | /// 16 | /// # ABNF 17 | /// ```plain 18 | /// ETag = entity-tag 19 | /// ``` 20 | /// 21 | /// # Example values 22 | /// * `"xyzzy"` 23 | /// * `W/"xyzzy"` 24 | /// * `""` 25 | /// 26 | /// # Examples 27 | /// ``` 28 | /// use hyper::header::{Headers, ETag, EntityTag}; 29 | /// 30 | /// let mut headers = Headers::new(); 31 | /// headers.set(ETag(EntityTag::new(false, "xyzzy".to_owned()))); 32 | /// ``` 33 | /// ``` 34 | /// use hyper::header::{Headers, ETag, EntityTag}; 35 | /// 36 | /// let mut headers = Headers::new(); 37 | /// headers.set(ETag(EntityTag::new(true, "xyzzy".to_owned()))); 38 | /// ``` 39 | (ETag, "ETag") => [EntityTag] 40 | 41 | test_etag { 42 | // From the RFC 43 | test_header!(test1, 44 | vec![b"\"xyzzy\""], 45 | Some(ETag(EntityTag::new(false, "xyzzy".to_owned())))); 46 | test_header!(test2, 47 | vec![b"W/\"xyzzy\""], 48 | Some(ETag(EntityTag::new(true, "xyzzy".to_owned())))); 49 | test_header!(test3, 50 | vec![b"\"\""], 51 | Some(ETag(EntityTag::new(false, "".to_owned())))); 52 | // Own tests 53 | test_header!(test4, 54 | vec![b"\"foobar\""], 55 | Some(ETag(EntityTag::new(false, "foobar".to_owned())))); 56 | test_header!(test5, 57 | vec![b"\"\""], 58 | Some(ETag(EntityTag::new(false, "".to_owned())))); 59 | test_header!(test6, 60 | vec![b"W/\"weak-etag\""], 61 | Some(ETag(EntityTag::new(true, "weak-etag".to_owned())))); 62 | test_header!(test7, 63 | vec![b"W/\"\x65\x62\""], 64 | Some(ETag(EntityTag::new(true, "\u{0065}\u{0062}".to_owned())))); 65 | test_header!(test8, 66 | vec![b"W/\"\""], 67 | Some(ETag(EntityTag::new(true, "".to_owned())))); 68 | test_header!(test9, 69 | vec![b"no-dquotes"], 70 | None::); 71 | test_header!(test10, 72 | vec![b"w/\"the-first-w-is-case-sensitive\""], 73 | None::); 74 | test_header!(test11, 75 | vec![b""], 76 | None::); 77 | test_header!(test12, 78 | vec![b"\"unmatched-dquotes1"], 79 | None::); 80 | test_header!(test13, 81 | vec![b"unmatched-dquotes2\""], 82 | None::); 83 | test_header!(test14, 84 | vec![b"matched-\"dquotes\""], 85 | None::); 86 | } 87 | } 88 | 89 | bench_header!(bench, ETag, { vec![b"W/\"nonemptytag\"".to_vec()] }); 90 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/expect.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::str; 3 | 4 | use unicase::UniCase; 5 | 6 | use header::{Header, HeaderFormat}; 7 | 8 | /// The `Expect` header. 9 | /// 10 | /// > The "Expect" header field in a request indicates a certain set of 11 | /// > behaviors (expectations) that need to be supported by the server in 12 | /// > order to properly handle this request. The only such expectation 13 | /// > defined by this specification is 100-continue. 14 | /// > 15 | /// > Expect = "100-continue" 16 | /// 17 | /// # Example 18 | /// ``` 19 | /// use hyper::header::{Headers, Expect}; 20 | /// let mut headers = Headers::new(); 21 | /// headers.set(Expect::Continue); 22 | /// ``` 23 | #[derive(Copy, Clone, PartialEq, Debug)] 24 | pub enum Expect { 25 | /// The value `100-continue`. 26 | Continue 27 | } 28 | 29 | const EXPECT_CONTINUE: UniCase<&'static str> = UniCase("100-continue"); 30 | 31 | impl Header for Expect { 32 | fn header_name() -> &'static str { 33 | "Expect" 34 | } 35 | 36 | fn parse_header>(raw: &[T]) -> ::Result { 37 | if raw.len() == 1 { 38 | let text = unsafe { 39 | // safe because: 40 | // 1. we just checked raw.len == 1 41 | // 2. we don't actually care if it's utf8, we just want to 42 | // compare the bytes with the "case" normalized. If it's not 43 | // utf8, then the byte comparison will fail, and we'll return 44 | // None. No big deal. 45 | str::from_utf8_unchecked(raw.get_unchecked(0).as_ref()) 46 | }; 47 | if UniCase(text) == EXPECT_CONTINUE { 48 | Ok(Expect::Continue) 49 | } else { 50 | Err(::Error::Header) 51 | } 52 | } else { 53 | Err(::Error::Header) 54 | } 55 | } 56 | } 57 | 58 | impl HeaderFormat for Expect { 59 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 60 | fmt::Display::fmt(self, f) 61 | } 62 | } 63 | 64 | impl fmt::Display for Expect { 65 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 66 | f.write_str("100-continue") 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/expires.rs: -------------------------------------------------------------------------------- 1 | use header::HttpDate; 2 | 3 | header! { 4 | /// `Expires` header, defined in [RFC7234](http://tools.ietf.org/html/rfc7234#section-5.3) 5 | /// 6 | /// The `Expires` header field gives the date/time after which the 7 | /// response is considered stale. 8 | /// 9 | /// The presence of an Expires field does not imply that the original 10 | /// resource will change or cease to exist at, before, or after that 11 | /// time. 12 | /// 13 | /// # ABNF 14 | /// ```plain 15 | /// Expires = HTTP-date 16 | /// ``` 17 | /// 18 | /// # Example values 19 | /// * `Thu, 01 Dec 1994 16:00:00 GMT` 20 | /// 21 | /// # Example 22 | /// ``` 23 | /// # extern crate hyper; 24 | /// # extern crate time; 25 | /// # fn main() { 26 | /// // extern crate time; 27 | /// 28 | /// use hyper::header::{Headers, Expires, HttpDate}; 29 | /// use time::{self, Duration}; 30 | /// 31 | /// let mut headers = Headers::new(); 32 | /// headers.set(Expires(HttpDate(time::now() + Duration::days(1)))); 33 | /// # } 34 | /// ``` 35 | (Expires, "Expires") => [HttpDate] 36 | 37 | test_expires { 38 | // Testcase from RFC 39 | test_header!(test1, vec![b"Thu, 01 Dec 1994 16:00:00 GMT"]); 40 | } 41 | } 42 | 43 | bench_header!(imf_fixdate, Expires, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); 44 | bench_header!(rfc_850, Expires, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); 45 | bench_header!(asctime, Expires, { vec![b"Sun Nov 6 08:49:37 1994".to_vec()] }); 46 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/from.rs: -------------------------------------------------------------------------------- 1 | header! { 2 | /// `From` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.5.1) 3 | /// 4 | /// The `From` header field contains an Internet email address for a 5 | /// human user who controls the requesting user agent. The address ought 6 | /// to be machine-usable. 7 | /// # ABNF 8 | /// ```plain 9 | /// From = mailbox 10 | /// mailbox = 11 | /// ``` 12 | /// 13 | /// # Example 14 | /// ``` 15 | /// use hyper::header::{Headers, From}; 16 | /// 17 | /// let mut headers = Headers::new(); 18 | /// headers.set(From("webmaster@example.org".to_owned())); 19 | /// ``` 20 | // FIXME: Maybe use mailbox? 21 | (From, "From") => [String] 22 | 23 | test_from { 24 | test_header!(test1, vec![b"webmaster@example.org"]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/host.rs: -------------------------------------------------------------------------------- 1 | use header::{Header, HeaderFormat}; 2 | use std::fmt; 3 | use std::str::FromStr; 4 | use header::parsing::from_one_raw_str; 5 | use url::idna::domain_to_unicode; 6 | 7 | /// The `Host` header. 8 | /// 9 | /// HTTP/1.1 requires that all requests include a `Host` header, and so hyper 10 | /// client requests add one automatically. 11 | /// 12 | /// Currently is just a String, but it should probably become a better type, 13 | /// like `url::Host` or something. 14 | /// 15 | /// # Examples 16 | /// ``` 17 | /// use hyper::header::{Headers, Host}; 18 | /// 19 | /// let mut headers = Headers::new(); 20 | /// headers.set( 21 | /// Host{ 22 | /// hostname: "hyper.rs".to_owned(), 23 | /// port: None, 24 | /// } 25 | /// ); 26 | /// ``` 27 | /// ``` 28 | /// use hyper::header::{Headers, Host}; 29 | /// 30 | /// let mut headers = Headers::new(); 31 | /// headers.set( 32 | /// Host{ 33 | /// hostname: "hyper.rs".to_owned(), 34 | /// port: Some(8080), 35 | /// } 36 | /// ); 37 | /// ``` 38 | #[derive(Clone, PartialEq, Debug)] 39 | pub struct Host { 40 | /// The hostname, such a example.domain. 41 | pub hostname: String, 42 | /// An optional port number. 43 | pub port: Option 44 | } 45 | 46 | impl Header for Host { 47 | fn header_name() -> &'static str { 48 | "Host" 49 | } 50 | 51 | fn parse_header>(raw: &[T]) -> ::Result { 52 | from_one_raw_str(raw) 53 | } 54 | } 55 | 56 | impl HeaderFormat for Host { 57 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 58 | match self.port { 59 | None | Some(80) | Some(443) => f.write_str(&self.hostname[..]), 60 | Some(port) => write!(f, "{}:{}", self.hostname, port) 61 | } 62 | } 63 | } 64 | 65 | impl fmt::Display for Host { 66 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 67 | self.fmt_header(f) 68 | } 69 | } 70 | 71 | impl FromStr for Host { 72 | type Err = ::Error; 73 | 74 | fn from_str(s: &str) -> ::Result { 75 | let idx = s.rfind(':'); 76 | let port = idx.and_then( 77 | |idx| s[idx + 1..].parse().ok() 78 | ); 79 | let hostname_encoded = match port { 80 | None => s, 81 | Some(_) => &s[..idx.unwrap()] 82 | }; 83 | 84 | let hostname = if hostname_encoded.starts_with("[") { 85 | if !hostname_encoded.ends_with("]") { 86 | return Err(::Error::Header) 87 | } 88 | hostname_encoded.to_owned() 89 | } else { 90 | let (hostname, res) = domain_to_unicode(hostname_encoded); 91 | if res.is_err() { 92 | return Err(::Error::Header) 93 | } 94 | hostname 95 | }; 96 | 97 | Ok(Host { 98 | hostname: hostname, 99 | port: port 100 | }) 101 | } 102 | } 103 | 104 | #[cfg(test)] 105 | mod tests { 106 | use super::Host; 107 | use header::Header; 108 | 109 | 110 | #[test] 111 | fn test_host() { 112 | let host = Header::parse_header([b"foo.com".to_vec()].as_ref()); 113 | assert_eq!(host.ok(), Some(Host { 114 | hostname: "foo.com".to_owned(), 115 | port: None 116 | })); 117 | 118 | 119 | let host = Header::parse_header([b"foo.com:8080".to_vec()].as_ref()); 120 | assert_eq!(host.ok(), Some(Host { 121 | hostname: "foo.com".to_owned(), 122 | port: Some(8080) 123 | })); 124 | 125 | let host = Header::parse_header([b"foo.com".to_vec()].as_ref()); 126 | assert_eq!(host.ok(), Some(Host { 127 | hostname: "foo.com".to_owned(), 128 | port: None 129 | })); 130 | 131 | let host = Header::parse_header([b"[::1]:8080".to_vec()].as_ref()); 132 | assert_eq!(host.ok(), Some(Host { 133 | hostname: "[::1]".to_owned(), 134 | port: Some(8080) 135 | })); 136 | 137 | let host = Header::parse_header([b"[::1]".to_vec()].as_ref()); 138 | assert_eq!(host.ok(), Some(Host { 139 | hostname: "[::1]".to_owned(), 140 | port: None 141 | })); 142 | } 143 | } 144 | 145 | bench_header!(bench, Host, { vec![b"foo.com:3000".to_vec()] }); 146 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/if_match.rs: -------------------------------------------------------------------------------- 1 | use header::EntityTag; 2 | 3 | header! { 4 | /// `If-Match` header, defined in 5 | /// [RFC7232](https://tools.ietf.org/html/rfc7232#section-3.1) 6 | /// 7 | /// The `If-Match` header field makes the request method conditional on 8 | /// the recipient origin server either having at least one current 9 | /// representation of the target resource, when the field-value is "*", 10 | /// or having a current representation of the target resource that has an 11 | /// entity-tag matching a member of the list of entity-tags provided in 12 | /// the field-value. 13 | /// 14 | /// An origin server MUST use the strong comparison function when 15 | /// comparing entity-tags for `If-Match`, since the client 16 | /// intends this precondition to prevent the method from being applied if 17 | /// there have been any changes to the representation data. 18 | /// 19 | /// # ABNF 20 | /// ```plain 21 | /// If-Match = "*" / 1#entity-tag 22 | /// ``` 23 | /// 24 | /// # Example values 25 | /// * `"xyzzy"` 26 | /// * "xyzzy", "r2d2xxxx", "c3piozzzz" 27 | /// 28 | /// # Examples 29 | /// ``` 30 | /// use hyper::header::{Headers, IfMatch}; 31 | /// 32 | /// let mut headers = Headers::new(); 33 | /// headers.set(IfMatch::Any); 34 | /// ``` 35 | /// ``` 36 | /// use hyper::header::{Headers, IfMatch, EntityTag}; 37 | /// 38 | /// let mut headers = Headers::new(); 39 | /// headers.set( 40 | /// IfMatch::Items(vec![ 41 | /// EntityTag::new(false, "xyzzy".to_owned()), 42 | /// EntityTag::new(false, "foobar".to_owned()), 43 | /// EntityTag::new(false, "bazquux".to_owned()), 44 | /// ]) 45 | /// ); 46 | /// ``` 47 | (IfMatch, "If-Match") => {Any / (EntityTag)+} 48 | 49 | test_if_match { 50 | test_header!( 51 | test1, 52 | vec![b"\"xyzzy\""], 53 | Some(HeaderField::Items( 54 | vec![EntityTag::new(false, "xyzzy".to_owned())]))); 55 | test_header!( 56 | test2, 57 | vec![b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""], 58 | Some(HeaderField::Items( 59 | vec![EntityTag::new(false, "xyzzy".to_owned()), 60 | EntityTag::new(false, "r2d2xxxx".to_owned()), 61 | EntityTag::new(false, "c3piozzzz".to_owned())]))); 62 | test_header!(test3, vec![b"*"], Some(IfMatch::Any)); 63 | } 64 | } 65 | 66 | bench_header!(star, IfMatch, { vec![b"*".to_vec()] }); 67 | bench_header!(single , IfMatch, { vec![b"\"xyzzy\"".to_vec()] }); 68 | bench_header!(multi, IfMatch, 69 | { vec![b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\"".to_vec()] }); 70 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/if_modified_since.rs: -------------------------------------------------------------------------------- 1 | use header::HttpDate; 2 | 3 | header! { 4 | /// `If-Modified-Since` header, defined in 5 | /// [RFC7232](http://tools.ietf.org/html/rfc7232#section-3.3) 6 | /// 7 | /// The `If-Modified-Since` header field makes a GET or HEAD request 8 | /// method conditional on the selected representation's modification date 9 | /// being more recent than the date provided in the field-value. 10 | /// Transfer of the selected representation's data is avoided if that 11 | /// data has not changed. 12 | /// 13 | /// # ABNF 14 | /// ```plain 15 | /// If-Unmodified-Since = HTTP-date 16 | /// ``` 17 | /// 18 | /// # Example values 19 | /// * `Sat, 29 Oct 1994 19:43:31 GMT` 20 | /// 21 | /// # Example 22 | /// ``` 23 | /// # extern crate hyper; 24 | /// # extern crate time; 25 | /// # fn main() { 26 | /// // extern crate time; 27 | /// 28 | /// use hyper::header::{Headers, IfModifiedSince, HttpDate}; 29 | /// use time::{self, Duration}; 30 | /// 31 | /// let mut headers = Headers::new(); 32 | /// headers.set(IfModifiedSince(HttpDate(time::now() - Duration::days(1)))); 33 | /// # } 34 | /// ``` 35 | (IfModifiedSince, "If-Modified-Since") => [HttpDate] 36 | 37 | test_if_modified_since { 38 | // Testcase from RFC 39 | test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); 40 | } 41 | } 42 | 43 | bench_header!(imf_fixdate, IfModifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); 44 | bench_header!(rfc_850, IfModifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); 45 | bench_header!(asctime, IfModifiedSince, { vec![b"Sun Nov 6 08:49:37 1994".to_vec()] }); 46 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/if_none_match.rs: -------------------------------------------------------------------------------- 1 | use header::EntityTag; 2 | 3 | header! { 4 | /// `If-None-Match` header, defined in 5 | /// [RFC7232](https://tools.ietf.org/html/rfc7232#section-3.2) 6 | /// 7 | /// The `If-None-Match` header field makes the request method conditional 8 | /// on a recipient cache or origin server either not having any current 9 | /// representation of the target resource, when the field-value is "*", 10 | /// or having a selected representation with an entity-tag that does not 11 | /// match any of those listed in the field-value. 12 | /// 13 | /// A recipient MUST use the weak comparison function when comparing 14 | /// entity-tags for If-None-Match (Section 2.3.2), since weak entity-tags 15 | /// can be used for cache validation even if there have been changes to 16 | /// the representation data. 17 | /// 18 | /// # ABNF 19 | /// ```plain 20 | /// If-None-Match = "*" / 1#entity-tag 21 | /// ``` 22 | /// 23 | /// # Example values 24 | /// * `"xyzzy"` 25 | /// * `W/"xyzzy"` 26 | /// * `"xyzzy", "r2d2xxxx", "c3piozzzz"` 27 | /// * `W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"` 28 | /// * `*` 29 | /// 30 | /// # Examples 31 | /// ``` 32 | /// use hyper::header::{Headers, IfNoneMatch}; 33 | /// 34 | /// let mut headers = Headers::new(); 35 | /// headers.set(IfNoneMatch::Any); 36 | /// ``` 37 | /// ``` 38 | /// use hyper::header::{Headers, IfNoneMatch, EntityTag}; 39 | /// 40 | /// let mut headers = Headers::new(); 41 | /// headers.set( 42 | /// IfNoneMatch::Items(vec![ 43 | /// EntityTag::new(false, "xyzzy".to_owned()), 44 | /// EntityTag::new(false, "foobar".to_owned()), 45 | /// EntityTag::new(false, "bazquux".to_owned()), 46 | /// ]) 47 | /// ); 48 | /// ``` 49 | (IfNoneMatch, "If-None-Match") => {Any / (EntityTag)+} 50 | 51 | test_if_none_match { 52 | test_header!(test1, vec![b"\"xyzzy\""]); 53 | test_header!(test2, vec![b"W/\"xyzzy\""]); 54 | test_header!(test3, vec![b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""]); 55 | test_header!(test4, vec![b"W/\"xyzzy\", W/\"r2d2xxxx\", W/\"c3piozzzz\""]); 56 | test_header!(test5, vec![b"*"]); 57 | } 58 | } 59 | 60 | #[cfg(test)] 61 | mod tests { 62 | use super::IfNoneMatch; 63 | use header::Header; 64 | use header::EntityTag; 65 | 66 | #[test] 67 | fn test_if_none_match() { 68 | let mut if_none_match: ::Result; 69 | 70 | if_none_match = Header::parse_header([b"*".to_vec()].as_ref()); 71 | assert_eq!(if_none_match.ok(), Some(IfNoneMatch::Any)); 72 | 73 | if_none_match = Header::parse_header([b"\"foobar\", W/\"weak-etag\"".to_vec()].as_ref()); 74 | let mut entities: Vec = Vec::new(); 75 | let foobar_etag = EntityTag::new(false, "foobar".to_owned()); 76 | let weak_etag = EntityTag::new(true, "weak-etag".to_owned()); 77 | entities.push(foobar_etag); 78 | entities.push(weak_etag); 79 | assert_eq!(if_none_match.ok(), Some(IfNoneMatch::Items(entities))); 80 | } 81 | } 82 | 83 | bench_header!(bench, IfNoneMatch, { vec![b"W/\"nonemptytag\"".to_vec()] }); 84 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/if_range.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{self, Display}; 2 | use header::{self, Header, HeaderFormat, EntityTag, HttpDate}; 3 | 4 | /// `If-Range` header, defined in [RFC7233](http://tools.ietf.org/html/rfc7233#section-3.2) 5 | /// 6 | /// If a client has a partial copy of a representation and wishes to have 7 | /// an up-to-date copy of the entire representation, it could use the 8 | /// Range header field with a conditional GET (using either or both of 9 | /// If-Unmodified-Since and If-Match.) However, if the precondition 10 | /// fails because the representation has been modified, the client would 11 | /// then have to make a second request to obtain the entire current 12 | /// representation. 13 | /// 14 | /// The `If-Range` header field allows a client to \"short-circuit\" the 15 | /// second request. Informally, its meaning is as follows: if the 16 | /// representation is unchanged, send me the part(s) that I am requesting 17 | /// in Range; otherwise, send me the entire representation. 18 | /// 19 | /// # ABNF 20 | /// ```plain 21 | /// If-Range = entity-tag / HTTP-date 22 | /// ``` 23 | /// 24 | /// # Example values 25 | /// * `Sat, 29 Oct 1994 19:43:31 GMT` 26 | /// * `\"xyzzy\"` 27 | /// 28 | /// # Examples 29 | /// ``` 30 | /// use hyper::header::{Headers, IfRange, EntityTag}; 31 | /// 32 | /// let mut headers = Headers::new(); 33 | /// headers.set(IfRange::EntityTag(EntityTag::new(false, "xyzzy".to_owned()))); 34 | /// ``` 35 | /// ``` 36 | /// # extern crate hyper; 37 | /// # extern crate time; 38 | /// # fn main() { 39 | /// // extern crate time; 40 | /// 41 | /// use hyper::header::{Headers, IfRange, HttpDate}; 42 | /// use time::{self, Duration}; 43 | /// 44 | /// let mut headers = Headers::new(); 45 | /// headers.set(IfRange::Date(HttpDate(time::now() - Duration::days(1)))); 46 | /// # } 47 | /// ``` 48 | #[derive(Clone, Debug, PartialEq)] 49 | pub enum IfRange { 50 | /// The entity-tag the client has of the resource 51 | EntityTag(EntityTag), 52 | /// The date when the client retrieved the resource 53 | Date(HttpDate), 54 | } 55 | 56 | impl Header for IfRange { 57 | fn header_name() -> &'static str { 58 | "If-Range" 59 | } 60 | fn parse_header>(raw: &[T]) -> ::Result { 61 | let etag: ::Result = header::parsing::from_one_raw_str(raw); 62 | if etag.is_ok() { 63 | return Ok(IfRange::EntityTag(etag.unwrap())); 64 | } 65 | let date: ::Result = header::parsing::from_one_raw_str(raw); 66 | if date.is_ok() { 67 | return Ok(IfRange::Date(date.unwrap())); 68 | } 69 | Err(::Error::Header) 70 | } 71 | } 72 | 73 | impl HeaderFormat for IfRange { 74 | fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 75 | match *self { 76 | IfRange::EntityTag(ref x) => Display::fmt(x, f), 77 | IfRange::Date(ref x) => Display::fmt(x, f), 78 | } 79 | } 80 | } 81 | 82 | impl Display for IfRange { 83 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 84 | self.fmt_header(f) 85 | } 86 | } 87 | 88 | #[cfg(test)] 89 | mod test_if_range { 90 | use std::str; 91 | use header::*; 92 | use super::IfRange as HeaderField; 93 | test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); 94 | test_header!(test2, vec![b"\"xyzzy\""]); 95 | test_header!(test3, vec![b"this-is-invalid"], None::); 96 | } 97 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/if_unmodified_since.rs: -------------------------------------------------------------------------------- 1 | use header::HttpDate; 2 | 3 | header! { 4 | /// `If-Unmodified-Since` header, defined in 5 | /// [RFC7232](http://tools.ietf.org/html/rfc7232#section-3.4) 6 | /// 7 | /// The `If-Unmodified-Since` header field makes the request method 8 | /// conditional on the selected representation's last modification date 9 | /// being earlier than or equal to the date provided in the field-value. 10 | /// This field accomplishes the same purpose as If-Match for cases where 11 | /// the user agent does not have an entity-tag for the representation. 12 | /// 13 | /// # ABNF 14 | /// ```plain 15 | /// If-Unmodified-Since = HTTP-date 16 | /// ``` 17 | /// 18 | /// # Example values 19 | /// * `Sat, 29 Oct 1994 19:43:31 GMT` 20 | /// 21 | /// # Example 22 | /// ``` 23 | /// # extern crate hyper; 24 | /// # extern crate time; 25 | /// # fn main() { 26 | /// // extern crate time; 27 | /// 28 | /// use hyper::header::{Headers, IfUnmodifiedSince, HttpDate}; 29 | /// use time::{self, Duration}; 30 | /// 31 | /// let mut headers = Headers::new(); 32 | /// headers.set(IfUnmodifiedSince(HttpDate(time::now() - Duration::days(1)))); 33 | /// # } 34 | /// ``` 35 | (IfUnmodifiedSince, "If-Unmodified-Since") => [HttpDate] 36 | 37 | test_if_unmodified_since { 38 | // Testcase from RFC 39 | test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); 40 | } 41 | } 42 | 43 | bench_header!(imf_fixdate, IfUnmodifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); 44 | bench_header!(rfc_850, IfUnmodifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); 45 | bench_header!(asctime, IfUnmodifiedSince, { vec![b"Sun Nov 6 08:49:37 1994".to_vec()] }); 46 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/last-event-id.rs: -------------------------------------------------------------------------------- 1 | header! { 2 | /// `Last-Event-ID` header, defined in 3 | /// [RFC3864](https://html.spec.whatwg.org/multipage/references.html#refsRFC3864) 4 | /// 5 | /// The `Last-Event-ID` header contains information about 6 | /// the last event in an http interaction so that it's easier to 7 | /// track of event state. This is helpful when working 8 | /// with [Server-Sent-Events](http://www.html5rocks.com/en/tutorials/eventsource/basics/). If the connection were to be dropped, for example, it'd 9 | /// be useful to let the server know what the last event you 10 | /// recieved was. 11 | /// 12 | /// The spec is a String with the id of the last event, it can be 13 | /// an empty string which acts a sort of "reset". 14 | /// 15 | /// # Example 16 | /// ``` 17 | /// use hyper::header::{Headers, LastEventID}; 18 | /// 19 | /// let mut headers = Headers::new(); 20 | /// headers.set(LastEventID("1".to_owned())); 21 | /// ``` 22 | (LastEventID, "Last-Event-ID") => [String] 23 | 24 | test_last_event_id { 25 | // Initial state 26 | test_header!(test1, vec![b""]); 27 | // Own testcase 28 | test_header!(test2, vec![b"1"], Some(LastEventID("1".to_owned()))); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/last_modified.rs: -------------------------------------------------------------------------------- 1 | use header::HttpDate; 2 | 3 | header! { 4 | /// `Last-Modified` header, defined in 5 | /// [RFC7232](http://tools.ietf.org/html/rfc7232#section-2.2) 6 | /// 7 | /// The `Last-Modified` header field in a response provides a timestamp 8 | /// indicating the date and time at which the origin server believes the 9 | /// selected representation was last modified, as determined at the 10 | /// conclusion of handling the request. 11 | /// 12 | /// # ABNF 13 | /// ```plain 14 | /// Expires = HTTP-date 15 | /// ``` 16 | /// 17 | /// # Example values 18 | /// * `Sat, 29 Oct 1994 19:43:31 GMT` 19 | /// 20 | /// # Example 21 | /// ``` 22 | /// # extern crate hyper; 23 | /// # extern crate time; 24 | /// # fn main() { 25 | /// // extern crate time; 26 | /// 27 | /// use hyper::header::{Headers, LastModified, HttpDate}; 28 | /// use time::{self, Duration}; 29 | /// 30 | /// let mut headers = Headers::new(); 31 | /// headers.set(LastModified(HttpDate(time::now() - Duration::days(1)))); 32 | /// # } 33 | /// ``` 34 | (LastModified, "Last-Modified") => [HttpDate] 35 | 36 | test_last_modified { 37 | // Testcase from RFC 38 | test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]);} 39 | } 40 | 41 | bench_header!(imf_fixdate, LastModified, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); 42 | bench_header!(rfc_850, LastModified, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); 43 | bench_header!(asctime, LastModified, { vec![b"Sun Nov 6 08:49:37 1994".to_vec()] }); 44 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/location.rs: -------------------------------------------------------------------------------- 1 | header! { 2 | /// `Location` header, defined in 3 | /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.1.2) 4 | /// 5 | /// The `Location` header field is used in some responses to refer to a 6 | /// specific resource in relation to the response. The type of 7 | /// relationship is defined by the combination of request method and 8 | /// status code semantics. 9 | /// 10 | /// # ABNF 11 | /// ```plain 12 | /// Location = URI-reference 13 | /// ``` 14 | /// 15 | /// # Example values 16 | /// * `/People.html#tim` 17 | /// * `http://www.example.net/index.html` 18 | /// 19 | /// # Examples 20 | /// ``` 21 | /// use hyper::header::{Headers, Location}; 22 | /// 23 | /// let mut headers = Headers::new(); 24 | /// headers.set(Location("/People.html#tim".to_owned())); 25 | /// ``` 26 | /// ``` 27 | /// use hyper::header::{Headers, Location}; 28 | /// 29 | /// let mut headers = Headers::new(); 30 | /// headers.set(Location("http://www.example.com/index.html".to_owned())); 31 | /// ``` 32 | // TODO: Use URL 33 | (Location, "Location") => [String] 34 | 35 | test_location { 36 | // Testcase from RFC 37 | test_header!(test1, vec![b"/People.html#tim"]); 38 | test_header!(test2, vec![b"http://www.example.net/index.html"]); 39 | } 40 | 41 | } 42 | 43 | bench_header!(bench, Location, { vec![b"http://foo.com/hello:3000".to_vec()] }); 44 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/origin.rs: -------------------------------------------------------------------------------- 1 | use header::{Header, Host, HeaderFormat}; 2 | use std::fmt; 3 | use std::str::FromStr; 4 | use header::parsing::from_one_raw_str; 5 | 6 | /// The `Origin` header. 7 | /// 8 | /// The `Origin` header is a version of the `Referer` header that is used for all HTTP fetches and `POST`s whose CORS flag is set. 9 | /// This header is often used to inform recipients of the security context of where the request was initiated. 10 | /// 11 | /// 12 | /// Following the spec, https://fetch.spec.whatwg.org/#origin-header, the value of this header is composed of 13 | /// a String (scheme), header::Host (host/port) 14 | /// 15 | /// # Examples 16 | /// ``` 17 | /// use hyper::header::{Headers, Origin}; 18 | /// 19 | /// let mut headers = Headers::new(); 20 | /// headers.set( 21 | /// Origin::new("http", "hyper.rs", None) 22 | /// ); 23 | /// ``` 24 | /// ``` 25 | /// use hyper::header::{Headers, Origin}; 26 | /// 27 | /// let mut headers = Headers::new(); 28 | /// headers.set( 29 | /// Origin::new("https", "wikipedia.org", Some(443)) 30 | /// ); 31 | /// ``` 32 | 33 | #[derive(Clone, Debug)] 34 | pub struct Origin { 35 | /// The scheme, such as http or https 36 | pub scheme: String, 37 | /// The host, such as Host{hostname: "hyper.rs".to_owned(), port: None} 38 | pub host: Host, 39 | } 40 | 41 | impl Origin { 42 | /// Creates a new `Origin` header. 43 | pub fn new, H: Into>(scheme: S, hostname: H, port: Option) -> Origin{ 44 | Origin { 45 | scheme: scheme.into(), 46 | host: Host { 47 | hostname: hostname.into(), 48 | port: port 49 | } 50 | } 51 | } 52 | } 53 | 54 | impl Header for Origin { 55 | fn header_name() -> &'static str { 56 | static NAME: &'static str = "Origin"; 57 | NAME 58 | } 59 | 60 | fn parse_header>(raw: &[T]) -> ::Result { 61 | from_one_raw_str(raw) 62 | } 63 | } 64 | 65 | impl FromStr for Origin { 66 | type Err = ::Error; 67 | 68 | fn from_str(s: &str) -> ::Result { 69 | let idx = match s.find("://") { 70 | Some(idx) => idx, 71 | None => return Err(::Error::Header) 72 | }; 73 | // idx + 3 because thats how long "://" is 74 | let (scheme, etc) = (&s[..idx], &s[idx + 3..]); 75 | let host = try!(Host::from_str(etc)); 76 | 77 | 78 | Ok(Origin{ 79 | scheme: scheme.to_owned(), 80 | host: host 81 | }) 82 | } 83 | } 84 | 85 | impl HeaderFormat for Origin { 86 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 87 | fmt::Display::fmt(self, f) 88 | } 89 | } 90 | 91 | impl fmt::Display for Origin { 92 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 93 | write!(f, "{}://{}", self.scheme, self.host) 94 | } 95 | } 96 | 97 | impl PartialEq for Origin { 98 | fn eq(&self, other: &Origin) -> bool { 99 | self.scheme == other.scheme && self.host == other.host 100 | } 101 | } 102 | 103 | 104 | #[cfg(test)] 105 | mod tests { 106 | use super::Origin; 107 | use header::Header; 108 | 109 | #[test] 110 | fn test_origin() { 111 | let origin = Header::parse_header([b"http://foo.com".to_vec()].as_ref()); 112 | assert_eq!(origin.ok(), Some(Origin::new("http", "foo.com", None))); 113 | 114 | let origin = Header::parse_header([b"https://foo.com:443".to_vec()].as_ref()); 115 | assert_eq!(origin.ok(), Some(Origin::new("https", "foo.com", Some(443)))); 116 | } 117 | } 118 | 119 | bench_header!(bench, Origin, { vec![b"https://foo.com".to_vec()] }); 120 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/pragma.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | #[allow(unused_imports)] 4 | use std::ascii::AsciiExt; 5 | 6 | use header::{Header, HeaderFormat, parsing}; 7 | 8 | /// The `Pragma` header defined by HTTP/1.0. 9 | /// 10 | /// > The "Pragma" header field allows backwards compatibility with 11 | /// > HTTP/1.0 caches, so that clients can specify a "no-cache" request 12 | /// > that they will understand (as Cache-Control was not defined until 13 | /// > HTTP/1.1). When the Cache-Control header field is also present and 14 | /// > understood in a request, Pragma is ignored. 15 | 16 | /// > In HTTP/1.0, Pragma was defined as an extensible field for 17 | /// > implementation-specified directives for recipients. This 18 | /// > specification deprecates such extensions to improve interoperability. 19 | /// 20 | /// Spec: https://tools.ietf.org/html/rfc7234#section-5.4 21 | /// 22 | /// # Examples 23 | /// ``` 24 | /// use hyper::header::{Headers, Pragma}; 25 | /// 26 | /// let mut headers = Headers::new(); 27 | /// headers.set(Pragma::NoCache); 28 | /// ``` 29 | /// ``` 30 | /// use hyper::header::{Headers, Pragma}; 31 | /// 32 | /// let mut headers = Headers::new(); 33 | /// headers.set(Pragma::Ext("foobar".to_owned())); 34 | /// ``` 35 | #[derive(Clone, PartialEq, Debug)] 36 | pub enum Pragma { 37 | /// Corresponds to the `no-cache` value. 38 | NoCache, 39 | /// Every value other than `no-cache`. 40 | Ext(String), 41 | } 42 | 43 | impl Header for Pragma { 44 | fn header_name() -> &'static str { 45 | "Pragma" 46 | } 47 | 48 | fn parse_header>(raw: &[T]) -> ::Result { 49 | parsing::from_one_raw_str(raw).and_then(|s: String| { 50 | let slice = &s.to_ascii_lowercase()[..]; 51 | match slice { 52 | "no-cache" => Ok(Pragma::NoCache), 53 | _ => Ok(Pragma::Ext(s)), 54 | } 55 | }) 56 | } 57 | } 58 | 59 | impl HeaderFormat for Pragma { 60 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 61 | fmt::Display::fmt(self, f) 62 | } 63 | } 64 | 65 | impl fmt::Display for Pragma { 66 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 67 | f.write_str(match *self { 68 | Pragma::NoCache => "no-cache", 69 | Pragma::Ext(ref string) => &string[..], 70 | }) 71 | } 72 | } 73 | 74 | #[test] 75 | fn test_parse_header() { 76 | let a: Pragma = Header::parse_header([b"no-cache".to_vec()].as_ref()).unwrap(); 77 | let b = Pragma::NoCache; 78 | assert_eq!(a, b); 79 | let c: Pragma = Header::parse_header([b"FoObar".to_vec()].as_ref()).unwrap(); 80 | let d = Pragma::Ext("FoObar".to_owned()); 81 | assert_eq!(c, d); 82 | let e: ::Result = Header::parse_header([b"".to_vec()].as_ref()); 83 | assert_eq!(e.ok(), None); 84 | } 85 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/preference_applied.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use header::{Header, HeaderFormat, Preference}; 3 | use header::parsing::{from_comma_delimited, fmt_comma_delimited}; 4 | 5 | /// `Preference-Applied` header, defined in [RFC7240](http://tools.ietf.org/html/rfc7240) 6 | /// 7 | /// The `Preference-Applied` response header may be included within a 8 | /// response message as an indication as to which `Prefer` header tokens were 9 | /// honored by the server and applied to the processing of a request. 10 | /// 11 | /// # ABNF 12 | /// ```plain 13 | /// Preference-Applied = "Preference-Applied" ":" 1#applied-pref 14 | /// applied-pref = token [ BWS "=" BWS word ] 15 | /// ``` 16 | /// 17 | /// # Example values 18 | /// * `respond-async` 19 | /// * `return=minimal` 20 | /// * `wait=30` 21 | /// 22 | /// # Examples 23 | /// ``` 24 | /// use hyper::header::{Headers, PreferenceApplied, Preference}; 25 | /// 26 | /// let mut headers = Headers::new(); 27 | /// headers.set( 28 | /// PreferenceApplied(vec![Preference::RespondAsync]) 29 | /// ); 30 | /// ``` 31 | /// ``` 32 | /// use hyper::header::{Headers, PreferenceApplied, Preference}; 33 | /// 34 | /// let mut headers = Headers::new(); 35 | /// headers.set( 36 | /// PreferenceApplied(vec![ 37 | /// Preference::RespondAsync, 38 | /// Preference::ReturnRepresentation, 39 | /// Preference::Wait(10u32), 40 | /// Preference::Extension("foo".to_owned(), 41 | /// "bar".to_owned(), 42 | /// vec![]), 43 | /// ]) 44 | /// ); 45 | /// ``` 46 | #[derive(PartialEq, Clone, Debug)] 47 | pub struct PreferenceApplied(pub Vec); 48 | 49 | __hyper__deref!(PreferenceApplied => Vec); 50 | 51 | impl Header for PreferenceApplied { 52 | fn header_name() -> &'static str { 53 | "Preference-Applied" 54 | } 55 | 56 | fn parse_header>(raw: &[T]) -> ::Result { 57 | let preferences = try!(from_comma_delimited(raw)); 58 | if !preferences.is_empty() { 59 | Ok(PreferenceApplied(preferences)) 60 | } else { 61 | Err(::Error::Header) 62 | } 63 | } 64 | } 65 | 66 | impl HeaderFormat for PreferenceApplied { 67 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 68 | fmt::Display::fmt(self, f) 69 | } 70 | } 71 | 72 | impl fmt::Display for PreferenceApplied { 73 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 74 | //TODO: format this without allocating a Vec and cloning contents 75 | let preferences: Vec<_> = self.0.iter().map(|pref| match pref { 76 | // The spec ignores parameters in `Preferences-Applied` 77 | &Preference::Extension(ref name, ref value, _) => Preference::Extension( 78 | name.to_owned(), 79 | value.to_owned(), 80 | vec![] 81 | ), 82 | preference @ _ => preference.clone() 83 | }).collect(); 84 | fmt_comma_delimited(f, &preferences) 85 | } 86 | } 87 | 88 | #[cfg(test)] 89 | mod tests { 90 | use header::{HeaderFormat, Preference}; 91 | use super::*; 92 | 93 | #[test] 94 | fn test_format_ignore_parameters() { 95 | assert_eq!( 96 | format!("{}", &PreferenceApplied(vec![Preference::Extension( 97 | "foo".to_owned(), 98 | "bar".to_owned(), 99 | vec![("bar".to_owned(), "foo".to_owned()), ("buz".to_owned(), "".to_owned())] 100 | )]) as &(HeaderFormat + Send + Sync)), 101 | "foo=bar".to_owned() 102 | ); 103 | } 104 | } 105 | 106 | bench_header!(normal, 107 | PreferenceApplied, { vec![b"respond-async, return=representation".to_vec(), b"wait=100".to_vec()] }); 108 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/referer.rs: -------------------------------------------------------------------------------- 1 | header! { 2 | /// `Referer` header, defined in 3 | /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.5.2) 4 | /// 5 | /// The `Referer` [sic] header field allows the user agent to specify a 6 | /// URI reference for the resource from which the target URI was obtained 7 | /// (i.e., the "referrer", though the field name is misspelled). A user 8 | /// agent MUST NOT include the fragment and userinfo components of the 9 | /// URI reference, if any, when generating the Referer field value. 10 | /// 11 | /// # ABNF 12 | /// ```plain 13 | /// Referer = absolute-URI / partial-URI 14 | /// ``` 15 | /// 16 | /// # Example values 17 | /// * `http://www.example.org/hypertext/Overview.html` 18 | /// 19 | /// # Examples 20 | /// ``` 21 | /// use hyper::header::{Headers, Referer}; 22 | /// 23 | /// let mut headers = Headers::new(); 24 | /// headers.set(Referer("/People.html#tim".to_owned())); 25 | /// ``` 26 | /// ``` 27 | /// use hyper::header::{Headers, Referer}; 28 | /// 29 | /// let mut headers = Headers::new(); 30 | /// headers.set(Referer("http://www.example.com/index.html".to_owned())); 31 | /// ``` 32 | // TODO Use URL 33 | (Referer, "Referer") => [String] 34 | 35 | test_referer { 36 | // Testcase from the RFC 37 | test_header!(test1, vec![b"http://www.example.org/hypertext/Overview.html"]); 38 | } 39 | } 40 | 41 | bench_header!(bench, Referer, { vec![b"http://foo.com/hello:3000".to_vec()] }); 42 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/referrer_policy.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | #[allow(unused_imports)] 4 | use std::ascii::AsciiExt; 5 | 6 | use header::{Header, HeaderFormat, parsing}; 7 | 8 | /// `Referrer-Policy` header, part of 9 | /// [Referrer Policy](https://www.w3.org/TR/referrer-policy/#referrer-policy-header) 10 | /// 11 | /// The `Referrer-Policy` HTTP header specifies the referrer 12 | /// policy that the user agent applies when determining what 13 | /// referrer information should be included with requests made, 14 | /// and with browsing contexts created from the context of the 15 | /// protected resource. 16 | /// 17 | /// # ABNF 18 | /// ```plain 19 | /// Referrer-Policy: 1#policy-token 20 | /// policy-token = "no-referrer" / "no-referrer-when-downgrade" 21 | /// / "same-origin" / "origin" 22 | /// / "origin-when-cross-origin" / "unsafe-url" 23 | /// ``` 24 | /// 25 | /// # Example values 26 | /// * `no-referrer` 27 | /// 28 | /// # Example 29 | /// ``` 30 | /// use hyper::header::{Headers, ReferrerPolicy}; 31 | /// 32 | /// let mut headers = Headers::new(); 33 | /// headers.set(ReferrerPolicy::NoReferrer); 34 | /// ``` 35 | #[derive(Clone, PartialEq, Eq, Debug)] 36 | pub enum ReferrerPolicy { 37 | /// `no-referrer` 38 | NoReferrer, 39 | /// `no-referrer-when-downgrade` 40 | NoReferrerWhenDowngrade, 41 | /// `same-origin` 42 | SameOrigin, 43 | /// `origin` 44 | Origin, 45 | /// `origin-when-cross-origin` 46 | OriginWhenCrossOrigin, 47 | /// `unsafe-url` 48 | UnsafeUrl, 49 | /// `strict-origin` 50 | StrictOrigin, 51 | ///`strict-origin-when-cross-origin` 52 | StrictOriginWhenCrossOrigin, 53 | } 54 | 55 | impl Header for ReferrerPolicy { 56 | fn header_name() -> &'static str { 57 | static NAME: &'static str = "Referrer-Policy"; 58 | NAME 59 | } 60 | 61 | fn parse_header>(raw: &[T]) -> ::Result { 62 | use self::ReferrerPolicy::*; 63 | // See https://www.w3.org/TR/referrer-policy/#determine-policy-for-token 64 | let headers: Vec = try!(parsing::from_comma_delimited(raw)); 65 | 66 | for h in headers.iter().rev() { 67 | let slice = &h.to_ascii_lowercase()[..]; 68 | match slice { 69 | "no-referrer" | "never" => return Ok(NoReferrer), 70 | "no-referrer-when-downgrade" | "default" => return Ok(NoReferrerWhenDowngrade), 71 | "same-origin" => return Ok(SameOrigin), 72 | "origin" => return Ok(Origin), 73 | "origin-when-cross-origin" => return Ok(OriginWhenCrossOrigin), 74 | "strict-origin" => return Ok(StrictOrigin), 75 | "strict-origin-when-cross-origin" => return Ok(StrictOriginWhenCrossOrigin), 76 | "unsafe-url" | "always" => return Ok(UnsafeUrl), 77 | _ => continue, 78 | } 79 | } 80 | 81 | Err(::Error::Header) 82 | } 83 | } 84 | 85 | impl HeaderFormat for ReferrerPolicy { 86 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 87 | fmt::Display::fmt(self, f) 88 | } 89 | } 90 | 91 | impl fmt::Display for ReferrerPolicy { 92 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 93 | use self::ReferrerPolicy::*; 94 | f.write_str(match *self { 95 | NoReferrer => "no-referrer", 96 | NoReferrerWhenDowngrade => "no-referrer-when-downgrade", 97 | SameOrigin => "same-origin", 98 | Origin => "origin", 99 | OriginWhenCrossOrigin => "origin-when-cross-origin", 100 | StrictOrigin => "strict-origin", 101 | StrictOriginWhenCrossOrigin => "strict-origin-when-cross-origin", 102 | UnsafeUrl => "unsafe-url", 103 | }) 104 | } 105 | } 106 | 107 | #[test] 108 | fn test_parse_header() { 109 | let a: ReferrerPolicy = Header::parse_header([b"origin".to_vec()].as_ref()).unwrap(); 110 | let b = ReferrerPolicy::Origin; 111 | assert_eq!(a, b); 112 | let e: ::Result = Header::parse_header([b"foobar".to_vec()].as_ref()); 113 | assert!(e.is_err()); 114 | } 115 | 116 | #[test] 117 | fn test_rightmost_header() { 118 | let a: ReferrerPolicy = Header::parse_header(&["same-origin, origin, foobar".into()]).unwrap(); 119 | let b = ReferrerPolicy::Origin; 120 | assert_eq!(a, b); 121 | } 122 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/server.rs: -------------------------------------------------------------------------------- 1 | /// `Server` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.4.2) 2 | /// 3 | /// The `Server` header field contains information about the software 4 | /// used by the origin server to handle the request, which is often used 5 | /// by clients to help identify the scope of reported interoperability 6 | /// problems, to work around or tailor requests to avoid particular 7 | /// server limitations, and for analytics regarding server or operating 8 | /// system use. An origin server MAY generate a Server field in its 9 | /// responses. 10 | /// 11 | /// # ABNF 12 | /// ```plain 13 | /// Server = product *( RWS ( product / comment ) ) 14 | /// ``` 15 | /// 16 | /// # Example values 17 | /// * `CERN/3.0 libwww/2.17` 18 | /// 19 | /// # Example 20 | /// ``` 21 | /// use hyper::header::{Headers, Server}; 22 | /// 23 | /// let mut headers = Headers::new(); 24 | /// headers.set(Server("hyper/0.5.2".to_owned())); 25 | /// ``` 26 | // TODO: Maybe parse as defined in the spec? 27 | #[derive(Clone, Debug, PartialEq)] 28 | pub struct Server(pub std::borrow::Cow<'static, str>); 29 | impl ::header::Header for Server { 30 | fn header_name() -> &'static str { 31 | "Server" 32 | } 33 | fn parse_header>(raw: &[T]) -> ::Result { 34 | ::header::parsing::from_one_raw_str(raw).map(std::borrow::Cow::Owned).map(Server) 35 | } 36 | } 37 | impl ::header::HeaderFormat for Server { 38 | fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 39 | ::std::fmt::Display::fmt(&**self, f) 40 | } 41 | } 42 | impl ::std::fmt::Display for Server { 43 | fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { 44 | ::std::fmt::Display::fmt(&**self, f) 45 | } 46 | } 47 | impl ::std::ops::Deref for Server { 48 | type Target = str; 49 | 50 | fn deref(&self) -> &str { 51 | &self.0 52 | } 53 | } 54 | 55 | bench_header!(bench, Server, { vec![b"Some String".to_vec()] }); 56 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/set_cookie.rs: -------------------------------------------------------------------------------- 1 | use header::{Header, HeaderFormat}; 2 | use std::fmt::{self}; 3 | use std::str::from_utf8; 4 | 5 | 6 | /// `Set-Cookie` header, defined [RFC6265](http://tools.ietf.org/html/rfc6265#section-4.1) 7 | /// 8 | /// The Set-Cookie HTTP response header is used to send cookies from the 9 | /// server to the user agent. 10 | /// 11 | /// Informally, the Set-Cookie response header contains the header name 12 | /// "Set-Cookie" followed by a ":" and a cookie. Each cookie begins with 13 | /// a name-value-pair, followed by zero or more attribute-value pairs. 14 | /// 15 | /// # ABNF 16 | /// ```plain 17 | /// set-cookie-header = "Set-Cookie:" SP set-cookie-string 18 | /// set-cookie-string = cookie-pair *( ";" SP cookie-av ) 19 | /// cookie-pair = cookie-name "=" cookie-value 20 | /// cookie-name = token 21 | /// cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) 22 | /// cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E 23 | /// ; US-ASCII characters excluding CTLs, 24 | /// ; whitespace DQUOTE, comma, semicolon, 25 | /// ; and backslash 26 | /// token = 27 | /// 28 | /// cookie-av = expires-av / max-age-av / domain-av / 29 | /// path-av / secure-av / httponly-av / 30 | /// extension-av 31 | /// expires-av = "Expires=" sane-cookie-date 32 | /// sane-cookie-date = 33 | /// max-age-av = "Max-Age=" non-zero-digit *DIGIT 34 | /// ; In practice, both expires-av and max-age-av 35 | /// ; are limited to dates representable by the 36 | /// ; user agent. 37 | /// non-zero-digit = %x31-39 38 | /// ; digits 1 through 9 39 | /// domain-av = "Domain=" domain-value 40 | /// domain-value = 41 | /// ; defined in [RFC1034], Section 3.5, as 42 | /// ; enhanced by [RFC1123], Section 2.1 43 | /// path-av = "Path=" path-value 44 | /// path-value = 45 | /// secure-av = "Secure" 46 | /// httponly-av = "HttpOnly" 47 | /// extension-av = 48 | /// ``` 49 | /// 50 | /// # Example values 51 | /// * `SID=31d4d96e407aad42` 52 | /// * `lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT` 53 | /// * `lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT` 54 | /// * `lang=en-US; Path=/; Domain=example.com` 55 | /// 56 | /// # Example 57 | /// ``` 58 | /// use hyper::header::{Headers, SetCookie}; 59 | /// 60 | /// let mut headers = Headers::new(); 61 | /// 62 | /// headers.set( 63 | /// SetCookie(vec![ 64 | /// String::from("foo=bar; Path=/path; Domain=example.com") 65 | /// ]) 66 | /// ); 67 | /// ``` 68 | #[derive(Clone, PartialEq, Debug)] 69 | pub struct SetCookie(pub Vec); 70 | 71 | __hyper__deref!(SetCookie => Vec); 72 | 73 | impl Header for SetCookie { 74 | fn header_name() -> &'static str { 75 | "Set-Cookie" 76 | } 77 | 78 | fn parse_header>(raw: &[T]) -> ::Result { 79 | let mut set_cookies = Vec::with_capacity(raw.len()); 80 | for set_cookies_raw in raw { 81 | if let Ok(s) = from_utf8(set_cookies_raw.as_ref()) { 82 | set_cookies.push(s.trim().to_owned()); 83 | } 84 | } 85 | 86 | if !set_cookies.is_empty() { 87 | Ok(SetCookie(set_cookies)) 88 | } else { 89 | Err(::Error::Header) 90 | } 91 | } 92 | 93 | } 94 | 95 | impl HeaderFormat for SetCookie { 96 | fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { 97 | if self.0.len() == 1 { 98 | write!(f, "{}", &self.0[0]) 99 | } else { 100 | panic!("SetCookie with multiple cookies cannot be used with fmt_header, must use fmt_multi_header"); 101 | } 102 | } 103 | 104 | fn fmt_multi_header(&self, f: &mut ::header::MultilineFormatter) -> fmt::Result { 105 | for cookie in &self.0 { 106 | try!(f.fmt_line(cookie)); 107 | } 108 | Ok(()) 109 | } 110 | } 111 | 112 | #[test] 113 | fn test_set_cookie_fmt() { 114 | use ::header::Headers; 115 | let mut headers = Headers::new(); 116 | headers.set(SetCookie(vec![ 117 | "foo=bar".into(), 118 | "baz=quux".into(), 119 | ])); 120 | assert_eq!(headers.to_string(), "Set-Cookie: foo=bar\r\nSet-Cookie: baz=quux\r\n"); 121 | } 122 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/transfer_encoding.rs: -------------------------------------------------------------------------------- 1 | use header::Encoding; 2 | 3 | header! { 4 | /// `Transfer-Encoding` header, defined in 5 | /// [RFC7230](http://tools.ietf.org/html/rfc7230#section-3.3.1) 6 | /// 7 | /// The `Transfer-Encoding` header field lists the transfer coding names 8 | /// corresponding to the sequence of transfer codings that have been (or 9 | /// will be) applied to the payload body in order to form the message 10 | /// body. 11 | /// 12 | /// # ABNF 13 | /// ```plain 14 | /// Transfer-Encoding = 1#transfer-coding 15 | /// ``` 16 | /// 17 | /// # Example values 18 | /// * `gzip, chunked` 19 | /// 20 | /// # Example 21 | /// ``` 22 | /// use hyper::header::{Headers, TransferEncoding, Encoding}; 23 | /// 24 | /// let mut headers = Headers::new(); 25 | /// headers.set( 26 | /// TransferEncoding(vec![ 27 | /// Encoding::Gzip, 28 | /// Encoding::Chunked, 29 | /// ]) 30 | /// ); 31 | /// ``` 32 | (TransferEncoding, "Transfer-Encoding") => (Encoding)+ 33 | 34 | transfer_encoding { 35 | test_header!( 36 | test1, 37 | vec![b"gzip, chunked"], 38 | Some(HeaderField( 39 | vec![Encoding::Gzip, Encoding::Chunked] 40 | ))); 41 | // Issue: #683 42 | test_header!( 43 | test2, 44 | vec![b"chunked", b"chunked"], 45 | Some(HeaderField( 46 | vec![Encoding::Chunked, Encoding::Chunked] 47 | ))); 48 | 49 | } 50 | } 51 | 52 | bench_header!(normal, TransferEncoding, { vec![b"chunked, gzip".to_vec()] }); 53 | bench_header!(ext, TransferEncoding, { vec![b"ext".to_vec()] }); 54 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/user_agent.rs: -------------------------------------------------------------------------------- 1 | header! { 2 | /// `User-Agent` header, defined in 3 | /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.5.3) 4 | /// 5 | /// The `User-Agent` header field contains information about the user 6 | /// agent originating the request, which is often used by servers to help 7 | /// identify the scope of reported interoperability problems, to work 8 | /// around or tailor responses to avoid particular user agent 9 | /// limitations, and for analytics regarding browser or operating system 10 | /// use. A user agent SHOULD send a User-Agent field in each request 11 | /// unless specifically configured not to do so. 12 | /// 13 | /// # ABNF 14 | /// ```plain 15 | /// User-Agent = product *( RWS ( product / comment ) ) 16 | /// product = token ["/" product-version] 17 | /// product-version = token 18 | /// ``` 19 | /// 20 | /// # Example values 21 | /// * `CERN-LineMode/2.15 libwww/2.17b3` 22 | /// * `Bunnies` 23 | /// 24 | /// # Notes 25 | /// * The parser does not split the value 26 | /// 27 | /// # Example 28 | /// ``` 29 | /// use hyper::header::{Headers, UserAgent}; 30 | /// 31 | /// let mut headers = Headers::new(); 32 | /// headers.set(UserAgent("hyper/0.5.2".to_owned())); 33 | /// ``` 34 | (UserAgent, "User-Agent") => [String] 35 | 36 | test_user_agent { 37 | // Testcase from RFC 38 | test_header!(test1, vec![b"CERN-LineMode/2.15 libwww/2.17b3"]); 39 | // Own testcase 40 | test_header!(test2, vec![b"Bunnies"], Some(UserAgent("Bunnies".to_owned()))); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/common/vary.rs: -------------------------------------------------------------------------------- 1 | use unicase::UniCase; 2 | 3 | header! { 4 | /// `Vary` header, defined in [RFC7231](https://tools.ietf.org/html/rfc7231#section-7.1.4) 5 | /// 6 | /// The "Vary" header field in a response describes what parts of a 7 | /// request message, aside from the method, Host header field, and 8 | /// request target, might influence the origin server's process for 9 | /// selecting and representing this response. The value consists of 10 | /// either a single asterisk ("*") or a list of header field names 11 | /// (case-insensitive). 12 | /// 13 | /// # ABNF 14 | /// ```plain 15 | /// Vary = "*" / 1#field-name 16 | /// ``` 17 | /// 18 | /// # Example values 19 | /// * `accept-encoding, accept-language` 20 | /// 21 | /// # Example 22 | /// ``` 23 | /// use hyper::header::{Headers, Vary}; 24 | /// 25 | /// let mut headers = Headers::new(); 26 | /// headers.set(Vary::Any); 27 | /// ``` 28 | /// 29 | /// # Example 30 | /// ``` 31 | /// # extern crate hyper; 32 | /// # extern crate unicase; 33 | /// # fn main() { 34 | /// // extern crate unicase; 35 | /// 36 | /// use hyper::header::{Headers, Vary}; 37 | /// use unicase::UniCase; 38 | /// 39 | /// let mut headers = Headers::new(); 40 | /// headers.set( 41 | /// Vary::Items(vec![ 42 | /// UniCase("accept-encoding".to_owned()), 43 | /// UniCase("accept-language".to_owned()), 44 | /// ]) 45 | /// ); 46 | /// # } 47 | /// ``` 48 | (Vary, "Vary") => {Any / (UniCase)+} 49 | 50 | test_vary { 51 | test_header!(test1, vec![b"accept-encoding, accept-language"]); 52 | 53 | #[test] 54 | fn test2() { 55 | let mut vary: ::Result; 56 | 57 | vary = Header::parse_header([b"*".to_vec()].as_ref()); 58 | assert_eq!(vary.ok(), Some(Vary::Any)); 59 | 60 | vary = Header::parse_header([b"etag,cookie,allow".to_vec()].as_ref()); 61 | assert_eq!(vary.ok(), Some(Vary::Items(vec!["eTag".parse().unwrap(), 62 | "cookIE".parse().unwrap(), 63 | "AlLOw".parse().unwrap(),]))); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/internals/item.rs: -------------------------------------------------------------------------------- 1 | use std::any::Any; 2 | use std::any::TypeId; 3 | use std::fmt; 4 | use std::borrow::Cow; 5 | use std::str::from_utf8; 6 | 7 | use super::cell::{OptCell, PtrMapCell}; 8 | use header::{Header, HeaderFormat, MultilineFormatter}; 9 | 10 | 11 | #[derive(Clone)] 12 | pub struct Item { 13 | raw: OptCell>>, 14 | typed: PtrMapCell 15 | } 16 | 17 | impl Item { 18 | #[inline] 19 | pub fn new_raw(data: Vec>) -> Item { 20 | Item { 21 | raw: OptCell::new(Some(data)), 22 | typed: PtrMapCell::new(), 23 | } 24 | } 25 | 26 | #[inline] 27 | pub fn new_typed(ty: Box) -> Item { 28 | let map = PtrMapCell::new(); 29 | unsafe { map.insert((*ty).get_type(), ty); } 30 | Item { 31 | raw: OptCell::new(None), 32 | typed: map, 33 | } 34 | } 35 | 36 | #[inline] 37 | pub fn raw_mut(&mut self) -> &mut Vec> { 38 | self.raw(); 39 | self.typed = PtrMapCell::new(); 40 | unsafe { 41 | self.raw.get_mut() 42 | } 43 | } 44 | 45 | pub fn raw(&self) -> &[Cow<'static, [u8]>] { 46 | if let Some(ref raw) = *self.raw { 47 | return &raw[..]; 48 | } 49 | 50 | let raw = vec![unsafe { self.typed.one() }.to_string().into_bytes().into()]; 51 | self.raw.set(raw); 52 | 53 | let raw = self.raw.as_ref().unwrap(); 54 | &raw[..] 55 | } 56 | 57 | pub fn typed(&self) -> Option<&H> { 58 | let tid = TypeId::of::(); 59 | match self.typed.get(tid) { 60 | Some(val) => Some(val), 61 | None => { 62 | match parse::(self.raw.as_ref().expect("item.raw must exist")) { 63 | Ok(typed) => { 64 | unsafe { self.typed.insert(tid, typed); } 65 | self.typed.get(tid) 66 | }, 67 | Err(_) => None 68 | } 69 | } 70 | }.map(|typed| unsafe { typed.downcast_ref_unchecked() }) 71 | } 72 | 73 | pub fn typed_mut(&mut self) -> Option<&mut H> { 74 | let tid = TypeId::of::(); 75 | if self.typed.get_mut(tid).is_none() { 76 | match parse::(self.raw.as_ref().expect("item.raw must exist")) { 77 | Ok(typed) => { 78 | unsafe { self.typed.insert(tid, typed); } 79 | }, 80 | Err(_) => () 81 | } 82 | } 83 | if self.raw.is_some() && self.typed.get_mut(tid).is_some() { 84 | self.raw = OptCell::new(None); 85 | } 86 | self.typed.get_mut(tid).map(|typed| unsafe { typed.downcast_mut_unchecked() }) 87 | } 88 | 89 | pub fn write_h1(&self, f: &mut MultilineFormatter) -> fmt::Result { 90 | match *self.raw { 91 | Some(ref raw) => { 92 | for part in raw.iter() { 93 | match from_utf8(&part[..]) { 94 | Ok(s) => { 95 | try!(f.fmt_line(&s)); 96 | }, 97 | Err(_) => { 98 | error!("raw header value is not utf8, value={:?}", part); 99 | return Err(fmt::Error); 100 | } 101 | } 102 | } 103 | Ok(()) 104 | }, 105 | None => { 106 | let typed = unsafe { self.typed.one() }; 107 | typed.fmt_multi_header(f) 108 | } 109 | } 110 | } 111 | } 112 | 113 | #[inline] 114 | fn parse(raw: &Vec>) -> 115 | ::Result> { 116 | Header::parse_header(&raw[..]).map(|h: H| { 117 | // FIXME: Use Type ascription 118 | let h: Box = Box::new(h); 119 | h 120 | }) 121 | } 122 | 123 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/internals/mod.rs: -------------------------------------------------------------------------------- 1 | pub use self::item::Item; 2 | pub use self::vec_map::{VecMap, Entry}; 3 | 4 | mod cell; 5 | mod item; 6 | mod vec_map; 7 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/internals/vec_map.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone, Debug)] 2 | pub struct VecMap { 3 | vec: Vec<(K, V)>, 4 | } 5 | 6 | impl VecMap { 7 | pub fn new() -> VecMap { 8 | VecMap { 9 | vec: Vec::new() 10 | } 11 | } 12 | 13 | pub fn with_capacity(cap: usize) -> VecMap { 14 | VecMap { 15 | vec: Vec::with_capacity(cap) 16 | } 17 | } 18 | 19 | pub fn insert(&mut self, key: K, value: V) { 20 | match self.find(&key) { 21 | Some(pos) => self.vec[pos] = (key, value), 22 | None => self.vec.push((key, value)) 23 | } 24 | } 25 | 26 | pub fn entry(&mut self, key: K) -> Entry { 27 | match self.find(&key) { 28 | Some(pos) => Entry::Occupied(OccupiedEntry { 29 | vec: self, 30 | pos: pos, 31 | }), 32 | None => Entry::Vacant(VacantEntry { 33 | vec: self, 34 | key: key, 35 | }) 36 | } 37 | } 38 | 39 | pub fn get(&self, key: &K) -> Option<&V> { 40 | self.find(key).map(move |pos| &self.vec[pos].1) 41 | } 42 | 43 | pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { 44 | self.find(key).map(move |pos| &mut self.vec[pos].1) 45 | } 46 | 47 | pub fn contains_key(&self, key: &K) -> bool { 48 | self.find(key).is_some() 49 | } 50 | 51 | pub fn len(&self) -> usize { self.vec.len() } 52 | pub fn iter(&self) -> ::std::slice::Iter<(K, V)> { 53 | self.vec.iter() 54 | } 55 | pub fn remove(&mut self, key: &K) -> Option { 56 | self.find(key).map(|pos| self.vec.remove(pos)).map(|(_, v)| v) 57 | } 58 | pub fn clear(&mut self) { 59 | self.vec.clear(); 60 | } 61 | 62 | fn find(&self, key: &K) -> Option { 63 | self.vec.iter().position(|entry| key == &entry.0) 64 | } 65 | } 66 | 67 | pub enum Entry<'a, K: 'a, V: 'a> { 68 | Vacant(VacantEntry<'a, K, V>), 69 | Occupied(OccupiedEntry<'a, K, V>) 70 | } 71 | 72 | pub struct VacantEntry<'a, K: 'a, V: 'a> { 73 | vec: &'a mut VecMap, 74 | key: K, 75 | } 76 | 77 | impl<'a, K, V> VacantEntry<'a, K, V> { 78 | pub fn insert(self, val: V) -> &'a mut V { 79 | let vec = self.vec; 80 | vec.vec.push((self.key, val)); 81 | let pos = vec.vec.len() - 1; 82 | &mut vec.vec[pos].1 83 | } 84 | } 85 | 86 | pub struct OccupiedEntry<'a, K: 'a, V: 'a> { 87 | vec: &'a mut VecMap, 88 | pos: usize, 89 | } 90 | 91 | impl<'a, K, V> OccupiedEntry<'a, K, V> { 92 | pub fn into_mut(self) -> &'a mut V { 93 | &mut self.vec.vec[self.pos].1 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/shared/encoding.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::str; 3 | 4 | /// A value to represent an encoding used in `Transfer-Encoding` 5 | /// or `Accept-Encoding` header. 6 | /// 7 | /// bool is `x-`-prefixed. 8 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] 9 | pub struct Encoding(pub EncodingType, pub String, pub bool); 10 | impl Encoding { 11 | #[allow(non_upper_case_globals)] 12 | pub const Chunked: Encoding = Encoding(EncodingType::Chunked, String::new(), false); 13 | } 14 | 15 | #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] 16 | pub enum EncodingType { 17 | /// The `chunked` encoding. 18 | Chunked, 19 | /// The `gzip` encoding. 20 | Gzip, 21 | /// The `deflate` encoding. 22 | Deflate, 23 | /// The `compress` encoding. 24 | Compress, 25 | /// The `identity` encoding. 26 | Identity, 27 | /// The `br` encoding. 28 | Brotli, 29 | /// The `bzip2` encoding. 30 | Bzip2, 31 | /// The `zstd` encoding. 32 | Zstd, 33 | /// See upper String. 34 | Custom, 35 | } 36 | 37 | impl fmt::Display for Encoding { 38 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 39 | if self.2 { 40 | f.write_str("x-")?; 41 | } 42 | f.write_str(match self.0 { 43 | EncodingType::Chunked => "chunked", 44 | EncodingType::Gzip => "gzip", 45 | EncodingType::Deflate => "deflate", 46 | EncodingType::Compress => "compress", 47 | EncodingType::Identity => "identity", 48 | EncodingType::Brotli => "br", 49 | EncodingType::Bzip2 => "bzip2", 50 | EncodingType::Zstd => "zstd", 51 | EncodingType::Custom => self.1.as_ref(), 52 | }) 53 | } 54 | } 55 | 56 | impl str::FromStr for Encoding { 57 | type Err = ::Error; 58 | fn from_str(mut s: &str) -> ::Result { 59 | let x = s.starts_with("x-"); 60 | if x { 61 | s = &s[2..]; 62 | } 63 | let mut custom = String::new(); 64 | let enc = match s { 65 | "chunked" => EncodingType::Chunked, 66 | "deflate" => EncodingType::Deflate, 67 | "gzip" => EncodingType::Gzip, 68 | "compress" => EncodingType::Compress, 69 | "identity" => EncodingType::Identity, 70 | "br" => EncodingType::Brotli, 71 | "bzip2" => EncodingType::Bzip2, 72 | "zstd" => EncodingType::Zstd, 73 | _ => { 74 | custom = s.to_owned(); 75 | EncodingType::Custom 76 | }, 77 | }; 78 | Ok(Encoding(enc, custom, x)) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/shared/httpdate.rs: -------------------------------------------------------------------------------- 1 | use std::str::FromStr; 2 | use std::fmt::{self, Display}; 3 | 4 | use time; 5 | 6 | /// A `time::Time` with HTTP formatting and parsing 7 | /// 8 | // Prior to 1995, there were three different formats commonly used by 9 | // servers to communicate timestamps. For compatibility with old 10 | // implementations, all three are defined here. The preferred format is 11 | // a fixed-length and single-zone subset of the date and time 12 | // specification used by the Internet Message Format [RFC5322]. 13 | // 14 | // HTTP-date = IMF-fixdate / obs-date 15 | // 16 | // An example of the preferred format is 17 | // 18 | // Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate 19 | // 20 | // Examples of the two obsolete formats are 21 | // 22 | // Sunday, 06-Nov-94 08:49:37 GMT ; obsolete RFC 850 format 23 | // Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format 24 | // 25 | // A recipient that parses a timestamp value in an HTTP header field 26 | // MUST accept all three HTTP-date formats. When a sender generates a 27 | // header field that contains one or more timestamps defined as 28 | // HTTP-date, the sender MUST generate those timestamps in the 29 | // IMF-fixdate format. 30 | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] 31 | pub struct HttpDate(pub time::Tm); 32 | 33 | impl FromStr for HttpDate { 34 | type Err = ::Error; 35 | fn from_str(s: &str) -> ::Result { 36 | match time::strptime(s, "%a, %d %b %Y %T %Z").or_else(|_| { 37 | time::strptime(s, "%A, %d-%b-%y %T %Z") 38 | }).or_else(|_| { 39 | time::strptime(s, "%c") 40 | }) { 41 | Ok(t) => Ok(HttpDate(t)), 42 | Err(_) => Err(::Error::Header), 43 | } 44 | } 45 | } 46 | 47 | impl Display for HttpDate { 48 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 49 | fmt::Display::fmt(&self.0.to_utc().rfc822(), f) 50 | } 51 | } 52 | 53 | #[cfg(test)] 54 | mod tests { 55 | use time::Tm; 56 | use super::HttpDate; 57 | 58 | const NOV_07: HttpDate = HttpDate(Tm { 59 | tm_nsec: 0, 60 | tm_sec: 37, 61 | tm_min: 48, 62 | tm_hour: 8, 63 | tm_mday: 7, 64 | tm_mon: 10, 65 | tm_year: 94, 66 | tm_wday: 0, 67 | tm_isdst: 0, 68 | tm_yday: 0, 69 | tm_utcoff: 0, 70 | }); 71 | 72 | #[test] 73 | fn test_imf_fixdate() { 74 | assert_eq!("Sun, 07 Nov 1994 08:48:37 GMT".parse::().unwrap(), NOV_07); 75 | } 76 | 77 | #[test] 78 | fn test_rfc_850() { 79 | assert_eq!("Sunday, 07-Nov-94 08:48:37 GMT".parse::().unwrap(), NOV_07); 80 | } 81 | 82 | #[test] 83 | fn test_asctime() { 84 | assert_eq!("Sun Nov 7 08:48:37 1994".parse::().unwrap(), NOV_07); 85 | } 86 | 87 | #[test] 88 | fn test_no_date() { 89 | assert!("this-is-no-date".parse::().is_err()); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/header/shared/mod.rs: -------------------------------------------------------------------------------- 1 | pub use self::charset::Charset; 2 | pub use self::encoding::{Encoding, EncodingType}; 3 | pub use self::entity::EntityTag; 4 | pub use self::httpdate::HttpDate; 5 | pub use self::quality_item::{Quality, QualityItem, qitem, q}; 6 | 7 | mod charset; 8 | mod encoding; 9 | mod entity; 10 | mod httpdate; 11 | mod quality_item; 12 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/http/mod.rs: -------------------------------------------------------------------------------- 1 | //! Pieces pertaining to the HTTP message protocol. 2 | use header::Connection; 3 | use header::ConnectionOption::{KeepAlive, Close}; 4 | use header::Headers; 5 | use version::HttpVersion; 6 | use version::HttpVersion::{Http10, Http11}; 7 | 8 | pub mod h1; 9 | 10 | #[inline] 11 | pub fn should_keep_alive(version: HttpVersion, headers: &Headers) -> bool { 12 | trace!("should_keep_alive( {:?}, {:?} )", version, headers.get::()); 13 | match (version, headers.get::()) { 14 | (Http10, None) => false, 15 | (Http10, Some(conn)) if !conn.contains(&KeepAlive) => false, 16 | (Http11, Some(conn)) if conn.contains(&Close) => false, 17 | _ => true 18 | } 19 | } 20 | 21 | #[test] 22 | fn test_should_keep_alive() { 23 | let mut headers = Headers::new(); 24 | 25 | assert!(!should_keep_alive(Http10, &headers)); 26 | assert!(should_keep_alive(Http11, &headers)); 27 | 28 | headers.set(Connection::close()); 29 | assert!(!should_keep_alive(Http10, &headers)); 30 | assert!(!should_keep_alive(Http11, &headers)); 31 | 32 | headers.set(Connection::keep_alive()); 33 | assert!(should_keep_alive(Http10, &headers)); 34 | assert!(should_keep_alive(Http11, &headers)); 35 | } 36 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/server/listener.rs: -------------------------------------------------------------------------------- 1 | use std::sync::atomic::{AtomicUsize, Ordering}; 2 | use std::time::Duration; 3 | use std::sync::Arc; 4 | use std::thread; 5 | 6 | use net::NetworkListener; 7 | 8 | 9 | pub struct ListenerPool { 10 | acceptor: A 11 | } 12 | 13 | impl ListenerPool { 14 | /// Create a thread pool to manage the acceptor. 15 | pub fn new(acceptor: A) -> ListenerPool { 16 | ListenerPool { acceptor: acceptor } 17 | } 18 | 19 | /// Runs the acceptor pool. Blocks until the acceptors are closed. 20 | /// 21 | /// ## Panics 22 | /// 23 | /// Panics if max_threads == 0. 24 | pub fn accept(mut self, work: F, max_threads: usize) 25 | where F: Fn(A::Stream) + Send + Sync + 'static { 26 | assert!(max_threads != 0, "Can't accept on 0 threads."); 27 | 28 | let work = Arc::new(work); 29 | let live_threads = Arc::new(AtomicUsize::new(0)); 30 | let free_threads = Arc::new(AtomicUsize::new(0)); 31 | let (send, recv) = crossbeam_channel::bounded(20); 32 | 33 | loop { 34 | let msg = match self.acceptor.accept() { 35 | Ok(stream) => stream, 36 | Err(e) => { 37 | info!("Connection failed: {}", e); 38 | continue; 39 | } 40 | }; 41 | 42 | let free = free_threads.load(Ordering::Acquire); 43 | let live = live_threads.load(Ordering::SeqCst); 44 | // eprintln!("free = {}, live = {}", free, live); 45 | if (live == 0 || free == 0) && live != max_threads { 46 | spawn_with::(recv.clone(), work.clone(), live_threads.clone(), free_threads.clone(), msg); 47 | } else { 48 | let _ = send.send(msg); 49 | } 50 | } 51 | } 52 | } 53 | 54 | fn spawn_with(recv: crossbeam_channel::Receiver, work: Arc, live_threads: Arc, free_threads: Arc, first: A::Stream) 55 | where A: NetworkListener + Send + 'static, 56 | F: Fn(::Stream) + Send + Sync + 'static { 57 | thread::spawn(move || { 58 | let thread_id = live_threads.fetch_add(1, Ordering::SeqCst); 59 | let _sentinel = LiveSentinel { live_threads }; 60 | 61 | let mut _free_sentinel = FreeSentinel { free_threads: &free_threads, subbed: true }; 62 | work(first); 63 | _free_sentinel.unsub(); 64 | 65 | loop { 66 | let stream = match if thread_id == 0 { 67 | recv.recv().ok() // infallible 68 | } else { 69 | recv.recv_timeout(Duration::from_secs((thread_id * 5).min(300) as u64)).ok() 70 | } { 71 | None => return, 72 | Some(stream) => stream, 73 | }; 74 | 75 | _free_sentinel.sub(); 76 | work(stream); 77 | _free_sentinel.unsub(); 78 | } 79 | }); 80 | } 81 | 82 | struct LiveSentinel { 83 | live_threads: Arc, 84 | } 85 | impl Drop for LiveSentinel { 86 | fn drop(&mut self) { 87 | self.live_threads.fetch_sub(1, Ordering::SeqCst); 88 | } 89 | } 90 | 91 | struct FreeSentinel<'t> { 92 | free_threads: &'t Arc, 93 | subbed: bool, 94 | } 95 | impl<'t> FreeSentinel<'t> { 96 | fn sub(&mut self) { 97 | self.free_threads.fetch_sub(1, Ordering::AcqRel); 98 | self.subbed = true; 99 | } 100 | fn unsub(&mut self) { 101 | self.free_threads.fetch_add(1, Ordering::AcqRel); 102 | self.subbed = false; 103 | } 104 | } 105 | impl<'t> Drop for FreeSentinel<'t> { 106 | fn drop(&mut self) { 107 | if !self.subbed { 108 | self.free_threads.fetch_sub(1, Ordering::AcqRel); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/uri.rs: -------------------------------------------------------------------------------- 1 | //! HTTP RequestUris 2 | use std::fmt::{Display, self}; 3 | use std::str::FromStr; 4 | use url::Url; 5 | use url::ParseError as UrlError; 6 | 7 | use Error; 8 | 9 | /// The Request-URI of a Request's StartLine. 10 | /// 11 | /// From Section 5.3, Request Target: 12 | /// > Once an inbound connection is obtained, the client sends an HTTP 13 | /// > request message (Section 3) with a request-target derived from the 14 | /// > target URI. There are four distinct formats for the request-target, 15 | /// > depending on both the method being requested and whether the request 16 | /// > is to a proxy. 17 | /// > 18 | /// > ```notrust 19 | /// > request-target = origin-form 20 | /// > / absolute-form 21 | /// > / authority-form 22 | /// > / asterisk-form 23 | /// > ``` 24 | #[derive(Debug, PartialEq, Clone)] 25 | pub enum RequestUri { 26 | /// The most common request target, an absolute path and optional query. 27 | /// 28 | /// For example, the line `GET /where?q=now HTTP/1.1` would parse the URI 29 | /// as `AbsolutePath("/where?q=now".to_string())`. 30 | AbsolutePath(String), 31 | 32 | /// An absolute URI. Used in conjunction with proxies. 33 | /// 34 | /// > When making a request to a proxy, other than a CONNECT or server-wide 35 | /// > OPTIONS request (as detailed below), a client MUST send the target 36 | /// > URI in absolute-form as the request-target. 37 | /// 38 | /// An example StartLine with an `AbsoluteUri` would be 39 | /// `GET http://www.example.org/pub/WWW/TheProject.html HTTP/1.1`. 40 | AbsoluteUri(Url), 41 | 42 | /// The authority form is only for use with `CONNECT` requests. 43 | /// 44 | /// An example StartLine: `CONNECT www.example.com:80 HTTP/1.1`. 45 | Authority(String), 46 | 47 | /// The star is used to target the entire server, instead of a specific resource. 48 | /// 49 | /// This is only used for a server-wide `OPTIONS` request. 50 | Star, 51 | } 52 | 53 | impl FromStr for RequestUri { 54 | type Err = Error; 55 | 56 | fn from_str(s: &str) -> Result { 57 | let bytes = s.as_bytes(); 58 | if bytes.is_empty() { 59 | Err(Error::Uri(UrlError::RelativeUrlWithoutBase)) 60 | } else if bytes == b"*" { 61 | Ok(RequestUri::Star) 62 | } else if bytes.starts_with(b"/") { 63 | Ok(RequestUri::AbsolutePath(s.to_owned())) 64 | } else if bytes.contains(&b'/') { 65 | Ok(RequestUri::AbsoluteUri(try!(Url::parse(s)))) 66 | } else { 67 | let mut temp = "http://".to_owned(); 68 | temp.push_str(s); 69 | try!(Url::parse(&temp[..])); 70 | todo!("compare vs u.authority()"); 71 | Ok(RequestUri::Authority(s.to_owned())) 72 | } 73 | } 74 | } 75 | 76 | impl Display for RequestUri { 77 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 78 | match *self { 79 | RequestUri::AbsolutePath(ref path) => f.write_str(path), 80 | RequestUri::AbsoluteUri(ref url) => write!(f, "{}", url), 81 | RequestUri::Authority(ref path) => f.write_str(path), 82 | RequestUri::Star => f.write_str("*") 83 | } 84 | } 85 | } 86 | 87 | #[test] 88 | fn test_uri_fromstr() { 89 | fn read(s: &str, result: RequestUri) { 90 | assert_eq!(s.parse::().unwrap(), result); 91 | } 92 | 93 | read("*", RequestUri::Star); 94 | read("http://hyper.rs/", RequestUri::AbsoluteUri(Url::parse("http://hyper.rs/").unwrap())); 95 | read("hyper.rs", RequestUri::Authority("hyper.rs".to_owned())); 96 | read("/", RequestUri::AbsolutePath("/".to_owned())); 97 | } 98 | 99 | #[test] 100 | fn test_uri_display() { 101 | fn assert_display(expected_string: &str, request_uri: RequestUri) { 102 | assert_eq!(expected_string, format!("{}", request_uri)); 103 | } 104 | 105 | assert_display("*", RequestUri::Star); 106 | assert_display("http://hyper.rs/", RequestUri::AbsoluteUri(Url::parse("http://hyper.rs/").unwrap())); 107 | assert_display("hyper.rs", RequestUri::Authority("hyper.rs".to_owned())); 108 | assert_display("/", RequestUri::AbsolutePath("/".to_owned())); 109 | 110 | } 111 | -------------------------------------------------------------------------------- /vendor/hyper-0.10.16/src/version.rs: -------------------------------------------------------------------------------- 1 | //! HTTP Versions enum 2 | //! 3 | //! Instead of relying on typo-prone Strings, use expected HTTP versions as 4 | //! the `HttpVersion` enum. 5 | use std::fmt; 6 | use std::str::FromStr; 7 | 8 | use error::Error; 9 | use self::HttpVersion::{Http09, Http10, Http11, Http20}; 10 | 11 | /// Represents a version of the HTTP spec. 12 | #[derive(PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash, Debug)] 13 | pub enum HttpVersion { 14 | /// `HTTP/0.9` 15 | Http09, 16 | /// `HTTP/1.0` 17 | Http10, 18 | /// `HTTP/1.1` 19 | Http11, 20 | /// `HTTP/2.0` 21 | Http20, 22 | } 23 | 24 | impl fmt::Display for HttpVersion { 25 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 26 | fmt.write_str(self.as_ref()) 27 | } 28 | } 29 | 30 | impl AsRef for HttpVersion { 31 | fn as_ref(&self) -> &str { 32 | match *self { 33 | Http09 => "HTTP/0.9", 34 | Http10 => "HTTP/1.0", 35 | Http11 => "HTTP/1.1", 36 | Http20 => "HTTP/2.0", 37 | } 38 | } 39 | } 40 | 41 | impl FromStr for HttpVersion { 42 | type Err = Error; 43 | 44 | fn from_str(s: &str) -> Result { 45 | match s { 46 | "HTTP/0.9" => Ok(Http09), 47 | "HTTP/1.0" => Ok(Http10), 48 | "HTTP/1.1" => Ok(Http11), 49 | "HTTP/2.0" => Ok(Http20), 50 | _ => Err(Error::Version), 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/.cargo_vcs_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "sha1": "9e44ab85185e167841756613772632147b0bf892" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/.gitignore: -------------------------------------------------------------------------------- 1 | deps/ 2 | .DS_Store 3 | *~ 4 | *# 5 | *.o 6 | *.so 7 | *.swp 8 | *.dylib 9 | *.dSYM 10 | *.dll 11 | *.rlib 12 | *.dummy 13 | *.exe 14 | *-test 15 | /src/generated/mimes.txt 16 | /src/generated/mimegen 17 | /src/response/mimes/mod.rs 18 | /bin/main 19 | /bin/test-internal 20 | /bin/test-external 21 | /doc/ 22 | /target/ 23 | /build/ 24 | /.rust/ 25 | watch.sh 26 | rusti.sh 27 | /examples/* 28 | !/examples/*.rs 29 | Cargo.lock 30 | .cargo -------------------------------------------------------------------------------- /vendor/iron-0.6.1/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | - nightly 5 | sudo: false 6 | script: 7 | - cargo build 8 | - cargo test 9 | - cargo build --features native-tls-example 10 | - cargo test --features native-tls-example 11 | env: 12 | global: 13 | secure: DUE2yG7/ASacYARIs7nysUAUhK86AqwE/PdQ3j+D5dqzxs3IOMSOcc7PA1r2w3FkXd52rENCYqKz2iReniJn4fG5S3Q+NbcfaYkhS/6P1y0sQB8yIIVeBRf/Bo2bR2P5TRh+piYWDmqYLUvsQ0+DpQ78MRA6HSxz7gCKpkZS4Y4= 14 | after_success: 'curl https://raw.githubusercontent.com/iron/build-doc/master/build-doc.sh | sh ' 15 | 16 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ### Overview 4 | 5 | * Fork iron to your own account 6 | * Create a feature branch, namespaced by. 7 | * bug/... 8 | * feat/... 9 | * test/... 10 | * doc/... 11 | * refactor/... 12 | * Make commits to your feature branch. Prefix each commit like so: 13 | * (feat) Added a new feature 14 | * (fix) Fixed inconsistent tests [Fixes #0] 15 | * (refactor) ... 16 | * (cleanup) ... 17 | * (test) ... 18 | * (doc) ... 19 | * Make a pull request with your changes directly to master. Include a 20 | description of your changes. 21 | * Wait for one of the reviewers to look at your code and either merge it or 22 | give feedback which you should adapt to. 23 | 24 | #### Thank you for contributing! 25 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/Cargo.toml: -------------------------------------------------------------------------------- 1 | # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO 2 | # 3 | # When uploading crates to the registry Cargo will automatically 4 | # "normalize" Cargo.toml files for maximal compatibility 5 | # with all versions of Cargo and also rewrite `path` dependencies 6 | # to registry (e.g., crates.io) dependencies 7 | # 8 | # If you believe there's an error in this file please file an 9 | # issue against the rust-lang/cargo repository. If you're 10 | # editing this file be aware that the upstream Cargo.toml 11 | # will likely look very different (and much more reasonable) 12 | 13 | [package] 14 | name = "iron" 15 | version = "0.6.1" 16 | authors = ["Jonathan Reem ", "Zach Pomerantz ", "Michael Sproul ", "Patrick Tran "] 17 | description = "Extensible, Concurrency Focused Web Development in Rust." 18 | documentation = "http://ironframework.io/doc/iron/" 19 | readme = "README.md" 20 | license = "MIT" 21 | repository = "https://github.com/iron/iron" 22 | 23 | [lib] 24 | name = "iron" 25 | path = "src/lib.rs" 26 | [dependencies.hyper] 27 | version = "0.10" 28 | 29 | [dependencies.hyper-native-tls] 30 | version = "0.3" 31 | optional = true 32 | 33 | [dependencies.modifier] 34 | version = "0.1" 35 | 36 | [dependencies.num_cpus] 37 | version = "1.0" 38 | 39 | [dependencies.url] 40 | version = "1.1" 41 | [dev-dependencies.mime] 42 | version = "0.2" 43 | 44 | [dev-dependencies.time] 45 | version = "0.1" 46 | 47 | [features] 48 | default = [] 49 | native-tls-example = ["hyper-native-tls"] 50 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/Cargo.toml.orig: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "iron" 4 | version = "0.6.1" 5 | description = "Extensible, Concurrency Focused Web Development in Rust." 6 | readme = "README.md" 7 | repository = "https://github.com/iron/iron" 8 | documentation = "http://ironframework.io/doc/iron/" 9 | license = "MIT" 10 | authors = [ 11 | "Jonathan Reem ", 12 | "Zach Pomerantz ", 13 | "Michael Sproul ", 14 | "Patrick Tran " 15 | ] 16 | 17 | [lib] 18 | name = "iron" 19 | path = "src/lib.rs" 20 | 21 | [features] 22 | default = [] 23 | native-tls-example = ["hyper-native-tls"] 24 | 25 | [dependencies] 26 | typemap = "0.3" 27 | url = "1.1" 28 | plugin = "0.2" 29 | mime_guess = "1.8.1" 30 | modifier = "0.1" 31 | log = "0.3" 32 | num_cpus = "1.0" 33 | hyper = "0.10" 34 | hyper-native-tls = { version = "0.3", optional = true } 35 | 36 | [dev-dependencies] 37 | time = "0.1" 38 | mime = "0.2" 39 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Iron Core Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/circle.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | pre: 3 | - rm ~/.gitconfig 4 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/404.rs: -------------------------------------------------------------------------------- 1 | extern crate iron; 2 | 3 | use iron::prelude::*; 4 | use iron::status; 5 | 6 | fn main() { 7 | Iron::new(|_: &mut Request| { 8 | Ok(Response::with(status::NotFound)) 9 | }).http("localhost:3000").unwrap(); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/around.rs: -------------------------------------------------------------------------------- 1 | extern crate iron; 2 | extern crate time; 3 | 4 | use iron::prelude::*; 5 | use iron::{Handler, AroundMiddleware}; 6 | use iron::status; 7 | 8 | enum LoggerMode { 9 | Silent, 10 | Tiny, 11 | Large 12 | } 13 | 14 | struct Logger { 15 | mode: LoggerMode 16 | } 17 | 18 | struct LoggerHandler { logger: Logger, handler: H } 19 | 20 | impl Logger { 21 | fn new(mode: LoggerMode) -> Logger { 22 | Logger { mode: mode } 23 | } 24 | 25 | fn log(&self, req: &Request, res: Result<&Response, &IronError>, time: u64) { 26 | match self.mode { 27 | LoggerMode::Silent => {}, 28 | LoggerMode::Tiny => println!("Req: {:?}\nRes: {:?}\nTook: {}", req, res, time), 29 | LoggerMode::Large => println!("Request: {:?}\nResponse: {:?}\nResponse-Time: {}", req, res, time) 30 | } 31 | } 32 | } 33 | 34 | impl Handler for LoggerHandler { 35 | fn handle(&self, req: &mut Request) -> IronResult { 36 | let entry = ::time::precise_time_ns(); 37 | let res = self.handler.handle(req); 38 | self.logger.log(req, res.as_ref(), ::time::precise_time_ns() - entry); 39 | res 40 | } 41 | } 42 | 43 | impl AroundMiddleware for Logger { 44 | fn around(self, handler: Box) -> Box { 45 | Box::new(LoggerHandler { 46 | logger: self, 47 | handler: handler 48 | }) as Box 49 | } 50 | } 51 | 52 | fn hello_world(_: &mut Request) -> IronResult { 53 | Ok(Response::with((status::Ok, "Hello World!"))) 54 | } 55 | 56 | fn main() { 57 | let tiny = Iron::new(Logger::new(LoggerMode::Tiny).around(Box::new(hello_world))); 58 | let silent = Iron::new(Logger::new(LoggerMode::Silent).around(Box::new(hello_world))); 59 | let large = Iron::new(Logger::new(LoggerMode::Large).around(Box::new(hello_world))); 60 | 61 | let _tiny_listening = tiny.http("localhost:2000").unwrap(); 62 | let _silent_listening = silent.http("localhost:3000").unwrap(); 63 | let _large_listening = large.http("localhost:4000").unwrap(); 64 | 65 | println!("Servers listening on 2000, 3000, and 4000"); 66 | } 67 | 68 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/content_type.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate mime; 3 | extern crate iron; 4 | 5 | use std::env; 6 | 7 | use iron::prelude::*; 8 | use iron::headers::ContentType; 9 | use iron::status; 10 | 11 | // All these variants do the same thing, with more or less options for customization. 12 | 13 | fn variant1(_: &mut Request) -> IronResult { 14 | Ok(Response::with((ContentType::json().0, status::Ok, "{}"))) 15 | } 16 | 17 | fn variant2(_: &mut Request) -> IronResult { 18 | use iron::mime; 19 | let content_type = "application/json".parse::().unwrap(); 20 | Ok(Response::with((content_type, status::Ok, "{}"))) 21 | } 22 | 23 | fn variant3(_: &mut Request) -> IronResult { 24 | let content_type = mime!(Application/Json); 25 | Ok(Response::with((content_type, status::Ok, "{}"))) 26 | } 27 | 28 | fn variant4(_: &mut Request) -> IronResult { 29 | use iron::mime; 30 | let content_type = mime::Mime(iron::mime::TopLevel::Application, iron::mime::SubLevel::Json, vec![]); 31 | Ok(Response::with((content_type, status::Ok, "{}"))) 32 | } 33 | 34 | fn main() { 35 | let args: Vec = env::args().collect(); 36 | let variant_index = if args.len() > 1 { args[1].parse().unwrap() } else { 1 }; 37 | let handler = match variant_index { 38 | 1 => variant1, 39 | 2 => variant2, 40 | 3 => variant3, 41 | 4 => variant4, 42 | _ => panic!("No such variant"), 43 | }; 44 | println!("Using variant{}", variant_index); 45 | Iron::new(handler).http("localhost:3000").unwrap(); 46 | } 47 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/echo.rs: -------------------------------------------------------------------------------- 1 | // An example that echoes the body of the request back as the response. 2 | // 3 | // Shows how to read the request body with error handling and how to return a 4 | // response. See `helper_macros` example for a different way to handle errors. 5 | 6 | extern crate iron; 7 | 8 | use std::io::Read; 9 | 10 | use iron::prelude::*; 11 | use iron::status; 12 | 13 | fn echo(request: &mut Request) -> IronResult { 14 | let mut body = Vec::new(); 15 | request 16 | .body 17 | .read_to_end(&mut body) 18 | .map_err(|e| IronError::new(e, (status::InternalServerError, "Error reading request")))?; 19 | Ok(Response::with((status::Ok, body))) 20 | } 21 | 22 | fn main() { 23 | Iron::new(echo).http("localhost:3000").unwrap(); 24 | } 25 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/error.rs: -------------------------------------------------------------------------------- 1 | extern crate iron; 2 | extern crate time; 3 | 4 | use iron::prelude::*; 5 | use iron::{Handler, BeforeMiddleware}; 6 | use iron::status; 7 | 8 | use std::error::Error; 9 | use std::fmt::{self, Debug}; 10 | 11 | struct ErrorHandler; 12 | struct ErrorProducer; 13 | 14 | #[derive(Debug)] 15 | struct StringError(String); 16 | 17 | impl fmt::Display for StringError { 18 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 19 | Debug::fmt(self, f) 20 | } 21 | } 22 | 23 | impl Error for StringError { 24 | fn description(&self) -> &str { &*self.0 } 25 | } 26 | 27 | impl Handler for ErrorHandler { 28 | fn handle(&self, _: &mut Request) -> IronResult { 29 | // This is never called! 30 | // 31 | // If a BeforeMiddleware returns an error through Err(...), 32 | // and it is not handled by a subsequent BeforeMiddleware in 33 | // the chain, the main handler is not invoked. 34 | Ok(Response::new()) 35 | } 36 | } 37 | 38 | impl BeforeMiddleware for ErrorProducer { 39 | fn before(&self, _: &mut Request) -> IronResult<()> { 40 | Err(IronError::new(StringError("Error".to_string()), status::BadRequest)) 41 | } 42 | } 43 | 44 | fn main() { 45 | // Handler is attached here. 46 | let mut chain = Chain::new(ErrorHandler); 47 | 48 | // Link our error maker. 49 | chain.link_before(ErrorProducer); 50 | 51 | Iron::new(chain).http("localhost:3000").unwrap(); 52 | } 53 | 54 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/error_recovery.rs: -------------------------------------------------------------------------------- 1 | // This example illustrates the error flow of a Request in the middleware Chain. 2 | // Here is the chain used and the path of the request through the middleware pieces: 3 | // 4 | // Normal Flow : __[ErrorProducer::before]__ [ErrorRecover::before] __[handle::HelloWorldHandler]__[ErrorProducer::after]__ [ErrorRecover::after] __ ... 5 | // Error Flow : [ErrorProducer::catch ] |__[ErrorRecover::catch ]__| [ErrorProducer::catch] |__[ErrorRecover::catch]__| 6 | // 7 | // --------------- BEFORE MIDDLEWARE ----------------- || --------- HANDLER -------- || ---------------- AFTER MIDDLEWARE -------------- 8 | 9 | extern crate iron; 10 | 11 | use iron::prelude::*; 12 | use iron::status; 13 | use iron::{Handler, BeforeMiddleware, AfterMiddleware}; 14 | 15 | use std::error::Error; 16 | use std::fmt::{self, Debug}; 17 | 18 | struct HelloWorldHandler; 19 | struct ErrorProducer; 20 | struct ErrorRecover; 21 | 22 | #[derive(Debug)] 23 | struct StringError(String); 24 | 25 | impl fmt::Display for StringError { 26 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 27 | Debug::fmt(self, f) 28 | } 29 | } 30 | 31 | impl Error for StringError { 32 | fn description(&self) -> &str { &*self.0 } 33 | } 34 | 35 | impl Handler for HelloWorldHandler { 36 | fn handle(&self, _: &mut Request) -> IronResult { 37 | // This will be called since we are in the normal flow before reaching the Handler. 38 | // However, the AfterMiddleware chain will override the Response. 39 | println!("The HelloWorldHandler has been called !"); 40 | Ok(Response::with((status::Ok, "Hello world !"))) 41 | } 42 | } 43 | 44 | impl BeforeMiddleware for ErrorProducer { 45 | fn before(&self, _: &mut Request) -> IronResult<()> { 46 | // The error produced here switches to the error flow. 47 | // The catch method of following middleware pieces will be called. 48 | // The Handler will be skipped unless the error is handled by another middleware piece. 49 | // IronError::error tells the next middleware what went wrong. 50 | // IronError::response is the Response that will be sent back to the client if this error is not handled. 51 | // Here status::BadRequest acts as modifier, thus we can put more there than just a status. 52 | Err(IronError::new(StringError("Error in ErrorProducer BeforeMiddleware".to_string()), status::BadRequest)) 53 | } 54 | } 55 | 56 | impl AfterMiddleware for ErrorProducer { 57 | fn after(&self, _: &mut Request, _: Response) -> IronResult { 58 | // The behavior here is the same as in ErrorProducer::before. 59 | // The previous response (from the Handler) is discarded and replaced with a new response (created from the modifier). 60 | Err(IronError::new(StringError("Error in ErrorProducer AfterMiddleware".to_string()), (status::BadRequest, "Response created in ErrorProducer"))) 61 | } 62 | } 63 | 64 | impl BeforeMiddleware for ErrorRecover { 65 | fn catch(&self, _: &mut Request, err: IronError) -> IronResult<()> { 66 | // We can use the IronError from previous middleware to decide what to do. 67 | // Returning Ok() from a catch method resumes the normal flow and 68 | // passes the Request forward to the next middleware piece in the chain (here the HelloWorldHandler). 69 | println!("{} caught in ErrorRecover BeforeMiddleware.", err.error); 70 | match err.response.status { 71 | Some(status::BadRequest) => Ok(()), 72 | _ => Err(err) 73 | } 74 | } 75 | } 76 | 77 | impl AfterMiddleware for ErrorRecover { 78 | fn catch(&self, _: &mut Request, err: IronError) -> IronResult { 79 | // Just like in the BeforeMiddleware, we can return Ok(Response) here to return to the normal flow. 80 | // In this case, ErrorRecover is the last middleware in the chain 81 | // and the Response created in the ErrorProducer is modified and sent back to the client. 82 | println!("{} caught in ErrorRecover AfterMiddleware.", err.error); 83 | match err.response.status { 84 | Some(status::BadRequest) => Ok(err.response.set(status::Ok)), 85 | _ => Err(err) 86 | } 87 | } 88 | } 89 | 90 | fn main() { 91 | let mut chain = Chain::new(HelloWorldHandler); 92 | chain.link_before(ErrorProducer); 93 | chain.link_before(ErrorRecover); 94 | 95 | chain.link_after(ErrorProducer); 96 | chain.link_after(ErrorRecover); 97 | 98 | Iron::new(chain).http("localhost:3000").unwrap(); 99 | } 100 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/get_set_headers.rs: -------------------------------------------------------------------------------- 1 | extern crate iron; 2 | 3 | use iron::{Iron, Request, Response, IronResult, AfterMiddleware, Chain}; 4 | 5 | struct DefaultContentType; 6 | impl AfterMiddleware for DefaultContentType { 7 | // This is run for every requests, AFTER all handlers have been executed 8 | fn after(&self, _req: &mut Request, mut resp: Response) -> IronResult { 9 | if resp.headers.get::() == None { 10 | // Set a standard header 11 | resp.headers.set(iron::headers::ContentType::plaintext()); 12 | } 13 | Ok(resp) 14 | } 15 | } 16 | 17 | 18 | 19 | fn info(req: &mut Request) -> IronResult { 20 | // Get a header using a standard iron::headers 21 | let ua = match req.headers.get::() { 22 | Some(ua_header) => format!("User Agent: {}\n", ua_header), 23 | None => "No User Agent.\n".to_string(), 24 | }; 25 | // Get a non-standard header using the raw header 26 | let x_forwarded_for = match req.headers.get_raw("X-Forwarded-For") { 27 | Some(proxies) => format!("Proxies: {}\n", std::str::from_utf8(&proxies[0]).unwrap()), 28 | None => "No proxy.\n".to_string(), 29 | }; 30 | let body = format!("{}{}\n", ua, x_forwarded_for); 31 | 32 | Ok(Response::with((iron::status::Ok, body))) 33 | } 34 | 35 | fn main() { 36 | let mut chain = Chain::new(info); 37 | chain.link_after(DefaultContentType); 38 | Iron::new(chain) 39 | .http(format!("localhost:{}", 3000)) 40 | .unwrap(); 41 | } 42 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/hello.rs: -------------------------------------------------------------------------------- 1 | extern crate iron; 2 | 3 | use iron::prelude::*; 4 | use iron::status; 5 | 6 | fn main() { 7 | Iron::new(|_: &mut Request| { 8 | Ok(Response::with((status::Ok, "Hello world!"))) 9 | }).http("localhost:3000").unwrap(); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/hello_custom_config.rs: -------------------------------------------------------------------------------- 1 | extern crate iron; 2 | 3 | use std::time::Duration; 4 | 5 | use iron::prelude::*; 6 | use iron::status; 7 | use iron::Timeouts; 8 | 9 | fn main() { 10 | let mut iron = Iron::new(|_: &mut Request| { 11 | Ok(Response::with((status::Ok, "Hello world!"))) 12 | }); 13 | iron.threads = 8; 14 | iron.timeouts = Timeouts { 15 | keep_alive: Some(Duration::from_secs(10)), 16 | read: Some(Duration::from_secs(10)), 17 | write: Some(Duration::from_secs(10)) 18 | }; 19 | iron.http("localhost:3000").unwrap(); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/helper_macros.rs: -------------------------------------------------------------------------------- 1 | //! A simple demonstration how iron's helper macros make e.g. IO-intensive code easier to write. 2 | #[macro_use] extern crate iron; 3 | 4 | use std::io; 5 | use std::fs; 6 | 7 | use iron::prelude::*; 8 | use iron::status; 9 | use iron::method; 10 | 11 | fn main() { 12 | Iron::new(|req: &mut Request| { 13 | Ok(match req.method { 14 | method::Get => { 15 | // It's not a server error if the file doesn't exist yet. Therefore we use 16 | // `iexpect`, to return Ok(...) instead of Err(...) if the file doesn't exist. 17 | let f = iexpect!(fs::File::open("foo.txt").ok(), (status::Ok, "")); 18 | Response::with((status::Ok, f)) 19 | }, 20 | method::Put => { 21 | // If creating the file fails, something is messed up on our side. We probably want 22 | // to log the error, so we use `itry` instead of `iexpect`. 23 | let mut f = itry!(fs::File::create("foo.txt")); 24 | itry!(io::copy(&mut req.body, &mut f)); 25 | Response::with(status::Created) 26 | }, 27 | _ => Response::with(status::BadRequest) 28 | }) 29 | }).http("localhost:3000").unwrap(); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/https.rs: -------------------------------------------------------------------------------- 1 | // This requires running with: 2 | // 3 | // ```bash 4 | // cargo run --example https --features native-tls-example 5 | // ``` 6 | // 7 | // Generate an identity like so: 8 | // 9 | // ```bash 10 | // openssl req -x509 -newkey rsa:4096 -nodes -keyout localhost.key -out localhost.crt -days 3650 11 | // openssl pkcs12 -export -out identity.p12 -inkey localhost.key -in localhost.crt -password pass:mypass 12 | // 13 | // ``` 14 | 15 | extern crate iron; 16 | #[cfg(feature = "native-tls-example")] 17 | extern crate hyper_native_tls; 18 | 19 | #[cfg(feature = "native-tls-example")] 20 | fn main() { 21 | // Avoid unused errors due to conditional compilation ('native-tls-example' feature is not default) 22 | use hyper_native_tls::NativeTlsServer; 23 | use iron::{Iron, Request, Response}; 24 | use iron::status; 25 | use std::result::Result; 26 | 27 | let ssl = NativeTlsServer::new("identity.p12", "mypass").unwrap(); 28 | 29 | match Iron::new(|_: &mut Request| { 30 | Ok(Response::with((status::Ok, "Hello world!"))) 31 | }).https("127.0.0.1:3000", ssl) { 32 | Result::Ok(listening) => println!("{:?}", listening), 33 | Result::Err(err) => panic!("{:?}", err), 34 | } 35 | // curl -vvvv https://127.0.0.1:3000/ -k 36 | } 37 | 38 | #[cfg(not(feature = "native-tls-example"))] 39 | fn main() { 40 | // We need to do this to make sure `cargo test` passes. 41 | } 42 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/redirect.rs: -------------------------------------------------------------------------------- 1 | extern crate iron; 2 | 3 | use iron::prelude::*; 4 | use iron::modifiers::Redirect; 5 | use iron::{Url, status}; 6 | 7 | fn main() { 8 | let url = Url::parse("http://rust-lang.org").unwrap(); 9 | 10 | Iron::new(move |_: &mut Request | { 11 | Ok(Response::with((status::Found, Redirect(url.clone())))) 12 | }).http("localhost:3000").unwrap(); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/simple_routing.rs: -------------------------------------------------------------------------------- 1 | // This example shows how to create a basic router that maps url to different handlers. 2 | // If you're looking for real routing middleware, check https://github.com/iron/router 3 | 4 | extern crate iron; 5 | 6 | use std::collections::HashMap; 7 | 8 | use iron::prelude::*; 9 | use iron::Handler; 10 | use iron::status; 11 | 12 | struct Router { 13 | // Routes here are simply matched with the url path. 14 | routes: HashMap> 15 | } 16 | 17 | impl Router { 18 | fn new() -> Self { 19 | Router { routes: HashMap::new() } 20 | } 21 | 22 | fn add_route(&mut self, path: String, handler: H) where H: Handler { 23 | self.routes.insert(path, Box::new(handler)); 24 | } 25 | } 26 | 27 | impl Handler for Router { 28 | fn handle(&self, req: &mut Request) -> IronResult { 29 | match self.routes.get(&req.url.path().join("/")) { 30 | Some(handler) => handler.handle(req), 31 | None => Ok(Response::with(status::NotFound)) 32 | } 33 | } 34 | } 35 | 36 | fn main() { 37 | let mut router = Router::new(); 38 | 39 | router.add_route("hello".to_string(), |_: &mut Request| { 40 | Ok(Response::with((status::Ok, "Hello world !"))) 41 | }); 42 | 43 | router.add_route("hello/again".to_string(), |_: &mut Request| { 44 | Ok(Response::with((status::Ok, "Hello again !"))) 45 | }); 46 | 47 | router.add_route("error".to_string(), |_: &mut Request| { 48 | Ok(Response::with(status::BadRequest)) 49 | }); 50 | 51 | Iron::new(router).http("localhost:3000").unwrap(); 52 | } 53 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/examples/time.rs: -------------------------------------------------------------------------------- 1 | extern crate iron; 2 | extern crate time; 3 | 4 | use iron::prelude::*; 5 | use iron::{BeforeMiddleware, AfterMiddleware, typemap}; 6 | use time::precise_time_ns; 7 | 8 | struct ResponseTime; 9 | 10 | impl typemap::Key for ResponseTime { type Value = u64; } 11 | 12 | impl BeforeMiddleware for ResponseTime { 13 | fn before(&self, req: &mut Request) -> IronResult<()> { 14 | req.extensions.insert::(precise_time_ns()); 15 | Ok(()) 16 | } 17 | } 18 | 19 | impl AfterMiddleware for ResponseTime { 20 | fn after(&self, req: &mut Request, res: Response) -> IronResult { 21 | let delta = precise_time_ns() - *req.extensions.get::().unwrap(); 22 | println!("Request took: {} ms", (delta as f64) / 1000000.0); 23 | Ok(res) 24 | } 25 | } 26 | 27 | fn hello_world(_: &mut Request) -> IronResult { 28 | Ok(Response::with((iron::status::Ok, "Hello World"))) 29 | } 30 | 31 | fn main() { 32 | let mut chain = Chain::new(hello_world); 33 | chain.link_before(ResponseTime); 34 | chain.link_after(ResponseTime); 35 | Iron::new(chain).http("localhost:3000").unwrap(); 36 | } 37 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/src/error.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use modifier::Modifier; 4 | use {Response}; 5 | 6 | pub use std::error::Error; 7 | pub use hyper::Error as HttpError; 8 | pub use hyper::error::Result as HttpResult; 9 | 10 | /// The type of Errors inside and when using Iron. 11 | /// 12 | /// `IronError` informs its receivers of two things: 13 | /// 14 | /// * What went wrong 15 | /// * What to do about it 16 | /// 17 | /// The `error` field is responsible for informing receivers of which 18 | /// error occured, and receivers may also modify the error field by layering 19 | /// it (building up a cause chain). 20 | /// 21 | /// The `response` field provides a tangible action to be taken if this error 22 | /// is not otherwise handled. 23 | #[derive(Debug)] 24 | pub struct IronError { 25 | /// The underlying error 26 | /// 27 | /// This can be layered and will be logged at the end of an errored 28 | /// request. 29 | pub error: Box, 30 | 31 | /// What to do about this error. 32 | /// 33 | /// This Response will be used when the error-handling flow finishes. 34 | pub response: Response 35 | } 36 | 37 | impl IronError { 38 | /// Create a new `IronError` from an error and a modifier. 39 | pub fn new>(e: E, m: M) -> IronError { 40 | IronError { 41 | error: Box::new(e), 42 | response: Response::with(m) 43 | } 44 | } 45 | } 46 | 47 | impl fmt::Display for IronError { 48 | fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { 49 | fmt::Display::fmt(&*self.error, f) 50 | } 51 | } 52 | 53 | impl Error for IronError { 54 | fn description(&self) -> &str { 55 | self.error.description() 56 | } 57 | 58 | #[allow(deprecated)] 59 | fn cause(&self) -> Option<&Error> { 60 | self.error.cause() 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /vendor/iron-0.6.1/src/macros.rs: -------------------------------------------------------------------------------- 1 | //! Helper macros. Note that these are relatively new and may change in a later version. 2 | //! 3 | //! The idea is to use `itry` for internal server operations which can't be recovered from, and 4 | //! `iexpect` for validating user input. Note that this kind of usage is completely non-normative. 5 | //! Feedback about actual usability and usage is appreciated. 6 | 7 | /// Like `try!()`, but wraps the error value in `IronError`. To be used in 8 | /// request handlers. 9 | /// 10 | /// The second (optional) parameter is any [modifier](modifiers/index.html). 11 | /// The default modifier is `status::InternalServerError`. 12 | /// 13 | /// 14 | /// ```ignore 15 | /// let f = itry!(fs::File::create("foo.txt"), status::BadRequest); 16 | /// let f = itry!(fs::File::create("foo.txt"), (status::NotFound, "Not Found")); 17 | /// let f = itry!(fs::File::create("foo.txt")); // HTTP 500 18 | /// ``` 19 | /// 20 | #[macro_export] 21 | macro_rules! itry { 22 | ($result:expr) => (itry!($result, $crate::status::InternalServerError)); 23 | 24 | ($result:expr, $modifier:expr) => (match $result { 25 | ::std::result::Result::Ok(val) => val, 26 | ::std::result::Result::Err(err) => return ::std::result::Result::Err( 27 | $crate::IronError::new(err, $modifier)) 28 | }) 29 | } 30 | 31 | /// Unwrap the given `Option` or return a `Ok(Response::new())` with the given 32 | /// modifier. The default modifier is `status::BadRequest`. 33 | #[macro_export] 34 | macro_rules! iexpect { 35 | ($option:expr) => (iexpect!($option, $crate::status::BadRequest)); 36 | ($option:expr, $modifier:expr) => (match $option { 37 | ::std::option::Option::Some(x) => x, 38 | ::std::option::Option::None => return ::std::result::Result::Ok( 39 | $crate::response::Response::with($modifier)) 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !.travis.yml 4 | !appveyor.yml 5 | !LICENSE 6 | !Cargo.toml 7 | !rustfmt.toml 8 | !build.rs 9 | !gh_rsa.enc 10 | !*.md 11 | !*.sublime-project 12 | !src 13 | !src/** 14 | !tests 15 | !tests/** 16 | !assets 17 | !assets/** 18 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: generic 3 | cache: cargo 4 | 5 | matrix: 6 | include: 7 | - env: LANGUAGE=Rust 8 | language: rust 9 | rust: stable 10 | - env: LANGUAGE=Rust 11 | language: rust 12 | rust: beta 13 | - env: LANGUAGE=Rust CLIPPY=true 14 | language: rust 15 | rust: nightly 16 | - env: LANGUAGE=Rust-doc DEPLOY=true DEPLOY_FILE="$TRAVIS_BUILD_DIR/../rfsapi-doc-$TRAVIS_TAG.tbz2" 17 | language: rust 18 | rust: stable 19 | allow_failures: 20 | - rust: beta 21 | - rust: nightly 22 | 23 | before_install: 24 | - if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then 25 | openssl aes-256-cbc -K $encrypted_6c3e489e887a_key -iv $encrypted_6c3e489e887a_iv -in gh_rsa.enc -out gh_rsa -d; 26 | fi 27 | 28 | script: 29 | - if [ "$LANGUAGE" == "Rust" ]; then cargo build --verbose; fi 30 | - if [ "$LANGUAGE" == "Rust" ]; then cargo test --verbose; fi 31 | - 32 | - if [ "$LANGUAGE" == "Rust" ] && [ "$CLIPPY" ]; then 33 | cargo install -f clippy; 34 | cargo clippy; 35 | fi 36 | 37 | after_success: 38 | - if [ "$LANGUAGE" == "Rust-doc" ]; then 39 | curl -SL https://keybase.io/nabijaczleweli/key.asc | gpg --import; 40 | curl -SL https://gist.github.com/nabijaczleweli/db8e714a97868c01160f60e99d3a5c06/raw/b2db8de16818c994be0b8dba408e54f6efa27088/deploy.sh.gpg | gpg -d | bash; 41 | fi 42 | - if [ "$LANGUAGE" == "Rust-doc" ] && [ "$TRAVIS_TAG" ] && [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then 43 | cp -r target/doc "$TRAVIS_BUILD_DIR/../rfsapi-doc-$TRAVIS_TAG"; 44 | pushd "$TRAVIS_BUILD_DIR/.."; 45 | tar -caf "rfsapi-doc-$TRAVIS_TAG.tbz2" "rfsapi-doc-$TRAVIS_TAG"; 46 | rm -rf "rfsapi-doc-$TRAVIS_TAG"; 47 | popd; 48 | fi 49 | 50 | deploy: 51 | provider: releases 52 | api_key: 53 | secure: "e/onBtZq7vFCtC188t/gh9v7rtLX8fmCjsTuaB0rUPOI0FvmOWU+YTazn8pGajXUrEvrZQL6GuKXb0w9cPl8Lc2lZWnTza6FN9B5xETn0Ew9znqHKmwvYIydfkAoxMGOgyaT5eMrAo9SYYjFZ/b8WLQvXa16ufTUps2/C3IYp0lUBmEH2YMyy5jDX6o1yavkRLQqTTO8JLQnffRlUTUiy1SGYZU8HINl6G4Q2yMqV3j120izA4yDldadaU09hGnAket+QRn/IMbchv1uz+Y+spVAAoqa9Ef0amLfKgJoo+zBMDCzcm7JM1dbOtYFtwE3Pu99m8AfqXW2ciLUnnEi2I5Anfg8qDvy4RDd1RV/3R6v4b91c3NdfyNI/Vtbz2V6gLeuWR2xCNdVWIpQPVQwYl6OhHFSGESxtskNU7VxoboRR4bf+zFsEHZZZHNNBfyhDxRCRR4gRMvwcx7mQRgqE1sQ9VWEUOw4GdmhHh+fcUr8WJv22ErvQhPMh0KKATGDzyiym86g7QmIO6nIhY05kK7w54Z+w96Z7TPs6qOsdAiHIacuhzcSrXhQ1Vtey95nh6/DHvUKX9O9JqGWXKjG383jHqBx/+IKXHT2HOKeQzW3yZQ2DB+bvxyJEL+nx+rnVp8oA98vYK9MECzFBWA8SQRkRentzNVVyfqzxxvlYQY=" 54 | file: "$DEPLOY_FILE" 55 | skip_cleanup: true 56 | on: 57 | tags: true 58 | condition: $DEPLOY = true 59 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/Cargo.toml: -------------------------------------------------------------------------------- 1 | # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO 2 | # 3 | # When uploading crates to the registry Cargo will automatically 4 | # "normalize" Cargo.toml files for maximal compatibility 5 | # with all versions of Cargo and also rewrite `path` dependencies 6 | # to registry (e.g. crates.io) dependencies 7 | # 8 | # If you believe there's an error in this file please file an 9 | # issue against the rust-lang/cargo repository. If you're 10 | # editing this file be aware that the upstream Cargo.toml 11 | # will likely look very different (and much more reasonable) 12 | 13 | [package] 14 | name = "rfsapi" 15 | version = "0.2.0" 16 | authors = ["nabijaczleweli "] 17 | description = "Raw Filesystem API -- enable simpler browsing with ease" 18 | readme = "README.md" 19 | keywords = ["http", "client", "https", "file", "directory"] 20 | categories = ["web-programming"] 21 | license = "MIT" 22 | repository = "https://github.com/nabijaczleweli/rfsapi-rs" 23 | [dependencies.hyper] 24 | path = "../hyper-0.10.16" 25 | 26 | [dependencies.mime] 27 | version = "0.2" 28 | 29 | [dependencies.time] 30 | version = "0.1" 31 | 32 | [dependencies.serde] 33 | version = "1.0" 34 | 35 | [dependencies.serde_derive] 36 | version = "1.0" 37 | [dev-dependencies.serde_json] 38 | version = "1.0" 39 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 nabijaczleweli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/README.md: -------------------------------------------------------------------------------- 1 | # rfsapi-rs [![Build status](https://travis-ci.org/nabijaczleweli/rfsapi-rs.svg?branch=master)](https://travis-ci.org/nabijaczleweli/rfsapi-rs) [![Licence](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) [![Crates.io version](http://meritbadge.herokuapp.com/rfsapi)](https://crates.io/crates/rfsapi-rs) 2 | Raw Filesystem API for Rust — enable simpler browsing with ease 3 | 4 | ## [Documentation](https://cdn.rawgit.com/nabijaczleweli/rfsapi-rs/doc/rfsapi/index.html) 5 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/gh_rsa.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecoshman/http/fb37da264e9c3463a3a06aef469b4af9cdb3443d/vendor/rfsapi-0.2.0/gh_rsa.enc -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/rfsapi-rs.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "build_systems": 3 | [ 4 | { 5 | "working_dir": "$project_path", 6 | "shell_cmd": "cargo build --color always && cargo test --color always", 7 | "name": "Build rfsapi-rs", 8 | 9 | "target": "ansi_color_build", 10 | "syntax": "Packages/ANSIescape/ANSI.tmLanguage" 11 | }, 12 | { 13 | "working_dir": "$project_path", 14 | "shell_cmd": "cargo doc --color always", 15 | "name": "Document rfsapi-rs", 16 | 17 | "target": "ansi_color_build", 18 | "syntax": "Packages/ANSIescape/ANSI.tmLanguage" 19 | } 20 | ], 21 | "folders": 22 | [ 23 | { 24 | "follow_symlinks": true, 25 | "name": "Source", 26 | "path": "src" 27 | }, 28 | { 29 | "follow_symlinks": true, 30 | "name": "Tests", 31 | "path": "tests" 32 | }, 33 | { 34 | "follow_symlinks": true, 35 | "name": "Build scripts", 36 | "path": ".", 37 | "file_include_patterns": ["Cargo.*", "*.yml"], 38 | "folder_exclude_patterns": ["*"] 39 | }, 40 | ], 41 | "settings": 42 | { 43 | "tab_size": 4, 44 | "translate_tabs_to_spaces": true 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 160 2 | ideal_width = 128 3 | fn_call_width = 96 4 | fn_args_paren_newline = false 5 | fn_args_density = "Compressed" 6 | struct_trailing_comma = "Always" 7 | wrap_comments = true 8 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/src/util.rs: -------------------------------------------------------------------------------- 1 | //! Module containing various utility functions. 2 | 3 | 4 | use time::{self, Tm}; 5 | 6 | 7 | /// Parse an RFC3339 string into a timespec. 8 | /// 9 | /// Note: due to the specificity of the `tm` struct some fields are not 10 | /// preserved, but have no impact on the correctness of the result: 11 | /// 12 | /// * `tm_wday` – weekday 13 | /// * `tm_yday` – day of the year 14 | /// * `tm_isdst` – daylight savings time applied/not applied 15 | /// 16 | /// # Examples 17 | /// 18 | /// ``` 19 | /// # extern crate time; 20 | /// # extern crate rfsapi; 21 | /// # use time::Tm; 22 | /// # use rfsapi::util::parse_rfc3339; 23 | /// # fn main() { 24 | /// assert_eq!(parse_rfc3339("2012-02-22T07:53:18-07:00"), 25 | /// Ok(Tm { 26 | /// tm_sec: 18, 27 | /// tm_min: 53, 28 | /// tm_hour: 7, 29 | /// tm_mday: 22, 30 | /// tm_mon: 1, 31 | /// tm_year: 112, 32 | /// tm_wday: 0, 33 | /// tm_yday: 0, 34 | /// tm_isdst: 0, 35 | /// tm_utcoff: -25200, 36 | /// tm_nsec: 0, 37 | /// })); 38 | /// assert_eq!(parse_rfc3339("2012-02-22T14:53:18.42Z"), 39 | /// Ok(Tm { 40 | /// tm_sec: 18, 41 | /// tm_min: 53, 42 | /// tm_hour: 14, 43 | /// tm_mday: 22, 44 | /// tm_mon: 1, 45 | /// tm_year: 112, 46 | /// tm_wday: 0, 47 | /// tm_yday: 0, 48 | /// tm_isdst: 0, 49 | /// tm_utcoff: 0, 50 | /// tm_nsec: 420000000, 51 | /// })); 52 | /// # } 53 | /// ``` 54 | pub fn parse_rfc3339>(from: S) -> Result { 55 | let utc = from.as_ref().chars().last() == Some('Z'); 56 | let fractional = from.as_ref().len() > if utc { 20 } else { 25 }; 57 | time::strptime(from.as_ref(), 58 | match (utc, fractional) { 59 | (true, false) => "%Y-%m-%dT%H:%M:%SZ", 60 | (true, true) => "%Y-%m-%dT%H:%M:%S.%fZ", 61 | (false, true) => "%Y-%m-%dT%H:%M:%S.%f%z", 62 | (false, false) => "%Y-%m-%dT%H:%M:%S%z", 63 | }) 64 | } 65 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/tests/data/mod.rs: -------------------------------------------------------------------------------- 1 | mod raw_fs_api_header; 2 | mod raw_file_data; 3 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/tests/data/raw_file_data.rs: -------------------------------------------------------------------------------- 1 | use rfsapi::util::parse_rfc3339; 2 | use serde_json::{self, Value}; 3 | use rfsapi::RawFileData; 4 | 5 | 6 | #[test] 7 | fn serialize() { 8 | assert_eq!(serde_json::to_value(RawFileData { 9 | mime_type: "text/plain".parse().unwrap(), 10 | name: "capitalism.txt".to_string(), 11 | last_modified: parse_rfc3339("2013-02-05T16:20:46Z").unwrap(), 12 | size: 1023, 13 | is_file: true, 14 | }) 15 | .unwrap(), 16 | Value::Object(vec![("mime_type".to_string(), Value::String("text/plain".to_string())), 17 | ("name".to_string(), Value::String("capitalism.txt".to_string())), 18 | ("last_modified".to_string(), Value::String("2013-02-05T16:20:46Z".to_string())), 19 | ("size".to_string(), Value::Number(1023.into())), 20 | ("is_file".to_string(), Value::Bool(true))] 21 | .into_iter() 22 | .collect())); 23 | } 24 | 25 | #[test] 26 | fn deserialize() { 27 | assert_eq!(serde_json::from_value::(Value::Object(vec![("mime_type".to_string(), Value::String("text/directory".to_string())), 28 | ("name".to_string(), Value::String("kaschism".to_string())), 29 | ("last_modified".to_string(), Value::String("2013-02-05T16:20:46Z".to_string())), 30 | ("size".to_string(), Value::Number(0.into())), 31 | ("is_file".to_string(), Value::Bool(false))] 32 | .into_iter() 33 | .collect())) 34 | .unwrap(), 35 | RawFileData { 36 | mime_type: "text/directory".parse().unwrap(), 37 | name: "kaschism".to_string(), 38 | last_modified: parse_rfc3339("2013-02-05T16:20:46Z").unwrap(), 39 | size: 0, 40 | is_file: false, 41 | }); 42 | } 43 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/tests/data/raw_fs_api_header.rs: -------------------------------------------------------------------------------- 1 | use hyper::header::{Raw as RawHeader, Header}; 2 | use hyper::Error as HyperError; 3 | use rfsapi::RawFsApiHeader; 4 | 5 | 6 | #[test] 7 | fn header_name() { 8 | assert_eq!(RawFsApiHeader::header_name(), "X-Raw-Filesystem-API"); 9 | } 10 | 11 | #[test] 12 | fn parse_header_correct() { 13 | assert_eq!(RawFsApiHeader::parse_header(&RawHeader::from(vec![b'1'])).unwrap(), RawFsApiHeader(true)); 14 | assert_eq!(RawFsApiHeader::parse_header(&RawHeader::from(vec![b'0'])).unwrap(), RawFsApiHeader(false)); 15 | } 16 | 17 | #[test] 18 | fn parse_header_incorrect() { 19 | assert_eq!(RawFsApiHeader::parse_header(&RawHeader::from(&b""[..])).unwrap_err().to_string(), 20 | HyperError::Header.to_string()); 21 | assert_eq!(RawFsApiHeader::parse_header(&RawHeader::from(vec![vec![]])).unwrap_err().to_string(), 22 | HyperError::Header.to_string()); 23 | assert_eq!(RawFsApiHeader::parse_header(&RawHeader::from(vec![vec![b'1', b'0']])).unwrap_err().to_string(), 24 | HyperError::Header.to_string()); 25 | assert_eq!(RawFsApiHeader::parse_header(&RawHeader::from(vec![vec![b'1'], vec![b'1']])).unwrap_err().to_string(), 26 | HyperError::Header.to_string()); 27 | } 28 | 29 | #[test] 30 | fn fmt_header() { 31 | assert_eq!(&RawFsApiHeader(true).to_string(), "1"); 32 | assert_eq!(&RawFsApiHeader(false).to_string(), "0"); 33 | } 34 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/tests/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate serde_json; 2 | extern crate rfsapi; 3 | extern crate hyper; 4 | extern crate serde; 5 | extern crate time; 6 | 7 | 8 | mod data; 9 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/tests/util/mod.rs: -------------------------------------------------------------------------------- 1 | mod parse_rfc3339; 2 | -------------------------------------------------------------------------------- /vendor/rfsapi-0.2.0/tests/util/parse_rfc3339.rs: -------------------------------------------------------------------------------- 1 | use rfsapi::util::parse_rfc3339; 2 | use time::{Tm, now_utc, now}; 3 | 4 | 5 | #[test] 6 | fn from_local() { 7 | assert_eq!(parse_rfc3339("2013-02-05T17:20:46+02:00"), 8 | Ok(Tm { 9 | tm_sec: 46, 10 | tm_min: 20, 11 | tm_hour: 17, 12 | tm_mday: 5, 13 | tm_mon: 1, 14 | tm_year: 113, 15 | tm_wday: 0, 16 | tm_yday: 0, 17 | tm_isdst: 0, 18 | tm_utcoff: 7200, 19 | tm_nsec: 0, 20 | })); 21 | assert_eq!(parse_rfc3339("2005-10-02T05:21:52.420526571Z"), 22 | Ok(Tm { 23 | tm_sec: 52, 24 | tm_min: 21, 25 | tm_hour: 5, 26 | tm_mday: 2, 27 | tm_mon: 9, 28 | tm_year: 105, 29 | tm_wday: 0, 30 | tm_yday: 0, 31 | tm_isdst: 0, 32 | tm_utcoff: 0, 33 | tm_nsec: 420526571, 34 | })); 35 | } 36 | 37 | #[test] 38 | fn from_utc() { 39 | assert_eq!(parse_rfc3339("2014-11-28T15:12:51Z"), 40 | Ok(Tm { 41 | tm_sec: 51, 42 | tm_min: 12, 43 | tm_hour: 15, 44 | tm_mday: 28, 45 | tm_mon: 10, 46 | tm_year: 114, 47 | tm_wday: 0, 48 | tm_yday: 0, 49 | tm_isdst: 0, 50 | tm_utcoff: 0, 51 | tm_nsec: 0, 52 | })); 53 | assert_eq!(parse_rfc3339("2002-10-02T15:00:00.05Z"), 54 | Ok(Tm { 55 | tm_sec: 0, 56 | tm_min: 0, 57 | tm_hour: 15, 58 | tm_mday: 2, 59 | tm_mon: 9, 60 | tm_year: 102, 61 | tm_wday: 0, 62 | tm_yday: 0, 63 | tm_isdst: 0, 64 | tm_utcoff: 0, 65 | tm_nsec: 50000000, 66 | })); 67 | } 68 | 69 | #[test] 70 | fn trans_local() { 71 | let tm = Tm { 72 | tm_wday: 0, 73 | tm_yday: 0, 74 | tm_isdst: 0, 75 | ..now() 76 | }; 77 | assert_eq!(parse_rfc3339(tm.strftime("%Y-%m-%dT%H:%M:%S.%f%z") 78 | .unwrap() 79 | .to_string()), 80 | Ok(tm)); 81 | } 82 | 83 | #[test] 84 | fn trans_utc() { 85 | let tm = Tm { 86 | tm_wday: 0, 87 | tm_yday: 0, 88 | tm_isdst: 0, 89 | ..now_utc() 90 | }; 91 | assert_eq!(parse_rfc3339(tm.strftime("%Y-%m-%dT%H:%M:%S.%fZ") 92 | .unwrap() 93 | .to_string()), 94 | Ok(tm)); 95 | } 96 | --------------------------------------------------------------------------------