Skip to content

Instantly share code, notes, and snippets.

@justinrlle
Last active July 20, 2020 10:54
Show Gist options
  • Save justinrlle/732e916ff65aa6a7111f0360027f0ab3 to your computer and use it in GitHub Desktop.
Save justinrlle/732e916ff65aa6a7111f0360027f0ab3 to your computer and use it in GitHub Desktop.
https://github.com/sagebind/isahc does not send empty headers

When passing an empty header to isahc, it is not send inside the request.

It looks like this is the default behavior of curl, but it can be overriden:

$ curl -H 'X-with-value: a value which is preserved' -H 'X-without-value:' https://httpbin.org/get
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.65.3", 
    "X-Amzn-Trace-Id": "Root=1-5f157454-942b9837318cfebb67180e01", 
    "X-With-Value": "a value which is preserved"
  }, 
  "origin": "REDACTED", 
  "url": "https://httpbin.org/get"
}
# but if we add a `-H 'X-without-value;'`, it works
$ curl -H 'X-with-value: a value which is preserved' -H 'X-without-value:' -H 'X-without-value;' https://httpbin.org/get
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.65.3", 
    "X-Amzn-Trace-Id": "Root=1-5f157471-2b95cde35a4027182631ca8d", 
    "X-With-Value": "a value which is preserved", 
    "X-Without-Value": ""
  }, 
  "origin": "REDACTED", 
  "url": "https://httpbin.org/get"
}
[package]
name = "isahc-empty-headers"
version = "0.1.0"
authors = ["JustinRlle <[email protected]>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "isahc-empty-headers"
path = "./main.rs"
[dependencies]
isahc = "0.9.5"
use isahc::http::Request;
use std::io::Read;
fn main() {
let req = Request::builder()
.uri("https://httpbin.org/get")
.header("X-with-value", "a value which is preserved")
.header("X-without-value", "")
.body(()).expect("failed to build request");
println!("-> request:\n{:#?}", req);
let res = isahc::send(req).expect("failed to send request");
println!("-> response:\n{:#?}", res);
let mut body = res.into_body();
let mut buffer = Vec::new();
body.read_to_end(&mut buffer).expect("failed to read body");
let body = String::from_utf8(buffer).expect("body is invalid utf-8");
println!("-> body:\n{}", body);
}
-> request:
Request {
method: GET,
uri: https://httpbin.org/get,
version: HTTP/1.1,
headers: {
"x-with-value": "a value which is preserved",
"x-without-value": "",
},
body: (),
}
-> response:
Response {
status: 200,
version: HTTP/2.0,
headers: {
"date": "Mon, 20 Jul 2020 10:36:32 GMT",
"content-type": "application/json",
"content-length": "363",
"server": "gunicorn/19.9.0",
"access-control-allow-origin": "*",
"access-control-allow-credentials": "true",
},
body: Body(363),
}
-> body:
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "deflate, gzip",
"Host": "httpbin.org",
"User-Agent": "curl/7.70.0-DEV isahc/0.9.5",
"X-Amzn-Trace-Id": "Root=1-5f1573b0-a7a7fdf43076e25ceaa9e2b0",
"X-With-Value": "a value which is preserved"
},
"origin": "REDACTED",
"url": "https://httpbin.org/get"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment