servo: Merge #11692 - Add a default Accept-Language header to HTTP requests (from jdm:language); r=Manishearth
authorJosh Matthews <josh@joshmatthews.net>
Fri, 10 Jun 2016 05:52:37 -0500
changeset 339058 261172d1f7037d80f247732a93355ade4bcb3db5
parent 339057 86e3ca7e08e578761feb3448930fce01975edf6f
child 339059 6878828310df2ecfbe70be08728bfdd7887d373e
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersManishearth
servo: Merge #11692 - Add a default Accept-Language header to HTTP requests (from jdm:language); r=Manishearth - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #11008 - [X] There are tests for these changes Source-Repo: https://github.com/servo/servo Source-Revision: 2ae8a70e2b929ac413c4bb09f00cc45d7433c05b
servo/components/net/http_loader.rs
servo/tests/unit/net/http_loader.rs
--- a/servo/components/net/http_loader.rs
+++ b/servo/components/net/http_loader.rs
@@ -8,19 +8,20 @@ use content_blocker_parser::{LoadType, R
 use content_blocker_parser::{RuleList, process_rules_for_request};
 use cookie;
 use cookie_storage::CookieStorage;
 use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, HttpRequest as DevtoolsHttpRequest};
 use devtools_traits::{HttpResponse as DevtoolsHttpResponse, NetworkEvent};
 use flate2::read::{DeflateDecoder, GzDecoder};
 use hsts::{HstsEntry, HstsList, secure_url};
 use hyper::Error as HttpError;
+use hyper::LanguageTag;
 use hyper::client::{Pool, Request, Response};
 use hyper::header::{Accept, AcceptEncoding, ContentLength, ContentEncoding, ContentType, Host, Referer};
-use hyper::header::{Authorization, Basic};
+use hyper::header::{Authorization, AcceptLanguage, Basic};
 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;
@@ -388,16 +389,32 @@ fn set_default_accept(headers: &mut Head
                             qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_owned()), vec![])),
                             QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), Quality(900u16)),
                             QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), Quality(800u16)),
                             ]);
         headers.set(accept);
     }
 }
 
+fn set_default_accept_language(headers: &mut Headers) {
+    if headers.has::<AcceptLanguage>() {
+        return;
+    }
+
+    let mut en_us: LanguageTag = Default::default();
+    en_us.language = Some("en".to_owned());
+    en_us.region = Some("US".to_owned());
+    let mut en: LanguageTag = Default::default();
+    en.language = Some("en".to_owned());
+    headers.set(AcceptLanguage(vec![
+        qitem(en_us),
+        QualityItem::new(en, Quality(500)),
+    ]));
+}
+
 /// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-state-no-referrer-when-downgrade
 fn no_ref_when_downgrade_header(referrer_url: Url, url: Url) -> Option<Url> {
     if referrer_url.scheme() == "https" && url.scheme() != "https" {
         return None;
     }
     return strip_url(referrer_url, false);
 }
 
