MCPcopy Index your code
hub / github.com/NativeScript/SimDeck / fetch_metro_resource

Function fetch_metro_resource

packages/server/src/devtools.rs:914–990  ·  view source on GitHub ↗

Reverse-proxies a Metro HTTP path over the SimDeck origin. The upstream request omits the browser `Origin` so Metro's dev-middleware does not reject DevTools resources.

(
    port: u16,
    path: &str,
    query: Option<&str>,
    method: &str,
    body: Option<&[u8]>,
    content_type: Option<&str>,
)

Source from the content-addressed store, hash-verified

912/// request omits the browser `Origin` so Metro's dev-middleware does not reject
913/// DevTools resources.
914pub async fn fetch_metro_resource(
915 port: u16,
916 path: &str,
917 query: Option<&str>,
918 method: &str,
919 body: Option<&[u8]>,
920 content_type: Option<&str>,
921) -> Result<ProxiedAsset, String> {
922 if !is_metro_proxy_path(path) {
923 return Err("Not a safe Metro proxy path.".to_owned());
924 }
925 if !is_metro_proxy_method(method) {
926 return Err("Not an allowed Metro proxy method.".to_owned());
927 }
928 let target = match query {
929 Some(query) => format!("{path}?{query}"),
930 None => path.to_owned(),
931 };
932 let body = body.unwrap_or(&[]);
933 let (address, mut stream) =
934 connect_loopback_devtools_service(port, METRO_ASSET_TIMEOUT, "Metro").await?;
935 let mut request = format!(
936 "{method} {target} HTTP/1.1\r\nHost: {address}\r\nAccept: */*\r\nConnection: close\r\n"
937 );
938 if !body.is_empty() {
939 request.push_str(&format!("Content-Length: {}\r\n", body.len()));
940 if let Some(content_type) = content_type {
941 request.push_str(&format!("Content-Type: {content_type}\r\n"));
942 }
943 }
944 request.push_str("\r\n");
945 timeout(METRO_ASSET_TIMEOUT, stream.write_all(request.as_bytes()))
946 .await
947 .map_err(|_| "Timed out requesting Metro asset.".to_owned())?
948 .map_err(|error| format!("Unable to request Metro asset: {error}"))?;
949 if !body.is_empty() {
950 timeout(METRO_ASSET_TIMEOUT, stream.write_all(body))
951 .await
952 .map_err(|_| "Timed out writing Metro request body.".to_owned())?
953 .map_err(|error| format!("Unable to write Metro request body: {error}"))?;
954 }
955
956 let mut response = Vec::new();
957 let mut chunk = [0_u8; 16384];
958 loop {
959 let count = timeout(METRO_ASSET_TIMEOUT, stream.read(&mut chunk))
960 .await
961 .map_err(|_| "Timed out reading Metro asset.".to_owned())?
962 .map_err(|error| format!("Unable to read Metro asset: {error}"))?;
963 if count == 0 {
964 break;
965 }
966 response.extend_from_slice(&chunk[..count]);
967 if response.len() > METRO_ASSET_MAX_BYTES {
968 return Err("Metro asset exceeded the size limit.".to_owned());
969 }
970 if response_has_complete_body(&response) {
971 break;

Calls 8

is_metro_proxy_pathFunction · 0.85
is_metro_proxy_methodFunction · 0.85
split_http_responseFunction · 0.85
header_valueFunction · 0.85
decoded_http_bodyFunction · 0.85
is_emptyMethod · 0.80

Tested by

no test coverage detected