elixir-mint / mint

Functional HTTP client for Elixir with support for HTTP/1 and HTTP/2 🌱
Apache License 2.0
1.37k stars 112 forks source link

:invalid_header_name for headers that begin with a colon (:) #370

Closed s3cur3 closed 2 years ago

s3cur3 commented 2 years ago

Hi there! Lemme start by saying thank you for maintaining such a foundational library in the Elixir community. ❤️

I have a project where I'm trying to replay browser interactions, and I'd like to do so exactly, down to the request headers. I'm hitting an error, though, trying to use Mint to send the exact headers that a real Chromium-based browser did. The headers that begin with a : character (":authority", ":method", ":path", and ":scheme") are rejected by Mint as invalid.

Here's an example of the headers I'm trying to reproduce:

chromium-request-headers

Minimal reproducer:

iex(1)> {:ok, conn} = Mint.HTTP.connect(:http, "httpbin.org", 80)
iex(2)> Mint.HTTP.request(conn, "GET", "/", [{":scheme", "http"}], "") 
{:error,
 %Mint.HTTP1{
   buffer: "",
   host: "httpbin.org",
   mode: :active,
   port: 80,
   private: %{},
   proxy_headers: [],
   request: nil,
   requests: {[], []},
   scheme_as_string: "http",
   socket: #Port<0.208>,
   state: :open,
   streaming_request: nil,
   transport: Mint.Core.Transport.TCP
 },
 %Mint.HTTPError{module: Mint.HTTP1, reason: {:invalid_header_name, ":scheme"}}}

If this is a behavior you're interested in changing, I'd be happy to submit a PR.

ericmj commented 2 years ago

You shouldn't be setting those headers manually, they will be picked up from other places (such as Mint.HTTP.connect/3) and set as appropriate by Mint.

Also, they are HTTP/2 specific headers so they will not be set for HTTP/1 requests.

s3cur3 commented 2 years ago

Ahhh... Thanks for pointing me in the right direction. Yeah, the reason I wasn't getting the headers by default was that I was on an HTTP1 connection. Thanks so much!