adding interface for custom responses

This commit is contained in:
Rahul Sharma 2016-05-01 01:11:15 +05:30
parent bcea0ada27
commit 3766cd1673
17 changed files with 663 additions and 146 deletions

View file

@ -13,15 +13,16 @@ use flate2::read::{DeflateDecoder, GzDecoder};
use hsts::{HstsEntry, HstsList, secure_url};
use hyper::Error as HttpError;
use hyper::client::{Pool, Request, Response};
use hyper::header::{Accept, AcceptEncoding, ContentLength, ContentType, Host, Referer};
use hyper::header::{Accept, AcceptEncoding, ContentLength, ContentEncoding, ContentType, Host, Referer};
use hyper::header::{Authorization, Basic};
use hyper::header::{ContentEncoding, Encoding, Header, Headers, Quality, QualityItem};
use hyper::header::{Encoding, Header, Headers, Quality, QualityItem};
use hyper::header::{Location, SetCookie, StrictTransportSecurity, UserAgent, qitem};
use hyper::http::RawStatus;
use hyper::method::Method;
use hyper::mime::{Mime, SubLevel, TopLevel};
use hyper::net::Fresh;
use hyper::status::{StatusClass, StatusCode};
use ipc_channel::ipc;
use log;
use mime_classifier::MIMEClassifier;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
@ -29,7 +30,7 @@ use net_traits::ProgressMsg::{Done, Payload};
use net_traits::hosts::replace_hosts;
use net_traits::response::HttpsState;
use net_traits::{CookieSource, IncludeSubdomains, LoadConsumer, LoadContext, LoadData};
use net_traits::{Metadata, NetworkError};
use net_traits::{Metadata, NetworkError, RequestSource, CustomResponse};
use openssl::ssl::error::{SslError, OpensslError};
use profile_traits::time::{ProfilerCategory, profile, ProfilerChan, TimerMetadata};
use profile_traits::time::{TimerMetadataReflowType, TimerMetadataFrameType};
@ -39,7 +40,7 @@ use std::boxed::FnBox;
use std::collections::HashSet;
use std::error::Error;
use std::fmt;
use std::io::{self, Read, Write};
use std::io::{self, Cursor, Read, Write};
use std::sync::mpsc::Sender;
use std::sync::{Arc, RwLock};
use time;
@ -149,6 +150,17 @@ fn load_for_consumer(load_data: LoadData,
}
}
pub struct WrappedHttpResponse {
pub response: Response
}
impl Read for WrappedHttpResponse {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.response.read(buf)
}
}
pub trait HttpResponse: Read {
fn headers(&self) -> &Headers;
fn status(&self) -> StatusCode;
@ -173,20 +185,6 @@ pub trait HttpResponse: Read {
}
}
pub struct WrappedHttpResponse {
pub response: Response
}
impl Read for WrappedHttpResponse {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.response.read(buf)
}
}
impl HttpResponse for WrappedHttpResponse {
fn headers(&self) -> &Headers {
&self.response.headers
@ -205,6 +203,34 @@ impl HttpResponse for WrappedHttpResponse {
}
}
pub struct ReadableCustomResponse {
headers: Headers,
raw_status: RawStatus,
body: Cursor<Vec<u8>>
}
pub fn to_readable_response(custom_response: CustomResponse) -> ReadableCustomResponse {
ReadableCustomResponse {
headers: custom_response.headers,
raw_status: custom_response.raw_status,
body: Cursor::new(custom_response.body)
}
}
impl HttpResponse for ReadableCustomResponse {
fn headers(&self) -> &Headers { &self.headers }
fn status(&self) -> StatusCode {
StatusCode::Ok
}
fn status_raw(&self) -> &RawStatus { &self.raw_status }
}
impl Read for ReadableCustomResponse {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.body.read(buf)
}
}
pub trait HttpRequestFactory {
type R: HttpRequest;
@ -466,13 +492,13 @@ fn update_sts_list_from_response(url: &Url, response: &HttpResponse, hsts_list:
}
}
pub struct StreamedResponse<R: HttpResponse> {
decoder: Decoder<R>,
pub struct StreamedResponse {
decoder: Decoder,
pub metadata: Metadata
}
impl<R: HttpResponse> Read for StreamedResponse<R> {
impl Read for StreamedResponse {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.decoder {
@ -484,12 +510,12 @@ impl<R: HttpResponse> Read for StreamedResponse<R> {
}
}
impl<R: HttpResponse> StreamedResponse<R> {
fn new(m: Metadata, d: Decoder<R>) -> StreamedResponse<R> {
impl StreamedResponse {
fn new(m: Metadata, d: Decoder) -> StreamedResponse {
StreamedResponse { metadata: m, decoder: d }
}
fn from_http_response(response: R, m: Metadata) -> Result<StreamedResponse<R>, LoadError> {
fn from_http_response(response: Box<HttpResponse>, m: Metadata) -> Result<StreamedResponse, LoadError> {
let decoder = match response.content_encoding() {
Some(Encoding::Gzip) => {
let result = GzDecoder::new(response);
@ -515,11 +541,11 @@ impl<R: HttpResponse> StreamedResponse<R> {
}
}
enum Decoder<R: Read> {
Gzip(GzDecoder<R>),
Deflate(DeflateDecoder<R>),
Brotli(Decompressor<R>),
Plain(R)
enum Decoder {
Gzip(GzDecoder<Box<HttpResponse>>),
Deflate(DeflateDecoder<Box<HttpResponse>>),
Brotli(Decompressor<Box<HttpResponse>>),
Plain(Box<HttpResponse>)
}
fn send_request_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>,
@ -771,7 +797,7 @@ pub fn load<A, B>(load_data: &LoadData,
request_factory: &HttpRequestFactory<R=A>,
user_agent: String,
cancel_listener: &CancellationListener)
-> Result<StreamedResponse<A::R>, LoadError> where A: HttpRequest + 'static, B: UIProvider {
-> Result<StreamedResponse, LoadError> where A: HttpRequest + 'static, B: UIProvider {
let max_redirects = prefs::get_pref("network.http.redirection-limit").as_i64().unwrap() as u32;
let mut iters = 0;
// URL of the document being loaded, as seen by all the higher-level code.
@ -785,6 +811,20 @@ pub fn load<A, B>(load_data: &LoadData,
return Err(LoadError::new(doc_url, LoadErrorType::Cancelled));
}
let (msg_sender, msg_receiver) = ipc::channel().unwrap();
match load_data.source {
RequestSource::Window(ref sender) | RequestSource::Worker(ref sender) => {
sender.send(msg_sender.clone()).unwrap();
let received_msg = msg_receiver.recv().unwrap();
if let Some(custom_response) = received_msg {
let metadata = Metadata::default(doc_url.clone());
let readable_response = to_readable_response(custom_response);
return StreamedResponse::from_http_response(box readable_response, metadata);
}
}
RequestSource::None => {}
}
// If the URL is a view-source scheme then the scheme data contains the
// real URL that should be used for which the source is to be viewed.
// Change our existing URL to that and keep note that we are viewing
@ -942,7 +982,7 @@ pub fn load<A, B>(load_data: &LoadData,
metadata.headers.clone(), metadata.status.clone(),
pipeline_id);
}
return StreamedResponse::from_http_response(response, metadata)
return StreamedResponse::from_http_response(box response, metadata)
}
}