mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-24 16:02:59 +01:00
move url module to different crate
This commit is contained in:
parent
22d4523c93
commit
7d66430324
@ -52,7 +52,7 @@ base64 = "0.9"
|
|||||||
bitflags = "1.0"
|
bitflags = "1.0"
|
||||||
http = "0.1.8"
|
http = "0.1.8"
|
||||||
httparse = "1.3"
|
httparse = "1.3"
|
||||||
failure = "0.1.2"
|
failure = "0.1.3"
|
||||||
indexmap = "1.0"
|
indexmap = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
@ -62,7 +62,6 @@ serde_json = "1.0"
|
|||||||
sha1 = "0.6"
|
sha1 = "0.6"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
encoding = "0.2"
|
encoding = "0.2"
|
||||||
lazy_static = "1.0"
|
|
||||||
serde_urlencoded = "0.5.3"
|
serde_urlencoded = "0.5.3"
|
||||||
|
|
||||||
cookie = { version="0.11", features=["percent-encode"] }
|
cookie = { version="0.11", features=["percent-encode"] }
|
||||||
@ -93,8 +92,6 @@ openssl = { version="0.10", optional = true }
|
|||||||
# rustls
|
# rustls
|
||||||
rustls = { version = "^0.14", optional = true }
|
rustls = { version = "^0.14", optional = true }
|
||||||
|
|
||||||
backtrace="*"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-web = "0.7"
|
actix-web = "0.7"
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
|
@ -234,7 +234,6 @@ impl MessageTypeDecoder for Request {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let inner = msg.inner_mut();
|
let inner = msg.inner_mut();
|
||||||
inner.url.update(&uri);
|
|
||||||
inner.head.uri = uri;
|
inner.head.uri = uri;
|
||||||
inner.head.method = method;
|
inner.head.method = method;
|
||||||
inner.head.version = ver;
|
inner.head.version = ver;
|
||||||
|
@ -76,8 +76,6 @@ extern crate bitflags;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate cookie;
|
extern crate cookie;
|
||||||
extern crate encoding;
|
extern crate encoding;
|
||||||
@ -124,7 +122,6 @@ mod payload;
|
|||||||
mod request;
|
mod request;
|
||||||
mod response;
|
mod response;
|
||||||
mod service;
|
mod service;
|
||||||
pub mod uri;
|
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod h1;
|
pub mod h1;
|
||||||
|
@ -6,7 +6,6 @@ use http::{HeaderMap, Method, StatusCode, Uri, Version};
|
|||||||
|
|
||||||
use extensions::Extensions;
|
use extensions::Extensions;
|
||||||
use payload::Payload;
|
use payload::Payload;
|
||||||
use uri::Url;
|
|
||||||
|
|
||||||
/// Represents various types of connection
|
/// Represents various types of connection
|
||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
@ -147,8 +146,6 @@ impl ResponseHead {
|
|||||||
|
|
||||||
pub struct Message<T: Head> {
|
pub struct Message<T: Head> {
|
||||||
pub head: T,
|
pub head: T,
|
||||||
pub url: Url,
|
|
||||||
pub status: StatusCode,
|
|
||||||
pub extensions: RefCell<Extensions>,
|
pub extensions: RefCell<Extensions>,
|
||||||
pub payload: RefCell<Option<Payload>>,
|
pub payload: RefCell<Option<Payload>>,
|
||||||
pub(crate) pool: &'static MessagePool<T>,
|
pub(crate) pool: &'static MessagePool<T>,
|
||||||
@ -168,9 +165,7 @@ impl<T: Head> Default for Message<T> {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Message {
|
Message {
|
||||||
pool: T::pool(),
|
pool: T::pool(),
|
||||||
url: Url::default(),
|
|
||||||
head: T::default(),
|
head: T::default(),
|
||||||
status: StatusCode::OK,
|
|
||||||
payload: RefCell::new(None),
|
payload: RefCell::new(None),
|
||||||
extensions: RefCell::new(Extensions::new()),
|
extensions: RefCell::new(Extensions::new()),
|
||||||
}
|
}
|
||||||
|
@ -94,11 +94,7 @@ impl Request {
|
|||||||
/// The target path of this Request.
|
/// The target path of this Request.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn path(&self) -> &str {
|
pub fn path(&self) -> &str {
|
||||||
if let Some(path) = self.inner().url.path() {
|
self.inner().head.uri.path()
|
||||||
path
|
|
||||||
} else {
|
|
||||||
self.inner().head.uri.path()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -15,7 +15,6 @@ use tokio::runtime::current_thread::Runtime;
|
|||||||
use header::{Header, IntoHeaderValue};
|
use header::{Header, IntoHeaderValue};
|
||||||
use payload::Payload;
|
use payload::Payload;
|
||||||
use request::Request;
|
use request::Request;
|
||||||
use uri::Url as InnerUrl;
|
|
||||||
// use ws;
|
// use ws;
|
||||||
|
|
||||||
/// The `TestServer` type.
|
/// The `TestServer` type.
|
||||||
@ -390,8 +389,8 @@ impl TestRequest {
|
|||||||
let mut req = Request::new();
|
let mut req = Request::new();
|
||||||
{
|
{
|
||||||
let inner = req.inner_mut();
|
let inner = req.inner_mut();
|
||||||
|
inner.head.uri = uri;
|
||||||
inner.head.method = method;
|
inner.head.method = method;
|
||||||
inner.url = InnerUrl::new(&uri);
|
|
||||||
inner.head.version = version;
|
inner.head.version = version;
|
||||||
inner.head.headers = headers;
|
inner.head.headers = headers;
|
||||||
*inner.payload.borrow_mut() = payload;
|
*inner.payload.borrow_mut() = payload;
|
||||||
|
169
src/uri.rs
169
src/uri.rs
@ -1,169 +0,0 @@
|
|||||||
use http::Uri;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
const GEN_DELIMS: &[u8] = b":/?#[]@";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
const SUB_DELIMS_WITHOUT_QS: &[u8] = b"!$'()*,";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
const SUB_DELIMS: &[u8] = b"!$'()*,+?=;";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
const RESERVED: &[u8] = b":/?#[]@!$'()*,+?=;";
|
|
||||||
#[allow(dead_code)]
|
|
||||||
const UNRESERVED: &[u8] = b"abcdefghijklmnopqrstuvwxyz
|
|
||||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
|
||||||
1234567890
|
|
||||||
-._~";
|
|
||||||
const ALLOWED: &[u8] = b"abcdefghijklmnopqrstuvwxyz
|
|
||||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
|
||||||
1234567890
|
|
||||||
-._~
|
|
||||||
!$'()*,";
|
|
||||||
const QS: &[u8] = b"+&=;b";
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn bit_at(array: &[u8], ch: u8) -> bool {
|
|
||||||
array[(ch >> 3) as usize] & (1 << (ch & 7)) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn set_bit(array: &mut [u8], ch: u8) {
|
|
||||||
array[(ch >> 3) as usize] |= 1 << (ch & 7)
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref DEFAULT_QUOTER: Quoter = { Quoter::new(b"@:", b"/+") };
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug)]
|
|
||||||
pub struct Url {
|
|
||||||
path: Option<Rc<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Url {
|
|
||||||
pub fn new(uri: &Uri) -> Url {
|
|
||||||
let path = DEFAULT_QUOTER.requote(uri.path().as_bytes());
|
|
||||||
|
|
||||||
Url { path }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn update(&mut self, uri: &Uri) {
|
|
||||||
self.path = DEFAULT_QUOTER.requote(uri.path().as_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn path(&self) -> Option<&str> {
|
|
||||||
self.path.as_ref().map(|s| s.as_str())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Quoter {
|
|
||||||
safe_table: [u8; 16],
|
|
||||||
protected_table: [u8; 16],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Quoter {
|
|
||||||
pub fn new(safe: &[u8], protected: &[u8]) -> Quoter {
|
|
||||||
let mut q = Quoter {
|
|
||||||
safe_table: [0; 16],
|
|
||||||
protected_table: [0; 16],
|
|
||||||
};
|
|
||||||
|
|
||||||
// prepare safe table
|
|
||||||
for i in 0..128 {
|
|
||||||
if ALLOWED.contains(&i) {
|
|
||||||
set_bit(&mut q.safe_table, i);
|
|
||||||
}
|
|
||||||
if QS.contains(&i) {
|
|
||||||
set_bit(&mut q.safe_table, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ch in safe {
|
|
||||||
set_bit(&mut q.safe_table, *ch)
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare protected table
|
|
||||||
for ch in protected {
|
|
||||||
set_bit(&mut q.safe_table, *ch);
|
|
||||||
set_bit(&mut q.protected_table, *ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
q
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn requote(&self, val: &[u8]) -> Option<Rc<String>> {
|
|
||||||
let mut has_pct = 0;
|
|
||||||
let mut pct = [b'%', 0, 0];
|
|
||||||
let mut idx = 0;
|
|
||||||
let mut cloned: Option<Vec<u8>> = None;
|
|
||||||
|
|
||||||
let len = val.len();
|
|
||||||
while idx < len {
|
|
||||||
let ch = val[idx];
|
|
||||||
|
|
||||||
if has_pct != 0 {
|
|
||||||
pct[has_pct] = val[idx];
|
|
||||||
has_pct += 1;
|
|
||||||
if has_pct == 3 {
|
|
||||||
has_pct = 0;
|
|
||||||
let buf = cloned.as_mut().unwrap();
|
|
||||||
|
|
||||||
if let Some(ch) = restore_ch(pct[1], pct[2]) {
|
|
||||||
if ch < 128 {
|
|
||||||
if bit_at(&self.protected_table, ch) {
|
|
||||||
buf.extend_from_slice(&pct);
|
|
||||||
idx += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if bit_at(&self.safe_table, ch) {
|
|
||||||
buf.push(ch);
|
|
||||||
idx += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf.push(ch);
|
|
||||||
} else {
|
|
||||||
buf.extend_from_slice(&pct[..]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ch == b'%' {
|
|
||||||
has_pct = 1;
|
|
||||||
if cloned.is_none() {
|
|
||||||
let mut c = Vec::with_capacity(len);
|
|
||||||
c.extend_from_slice(&val[..idx]);
|
|
||||||
cloned = Some(c);
|
|
||||||
}
|
|
||||||
} else if let Some(ref mut cloned) = cloned {
|
|
||||||
cloned.push(ch)
|
|
||||||
}
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(data) = cloned {
|
|
||||||
// Unsafe: we get data from http::Uri, which does utf-8 checks already
|
|
||||||
// this code only decodes valid pct encoded values
|
|
||||||
Some(Rc::new(unsafe { String::from_utf8_unchecked(data) }))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_hex(v: u8) -> Option<u8> {
|
|
||||||
if v >= b'0' && v <= b'9' {
|
|
||||||
Some(v - 0x30) // ord('0') == 0x30
|
|
||||||
} else if v >= b'A' && v <= b'F' {
|
|
||||||
Some(v - 0x41 + 10) // ord('A') == 0x41
|
|
||||||
} else if v > b'a' && v <= b'f' {
|
|
||||||
Some(v - 0x61 + 10) // ord('a') == 0x61
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn restore_ch(d1: u8, d2: u8) -> Option<u8> {
|
|
||||||
from_hex(d1).and_then(|d1| from_hex(d2).and_then(move |d2| Some(d1 << 4 | d2)))
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user