Clone in a terminal:
Commit 9f9bd43
Johan Mattsson - 2026-11-02T15:36:32+00:00
9f9bd43184cdcf93eb92c74d5438be5e3cbc921bjohan.mattsson.m@gmail.com

Show response headers

Changed files (3)

Diff

diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rsindex 4377b02..f0d7a5a 100644--- a/src-tauri/src/lib.rs+++ b/src-tauri/src/lib.rs@@ -64,9 +64,16 @@ struct PostResponse {     status: u16,     status_text: String,     url: String,+    headers: Vec<ResponseHeader>,     body: String, } +#[derive(Serialize)]+struct ResponseHeader {+    name: String,+    value: String,+}+ fn projects_file_path(app: &AppHandle) -> Result<PathBuf, String> {     let config_dir = app.path().app_config_dir().map_err(|error| {         format!("Could not find the application configuration directory: {error}")@@ -409,6 +416,14 @@ async fn send_request(         .canonical_reason()         .unwrap_or("Unknown status")         .to_owned();+    let headers = response+        .headers()+        .iter()+        .map(|(name, value)| ResponseHeader {+            name: name.as_str().to_owned(),+            value: String::from_utf8_lossy(value.as_bytes()).into_owned(),+        })+        .collect();     let body = response         .text()         .await@@ -419,6 +434,7 @@ async fn send_request(         status: status.as_u16(),         status_text,         url: response_url,+        headers,         body,     }) }diff --git a/src/lib.rs b/src/lib.rsindex 2ca2ce0..0cbb003 100644--- a/src/lib.rs+++ b/src/lib.rs@@ -54,9 +54,16 @@ struct PostResponse {     status: u16,     status_text: String,     url: String,+    headers: Vec<ResponseHeader>,     body: String, } +#[derive(Deserialize)]+struct ResponseHeader {+    name: String,+    value: String,+}+ #[component("app-root")] struct App {     #[attribute]@@ -303,6 +310,8 @@ impl RestCallSetupComponent {                 <p id="request-status" class="request-status" role="status" aria-live="polite"></p>                 <p id="request-url" class="request-url"></p>                 <section id="request-response" class="request-response" aria-label="Response" hidden>+                    <button id="response-headers-toggle" class="button-secondary response-headers-toggle" type="button" onclick="toggleResponseHeaders()" aria-controls="response-headers" aria-expanded="false">Show response headers</button>+                    <div id="response-headers" class="response-headers" hidden></div>                     <pre id="request-result"></pre>                 </section>             </main>@@ -1136,9 +1145,51 @@ fn clear_request_result() {         let _ = response.set_attribute("class", "request-response request-response-empty");         let _ = response.set_attribute("aria-hidden", "true");     }+    reset_response_headers();     try_inner_text("#request-result", ""); } +fn format_response_headers(headers: &[ResponseHeader]) -> String {+    headers+        .iter()+        .map(|header| format!("{}: {}", header.name, header.value))+        .collect::<Vec<_>>()+        .join("\n")+}++fn reset_response_headers() {+    if let Some(headers) = get_element("#response-headers") {+        let _ = headers.set_attribute("hidden", "");+        headers.set_text_content(None);+    }+    if let Some(toggle) = get_element("#response-headers-toggle") {+        let _ = toggle.set_attribute("aria-expanded", "false");+        toggle.set_text_content(Some("Show response headers"));+    }+}++#[callback(toggleResponseHeaders)]+fn toggle_response_headers() {+    let Some(headers) = get_element("#response-headers") else {+        return;+    };+    let expanded = headers.has_attribute("hidden");+    if expanded {+        let _ = headers.remove_attribute("hidden");+    } else {+        let _ = headers.set_attribute("hidden", "");+    }++    if let Some(toggle) = get_element("#response-headers-toggle") {+        let _ = toggle.set_attribute("aria-expanded", if expanded { "true" } else { "false" });+        toggle.set_text_content(Some(if expanded {+            "Hide response headers"+        } else {+            "Show response headers"+        }));+    }+}+ fn format_response_body(body: &str) -> String {     serde_json::from_str::<serde_json::Value>(body)         .and_then(|value| serde_json::to_string_pretty(&value))@@ -1151,17 +1202,17 @@ fn render_request_response(response: PostResponse) {         &format!("{} {}", response.method, response.url),     ); -    if response.body.trim().is_empty() {-        clear_request_result();-        return;-    }-     if let Some(response_container) = get_element("#request-response") {         let _ = response_container.remove_attribute("hidden");         let _ = response_container.set_attribute("class", "request-response");         let _ = response_container.remove_attribute("aria-hidden");     } +    reset_response_headers();+    try_inner_text(+        "#response-headers",+        &format_response_headers(&response.headers),+    );     try_inner_text("#request-result", &format_response_body(&response.body));     if let Some(result) = get_element("#request-result") {         let _ = result.remove_attribute("style");diff --git a/src/styles.css b/src/styles.cssindex 04b0ac1..00738fe 100644--- a/src/styles.css+++ b/src/styles.css@@ -432,6 +432,28 @@ button:focus-visible {   visibility: hidden; } +.response-headers-toggle {+  margin: 14px 14px 0;+}++.response-headers {+  margin: 12px 14px 0;+  padding: 12px;+  color: #334155;+  background: #ffffff;+  border: 1px solid #cbd5e1;+  border-radius: 7px;+  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;+  font-size: 0.875rem;+  line-height: 1.5;+  white-space: pre-wrap;+  overflow-wrap: anywhere;+}++.response-headers[hidden] {+  display: none;+}+ #request-result {   box-sizing: border-box;   margin: 0;@@ -545,6 +567,12 @@ button:focus-visible {     border-color: #334155;   } +  .response-headers {+    color: #cbd5e1;+    background: #1f2937;+    border-color: #334155;+  }+   button {     background: #1d4ed8;     border-color: #1d4ed8;

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112