mirror of
https://github.com/servo/servo.git
synced 2025-06-21 07:38:59 +01:00
auto merge of #977 : kmcallister/servo/redirect, r=jdm
This commit is contained in:
commit
b7d186dec2
6 changed files with 90 additions and 41 deletions
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* 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 resource_task::{ProgressMsg, Payload, Done, LoaderTask};
|
use resource_task::{ProgressMsg, Payload, Done, UrlChange, LoaderTask};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
@ -22,7 +22,7 @@ pub fn factory() -> LoaderTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(url: Url, progress_chan: Chan<ProgressMsg>) {
|
fn load(url: Url, progress_chan: Chan<ProgressMsg>) {
|
||||||
assert!(url.scheme == ~"http");
|
assert!("http" == url.scheme);
|
||||||
|
|
||||||
info!("requesting %s", url.to_str());
|
info!("requesting %s", url.to_str());
|
||||||
|
|
||||||
|
@ -35,8 +35,27 @@ fn load(url: Url, progress_chan: Chan<ProgressMsg>) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
info!("got HTTP response %s, headers:", response.status.to_str())
|
||||||
|
|
||||||
|
let is_redirect = 3 == (response.status.code() / 100);
|
||||||
|
let mut redirect: Option<Url> = None;
|
||||||
for header in response.headers.iter() {
|
for header in response.headers.iter() {
|
||||||
info!(" - %s: %s", header.header_name(), header.header_value());
|
let name = header.header_name();
|
||||||
|
let value = header.header_value();
|
||||||
|
info!(" - %s: %s", name, value);
|
||||||
|
if is_redirect && ("Location" == name) {
|
||||||
|
redirect = Some(FromStr::from_str(value).expect("Failed to parse redirect URL"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: detect redirect loops
|
||||||
|
match redirect {
|
||||||
|
Some(url) => {
|
||||||
|
info!("redirecting to %s", url.to_str());
|
||||||
|
progress_chan.send(UrlChange(url.clone()));
|
||||||
|
return load(url, progress_chan);
|
||||||
|
}
|
||||||
|
None => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -444,6 +444,7 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match response_port.recv() {
|
match response_port.recv() {
|
||||||
|
resource_task::UrlChange(*) => (), // don't care that URL changed
|
||||||
resource_task::Payload(data) => {
|
resource_task::Payload(data) => {
|
||||||
image_data.push_all(data);
|
image_data.push_all(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,9 @@ pub enum ControlMsg {
|
||||||
/// Messages sent in response to a `Load` message
|
/// Messages sent in response to a `Load` message
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
pub enum ProgressMsg {
|
pub enum ProgressMsg {
|
||||||
|
/// URL changed due to a redirect. There can be zero or more of these,
|
||||||
|
/// but they are guaranteed to arrive before messages of any other type.
|
||||||
|
UrlChange(Url),
|
||||||
/// Binary data - there may be multiple of these
|
/// Binary data - there may be multiple of these
|
||||||
Payload(~[u8]),
|
Payload(~[u8]),
|
||||||
/// Indicates loading is complete, either successfully or not
|
/// Indicates loading is complete, either successfully or not
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::comm::Port;
|
||||||
use std::task;
|
use std::task;
|
||||||
use newcss::stylesheet::Stylesheet;
|
use newcss::stylesheet::Stylesheet;
|
||||||
use newcss::util::DataStream;
|
use newcss::util::DataStream;
|
||||||
use servo_net::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
|
use servo_net::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done, UrlChange};
|
||||||
use extra::url::Url;
|
use extra::url::Url;
|
||||||
|
|
||||||
/// Where a style sheet comes from.
|
/// Where a style sheet comes from.
|
||||||
|
@ -57,10 +57,19 @@ fn data_stream(provenance: StylesheetProvenance, resource_task: ResourceTask) ->
|
||||||
|
|
||||||
fn resource_port_to_data_stream(input_port: Port<ProgressMsg>) -> DataStream {
|
fn resource_port_to_data_stream(input_port: Port<ProgressMsg>) -> DataStream {
|
||||||
return || {
|
return || {
|
||||||
match input_port.recv() {
|
// Can't just 'return' the value since we're inside a lambda
|
||||||
Payload(data) => Some(data),
|
let mut result = None;
|
||||||
Done(*) => None
|
loop {
|
||||||
|
match input_port.recv() {
|
||||||
|
UrlChange(*) => (), // don't care that URL changed
|
||||||
|
Payload(data) => {
|
||||||
|
result = Some(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Done(*) => break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ use std::from_str::FromStr;
|
||||||
use hubbub::hubbub;
|
use hubbub::hubbub;
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, SubpageId};
|
use servo_msg::constellation_msg::{ConstellationChan, SubpageId};
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_net::resource_task::{Done, Load, Payload, ResourceTask};
|
use servo_net::resource_task::{ProgressMsg, Done, Load, Payload, UrlChange, ResourceTask};
|
||||||
use servo_util::tree::TreeNodeRef;
|
use servo_util::tree::TreeNodeRef;
|
||||||
use servo_util::url::make_url;
|
use servo_util::url::make_url;
|
||||||
use extra::url::Url;
|
use extra::url::Url;
|
||||||
|
@ -98,6 +98,7 @@ pub enum HtmlDiscoveryMessage {
|
||||||
pub struct HtmlParserResult {
|
pub struct HtmlParserResult {
|
||||||
root: AbstractNode<ScriptView>,
|
root: AbstractNode<ScriptView>,
|
||||||
discovery_port: Port<HtmlDiscoveryMessage>,
|
discovery_port: Port<HtmlDiscoveryMessage>,
|
||||||
|
url: Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait NodeWrapping {
|
trait NodeWrapping {
|
||||||
|
@ -171,6 +172,7 @@ fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
|
||||||
let mut buf = ~[];
|
let mut buf = ~[];
|
||||||
loop {
|
loop {
|
||||||
match input_port.recv() {
|
match input_port.recv() {
|
||||||
|
UrlChange(*) => (), // don't care that URL changed
|
||||||
Payload(data) => {
|
Payload(data) => {
|
||||||
buf.push_all(data);
|
buf.push_all(data);
|
||||||
}
|
}
|
||||||
|
@ -329,8 +331,25 @@ pub fn parse_html(cx: *JSContext,
|
||||||
}
|
}
|
||||||
let js_chan = SharedChan::new(js_msg_chan);
|
let js_chan = SharedChan::new(js_msg_chan);
|
||||||
|
|
||||||
let url2 = url.clone();
|
// Process any UrlChange messages before we build the parser, because the
|
||||||
let url3 = url.clone();
|
// tree handler functions need to know the final URL.
|
||||||
|
let mut final_url = url.clone();
|
||||||
|
let (input_port, input_chan) = comm::stream();
|
||||||
|
resource_task.send(Load(url.clone(), input_chan));
|
||||||
|
let mut progress_msg: ProgressMsg;
|
||||||
|
loop {
|
||||||
|
progress_msg = input_port.recv();
|
||||||
|
match progress_msg {
|
||||||
|
UrlChange(url) => {
|
||||||
|
debug!("page URL changed to %s", url.to_str());
|
||||||
|
final_url = url;
|
||||||
|
}
|
||||||
|
_ => break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let url2 = final_url.clone();
|
||||||
|
let url3 = final_url.clone();
|
||||||
|
|
||||||
// Build the root node.
|
// Build the root node.
|
||||||
let root = @HTMLHtmlElement { htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html") };
|
let root = @HTMLHtmlElement { htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html") };
|
||||||
|
@ -500,37 +519,31 @@ pub fn parse_html(cx: *JSContext,
|
||||||
debug!("encoding change");
|
debug!("encoding change");
|
||||||
},
|
},
|
||||||
complete_script: |script| {
|
complete_script: |script| {
|
||||||
// A little function for holding this lint attr
|
unsafe {
|
||||||
fn complete_script(script: hubbub::NodeDataPtr,
|
let scriptnode: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(script);
|
||||||
url: Url,
|
do scriptnode.with_imm_element |script| {
|
||||||
js_chan: SharedChan<JSMessage>) {
|
match script.get_attr("src") {
|
||||||
unsafe {
|
Some(src) => {
|
||||||
let scriptnode: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(script);
|
debug!("found script: %s", src);
|
||||||
do scriptnode.with_imm_element |script| {
|
let new_url = make_url(src.to_str(), Some(url3.clone()));
|
||||||
match script.get_attr("src") {
|
js_chan2.send(JSTaskNewFile(new_url));
|
||||||
Some(src) => {
|
}
|
||||||
debug!("found script: %s", src);
|
None => {
|
||||||
let new_url = make_url(src.to_str(), Some(url.clone()));
|
let mut data = ~[];
|
||||||
js_chan.send(JSTaskNewFile(new_url));
|
debug!("iterating over children %?", scriptnode.first_child());
|
||||||
}
|
for child in scriptnode.children() {
|
||||||
None => {
|
debug!("child = %?", child);
|
||||||
let mut data = ~[];
|
do child.with_imm_text() |text| {
|
||||||
debug!("iterating over children %?", scriptnode.first_child());
|
data.push(text.element.data.to_str()); // FIXME: Bad copy.
|
||||||
for child in scriptnode.children() {
|
|
||||||
debug!("child = %?", child);
|
|
||||||
do child.with_imm_text() |text| {
|
|
||||||
data.push(text.element.data.to_str()); // FIXME: Bad copy.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("data = %?", data);
|
|
||||||
js_chan.send(JSTaskNewInlineScript(data.concat(), url.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("script data = %?", data);
|
||||||
|
js_chan2.send(JSTaskNewInlineScript(data.concat(), url3.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
complete_script(script, url3.clone(), js_chan2.clone());
|
|
||||||
debug!("complete script");
|
debug!("complete script");
|
||||||
},
|
},
|
||||||
complete_style: |style| {
|
complete_style: |style| {
|
||||||
|
@ -549,7 +562,7 @@ pub fn parse_html(cx: *JSContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("data = %?", data);
|
debug!("style data = %?", data);
|
||||||
let provenance = InlineProvenance(url_cell.take().unwrap(), data.concat());
|
let provenance = InlineProvenance(url_cell.take().unwrap(), data.concat());
|
||||||
css_chan3.send(CSSTaskNewFile(provenance));
|
css_chan3.send(CSSTaskNewFile(provenance));
|
||||||
}
|
}
|
||||||
|
@ -557,11 +570,13 @@ pub fn parse_html(cx: *JSContext,
|
||||||
});
|
});
|
||||||
debug!("set tree handler");
|
debug!("set tree handler");
|
||||||
|
|
||||||
let (input_port, input_chan) = comm::stream();
|
|
||||||
resource_task.send(Load(url.clone(), input_chan));
|
|
||||||
debug!("loaded page");
|
debug!("loaded page");
|
||||||
loop {
|
loop {
|
||||||
match input_port.recv() {
|
// We already have a message from the earlier UrlChange processing.
|
||||||
|
match progress_msg {
|
||||||
|
UrlChange(*) => {
|
||||||
|
fail!("got UrlChange message after others");
|
||||||
|
}
|
||||||
Payload(data) => {
|
Payload(data) => {
|
||||||
debug!("received data");
|
debug!("received data");
|
||||||
parser.parse_chunk(data);
|
parser.parse_chunk(data);
|
||||||
|
@ -573,6 +588,7 @@ pub fn parse_html(cx: *JSContext,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
progress_msg = input_port.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
css_chan.send(CSSTaskExit);
|
css_chan.send(CSSTaskExit);
|
||||||
|
@ -581,6 +597,7 @@ pub fn parse_html(cx: *JSContext,
|
||||||
HtmlParserResult {
|
HtmlParserResult {
|
||||||
root: root,
|
root: root,
|
||||||
discovery_port: discovery_port,
|
discovery_port: discovery_port,
|
||||||
|
url: final_url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -702,7 +702,7 @@ impl ScriptTask {
|
||||||
page.next_subpage_id.clone(),
|
page.next_subpage_id.clone(),
|
||||||
self.constellation_chan.clone());
|
self.constellation_chan.clone());
|
||||||
|
|
||||||
let HtmlParserResult {root, discovery_port} = html_parsing_result;
|
let HtmlParserResult {root, discovery_port, url: final_url} = html_parsing_result;
|
||||||
|
|
||||||
let document = HTMLDocument::new(root, Some(window));
|
let document = HTMLDocument::new(root, Some(window));
|
||||||
|
|
||||||
|
@ -711,7 +711,7 @@ impl ScriptTask {
|
||||||
document: document,
|
document: document,
|
||||||
window: window,
|
window: window,
|
||||||
});
|
});
|
||||||
page.url = Some((url.clone(), true));
|
page.url = Some((final_url, true));
|
||||||
|
|
||||||
// Send style sheets over to layout.
|
// Send style sheets over to layout.
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue