mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-08-25 12:54:09 +02:00
Share the send settings and their timeline lines across desktop, tab and proxy
This commit is contained in:
@@ -46,9 +46,9 @@ const WorkspacesWorkspaceIdRequestsRequestIdRoute =
|
|||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
'/workspaces/': typeof WorkspacesIndexRoute
|
'/workspaces': typeof WorkspacesIndexRoute
|
||||||
'/workspaces/$workspaceId/settings': typeof WorkspacesWorkspaceIdSettingsRoute
|
'/workspaces/$workspaceId/settings': typeof WorkspacesWorkspaceIdSettingsRoute
|
||||||
'/workspaces/$workspaceId/': typeof WorkspacesWorkspaceIdIndexRoute
|
'/workspaces/$workspaceId': typeof WorkspacesWorkspaceIdIndexRoute
|
||||||
'/workspaces/$workspaceId/requests/$requestId': typeof WorkspacesWorkspaceIdRequestsRequestIdRoute
|
'/workspaces/$workspaceId/requests/$requestId': typeof WorkspacesWorkspaceIdRequestsRequestIdRoute
|
||||||
}
|
}
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
@@ -70,9 +70,9 @@ export interface FileRouteTypes {
|
|||||||
fileRoutesByFullPath: FileRoutesByFullPath
|
fileRoutesByFullPath: FileRoutesByFullPath
|
||||||
fullPaths:
|
fullPaths:
|
||||||
| '/'
|
| '/'
|
||||||
| '/workspaces/'
|
| '/workspaces'
|
||||||
| '/workspaces/$workspaceId/settings'
|
| '/workspaces/$workspaceId/settings'
|
||||||
| '/workspaces/$workspaceId/'
|
| '/workspaces/$workspaceId'
|
||||||
| '/workspaces/$workspaceId/requests/$requestId'
|
| '/workspaces/$workspaceId/requests/$requestId'
|
||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to:
|
to:
|
||||||
@@ -110,14 +110,14 @@ declare module '@tanstack/react-router' {
|
|||||||
'/workspaces/': {
|
'/workspaces/': {
|
||||||
id: '/workspaces/'
|
id: '/workspaces/'
|
||||||
path: '/workspaces'
|
path: '/workspaces'
|
||||||
fullPath: '/workspaces/'
|
fullPath: '/workspaces'
|
||||||
preLoaderRoute: typeof WorkspacesIndexRouteImport
|
preLoaderRoute: typeof WorkspacesIndexRouteImport
|
||||||
parentRoute: typeof rootRouteImport
|
parentRoute: typeof rootRouteImport
|
||||||
}
|
}
|
||||||
'/workspaces/$workspaceId/': {
|
'/workspaces/$workspaceId/': {
|
||||||
id: '/workspaces/$workspaceId/'
|
id: '/workspaces/$workspaceId/'
|
||||||
path: '/workspaces/$workspaceId'
|
path: '/workspaces/$workspaceId'
|
||||||
fullPath: '/workspaces/$workspaceId/'
|
fullPath: '/workspaces/$workspaceId'
|
||||||
preLoaderRoute: typeof WorkspacesWorkspaceIdIndexRouteImport
|
preLoaderRoute: typeof WorkspacesWorkspaceIdIndexRouteImport
|
||||||
parentRoute: typeof rootRouteImport
|
parentRoute: typeof rootRouteImport
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
//! would write to its database is written to the reply stream instead, and the tab stores it.
|
//! would write to its database is written to the reply stream instead, and the tab stores it.
|
||||||
|
|
||||||
use crate::guard::{DestinationPolicy, GuardedSender};
|
use crate::guard::{DestinationPolicy, GuardedSender};
|
||||||
use crate::wire::{Frame, SendRequest, WireHeader};
|
use crate::wire::{Frame, SendRequest};
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
@@ -21,6 +21,7 @@ use yaak_http::cookies::CookieStore;
|
|||||||
use yaak_http::sender::{HttpResponseEvent, ReqwestSender};
|
use yaak_http::sender::{HttpResponseEvent, ReqwestSender};
|
||||||
use yaak_http::transaction::HttpTransaction;
|
use yaak_http::transaction::HttpTransaction;
|
||||||
use yaak_http::types::{SendableHttpRequest, SendableHttpRequestOptions};
|
use yaak_http::types::{SendableHttpRequest, SendableHttpRequestOptions};
|
||||||
|
use yaak_models::models::HttpResponseHeader;
|
||||||
|
|
||||||
/// How many frames may sit unread by the client before body reading pauses. Backpressure, so a
|
/// How many frames may sit unread by the client before body reading pauses. Backpressure, so a
|
||||||
/// slow tab slows the upstream read rather than filling memory.
|
/// slow tab slows the upstream read rather than filling memory.
|
||||||
@@ -115,7 +116,7 @@ pub async fn prepare(limits: Arc<SendLimits>, send: SendRequest) -> Result<Prepa
|
|||||||
pub struct PreparedSend {
|
pub struct PreparedSend {
|
||||||
limits: Arc<SendLimits>,
|
limits: Arc<SendLimits>,
|
||||||
sendable: SendableHttpRequest,
|
sendable: SendableHttpRequest,
|
||||||
settings: crate::wire::SendSettings,
|
settings: yaak_models::models::HttpSendSettings,
|
||||||
cookies: Option<Vec<yaak_models::models::Cookie>>,
|
cookies: Option<Vec<yaak_models::models::Cookie>>,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
timeout_capped: bool,
|
timeout_capped: bool,
|
||||||
@@ -331,10 +332,10 @@ struct DoneStats {
|
|||||||
content_length_compressed: u64,
|
content_length_compressed: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_wire_headers(headers: &[(String, String)]) -> Vec<WireHeader> {
|
fn to_wire_headers(headers: &[(String, String)]) -> Vec<HttpResponseHeader> {
|
||||||
headers
|
headers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, value)| WireHeader { name: name.clone(), value: value.clone() })
|
.map(|(name, value)| HttpResponseHeader { name: name.clone(), value: value.clone() })
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
//! back.
|
//! back.
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use yaak_models::models::{Cookie, HttpRequest, HttpResponseEventData};
|
use yaak_models::models::{
|
||||||
|
Cookie, HttpRequest, HttpResponseEventData, HttpResponseHeader, HttpSendSettings,
|
||||||
|
};
|
||||||
|
|
||||||
/// The body of `POST /v1/http/send`.
|
/// The body of `POST /v1/http/send`.
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
@@ -21,32 +23,14 @@ pub struct SendRequest {
|
|||||||
/// rendered by the tab. The proxy builds the URL, headers and body from it exactly the way
|
/// rendered by the tab. The proxy builds the URL, headers and body from it exactly the way
|
||||||
/// the desktop does after rendering.
|
/// the desktop does after rendering.
|
||||||
pub request: HttpRequest,
|
pub request: HttpRequest,
|
||||||
pub settings: SendSettings,
|
/// The resolved settings, values only. Where they came from is the tab's to record in
|
||||||
|
/// its timeline; the proxy only needs to obey them.
|
||||||
|
pub settings: HttpSendSettings,
|
||||||
/// The cookies to start with. `None` means no jar at all: nothing sent, nothing kept.
|
/// The cookies to start with. `None` means no jar at all: nothing sent, nothing kept.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub cookies: Option<Vec<Cookie>>,
|
pub cookies: Option<Vec<Cookie>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The resolved send settings, values only. Where they came from (request, folder, workspace)
|
|
||||||
/// is the tab's to record in its timeline; the proxy only needs to obey them.
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct SendSettings {
|
|
||||||
pub validate_certificates: bool,
|
|
||||||
pub follow_redirects: bool,
|
|
||||||
/// Milliseconds. Zero or negative means "no timeout", which the proxy caps regardless.
|
|
||||||
pub timeout_ms: i64,
|
|
||||||
pub send_cookies: bool,
|
|
||||||
pub store_cookies: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Debug)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct WireHeader {
|
|
||||||
pub name: String,
|
|
||||||
pub value: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// One line of the reply stream. Tags are snake_case like the timeline event tags; fields are
|
/// One line of the reply stream. Tags are snake_case like the timeline event tags; fields are
|
||||||
/// camelCase like every model the tab stores.
|
/// camelCase like every model the tab stores.
|
||||||
#[derive(Serialize, Debug)]
|
#[derive(Serialize, Debug)]
|
||||||
@@ -68,9 +52,9 @@ pub enum Frame {
|
|||||||
url: String,
|
url: String,
|
||||||
remote_addr: Option<String>,
|
remote_addr: Option<String>,
|
||||||
version: Option<String>,
|
version: Option<String>,
|
||||||
headers: Vec<WireHeader>,
|
headers: Vec<HttpResponseHeader>,
|
||||||
/// The headers that were actually sent on the final hop, cookies and all.
|
/// The headers that were actually sent on the final hop, cookies and all.
|
||||||
request_headers: Vec<WireHeader>,
|
request_headers: Vec<HttpResponseHeader>,
|
||||||
/// `Content-Length` as declared by the server, if it declared one.
|
/// `Content-Length` as declared by the server, if it declared one.
|
||||||
content_length: Option<u64>,
|
content_length: Option<u64>,
|
||||||
/// Milliseconds from the start of the send to the response head.
|
/// Milliseconds from the start of the send to the response head.
|
||||||
|
|||||||
@@ -70,6 +70,17 @@ export type HttpResponseHeader = { name: string, value: string, };
|
|||||||
|
|
||||||
export type HttpResponseState = "initialized" | "connected" | "closed";
|
export type HttpResponseState = "initialized" | "connected" | "closed";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resolved send settings, values only: what an executor has to obey, with the sources
|
||||||
|
* (which model each came from) left behind in [`ResolvedHttpRequestSettings`]. This is what
|
||||||
|
* crosses from a tab to the send proxy, and what the proxy reads.
|
||||||
|
*/
|
||||||
|
export type HttpSendSettings = { validateCertificates: boolean, followRedirects: boolean,
|
||||||
|
/**
|
||||||
|
* Milliseconds. Zero or negative means no timeout.
|
||||||
|
*/
|
||||||
|
timeoutMs: number, sendCookies: boolean, storeCookies: boolean, };
|
||||||
|
|
||||||
export type HttpUrlParameter = { enabled?: boolean,
|
export type HttpUrlParameter = { enabled?: boolean,
|
||||||
/**
|
/**
|
||||||
* Colon-prefixed parameters are treated as path parameters if they match, like `/users/:id`
|
* Colon-prefixed parameters are treated as path parameters if they match, like `/users/:id`
|
||||||
|
|||||||
+16
@@ -304,6 +304,22 @@ export type HttpResponseHeader = { name: string; value: string };
|
|||||||
|
|
||||||
export type HttpResponseState = "initialized" | "connected" | "closed";
|
export type HttpResponseState = "initialized" | "connected" | "closed";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resolved send settings, values only: what an executor has to obey, with the sources
|
||||||
|
* (which model each came from) left behind in [`ResolvedHttpRequestSettings`]. This is what
|
||||||
|
* crosses from a tab to the send proxy, and what the proxy reads.
|
||||||
|
*/
|
||||||
|
export type HttpSendSettings = {
|
||||||
|
validateCertificates: boolean;
|
||||||
|
followRedirects: boolean;
|
||||||
|
/**
|
||||||
|
* Milliseconds. Zero or negative means no timeout.
|
||||||
|
*/
|
||||||
|
timeoutMs: number;
|
||||||
|
sendCookies: boolean;
|
||||||
|
storeCookies: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export type HttpUrlParameter = {
|
export type HttpUrlParameter = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -140,6 +140,70 @@ impl Default for ResolvedHttpRequestSettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ResolvedHttpRequestSettings {
|
||||||
|
/// The `* Setting name=value` lines a send writes at the top of its timeline, sources and
|
||||||
|
/// all. Built here, once, so every host that runs a send — the desktop, the CLI, the browser
|
||||||
|
/// tab handing off to a proxy — records the same lines the same way.
|
||||||
|
pub fn timeline_events(&self) -> Vec<HttpResponseEventData> {
|
||||||
|
fn event<T>(
|
||||||
|
name: &str,
|
||||||
|
value: String,
|
||||||
|
setting: &ResolvedSetting<T>,
|
||||||
|
) -> HttpResponseEventData {
|
||||||
|
HttpResponseEventData::Setting {
|
||||||
|
name: name.to_string(),
|
||||||
|
value,
|
||||||
|
source_model: Some(setting.source_model.clone()),
|
||||||
|
source_id: setting.source_id.clone(),
|
||||||
|
source_name: setting.source_name.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let timeout = if self.request_timeout.value > 0 {
|
||||||
|
format!("{:?}", std::time::Duration::from_millis(self.request_timeout.value as u64))
|
||||||
|
} else {
|
||||||
|
"Infinity".to_string()
|
||||||
|
};
|
||||||
|
vec![
|
||||||
|
event(
|
||||||
|
"validate_certificates",
|
||||||
|
self.validate_certificates.value.to_string(),
|
||||||
|
&self.validate_certificates,
|
||||||
|
),
|
||||||
|
event("redirects", self.follow_redirects.value.to_string(), &self.follow_redirects),
|
||||||
|
event("timeout", timeout, &self.request_timeout),
|
||||||
|
event("send_cookies", self.send_cookies.value.to_string(), &self.send_cookies),
|
||||||
|
event("store_cookies", self.store_cookies.value.to_string(), &self.store_cookies),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The resolved send settings, values only: what an executor has to obey, with the sources
|
||||||
|
/// (which model each came from) left behind in [`ResolvedHttpRequestSettings`]. This is what
|
||||||
|
/// crosses from a tab to the send proxy, and what the proxy reads.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[ts(export, export_to = "gen_models.ts")]
|
||||||
|
pub struct HttpSendSettings {
|
||||||
|
pub validate_certificates: bool,
|
||||||
|
pub follow_redirects: bool,
|
||||||
|
/// Milliseconds. Zero or negative means no timeout.
|
||||||
|
pub timeout_ms: i32,
|
||||||
|
pub send_cookies: bool,
|
||||||
|
pub store_cookies: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ResolvedHttpRequestSettings> for HttpSendSettings {
|
||||||
|
fn from(s: &ResolvedHttpRequestSettings) -> Self {
|
||||||
|
Self {
|
||||||
|
validate_certificates: s.validate_certificates.value,
|
||||||
|
follow_redirects: s.follow_redirects.value,
|
||||||
|
timeout_ms: s.request_timeout.value,
|
||||||
|
send_cookies: s.send_cookies.value,
|
||||||
|
store_cookies: s.store_cookies.value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, TS)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to = "gen_models.ts")]
|
#[ts(export, export_to = "gen_models.ts")]
|
||||||
|
|||||||
@@ -694,22 +694,22 @@ export function __wbg_versions_215a3ab1c9d5745a(arg0) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
export function __wbindgen_cast_0000000000000001(arg0, arg1) {
|
export function __wbindgen_cast_0000000000000001(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1124, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 1123, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__ha1c2fa93df0107f3);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__ha1c2fa93df0107f3);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
export function __wbindgen_cast_0000000000000002(arg0, arg1) {
|
export function __wbindgen_cast_0000000000000002(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 214, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("Event")], shim_idx: 211, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__ha7903b6e296dd8f4);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__ha7903b6e296dd8f4);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
export function __wbindgen_cast_0000000000000003(arg0, arg1) {
|
export function __wbindgen_cast_0000000000000003(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("IDBVersionChangeEvent")], shim_idx: 198, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("IDBVersionChangeEvent")], shim_idx: 114, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h999df771f7987dc3);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h999df771f7987dc3);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
export function __wbindgen_cast_0000000000000004(arg0, arg1) {
|
export function __wbindgen_cast_0000000000000004(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 212, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [], shim_idx: 209, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__ha1b480b83daa641f);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__ha1b480b83daa641f);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -30,8 +30,7 @@ use std::collections::HashMap;
|
|||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use yaak_models::blob_manager::{BlobManager, BodyChunk};
|
use yaak_models::blob_manager::{BlobManager, BodyChunk};
|
||||||
use yaak_models::models::{
|
use yaak_models::models::{
|
||||||
AnyModel, CookieJar, HttpRequest, HttpResponseEvent, HttpResponseEventData,
|
AnyModel, CookieJar, HttpRequest, HttpResponseEvent, HttpResponseEventData, HttpSendSettings,
|
||||||
ResolvedHttpRequestSettings, ResolvedSetting,
|
|
||||||
};
|
};
|
||||||
use yaak_models::models_ops;
|
use yaak_models::models_ops;
|
||||||
use yaak_models::query_manager::QueryManager;
|
use yaak_models::query_manager::QueryManager;
|
||||||
@@ -378,17 +377,6 @@ struct PrepareHttpSendReq {
|
|||||||
cookie_jar_id: Option<String>,
|
cookie_jar_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The values the proxy needs to obey. Where each came from is in `setting_events`.
|
|
||||||
#[derive(Serialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
struct PreparedSendSettings {
|
|
||||||
validate_certificates: bool,
|
|
||||||
follow_redirects: bool,
|
|
||||||
timeout_ms: i64,
|
|
||||||
send_cookies: bool,
|
|
||||||
store_cookies: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Everything a send needs that lives in the database, resolved and rendered: the desktop's
|
/// Everything a send needs that lives in the database, resolved and rendered: the desktop's
|
||||||
/// `HttpSendInputs`, in the shape a tab hands to the proxy and keeps for itself.
|
/// `HttpSendInputs`, in the shape a tab hands to the proxy and keeps for itself.
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@@ -397,7 +385,7 @@ struct PreparedHttpSend {
|
|||||||
/// The request with inherited headers and authentication applied and every template
|
/// The request with inherited headers and authentication applied and every template
|
||||||
/// rendered. What the proxy sends, and what the response records as its request.
|
/// rendered. What the proxy sends, and what the response records as its request.
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
settings: PreparedSendSettings,
|
settings: HttpSendSettings,
|
||||||
/// The `* Setting name=value` timeline lines the desktop writes at the top of a send,
|
/// The `* Setting name=value` timeline lines the desktop writes at the top of a send,
|
||||||
/// sources and all. The tab records them before the proxy's own events.
|
/// sources and all. The tab records them before the proxy's own events.
|
||||||
setting_events: Vec<HttpResponseEventData>,
|
setting_events: Vec<HttpResponseEventData>,
|
||||||
@@ -490,17 +478,10 @@ pub async fn prepare_http_send(payload: JsValue) -> Result<JsValue> {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let setting_events = setting_events(&settings);
|
|
||||||
let prepared = PreparedHttpSend {
|
let prepared = PreparedHttpSend {
|
||||||
request: rendered,
|
request: rendered,
|
||||||
settings: PreparedSendSettings {
|
settings: HttpSendSettings::from(&settings),
|
||||||
validate_certificates: settings.validate_certificates.value,
|
setting_events: settings.timeline_events(),
|
||||||
follow_redirects: settings.follow_redirects.value,
|
|
||||||
timeout_ms: settings.request_timeout.value as i64,
|
|
||||||
send_cookies: settings.send_cookies.value,
|
|
||||||
store_cookies: settings.store_cookies.value,
|
|
||||||
},
|
|
||||||
setting_events,
|
|
||||||
cookie_jar,
|
cookie_jar,
|
||||||
};
|
};
|
||||||
// JSON-compatible, as `rpc` does: the tab posts this to the proxy with `JSON.stringify`,
|
// JSON-compatible, as `rpc` does: the tab posts this to the proxy with `JSON.stringify`,
|
||||||
@@ -509,39 +490,6 @@ pub async fn prepare_http_send(payload: JsValue) -> Result<JsValue> {
|
|||||||
prepared.serialize(&serde_wasm_bindgen::Serializer::json_compatible()).map_err(js_error)
|
prepared.serialize(&serde_wasm_bindgen::Serializer::json_compatible()).map_err(js_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The same five `Setting` lines `crates/yaak/src/send.rs` writes at the top of every send.
|
|
||||||
fn setting_events(settings: &ResolvedHttpRequestSettings) -> Vec<HttpResponseEventData> {
|
|
||||||
fn event<T: ToString>(
|
|
||||||
name: &str,
|
|
||||||
value: String,
|
|
||||||
setting: &ResolvedSetting<T>,
|
|
||||||
) -> HttpResponseEventData {
|
|
||||||
HttpResponseEventData::Setting {
|
|
||||||
name: name.to_string(),
|
|
||||||
value,
|
|
||||||
source_model: Some(setting.source_model.clone()),
|
|
||||||
source_id: setting.source_id.clone(),
|
|
||||||
source_name: setting.source_name.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let timeout = if settings.request_timeout.value > 0 {
|
|
||||||
format!("{}ms", settings.request_timeout.value)
|
|
||||||
} else {
|
|
||||||
"Infinity".to_string()
|
|
||||||
};
|
|
||||||
vec![
|
|
||||||
event(
|
|
||||||
"validate_certificates",
|
|
||||||
settings.validate_certificates.value.to_string(),
|
|
||||||
&settings.validate_certificates,
|
|
||||||
),
|
|
||||||
event("redirects", settings.follow_redirects.value.to_string(), &settings.follow_redirects),
|
|
||||||
event("timeout", timeout, &settings.request_timeout),
|
|
||||||
event("send_cookies", settings.send_cookies.value.to_string(), &settings.send_cookies),
|
|
||||||
event("store_cookies", settings.store_cookies.value.to_string(), &settings.store_cookies),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* Blobs */
|
/* Blobs */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|||||||
+20
-54
@@ -24,8 +24,8 @@ use yaak_http::types::{
|
|||||||
use yaak_models::blob_manager::{BlobManager, BodyChunk};
|
use yaak_models::blob_manager::{BlobManager, BodyChunk};
|
||||||
use yaak_models::models::{
|
use yaak_models::models::{
|
||||||
ClientCertificate, Cookie, CookieJar, DnsOverride, Environment, HttpRequest, HttpResponse,
|
ClientCertificate, Cookie, CookieJar, DnsOverride, Environment, HttpRequest, HttpResponse,
|
||||||
HttpResponseEvent, HttpResponseHeader, HttpResponseState, ProxySetting, ProxySettingAuth,
|
HttpResponseEvent, HttpResponseEventData, HttpResponseHeader, HttpResponseState, ProxySetting,
|
||||||
ResolvedHttpRequestSettings, ResolvedSetting,
|
ProxySettingAuth, ResolvedHttpRequestSettings,
|
||||||
};
|
};
|
||||||
use yaak_models::query_manager::QueryManager;
|
use yaak_models::query_manager::QueryManager;
|
||||||
use yaak_models::render::render_http_request;
|
use yaak_models::render::render_http_request;
|
||||||
@@ -716,36 +716,24 @@ pub async fn send_http_request<T: TemplateCallback>(
|
|||||||
let started_at = Instant::now();
|
let started_at = Instant::now();
|
||||||
let request_started_url = sendable_request.url.clone();
|
let request_started_url = sendable_request.url.clone();
|
||||||
|
|
||||||
send_setting_event(
|
for event in resolved_settings.timeline_events() {
|
||||||
&event_tx,
|
if let HttpResponseEventData::Setting {
|
||||||
"validate_certificates",
|
name,
|
||||||
resolved_settings.validate_certificates.value.to_string(),
|
value,
|
||||||
&resolved_settings.validate_certificates,
|
source_model,
|
||||||
);
|
source_id,
|
||||||
send_setting_event(
|
source_name,
|
||||||
&event_tx,
|
} = event
|
||||||
"redirects",
|
{
|
||||||
sendable_request.options.follow_redirects.to_string(),
|
let _ = event_tx.try_send(SenderHttpResponseEvent::Setting {
|
||||||
&resolved_settings.follow_redirects,
|
name,
|
||||||
);
|
value,
|
||||||
send_setting_event(
|
source_model,
|
||||||
&event_tx,
|
source_id,
|
||||||
"timeout",
|
source_name,
|
||||||
timeout_setting_value(sendable_request.options.timeout),
|
});
|
||||||
&resolved_settings.request_timeout,
|
}
|
||||||
);
|
}
|
||||||
send_setting_event(
|
|
||||||
&event_tx,
|
|
||||||
"send_cookies",
|
|
||||||
cookie_behavior.send_cookies.to_string(),
|
|
||||||
&resolved_settings.send_cookies,
|
|
||||||
);
|
|
||||||
send_setting_event(
|
|
||||||
&event_tx,
|
|
||||||
"store_cookies",
|
|
||||||
cookie_behavior.store_cookies.to_string(),
|
|
||||||
&resolved_settings.store_cookies,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut http_response =
|
let mut http_response =
|
||||||
match executor.send(sendable_request, event_tx, cookie_behavior.clone()).await {
|
match executor.send(sendable_request, event_tx, cookie_behavior.clone()).await {
|
||||||
@@ -1131,28 +1119,6 @@ pub fn persist_cookies_after_send(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_setting_event<T>(
|
|
||||||
event_tx: &mpsc::Sender<SenderHttpResponseEvent>,
|
|
||||||
name: impl Into<String>,
|
|
||||||
value: impl Into<String>,
|
|
||||||
setting: &ResolvedSetting<T>,
|
|
||||||
) {
|
|
||||||
let _ = event_tx.try_send(SenderHttpResponseEvent::Setting {
|
|
||||||
name: name.into(),
|
|
||||||
value: value.into(),
|
|
||||||
source_model: Some(setting.source_model.clone()),
|
|
||||||
source_id: setting.source_id.clone(),
|
|
||||||
source_name: setting.source_name.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn timeout_setting_value(timeout: Option<Duration>) -> String {
|
|
||||||
match timeout {
|
|
||||||
Some(timeout) if !timeout.is_zero() => format!("{timeout:?}"),
|
|
||||||
_ => "Infinity".to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn proxy_setting_from_settings(proxy: Option<ProxySetting>) -> HttpConnectionProxySetting {
|
fn proxy_setting_from_settings(proxy: Option<ProxySetting>) -> HttpConnectionProxySetting {
|
||||||
match proxy {
|
match proxy {
|
||||||
None => HttpConnectionProxySetting::System,
|
None => HttpConnectionProxySetting::System,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import type {
|
|||||||
HttpRequest,
|
HttpRequest,
|
||||||
HttpResponseEventData,
|
HttpResponseEventData,
|
||||||
HttpResponseHeader,
|
HttpResponseHeader,
|
||||||
|
HttpSendSettings,
|
||||||
} from "@yaakapp-internal/models";
|
} from "@yaakapp-internal/models";
|
||||||
|
|
||||||
/* ------------------------------- location -------------------------------- */
|
/* ------------------------------- location -------------------------------- */
|
||||||
@@ -38,13 +39,7 @@ export function proxySendUrl(): string {
|
|||||||
export interface ProxyRequestBody {
|
export interface ProxyRequestBody {
|
||||||
/** The rendered request, in the model shape (see `wire.rs` `SendRequest.request`). */
|
/** The rendered request, in the model shape (see `wire.rs` `SendRequest.request`). */
|
||||||
request: HttpRequest;
|
request: HttpRequest;
|
||||||
settings: {
|
settings: HttpSendSettings;
|
||||||
validateCertificates: boolean;
|
|
||||||
followRedirects: boolean;
|
|
||||||
timeoutMs: number;
|
|
||||||
sendCookies: boolean;
|
|
||||||
storeCookies: boolean;
|
|
||||||
};
|
|
||||||
/** The jar's cookies to start from, or `null` for no jar at all. */
|
/** The jar's cookies to start from, or `null` for no jar at all. */
|
||||||
cookies: Cookie[] | null;
|
cookies: Cookie[] | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import type {
|
|||||||
HttpRequest,
|
HttpRequest,
|
||||||
HttpResponse,
|
HttpResponse,
|
||||||
HttpResponseEventData,
|
HttpResponseEventData,
|
||||||
|
HttpSendSettings,
|
||||||
} from "@yaakapp-internal/models";
|
} from "@yaakapp-internal/models";
|
||||||
import type { WorkerConnection } from "./connection";
|
import type { WorkerConnection } from "./connection";
|
||||||
import type { ProxyFrame, ProxyRequestBody, ProxySendResponse } from "./proxy";
|
import type { ProxyFrame, ProxyRequestBody, ProxySendResponse } from "./proxy";
|
||||||
@@ -50,7 +51,7 @@ type ResponsePatch = Partial<HttpResponse>;
|
|||||||
/** What `prepare_http_send` (crates/yaak-web) hands back. */
|
/** What `prepare_http_send` (crates/yaak-web) hands back. */
|
||||||
interface PreparedHttpSend {
|
interface PreparedHttpSend {
|
||||||
request: HttpRequest;
|
request: HttpRequest;
|
||||||
settings: ProxyRequestBody["settings"];
|
settings: HttpSendSettings;
|
||||||
settingEvents: HttpResponseEventData[];
|
settingEvents: HttpResponseEventData[];
|
||||||
cookieJar: CookieJar | null;
|
cookieJar: CookieJar | null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user