mirror of
https://github.com/servo/servo.git
synced 2025-08-15 10:25:32 +01:00
net: Send Cookies to Devtools (#38601)
The current behaviour in dev tools network monitor is missing cookies in the cookies tab in Request Details, displaying "No cookies for this request" even for requests with cookies. The changes in this PR refactors the `request_cookies` and `response_cookies` to check and retrieve the cookies if available Also, the structure in which the cookies is sent to devtools is been refactored to match the format firefox's devtools client expects. With these changes, we now have the cookies displayed for requests that have one. Fixes: https://github.com/servo/servo/issues/38127 --------- Signed-off-by: uthmaniv <uthmanyahayababa@gmail.com>
This commit is contained in:
parent
122069cf43
commit
1995e22e19
3 changed files with 81 additions and 42 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1923,6 +1923,7 @@ dependencies = [
|
||||||
"http 1.3.1",
|
"http 1.3.1",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
"log",
|
"log",
|
||||||
|
"net",
|
||||||
"net_traits",
|
"net_traits",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
|
@ -27,6 +27,7 @@ serde_json = { workspace = true }
|
||||||
servo_config = { path = "../config" }
|
servo_config = { path = "../config" }
|
||||||
servo_rand = { path = "../rand" }
|
servo_rand = { path = "../rand" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
|
net = { path = "../net" }
|
||||||
uuid = { workspace = true }
|
uuid = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -10,10 +10,13 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
use chrono::{Local, LocalResult, TimeZone};
|
use chrono::{Local, LocalResult, TimeZone};
|
||||||
use devtools_traits::{HttpRequest as DevtoolsHttpRequest, HttpResponse as DevtoolsHttpResponse};
|
use devtools_traits::{HttpRequest as DevtoolsHttpRequest, HttpResponse as DevtoolsHttpResponse};
|
||||||
use headers::{ContentLength, ContentType, Cookie, HeaderMapExt};
|
use headers::{ContentLength, ContentType, Cookie, HeaderMapExt};
|
||||||
use http::{HeaderMap, Method, header};
|
use http::{HeaderMap, Method};
|
||||||
|
use net::cookie::ServoCookie;
|
||||||
|
use net_traits::CookieSource;
|
||||||
use net_traits::request::Destination as RequestDestination;
|
use net_traits::request::Destination as RequestDestination;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
|
use servo_url::ServoUrl;
|
||||||
|
|
||||||
use crate::StreamId;
|
use crate::StreamId;
|
||||||
use crate::actor::{Actor, ActorError, ActorRegistry};
|
use crate::actor::{Actor, ActorError, ActorRegistry};
|
||||||
|
@ -71,7 +74,7 @@ pub struct EventActor {
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct ResponseCookiesMsg {
|
pub struct ResponseCookiesMsg {
|
||||||
pub cookies: usize,
|
pub cookies: Vec<ResponseCookieObj>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -104,7 +107,7 @@ pub struct ResponseHeadersMsg {
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct RequestCookiesMsg {
|
pub struct RequestCookiesMsg {
|
||||||
pub cookies: usize,
|
pub cookies: Vec<RequestCookieObj>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -157,13 +160,32 @@ struct GetRequestPostDataReply {
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct GetRequestCookiesReply {
|
struct GetRequestCookiesReply {
|
||||||
from: String,
|
from: String,
|
||||||
cookies: Vec<u8>,
|
cookies: Vec<RequestCookieObj>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct GetResponseCookiesReply {
|
struct GetResponseCookiesReply {
|
||||||
from: String,
|
from: String,
|
||||||
cookies: Vec<u8>,
|
cookies: Vec<ResponseCookieObj>,
|
||||||
|
}
|
||||||
|
#[derive(Clone, Serialize)]
|
||||||
|
pub struct ResponseCookieObj {
|
||||||
|
pub name: String,
|
||||||
|
pub value: String,
|
||||||
|
pub path: Option<String>,
|
||||||
|
pub domain: Option<String>,
|
||||||
|
pub expires: Option<String>,
|
||||||
|
#[serde(rename = "httpOnly")]
|
||||||
|
pub http_only: Option<bool>,
|
||||||
|
pub secure: Option<bool>,
|
||||||
|
#[serde(rename = "sameSite")]
|
||||||
|
pub same_site: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize)]
|
||||||
|
pub struct RequestCookieObj {
|
||||||
|
pub name: String,
|
||||||
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize)]
|
#[derive(Clone, Default, Serialize)]
|
||||||
|
@ -236,14 +258,11 @@ impl Actor for NetworkEventActor {
|
||||||
request.reply_final(&msg)?
|
request.reply_final(&msg)?
|
||||||
},
|
},
|
||||||
"getRequestCookies" => {
|
"getRequestCookies" => {
|
||||||
let mut cookies = Vec::new();
|
let cookies = self
|
||||||
if let Some(ref headers) = self.request_headers_raw {
|
.request_cookies
|
||||||
for cookie in headers.get_all(header::COOKIE) {
|
.as_ref()
|
||||||
if let Ok(cookie_value) = String::from_utf8(cookie.as_bytes().to_vec()) {
|
.map(|msg| msg.cookies.clone())
|
||||||
cookies = cookie_value.into_bytes();
|
.unwrap_or_default();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let msg = GetRequestCookiesReply {
|
let msg = GetRequestCookiesReply {
|
||||||
from: self.name(),
|
from: self.name(),
|
||||||
cookies,
|
cookies,
|
||||||
|
@ -287,15 +306,11 @@ impl Actor for NetworkEventActor {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"getResponseCookies" => {
|
"getResponseCookies" => {
|
||||||
let mut cookies = Vec::new();
|
let cookies = self
|
||||||
// TODO: This seems quite broken
|
.response_cookies
|
||||||
if let Some(ref headers) = self.response_headers_raw {
|
.as_ref()
|
||||||
for cookie in headers.get_all(header::SET_COOKIE) {
|
.map(|msg| msg.cookies.clone())
|
||||||
if let Ok(cookie_value) = String::from_utf8(cookie.as_bytes().to_vec()) {
|
.unwrap_or_default();
|
||||||
cookies = cookie_value.into_bytes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let msg = GetResponseCookiesReply {
|
let msg = GetResponseCookiesReply {
|
||||||
from: self.name(),
|
from: self.name(),
|
||||||
cookies,
|
cookies,
|
||||||
|
@ -372,7 +387,7 @@ impl NetworkEventActor {
|
||||||
|
|
||||||
pub fn add_request(&mut self, request: DevtoolsHttpRequest) {
|
pub fn add_request(&mut self, request: DevtoolsHttpRequest) {
|
||||||
self.is_xhr = request.is_xhr;
|
self.is_xhr = request.is_xhr;
|
||||||
self.request_cookies = Some(Self::request_cookies(&request));
|
self.request_cookies = Self::request_cookies(&request);
|
||||||
self.request_headers = Some(Self::request_headers(&request));
|
self.request_headers = Some(Self::request_headers(&request));
|
||||||
self.total_time = Self::total_time(&request);
|
self.total_time = Self::total_time(&request);
|
||||||
self.event_timing = Some(Self::event_timing(&request));
|
self.event_timing = Some(Self::event_timing(&request));
|
||||||
|
@ -387,7 +402,10 @@ impl NetworkEventActor {
|
||||||
|
|
||||||
pub fn add_response(&mut self, response: DevtoolsHttpResponse) {
|
pub fn add_response(&mut self, response: DevtoolsHttpResponse) {
|
||||||
self.response_headers = Some(Self::response_headers(&response));
|
self.response_headers = Some(Self::response_headers(&response));
|
||||||
self.response_cookies = Some(Self::response_cookies(&response));
|
self.response_cookies = ServoUrl::parse(&self.request_url)
|
||||||
|
.ok()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|url| Self::response_cookies(&response, url));
|
||||||
self.response_start = Some(Self::response_start(&response));
|
self.response_start = Some(Self::response_start(&response));
|
||||||
self.response_content = Self::response_content(&response);
|
self.response_content = Self::response_content(&response);
|
||||||
self.response_body = response.body.clone();
|
self.response_body = response.body.clone();
|
||||||
|
@ -467,15 +485,33 @@ impl NetworkEventActor {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn response_cookies(response: &DevtoolsHttpResponse) -> ResponseCookiesMsg {
|
pub fn response_cookies(
|
||||||
let cookies_size = response
|
response: &DevtoolsHttpResponse,
|
||||||
.headers
|
url: &ServoUrl,
|
||||||
.as_ref()
|
) -> Option<ResponseCookiesMsg> {
|
||||||
.map(|headers| headers.get_all("set-cookie").iter().count())
|
let headers = response.headers.as_ref()?;
|
||||||
.unwrap_or(0);
|
let cookies = headers
|
||||||
ResponseCookiesMsg {
|
.get_all("set-cookie")
|
||||||
cookies: cookies_size,
|
.iter()
|
||||||
}
|
.filter_map(|cookie| {
|
||||||
|
let cookie_str = String::from_utf8(cookie.as_bytes().to_vec()).ok()?;
|
||||||
|
ServoCookie::from_cookie_string(cookie_str, url, CookieSource::HTTP)
|
||||||
|
})
|
||||||
|
.map(|servo_cookie| {
|
||||||
|
let c = &servo_cookie.cookie;
|
||||||
|
ResponseCookieObj {
|
||||||
|
name: c.name().to_string(),
|
||||||
|
value: c.value().to_string(),
|
||||||
|
path: c.path().map(|p| p.to_string()),
|
||||||
|
domain: c.domain().map(|d| d.to_string()),
|
||||||
|
expires: c.expires().map(|dt| format!("{:?}", dt)),
|
||||||
|
http_only: c.http_only(),
|
||||||
|
secure: c.secure(),
|
||||||
|
same_site: c.same_site().map(|s| s.to_string()),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
Some(ResponseCookiesMsg { cookies })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn response_headers(response: &DevtoolsHttpResponse) -> ResponseHeadersMsg {
|
pub fn response_headers(response: &DevtoolsHttpResponse) -> ResponseHeadersMsg {
|
||||||
|
@ -503,15 +539,16 @@ impl NetworkEventActor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_cookies(request: &DevtoolsHttpRequest) -> RequestCookiesMsg {
|
pub fn request_cookies(request: &DevtoolsHttpRequest) -> Option<RequestCookiesMsg> {
|
||||||
let cookies_size = request
|
let header_value = request.headers.typed_get::<Cookie>()?;
|
||||||
.headers
|
let cookies = header_value
|
||||||
.typed_get::<Cookie>()
|
.iter()
|
||||||
.map(|c| c.len())
|
.map(|cookie| RequestCookieObj {
|
||||||
.unwrap_or(0);
|
name: cookie.0.to_string(),
|
||||||
RequestCookiesMsg {
|
value: cookie.1.to_string(),
|
||||||
cookies: cookies_size,
|
})
|
||||||
}
|
.collect::<Vec<_>>();
|
||||||
|
Some(RequestCookiesMsg { cookies })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn total_time(request: &DevtoolsHttpRequest) -> Duration {
|
pub fn total_time(request: &DevtoolsHttpRequest) -> Duration {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue