Create HttpStatus to safely deal with HTTP responses status. (#33581)

Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
webbeef 2024-09-29 11:23:48 -07:00 committed by GitHub
parent 013473f1d5
commit 58f34ad7a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 344 additions and 403 deletions

View file

@ -8,10 +8,10 @@ use std::str::FromStr;
use dom_struct::dom_struct;
use http::header::HeaderMap as HyperHeaders;
use http::StatusCode;
use hyper_serde::Serde;
use js::jsapi::JSObject;
use js::rust::HandleObject;
use net_traits::http_status::HttpStatus;
use servo_url::ServoUrl;
use url::Position;
@ -37,11 +37,8 @@ use crate::script_runtime::{CanGc, JSContext as SafeJSContext, StreamConsumer};
pub struct Response {
reflector_: Reflector,
headers_reflector: MutNullableDom<Headers>,
/// `None` can be considered a StatusCode of `0`.
#[ignore_malloc_size_of = "Defined in hyper"]
#[no_trace]
status: DomRefCell<Option<StatusCode>>,
raw_status: DomRefCell<Option<(u16, Vec<u8>)>>,
status: DomRefCell<HttpStatus>,
response_type: DomRefCell<DOMResponseType>,
#[no_trace]
url: DomRefCell<Option<ServoUrl>>,
@ -64,8 +61,7 @@ impl Response {
Response {
reflector_: Reflector::new(),
headers_reflector: Default::default(),
status: DomRefCell::new(Some(StatusCode::OK)),
raw_status: DomRefCell::new(Some((200, b"".to_vec()))),
status: DomRefCell::new(HttpStatus::default()),
response_type: DomRefCell::new(DOMResponseType::Default),
url: DomRefCell::new(None),
url_list: DomRefCell::new(vec![]),
@ -119,11 +115,8 @@ impl Response {
let r = Response::new_with_proto(global, proto, can_gc);
// Step 3
*r.status.borrow_mut() = Some(StatusCode::from_u16(init.status).unwrap());
// Step 4
*r.raw_status.borrow_mut() = Some((init.status, init.statusText.clone().into()));
// Step 3 & 4
*r.status.borrow_mut() = HttpStatus::new_raw(init.status, init.statusText.clone().into());
// Step 5
if let Some(ref headers_member) = init.headers {
@ -177,7 +170,7 @@ impl Response {
let r = Response::new(global);
*r.response_type.borrow_mut() = DOMResponseType::Error;
r.Headers().set_guard(Guard::Immutable);
*r.raw_status.borrow_mut() = Some((0, b"".to_vec()));
*r.status.borrow_mut() = HttpStatus::new_error();
r
}
@ -207,8 +200,7 @@ impl Response {
let r = Response::new(global);
// Step 5
*r.status.borrow_mut() = Some(StatusCode::from_u16(status).unwrap());
*r.raw_status.borrow_mut() = Some((status, b"".to_vec()));
*r.status.borrow_mut() = HttpStatus::new_raw(status, vec![]);
// Step 6
let url_bytestring =
@ -298,29 +290,17 @@ impl ResponseMethods for Response {
// https://fetch.spec.whatwg.org/#dom-response-status
fn Status(&self) -> u16 {
match *self.raw_status.borrow() {
Some((s, _)) => s,
None => 0,
}
self.status.borrow().raw_code()
}
// https://fetch.spec.whatwg.org/#dom-response-ok
fn Ok(&self) -> bool {
match *self.status.borrow() {
Some(s) => {
let status_num = s.as_u16();
(200..=299).contains(&status_num)
},
None => false,
}
self.status.borrow().is_success()
}
// https://fetch.spec.whatwg.org/#dom-response-statustext
fn StatusText(&self) -> ByteString {
match *self.raw_status.borrow() {
Some((_, ref st)) => ByteString::new(st.clone()),
None => ByteString::new(b"".to_vec()),
}
ByteString::new(self.status.borrow().message().to_vec())
}
// https://fetch.spec.whatwg.org/#dom-response-headers
@ -345,11 +325,10 @@ impl ResponseMethods for Response {
// Instead of storing a net_traits::Response internally, we
// only store the relevant fields, and only clone them here
*new_response.response_type.borrow_mut() = *self.response_type.borrow();
*new_response.status.borrow_mut() = *self.status.borrow();
new_response
.raw_status
.status
.borrow_mut()
.clone_from(&self.raw_status.borrow());
.clone_from(&self.status.borrow());
new_response.url.borrow_mut().clone_from(&self.url.borrow());
new_response
.url_list
@ -420,8 +399,8 @@ impl Response {
});
}
pub fn set_raw_status(&self, status: Option<(u16, Vec<u8>)>) {
*self.raw_status.borrow_mut() = status;
pub fn set_status(&self, status: &HttpStatus) {
self.status.borrow_mut().clone_from(status);
}
pub fn set_final_url(&self, final_url: ServoUrl) {
@ -435,20 +414,17 @@ impl Response {
fn set_response_members_by_type(&self, response_type: DOMResponseType) {
match response_type {
DOMResponseType::Error => {
*self.status.borrow_mut() = None;
self.set_raw_status(None);
*self.status.borrow_mut() = HttpStatus::new_error();
self.set_headers(None);
},
DOMResponseType::Opaque => {
*self.url_list.borrow_mut() = vec![];
*self.status.borrow_mut() = None;
self.set_raw_status(None);
*self.status.borrow_mut() = HttpStatus::new_error();
self.set_headers(None);
self.body_stream.set(None);
},
DOMResponseType::Opaqueredirect => {
*self.status.borrow_mut() = None;
self.set_raw_status(None);
*self.status.borrow_mut() = HttpStatus::new_error();
self.set_headers(None);
self.body_stream.set(None);
},