Start dogfooding rust-url. Fix #1673.

This commit is contained in:
Simon Sapin 2014-07-16 00:01:47 +01:00
parent 71a869284e
commit dc49f4fda6
28 changed files with 101 additions and 223 deletions

View file

@ -95,6 +95,11 @@ DEPS_rust-url += \
rust-encoding \ rust-encoding \
$(NULL) $(NULL)
DEPS_rust-http += \
rust-encoding \
rust-url \
$(NULL)
# Platform-specific dependencies # Platform-specific dependencies
ifeq ($(CFG_OSTYPE),apple-darwin) ifeq ($(CFG_OSTYPE),apple-darwin)
DEPS_rust-azure += \ DEPS_rust-azure += \

View file

@ -37,7 +37,7 @@ extern crate servo_util = "util";
extern crate libc; extern crate libc;
extern crate time; extern crate time;
extern crate url; extern crate url = "url_";
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern crate core_graphics; extern crate core_graphics;

View file

@ -576,11 +576,11 @@ impl<LTF: LayoutTaskFactory> Constellation<LTF> {
let source_url = source_pipeline.url.clone(); let source_url = source_pipeline.url.clone();
let same_script = (source_url.host == url.host && let same_script = (source_url.host() == url.host() &&
source_url.port == url.port) && sandbox == IFrameUnsandboxed; source_url.port() == url.port()) && sandbox == IFrameUnsandboxed;
// FIXME(tkuehn): Need to follow the standardized spec for checking same-origin // FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
let pipeline = if same_script { let pipeline = if same_script {
debug!("Constellation: loading same-origin iframe at {:?}", url); debug!("Constellation: loading same-origin iframe at {}", url.serialize());
// Reuse the script task if same-origin url's // Reuse the script task if same-origin url's
Pipeline::with_script::<LTF>(next_pipeline_id, Pipeline::with_script::<LTF>(next_pipeline_id,
subpage_id, subpage_id,
@ -616,7 +616,7 @@ impl<LTF: LayoutTaskFactory> Constellation<LTF> {
} }
fn handle_load_url_msg(&mut self, source_id: PipelineId, url: Url) { fn handle_load_url_msg(&mut self, source_id: PipelineId, url: Url) {
debug!("Constellation: received message to load {:s}", url.to_str()); debug!("Constellation: received message to load {:s}", url.serialize());
// Make sure no pending page would be overridden. // Make sure no pending page would be overridden.
let source_frame = self.current_frame().get_ref().find(source_id).expect( let source_frame = self.current_frame().get_ref().find(source_id).expect(
"Constellation: received a LoadUrlMsg from a pipeline_id associated "Constellation: received a LoadUrlMsg from a pipeline_id associated

View file

@ -3,14 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use style::{Stylesheet, Stylist, UserAgentOrigin, with_errors_silenced}; use style::{Stylesheet, Stylist, UserAgentOrigin, with_errors_silenced};
use url; use url::Url;
pub fn new_stylist() -> Stylist { pub fn new_stylist() -> Stylist {
let mut stylist = Stylist::new(); let mut stylist = Stylist::new();
let ua_stylesheet = with_errors_silenced(|| Stylesheet::from_bytes( let ua_stylesheet = with_errors_silenced(|| Stylesheet::from_bytes(
include_bin!("user-agent.css"), include_bin!("user-agent.css"),
url::from_str("chrome:///user-agent.css").unwrap(), Url::parse("chrome:///user-agent.css").unwrap(),
None, None,
None)); None));
stylist.add_stylesheet(ua_stylesheet, UserAgentOrigin); stylist.add_stylesheet(ua_stylesheet, UserAgentOrigin);

View file

@ -33,7 +33,7 @@ extern crate collections;
extern crate green; extern crate green;
extern crate libc; extern crate libc;
extern crate sync; extern crate sync;
extern crate url; extern crate url = "url_";
pub mod block; pub mod block;
pub mod construct; pub mod construct;

View file

@ -563,7 +563,7 @@ impl LayoutTask {
mem::transmute(&mut node) mem::transmute(&mut node)
}; };
debug!("layout: received layout request for: {:s}", data.url.to_str()); debug!("layout: received layout request for: {:s}", data.url.serialize());
debug!("layout: damage is {:?}", data.damage); debug!("layout: damage is {:?}", data.damage);
debug!("layout: parsed Node tree"); debug!("layout: parsed Node tree");
debug!("{:?}", node.dump()); debug!("{:?}", node.dump());

View file

@ -26,7 +26,7 @@ extern crate gfx;
extern crate libc; extern crate libc;
extern crate native; extern crate native;
extern crate rustrt; extern crate rustrt;
extern crate url; extern crate url = "url_";
#[cfg(not(test))] #[cfg(not(test))]
use compositing::{CompositorChan, CompositorTask, Constellation}; use compositing::{CompositorChan, CompositorTask, Constellation};
@ -58,8 +58,6 @@ use std::os;
use std::str; use std::str;
#[cfg(not(test))] #[cfg(not(test))]
use rustrt::task::TaskOpts; use rustrt::task::TaskOpts;
#[cfg(not(test))]
use url::Url;
#[cfg(not(test), target_os="linux")] #[cfg(not(test), target_os="linux")]
@ -136,14 +134,7 @@ pub fn run(opts: opts::Opts) {
// Send the URL command to the constellation. // Send the URL command to the constellation.
for filename in opts.urls.iter() { for filename in opts.urls.iter() {
let url = if filename.as_slice().starts_with("data:") { let url = parse_url(filename.as_slice(), None);
// As a hack for easier command-line testing,
// assume that data URLs are not URL-encoded.
Url::new("data".to_string(), None, "".to_string(), None,
filename.as_slice().slice_from(5).to_string(), vec!(), None)
} else {
parse_url(filename.as_slice(), None)
};
let ConstellationChan(ref chan) = constellation_chan; let ConstellationChan(ref chan) = constellation_chan;
chan.send(InitLoadUrlMsg(url)); chan.send(InitLoadUrlMsg(url));

View file

@ -13,7 +13,7 @@ extern crate layers;
extern crate serialize; extern crate serialize;
extern crate servo_util = "util"; extern crate servo_util = "util";
extern crate std; extern crate std;
extern crate url; extern crate url = "url_";
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern crate core_foundation; extern crate core_foundation;

View file

@ -8,6 +8,8 @@ use serialize::base64::FromBase64;
use http::headers::test_utils::from_stream_with_str; use http::headers::test_utils::from_stream_with_str;
use http::headers::content_type::MediaType; use http::headers::content_type::MediaType;
use url::{percent_decode, OtherSchemeData};
pub fn factory() -> LoaderTask { pub fn factory() -> LoaderTask {
proc(url, start_chan) { proc(url, start_chan) {
@ -25,7 +27,18 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
let mut metadata = Metadata::default(url.clone()); let mut metadata = Metadata::default(url.clone());
// Split out content type and data. // Split out content type and data.
let parts: Vec<&str> = url.path.as_slice().splitn(',', 1).collect(); let mut scheme_data = match url.scheme_data {
OtherSchemeData(scheme_data) => scheme_data,
_ => fail!("Expected a non-relative scheme URL.")
};
match url.query {
Some(query) => {
scheme_data.push_str("?");
scheme_data.push_str(query.as_slice());
},
None => ()
}
let parts: Vec<&str> = scheme_data.as_slice().splitn(',', 1).collect();
if parts.len() != 2 { if parts.len() != 2 {
start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string()))); start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string())));
return; return;
@ -59,10 +72,9 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
} }
} }
} else { } else {
// FIXME: Since the %-decoded URL is already a str, we can't let mut bytes = Vec::new();
// handle UTF8-incompatible encodings. percent_decode(parts.get(1).as_bytes(), &mut bytes);
let bytes: &[u8] = (*parts.get(1)).as_bytes(); progress_chan.send(Payload(bytes));
progress_chan.send(Payload(bytes.iter().map(|&x| x).collect()));
progress_chan.send(Done(Ok(()))); progress_chan.send(Done(Ok(())));
} }
} }
@ -72,11 +84,11 @@ fn assert_parse(url: &'static str,
content_type: Option<(String, String)>, content_type: Option<(String, String)>,
charset: Option<String>, charset: Option<String>,
data: Option<Vec<u8>>) { data: Option<Vec<u8>>) {
use std::from_str::FromStr;
use std::comm; use std::comm;
use url::Url;
let (start_chan, start_port) = comm::channel(); let (start_chan, start_port) = comm::channel();
load(LoadData::new(FromStr::from_str(url).unwrap()), start_chan); load(LoadData::new(Url::parse(url).unwrap()), start_chan);
let response = start_port.recv(); let response = start_port.recv();
assert_eq!(&response.metadata.content_type, &content_type); assert_eq!(&response.metadata.content_type, &content_type);

View file

@ -31,7 +31,7 @@ pub fn factory() -> LoaderTask {
assert!("file" == url.scheme.as_slice()); assert!("file" == url.scheme.as_slice());
let progress_chan = start_sending(start_chan, Metadata::default(url.clone())); let progress_chan = start_sending(start_chan, Metadata::default(url.clone()));
spawn_named("file_loader", proc() { spawn_named("file_loader", proc() {
match File::open_mode(&Path::new(url.path), io::Open, io::Read) { match File::open_mode(&Path::new(url.serialize_path().unwrap()), io::Open, io::Read) {
Ok(ref mut reader) => { Ok(ref mut reader) => {
let res = read_all(reader as &mut io::Stream, &progress_chan); let res = read_all(reader as &mut io::Stream, &progress_chan);
progress_chan.send(Done(res)); progress_chan.send(Done(res));

View file

@ -56,7 +56,7 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
return; return;
} }
info!("requesting {:s}", url.to_str()); info!("requesting {:s}", url.serialize());
let request = RequestWriter::<NetworkStream>::new(load_data.method.clone(), url.clone()); let request = RequestWriter::<NetworkStream>::new(load_data.method.clone(), url.clone());
let mut writer = match request { let mut writer = match request {
@ -106,7 +106,7 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
if 3 == (response.status.code() / 100) { if 3 == (response.status.code() / 100) {
match response.headers.location { match response.headers.location {
Some(new_url) => { Some(new_url) => {
info!("redirecting to {:s}", new_url.to_str()); info!("redirecting to {:s}", new_url.serialize());
url = new_url; url = new_url;
continue; continue;
} }

View file

@ -27,7 +27,7 @@ pub struct ImageHolder {
impl ImageHolder { impl ImageHolder {
pub fn new(url: Url, local_image_cache: Arc<Mutex<LocalImageCache>>) -> ImageHolder { pub fn new(url: Url, local_image_cache: Arc<Mutex<LocalImageCache>>) -> ImageHolder {
debug!("ImageHolder::new() {}", url.to_str()); debug!("ImageHolder::new() {}", url.serialize());
let holder = ImageHolder { let holder = ImageHolder {
url: url, url: url,
image: None, image: None,
@ -61,7 +61,7 @@ impl ImageHolder {
/// Query and update the current image size. /// Query and update the current image size.
pub fn get_size(&mut self) -> Option<Size2D<int>> { pub fn get_size(&mut self) -> Option<Size2D<int>> {
debug!("get_size() {}", self.url.to_str()); debug!("get_size() {}", self.url.serialize());
self.get_image().map(|img| { self.get_image().map(|img| {
self.cached_size = Size2D(img.width as int, self.cached_size = Size2D(img.width as int,
img.height as int); img.height as int);
@ -70,12 +70,12 @@ impl ImageHolder {
} }
pub fn get_image_if_present(&self) -> Option<Arc<Box<Image>>> { pub fn get_image_if_present(&self) -> Option<Arc<Box<Image>>> {
debug!("get_image_if_present() {}", self.url.to_str()); debug!("get_image_if_present() {}", self.url.serialize());
self.image.clone() self.image.clone()
} }
pub fn get_image(&mut self) -> Option<Arc<Box<Image>>> { pub fn get_image(&mut self) -> Option<Arc<Box<Image>>> {
debug!("get_image() {}", self.url.to_str()); debug!("get_image() {}", self.url.serialize());
// If this is the first time we've called this function, load // If this is the first time we've called this function, load
// the image and store it for the future // the image and store it for the future
@ -90,10 +90,10 @@ impl ImageHolder {
self.image = Some(image); self.image = Some(image);
} }
ImageNotReady => { ImageNotReady => {
debug!("image not ready for {:s}", self.url.to_str()); debug!("image not ready for {:s}", self.url.serialize());
} }
ImageFailed => { ImageFailed => {
debug!("image decoding failed for {:s}", self.url.to_str()); debug!("image decoding failed for {:s}", self.url.serialize());
} }
} }
} }

View file

@ -10,7 +10,6 @@ use servo_util::url::{UrlMap, url_map};
use std::comm::{channel, Receiver, Sender}; use std::comm::{channel, Receiver, Sender};
use std::mem::replace; use std::mem::replace;
use std::task::spawn; use std::task::spawn;
use std::to_str::ToStr;
use std::result; use std::result;
use sync::{Arc, Mutex}; use sync::{Arc, Mutex};
use serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
@ -248,7 +247,7 @@ impl ImageCache {
spawn(proc() { spawn(proc() {
let url = url_clone; let url = url_clone;
debug!("image_cache_task: started fetch for {:s}", url.to_str()); debug!("image_cache_task: started fetch for {:s}", url.serialize());
let image = load_image_data(url.clone(), resource_task.clone()); let image = load_image_data(url.clone(), resource_task.clone());
@ -258,7 +257,7 @@ impl ImageCache {
Err(()) Err(())
}; };
to_cache.send(StorePrefetchedImageData(url.clone(), result)); to_cache.send(StorePrefetchedImageData(url.clone(), result));
debug!("image_cache_task: ended fetch for {:s}", (url.clone()).to_str()); debug!("image_cache_task: ended fetch for {:s}", url.serialize());
}); });
self.set_state(url, Prefetching(DoNotDecode)); self.set_state(url, Prefetching(DoNotDecode));
@ -317,7 +316,7 @@ impl ImageCache {
spawn(proc() { spawn(proc() {
let url = url_clone; let url = url_clone;
debug!("image_cache_task: started image decode for {:s}", url.to_str()); debug!("image_cache_task: started image decode for {:s}", url.serialize());
let image = load_from_memory(data.as_slice()); let image = load_from_memory(data.as_slice());
let image = if image.is_some() { let image = if image.is_some() {
Some(Arc::new(box image.unwrap())) Some(Arc::new(box image.unwrap()))
@ -325,7 +324,7 @@ impl ImageCache {
None None
}; };
to_cache.send(StoreImage(url.clone(), image)); to_cache.send(StoreImage(url.clone(), image));
debug!("image_cache_task: ended image decode for {:s}", url.to_str()); debug!("image_cache_task: ended image decode for {:s}", url.serialize());
}); });
self.set_state(url, Decoding); self.set_state(url, Decoding);

View file

@ -20,7 +20,7 @@ extern crate serialize;
extern crate servo_util = "util"; extern crate servo_util = "util";
extern crate stb_image; extern crate stb_image;
extern crate sync; extern crate sync;
extern crate url; extern crate url = "url_";
/// Image handling. /// Image handling.
/// ///

View file

@ -19,8 +19,6 @@ use url::Url;
use StatusOk = http::status::Ok; use StatusOk = http::status::Ok;
use http::status::Status; use http::status::Status;
#[cfg(test)]
use std::from_str::FromStr;
pub enum ControlMsg { pub enum ControlMsg {
/// Request the data associated with a particular URL /// Request the data associated with a particular URL
@ -220,7 +218,7 @@ impl ResourceManager {
fn load(&self, load_data: LoadData, start_chan: Sender<LoadResponse>) { fn load(&self, load_data: LoadData, start_chan: Sender<LoadResponse>) {
match self.get_loader_factory(&load_data) { match self.get_loader_factory(&load_data) {
Some(loader_factory) => { Some(loader_factory) => {
debug!("resource_task: loading url: {:s}", load_data.url.to_str()); debug!("resource_task: loading url: {:s}", load_data.url.serialize());
loader_factory(load_data, start_chan); loader_factory(load_data, start_chan);
} }
None => { None => {
@ -254,7 +252,8 @@ fn test_exit() {
fn test_bad_scheme() { fn test_bad_scheme() {
let resource_task = new_resource_task(); let resource_task = new_resource_task();
let (start_chan, start) = channel(); let (start_chan, start) = channel();
resource_task.send(Load(LoadData::new(FromStr::from_str("bogus://whatever").unwrap()), start_chan)); let url = Url::parse("bogus://whatever").unwrap();
resource_task.send(Load(LoadData::new(url), start_chan));
let response = start.recv(); let response = start.recv();
match response.progress_port.recv() { match response.progress_port.recv() {
Done(result) => { assert!(result.is_err()) } Done(result) => { assert!(result.is_err()) }
@ -281,7 +280,8 @@ fn should_delegate_to_scheme_loader() {
let loader_factories = vec!(("snicklefritz".to_string(), snicklefritz_loader_factory)); let loader_factories = vec!(("snicklefritz".to_string(), snicklefritz_loader_factory));
let resource_task = create_resource_task_with_loaders(loader_factories); let resource_task = create_resource_task_with_loaders(loader_factories);
let (start_chan, start) = channel(); let (start_chan, start) = channel();
resource_task.send(Load(LoadData::new(FromStr::from_str("snicklefritz://heya").unwrap()), start_chan)); let url = Url::parse("snicklefritz://heya").unwrap();
resource_task.send(Load(LoadData::new(url), start_chan));
let response = start.recv(); let response = start.recv();
let progress = response.progress_port; let progress = response.progress_port;

View file

@ -67,14 +67,15 @@ impl DedicatedWorkerGlobalScope {
resource_task: ResourceTask, resource_task: ResourceTask,
script_chan: ScriptChan) { script_chan: ScriptChan) {
let mut task_opts = TaskOpts::new(); let mut task_opts = TaskOpts::new();
task_opts.name = Some(format!("Web Worker at {}", worker_url).into_maybe_owned()); task_opts.name = Some(format!("Web Worker at {}", worker_url.serialize())
.into_maybe_owned());
native::task::spawn_opts(task_opts, proc() { native::task::spawn_opts(task_opts, proc() {
let roots = RootCollection::new(); let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots); let _stack_roots_tls = StackRootTLS::new(&roots);
let (filename, source) = match load_whole_resource(&resource_task, worker_url.clone()) { let (url, source) = match load_whole_resource(&resource_task, worker_url.clone()) {
Err(_) => { Err(_) => {
println!("error loading script {}", worker_url); println!("error loading script {}", worker_url.serialize());
return; return;
} }
Ok((metadata, bytes)) => { Ok((metadata, bytes)) => {
@ -87,7 +88,7 @@ impl DedicatedWorkerGlobalScope {
worker_url, js_context.clone(), receiver, resource_task, worker_url, js_context.clone(), receiver, resource_task,
script_chan).root(); script_chan).root();
match js_context.evaluate_script( match js_context.evaluate_script(
global.reflector().get_jsobject(), source, filename.to_str(), 1) { global.reflector().get_jsobject(), source, url.serialize(), 1) {
Ok(_) => (), Ok(_) => (),
Err(_) => println!("evaluate_script failed") Err(_) => println!("evaluate_script failed")
} }

View file

@ -50,7 +50,7 @@ use servo_util::str::{DOMString, null_str_as_empty_ref};
use std::collections::hashmap::HashMap; use std::collections::hashmap::HashMap;
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use url::{Url, from_str}; use url::Url;
#[deriving(PartialEq,Encodable)] #[deriving(PartialEq,Encodable)]
pub enum IsHTMLDocument { pub enum IsHTMLDocument {
@ -196,7 +196,7 @@ impl Document {
url: Option<Url>, url: Option<Url>,
is_html_document: IsHTMLDocument, is_html_document: IsHTMLDocument,
content_type: Option<DOMString>) -> Document { content_type: Option<DOMString>) -> Document {
let url = url.unwrap_or_else(|| from_str("about:blank").unwrap()); let url = url.unwrap_or_else(|| Url::parse("about:blank").unwrap());
Document { Document {
node: Node::new_without_doc(DocumentNodeTypeId), node: Node::new_without_doc(DocumentNodeTypeId),
@ -337,7 +337,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
// http://dom.spec.whatwg.org/#dom-document-url // http://dom.spec.whatwg.org/#dom-document-url
fn URL(&self) -> DOMString { fn URL(&self) -> DOMString {
self.url().to_str() self.url().serialize()
} }
// http://dom.spec.whatwg.org/#dom-document-documenturi // http://dom.spec.whatwg.org/#dom-document-documenturi

View file

@ -171,7 +171,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
scope: *mut JSObject, scope: *mut JSObject,
ty: &str, ty: &str,
source: DOMString) { source: DOMString) {
let url = url.to_str().to_c_str(); let url = url.serialize().to_c_str();
let name = ty.to_c_str(); let name = ty.to_c_str();
let lineno = 0; //XXXjdm need to get a real number here let lineno = 0; //XXXjdm need to get a real number here

View file

@ -13,7 +13,6 @@ use servo_util::str::DOMString;
use serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
use std::rc::Rc; use std::rc::Rc;
use url::query_to_str;
#[deriving(Encodable)] #[deriving(Encodable)]
pub struct Location { pub struct Location {
@ -43,15 +42,13 @@ pub trait LocationMethods {
impl<'a> LocationMethods for JSRef<'a, Location> { impl<'a> LocationMethods for JSRef<'a, Location> {
fn Href(&self) -> DOMString { fn Href(&self) -> DOMString {
self.page.get_url().to_str() self.page.get_url().serialize()
} }
fn Search(&self) -> DOMString { fn Search(&self) -> DOMString {
let query = query_to_str(&self.page.get_url().query); match self.page.get_url().query {
if query.as_slice() == "" { None => "".to_string(),
query Some(ref query) => "?".to_string().append(query.as_slice())
} else {
"?".to_string().append(query.as_slice())
} }
} }
} }

View file

@ -25,7 +25,7 @@ use dom::xmlhttprequestupload::XMLHttpRequestUpload;
use encoding::all::UTF_8; use encoding::all::UTF_8;
use encoding::label::encoding_from_whatwg_label; use encoding::label::encoding_from_whatwg_label;
use encoding::types::{DecodeReplace, Encoding, EncodeReplace}; use encoding::types::{DecodeReplace, Encoding, EncodingRef, EncodeReplace};
use ResponseHeaderCollection = http::headers::response::HeaderCollection; use ResponseHeaderCollection = http::headers::response::HeaderCollection;
use RequestHeaderCollection = http::headers::request::HeaderCollection; use RequestHeaderCollection = http::headers::request::HeaderCollection;
@ -517,16 +517,8 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
// XXXManishearth this is to be replaced with Origin for CORS (with no path) // XXXManishearth this is to be replaced with Origin for CORS (with no path)
let referer_url = self.global.root().root_ref().get_url(); let referer_url = self.global.root().root_ref().get_url();
let mut buf = String::new(); self.request_headers.deref().borrow_mut().referer =
buf.push_str(referer_url.scheme.as_slice()); Some(referer_url.serialize_no_fragment());
buf.push_str("://".as_slice());
buf.push_str(referer_url.host.as_slice());
referer_url.port.as_ref().map(|p| {
buf.push_str(":".as_slice());
buf.push_str(p.as_slice());
});
buf.push_str(referer_url.path.as_slice());
self.request_headers.deref().borrow_mut().referer = Some(buf);
load_data.headers = (*self.request_headers.deref().borrow()).clone(); load_data.headers = (*self.request_headers.deref().borrow()).clone();
load_data.method = (*self.request_method.deref().borrow()).clone(); load_data.method = (*self.request_method.deref().borrow()).clone();
@ -910,7 +902,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> {
self.timer.deref().borrow_mut().oneshot(0); self.timer.deref().borrow_mut().oneshot(0);
} }
fn text_response(&self) -> DOMString { fn text_response(&self) -> DOMString {
let mut encoding = UTF_8 as &Encoding+Send; let mut encoding = UTF_8 as EncodingRef;
match self.response_headers.deref().borrow().content_type { match self.response_headers.deref().borrow().content_type {
Some(ref x) => { Some(ref x) => {
for &(ref name, ref value) in x.parameters.iter() { for &(ref name, ref value) in x.parameters.iter() {
@ -945,7 +937,7 @@ trait Extractable {
impl Extractable for SendParam { impl Extractable for SendParam {
fn extract(&self) -> Vec<u8> { fn extract(&self) -> Vec<u8> {
// http://fetch.spec.whatwg.org/#concept-fetchbodyinit-extract // http://fetch.spec.whatwg.org/#concept-fetchbodyinit-extract
let encoding = UTF_8 as &Encoding+Send; let encoding = UTF_8 as EncodingRef;
match *self { match *self {
eString(ref s) => encoding.encode(s.as_slice(), EncodeReplace).unwrap(), eString(ref s) => encoding.encode(s.as_slice(), EncodeReplace).unwrap(),
eURLSearchParams(ref usp) => usp.root().serialize(None) // Default encoding is UTF8 eURLSearchParams(ref usp) => usp.root().serialize(None) // Default encoding is UTF8

View file

@ -29,7 +29,7 @@ fn parse_css(provenance: StylesheetProvenance) -> Stylesheet {
match provenance { match provenance {
UrlProvenance(url, resource_task) => { UrlProvenance(url, resource_task) => {
debug!("cssparse: loading style sheet at {:s}", url.to_str()); debug!("cssparse: loading style sheet at {:s}", url.serialize());
let (input_chan, input_port) = channel(); let (input_chan, input_port) = channel();
resource_task.send(Load(LoadData::new(url), input_chan)); resource_task.send(Load(LoadData::new(url), input_chan));
let LoadResponse { metadata: metadata, progress_port: progress_port , ..} let LoadResponse { metadata: metadata, progress_port: progress_port , ..}

View file

@ -133,7 +133,7 @@ fn js_script_listener(to_parent: Sender<HtmlDiscoveryMessage>,
Ok(JSTaskNewFile(url)) => { Ok(JSTaskNewFile(url)) => {
match load_whole_resource(&resource_task, url.clone()) { match load_whole_resource(&resource_task, url.clone()) {
Err(_) => { Err(_) => {
error!("error loading script {:s}", url.to_str()); error!("error loading script {:s}", url.serialize());
} }
Ok((metadata, bytes)) => { Ok((metadata, bytes)) => {
result_vec.push(JSFile { result_vec.push(JSFile {
@ -541,7 +541,7 @@ pub fn parse_html(page: &Page,
parser.parse_chunk(data.as_slice()); parser.parse_chunk(data.as_slice());
} }
Done(Err(err)) => { Done(Err(err)) => {
fail!("Failed to load page URL {:s}, error: {:s}", url.to_str(), err); fail!("Failed to load page URL {:s}, error: {:s}", url.serialize(), err);
} }
Done(..) => { Done(..) => {
break; break;

View file

@ -40,7 +40,7 @@ extern crate servo_util = "util";
extern crate style; extern crate style;
extern crate sync; extern crate sync;
extern crate servo_msg = "msg"; extern crate servo_msg = "msg";
extern crate url; extern crate url = "url_";
pub mod dom { pub mod dom {
pub mod bindings { pub mod bindings {

View file

@ -590,7 +590,7 @@ impl ScriptTask {
let global_obj = window.reflector().get_jsobject(); let global_obj = window.reflector().get_jsobject();
//FIXME: this should have some kind of error handling, or explicitly //FIXME: this should have some kind of error handling, or explicitly
// drop an exception on the floor. // drop an exception on the floor.
match cx.evaluate_script(global_obj, file.data.clone(), file.url.to_str(), 1) { match cx.evaluate_script(global_obj, file.data.clone(), file.url.serialize(), 1) {
Ok(_) => (), Ok(_) => (),
Err(_) => println!("evaluate_script failed") Err(_) => println!("evaluate_script failed")
} }

View file

@ -21,7 +21,7 @@ extern crate geom;
extern crate num; extern crate num;
extern crate serialize; extern crate serialize;
extern crate sync; extern crate sync;
extern crate url; extern crate url = "url_";
extern crate cssparser; extern crate cssparser;
extern crate encoding; extern crate encoding;

View file

@ -4,8 +4,8 @@
use std::collections::hashmap::HashMap; use std::collections::hashmap::HashMap;
use std::os; use std::os;
use std_url; use rust_url;
use std_url::Url; use rust_url::{Url, UrlParser};
/** /**
Create a URL object from a string. Does various helpful browsery things like Create a URL object from a string. Does various helpful browsery things like
@ -17,11 +17,14 @@ Create a URL object from a string. Does various helpful browsery things like
*/ */
// TODO: about:failure-> // TODO: about:failure->
pub fn try_parse_url(str_url: &str, base_url: Option<std_url::Url>) -> Result<std_url::Url, String> { pub fn try_parse_url(str_url: &str, base_url: Option<Url>) -> Result<Url, &'static str> {
let str_url = str_url.trim_chars(&[' ', '\t', '\n', '\r', '\x0C']).to_string(); let mut parser = UrlParser::new();
let schm = std_url::get_scheme(str_url.as_slice()); let parser = match base_url {
let str_url = match schm { Some(ref base) => &*parser.base_url(base),
Err(_) => { None => &parser,
};
let str_url = match parser.parse(str_url) {
Err(err) => {
if base_url.is_none() { if base_url.is_none() {
// Assume we've been given a file path. If it's absolute just return // Assume we've been given a file path. If it's absolute just return
// it, otherwise make it absolute with the cwd. // it, otherwise make it absolute with the cwd.
@ -34,31 +37,13 @@ pub fn try_parse_url(str_url: &str, base_url: Option<std_url::Url>) -> Result<st
format!("file://{}", path.display().to_str()) format!("file://{}", path.display().to_str())
} }
} else { } else {
let base_url = base_url.unwrap(); return Err(err)
debug!("parse_url: base_url: {:?}", base_url);
let mut new_url = base_url.clone();
new_url.query = vec!();
new_url.fragment = None;
if str_url.as_slice().starts_with("//") {
format!("{}:{}", new_url.scheme, str_url)
} else if base_url.path.is_empty() || str_url.as_slice().starts_with("/") {
new_url.path = "/".to_string();
format!("{}{}", new_url, str_url.as_slice().trim_left_chars('/'))
} else if str_url.as_slice().starts_with("#") {
format!("{}{}", new_url, str_url)
} else { // relative path
let base_path = base_url.path.as_slice().trim_right_chars(|c: char| c != '/');
new_url.path = base_path.to_string();
format!("{}{}", new_url, str_url)
}
} }
}, },
Ok((scheme, page)) => { Ok(url) => {
match scheme.as_slice() { match (url.scheme.as_slice(), url.scheme_data.clone()) {
"about" => { ("about", rust_url::OtherSchemeData(scheme_data)) => {
match page.as_slice() { match scheme_data.as_slice() {
"crash" => { "crash" => {
fail!("about:crash"); fail!("about:crash");
} }
@ -72,130 +57,26 @@ pub fn try_parse_url(str_url: &str, base_url: Option<std_url::Url>) -> Result<st
_ => str_url.to_string() _ => str_url.to_string()
} }
}, },
"data" => { ("data", _) => {
// Drop whitespace within data: URLs, e.g. newlines within a base64 // Drop whitespace within data: URLs, e.g. newlines within a base64
// src="..." block. Whitespace intended as content should be // src="..." block. Whitespace intended as content should be
// %-encoded or base64'd. // %-encoded or base64'd.
str_url.as_slice().chars().filter(|&c| !c.is_whitespace()).collect() str_url.as_slice().chars().filter(|&c| !c.is_whitespace()).collect()
}, },
_ => str_url.to_string() _ => return Ok(url)
} }
} }
}; };
parser.parse(str_url.as_slice())
std_url::from_str(str_url.as_slice())
} }
pub fn parse_url(str_url: &str, base_url: Option<std_url::Url>) -> std_url::Url { pub fn parse_url(str_url: &str, base_url: Option<rust_url::Url>) -> rust_url::Url {
// FIXME: Need to handle errors // FIXME: Need to handle errors
try_parse_url(str_url, base_url).ok().expect("URL parsing failed") try_parse_url(str_url, base_url).ok().expect("URL parsing failed")
} }
#[cfg(test)] pub type UrlMap<T> = HashMap<rust_url::Url, T>;
mod parse_url_tests {
use super::parse_url;
use std::os;
#[test]
fn should_create_absolute_file_url_if_base_url_is_none_and_str_url_looks_filey() {
let file = "local.html";
let url = parse_url(file, None);
debug!("url: {:?}", url);
assert!("file" == url.scheme.as_slice());
let path = os::getcwd();
// FIXME (#1094): not the right way to transform a path
assert!(url.path.as_slice().contains(path.display().to_str().as_slice()));
}
#[test]
fn should_create_url_based_on_old_url_1() {
let old_str = "http://example.com";
let old_url = parse_url(old_str, None);
let new_str = "index.html";
let new_url = parse_url(new_str, Some(old_url));
assert!("http" == new_url.scheme.as_slice());
assert!("example.com" == new_url.host.as_slice());
assert!("/index.html" == new_url.path.as_slice());
}
#[test]
fn should_create_url_based_on_old_url_2() {
let old_str = "http://example.com/";
let old_url = parse_url(old_str, None);
let new_str = "index.html";
let new_url = parse_url(new_str, Some(old_url));
assert!("http" == new_url.scheme.as_slice());
assert!("example.com" == new_url.host.as_slice());
assert!("/index.html" == new_url.path.as_slice());
}
#[test]
fn should_create_url_based_on_old_url_3() {
let old_str = "http://example.com/index.html";
let old_url = parse_url(old_str, None);
let new_str = "crumpet.html";
let new_url = parse_url(new_str, Some(old_url));
assert!("http" == new_url.scheme.as_slice());
assert!("example.com" == new_url.host.as_slice());
assert!("/crumpet.html" == new_url.path.as_slice());
}
#[test]
fn should_create_url_based_on_old_url_4() {
let old_str = "http://example.com/snarf/index.html";
let old_url = parse_url(old_str, None);
let new_str = "crumpet.html";
let new_url = parse_url(new_str, Some(old_url));
assert!("http" == new_url.scheme.as_slice());
assert!("example.com" == new_url.host.as_slice());
assert!("/snarf/crumpet.html" == new_url.path.as_slice());
}
#[test]
fn should_create_url_based_on_old_url_5() {
let old_str = "http://example.com/index.html";
let old_url = parse_url(old_str, None);
let new_str = "#top";
let new_url = parse_url(new_str, Some(old_url));
assert!("http" == new_url.scheme.as_slice());
assert!("example.com" == new_url.host.as_slice());
assert!("/index.html" == new_url.path.as_slice());
assert!(new_url.fragment == Some("top".to_string()));
}
#[test]
fn should_create_url_based_on_old_url_6() {
use std_url::UserInfo;
let old_str = "http://foo:bar@example.com:8080/index.html";
let old_url = parse_url(old_str, None);
let new_str = "#top";
let new_url = parse_url(new_str, Some(old_url));
assert!("http" == new_url.scheme.as_slice());
assert!(new_url.user == Some(UserInfo { user: "foo".to_string(), pass: Some("bar".to_string()) }));
assert!("example.com" == new_url.host.as_slice());
assert!(new_url.port == Some("8080".to_string()));
assert!("/index.html" == new_url.path.as_slice());
assert!(new_url.fragment == Some("top".to_string()));
}
#[test]
fn should_create_url_based_on_old_url_7() {
let old_str = "https://example.com/snarf/index.html";
let old_url = parse_url(old_str, None);
let new_str = "//example.com/crumpet.html";
let new_url = parse_url(new_str, Some(old_url));
assert!("https" == new_url.scheme.as_slice());
assert!("example.com" == new_url.host.as_slice());
assert!("/crumpet.html" == new_url.path.as_slice());
}
}
pub type UrlMap<T> = HashMap<std_url::Url, T>;
pub fn url_map<T: Clone + 'static>() -> UrlMap<T> { pub fn url_map<T: Clone + 'static>() -> UrlMap<T> {
HashMap::new() HashMap::new()

View file

@ -28,7 +28,7 @@ extern crate sync;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern crate task_info; extern crate task_info;
extern crate std_time = "time"; extern crate std_time = "time";
extern crate std_url = "url"; extern crate rust_url = "url_";
extern crate string_cache; extern crate string_cache;
pub mod atom; pub mod atom;

@ -1 +1 @@
Subproject commit ae4820bfd19af931bfc84f406b74dfb67ab5ebe8 Subproject commit e95cdaef5f366d9911e6d06340b79b8d23245b7b