refactor(uri): Remove Url parse
Remove usage of Url parse in Uri in order to improve performance. https://github.com/hyperium/hyper/issues/1022
This commit is contained in:
		
							
								
								
									
										71
									
								
								src/uri.rs
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								src/uri.rs
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | |||||||
| use std::borrow::Cow; | use std::borrow::Cow; | ||||||
| use std::fmt::{Display, self}; | use std::fmt::{Display, self}; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use url::{self, Url}; | use url::Url; | ||||||
| use url::ParseError as UrlError; | use url::ParseError as UrlError; | ||||||
|  |  | ||||||
| use Error; | use Error; | ||||||
| @@ -54,43 +54,21 @@ impl Uri { | |||||||
|         } else if bytes == b"/" { |         } else if bytes == b"/" { | ||||||
|             Ok(Uri::default()) |             Ok(Uri::default()) | ||||||
|         } else if bytes.starts_with(b"/") { |         } else if bytes.starts_with(b"/") { | ||||||
|             let mut temp = "http://example.com".to_owned(); |  | ||||||
|             temp.push_str(s); |  | ||||||
|             let url = try!(Url::parse(&temp)); |  | ||||||
|             let query_len = url.query().unwrap_or("").len(); |  | ||||||
|             let fragment_len = url.fragment().unwrap_or("").len(); |  | ||||||
|             Ok(Uri { |             Ok(Uri { | ||||||
|                 source: s.to_owned().into(), |                 source: s.to_owned().into(), | ||||||
|                 scheme_end: None, |                 scheme_end: None, | ||||||
|                 authority_end: None, |                 authority_end: None, | ||||||
|                 query: if query_len > 0 { Some(query_len) } else { None }, |                 query: parse_query(s), | ||||||
|                 fragment: if fragment_len > 0 { Some(fragment_len) } else { None }, |                 fragment: parse_fragment(s), | ||||||
|             }) |             }) | ||||||
|         } else if s.contains("://") { |         } else if s.contains("://") { | ||||||
|             let url = try!(Url::parse(s)); |  | ||||||
|             let query_len = url.query().unwrap_or("").len(); |  | ||||||
|             let new_s = url.to_string(); |  | ||||||
|             let authority_end = { |  | ||||||
|                 let v: Vec<&str> = new_s.split("://").collect(); |  | ||||||
|                 v.last().unwrap() |  | ||||||
|                         .split(url.path()) |  | ||||||
|                         .next() |  | ||||||
|                         .unwrap_or(&new_s) |  | ||||||
|                         .len() + if v.len() == 2 { v[0].len() + 3 } else { 0 } |  | ||||||
|             }; |  | ||||||
|             let fragment_len = url.fragment().unwrap_or("").len(); |  | ||||||
|             match url.origin() { |  | ||||||
|                 url::Origin::Opaque(_) => Err(Error::Method), |  | ||||||
|                 url::Origin::Tuple(scheme, _, _) => { |  | ||||||
|             Ok(Uri { |             Ok(Uri { | ||||||
|                         source: new_s.into(), |                 source: s.to_owned().into(), | ||||||
|                         scheme_end: Some(scheme.len()), |                 scheme_end: parse_scheme(s), | ||||||
|                         authority_end: if authority_end > 0 { Some(authority_end) } else { None }, |                 authority_end: parse_authority(s), | ||||||
|                         query: if query_len > 0 { Some(query_len) } else { None }, |                 query: parse_query(s), | ||||||
|                         fragment: if fragment_len > 0 { Some(fragment_len) } else { None }, |                 fragment: parse_fragment(s), | ||||||
|             }) |             }) | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } else { |         } else { | ||||||
|             Ok(Uri { |             Ok(Uri { | ||||||
|                 source: s.to_owned().into(), |                 source: s.to_owned().into(), | ||||||
| @@ -179,6 +157,39 @@ impl Uri { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | fn parse_scheme(s: &str) -> Option<usize> { | ||||||
|  |     s.find(':') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn parse_authority(s: &str) -> Option<usize> { | ||||||
|  |     let v: Vec<&str> = s.split("://").collect(); | ||||||
|  |     let auth = v.last().unwrap() | ||||||
|  |         .split("/") | ||||||
|  |         .next() | ||||||
|  |         .unwrap_or(s) | ||||||
|  |         .len() + if v.len() == 2 { v[0].len() + 3 } else { 0 }; | ||||||
|  |         | ||||||
|  |     return Some(auth); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn parse_query(s: &str) -> Option<usize> { | ||||||
|  |     match s.find('?') { | ||||||
|  |         Some(i) => { | ||||||
|  |             let frag_pos = s.find('#').unwrap_or(s.len()); | ||||||
|  |  | ||||||
|  |             return Some(frag_pos - i - 1); | ||||||
|  |         }, | ||||||
|  |         None => None, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn parse_fragment(s: &str) -> Option<usize> { | ||||||
|  |     match s.find('#') { | ||||||
|  |         Some(i) => Some(s.len() - i - 1), | ||||||
|  |         None => None, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| impl FromStr for Uri { | impl FromStr for Uri { | ||||||
|     type Err = Error; |     type Err = Error; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user