@@ -628,16 +645,17 @@ pub fn modify_request_headers(headers: &
     // modify it, as setting of the user-agent by the user is
     // allowed.
     // https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch step 8
     if !headers.has::<UserAgent>() {
         headers.set(UserAgent(user_agent.to_owned()));
     }
 
     set_default_accept(headers);
+    set_default_accept_language(headers);
     set_default_accept_encoding(headers);
 
     *referrer_url = determine_request_referrer(headers,
                                                load_data.referrer_policy.clone(),
                                                referrer_url.clone(),
                                                url.clone());
 
     if let Some(referer_val) = referrer_url.clone() {
--- a/servo/tests/unit/net/http_loader.rs
+++ b/servo/tests/unit/net/http_loader.rs
@@ -4,18 +4,19 @@
 
 use content_blocker::parse_list;
 use cookie_rs::Cookie as CookiePair;
 use devtools_traits::HttpRequest as DevtoolsHttpRequest;
 use devtools_traits::HttpResponse as DevtoolsHttpResponse;
 use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent};
 use flate2::Compression;
 use flate2::write::{GzEncoder, DeflateEncoder};
+use hyper::LanguageTag;
 use hyper::header::{Accept, AcceptEncoding, ContentEncoding, ContentLength, Cookie as CookieHeader};
-use hyper::header::{Authorization, Basic};
+use hyper::header::{Authorization, AcceptLanguage, Basic};
 use hyper::header::{Encoding, Headers, Host, Location, Quality, QualityItem, qitem, Referer, SetCookie};
 use hyper::header::{StrictTransportSecurity, UserAgent};
 use hyper::http::RawStatus;
 use hyper::method::Method;
 use hyper::mime::{Mime, SubLevel, TopLevel};
 use hyper::status::StatusCode;
 use msg::constellation_msg::{PipelineId, ReferrerPolicy};
 use net::cookie::Cookie;
@@ -388,27 +389,41 @@ fn test_check_default_headers_loaded_in_
     let http_state = HttpState::new();
     let ui_provider = TestProvider::new();
 
     let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
     load_data.data = None;
     load_data.method = Method::Get;
 
     let mut headers = Headers::new();
+
     headers.set(AcceptEncoding(vec![qitem(Encoding::Gzip),
                                     qitem(Encoding::Deflate),
                                     qitem(Encoding::EncodingExt("br".to_owned()))]));
+
     headers.set(Host { hostname: "mozilla.com".to_owned() , port: None });
+
     let accept = Accept(vec![
                             qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])),
                             qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_owned()), vec![])),
                             QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), Quality(900u16)),
                             QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), Quality(800u16)),
                             ]);
     headers.set(accept);
+
+    let mut en_us: LanguageTag = Default::default();
+    en_us.language = Some("en".to_owned());
+    en_us.region = Some("US".to_owned());
+    let mut en: LanguageTag = Default::default();
+    en.language = Some("en".to_owned());
+    headers.set(AcceptLanguage(vec![
+        qitem(en_us),
+        QualityItem::new(en, Quality(500)),
+    ]));
+
     headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned()));
 
     // Testing for method.GET
     let _ = load(&load_data, &ui_provider, &http_state, None,
                  &AssertMustHaveHeadersRequestFactory {
                      expected_headers: headers.clone(),
                      body: <[_]>::to_vec(&[])
                  }, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
@@ -478,30 +493,45 @@ fn test_request_and_response_data_with_n
                  DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
 
     // notification received from devtools
     let devhttprequest = expect_devtools_http_request(&devtools_port);
     let devhttpresponse = expect_devtools_http_response(&devtools_port);
 
     //Creating default headers for request
     let mut headers = Headers::new();
+
     headers.set(AcceptEncoding(vec![
                                    qitem(Encoding::Gzip),
                                    qitem(Encoding::Deflate),
                                    qitem(Encoding::EncodingExt("br".to_owned()))
                                    ]));
+
     headers.set(Host { hostname: "mozilla.com".to_owned() , port: None });
+
     let accept = Accept(vec![
                             qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])),
                             qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_owned()), vec![])),
                             QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), Quality(900u16)),
                             QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), Quality(800u16)),
                             ]);
     headers.set(accept);
+
+    let mut en_us: LanguageTag = Default::default();
+    en_us.language = Some("en".to_owned());
+    en_us.region = Some("US".to_owned());
+    let mut en: LanguageTag = Default::default();
+    en.language = Some("en".to_owned());
+    headers.set(AcceptLanguage(vec![
+        qitem(en_us),
+        QualityItem::new(en, Quality(500)),
+    ]));
+
     headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned()));
+
     let httprequest = DevtoolsHttpRequest {
         url: url,
         method: Method::Get,
         headers: headers,
         body: None,
         pipeline_id: pipeline_id,
         startedDateTime: devhttprequest.startedDateTime,
         timeStamp: devhttprequest.timeStamp,