///|
fn BidiProtocol::perform_synthetic_fetch_step(
self : BidiProtocol,
request_id : Int,
context_id : String,
request_step : @crater_network.SyntheticFetchPlanEntry,
raw_request_headers : Array[Json],
should_abort : Bool,
) -> @crater_network.SyntheticFetchStepResult {
let resolved_request_headers = self.resolve_network_extra_header_entries(
context_id, raw_request_headers,
)
let base_input : @crater_network.SyntheticNetworkEventInput = {
context_id,
url: request_step.url,
http_method: request_step.http_method,
request_token: request_step.request_token,
request_headers: resolved_request_headers,
request_value: request_step.request_value,
request_cookies: [],
request_cookies_override: false,
intercepts: [],
redirect_count: request_step.redirect_count,
navigation: None,
destination: "",
initiator_type: Some("fetch"),
}
let response_overrides = self.resolve_synthetic_response_overrides_internal(
context_id,
request_step.url,
request_step.http_method,
resolved_request_headers,
true,
)
let before_intercepts = self.resolve_matching_network_intercepts_internal(
context_id,
"beforeRequestSent",
request_step.url,
)
let before_subscribed = self.is_subscribed_for_context(
"network.beforeRequestSent", context_id,
)
let before_blocked = before_subscribed && before_intercepts.length() > 0
if before_subscribed {
let before_input = {
..base_input,
intercepts: if before_blocked {
before_intercepts
} else {
[]
},
}
match
self.build_synthetic_before_request_sent_event_json(
request_id, before_input,
) {
Some(event) =>
self.outbox.push(
Event({ event_method: "network.beforeRequestSent", params: event }),
)
None => return { blocked_text: None, response_value: None }
}
}
if before_blocked {
let blocked_request : Map[String, Json] = {
"phase": Json::string("beforeRequestSent"),
"context_id": Json::string(context_id),
"url": Json::string(request_step.url),
"method": Json::string(request_step.http_method),
"request_headers": synthetic_navigation_header_object_from_entries(
raw_request_headers,
),
"redirect_count": Json::number(request_step.redirect_count.to_double()),
"navigation": Json::null(),
"destination": Json::string(""),
"initiator_type": Json::string("fetch"),
"is_navigation": Json::boolean(false),
}
match request_step.request_value {
Some(request_value) => blocked_request["request_value"] = request_value
None => ()
}
self.remember_network_blocked_request(
request_step.request_token,
blocked_request,
)
return {
blocked_text: Some("Request blocked by network intercept"),
response_value: None,
}
}
if should_abort ||
synthetic_navigation_is_unreachable_test_url(request_step.url) {
if self.is_subscribed_for_context("network.fetchError", context_id) {
match
self.build_synthetic_fetch_error_event_json(
request_id, base_input, "Request failed",
) {
Some(event) =>
self.outbox.push(
Event({ event_method: "network.fetchError", params: event }),
)
None => ()
}
}
return { blocked_text: None, response_value: None }
}
let response_started_intercepts = self.resolve_matching_network_intercepts_internal(
context_id,
"responseStarted",
request_step.url,
)
let response_started_subscribed = self.is_subscribed_for_context(
"network.responseStarted", context_id,
)
let response_started_blocked = response_started_subscribed &&
response_started_intercepts.length() > 0
let mut response_started_event : Json? = None
if response_started_subscribed {
let response_input = {
..base_input,
intercepts: if response_started_blocked {
response_started_intercepts
} else {
[]
},
}
response_started_event = self.build_synthetic_response_event_json(
request_id, response_input, response_overrides,
)
match response_started_event {
Some(event) =>
self.outbox.push(
Event({ event_method: "network.responseStarted", params: event }),
)
None => return { blocked_text: None, response_value: None }
}
}
if response_started_blocked {
let blocked_request = synthetic_navigation_blocked_request_payload(
base_input, "responseStarted", response_started_event,
)
blocked_request["is_navigation"] = Json::boolean(false)
self.remember_network_blocked_request(
request_step.request_token,
blocked_request,
)
return {
blocked_text: Some("Request blocked by responseStarted intercept"),
response_value: None,
}
}
let auth_required_intercepts = self.resolve_matching_network_intercepts_internal(
context_id,
"authRequired",
request_step.url,
)
let auth_required_subscribed = self.is_subscribed_for_context(
"network.authRequired", context_id,
)
let auth_required_needed = synthetic_navigation_requires_auth_event(
response_overrides,
)
let auth_required_blocked = auth_required_needed &&
auth_required_subscribed &&
auth_required_intercepts.length() > 0
let mut auth_required_event : Json? = None
if auth_required_subscribed && auth_required_needed {
let auth_overrides : @crater_network.SyntheticNetworkResponseOverrides = if auth_required_blocked {
{
from_cache: response_overrides.from_cache,
headers: response_overrides.headers,
mime_type: response_overrides.mime_type,
protocol: response_overrides.protocol,
status: 401,
status_text: "Unauthorized",
auth_challenges: Some(
Json::array([
make_object({
"scheme": Json::string("Basic"),
"realm": Json::string("testrealm"),
}),
]),
),
}
} else {
response_overrides
}
let auth_input = {
..base_input,
intercepts: if auth_required_blocked {
auth_required_intercepts
} else {
[]
},
}
auth_required_event = self.build_synthetic_response_event_json(
request_id, auth_input, auth_overrides,
)
match auth_required_event {
Some(event) =>
self.outbox.push(
Event({ event_method: "network.authRequired", params: event }),
)
None => return { blocked_text: None, response_value: None }
}
}
if auth_required_blocked {
let blocked_request = synthetic_navigation_blocked_request_payload(
base_input, "authRequired", auth_required_event,
)
blocked_request["is_navigation"] = Json::boolean(false)
self.remember_network_blocked_request(
request_step.request_token,
blocked_request,
)
return {
blocked_text: Some("Request blocked by authRequired intercept"),
response_value: None,
}
}
let response_value = synthetic_fetch_synthesize_response_value(
request_step.url,
if synthetic_fetch_is_headers_echo_url(request_step.url) {
Some(
self.build_network_headers_echo_payload(
context_id, resolved_request_headers,
),
)
} else {
None
},
)
self.remember_network_collected_data_internal(
context_id,
request_step.request_token,
request_step.request_value,
Some(response_value),
)
if self.is_subscribed_for_context("network.responseCompleted", context_id) {
match
self.build_synthetic_response_event_json(
request_id, base_input, response_overrides,
) {
Some(event) =>
self.outbox.push(
Event({ event_method: "network.responseCompleted", params: event }),
)
None =>
return { blocked_text: None, response_value: Some(response_value) }
}
}
{ blocked_text: None, response_value: Some(response_value) }
}