tduccuong

tduccuong

HTTPoison & Cowboy 2 with HTTP2 support

I am writing a HTTP proxy based on Cowboy 2.7. Everything is fine except when it comes to HTTP2 support. Here is the context (sorry for the hidden parts):

$ curl --resolve www.wikipedia.org:443:192.168.178.2 https://www.wikipedia.org --cacert ca.crt -v
* Added www.wikipedia.org:443:192.168.178.2 to DNS cache
* Rebuilt URL to: https://www.wikipedia.org/
* Hostname www.wikipedia.org was found in DNS cache
*   Trying 192.168.178.2...
* TCP_NODELAY set
* Connected to www.wikipedia.org (192.168.178.2) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: ca.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Client hello (1):
* TLSv1.3 (OUT), TLS Unknown, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=<hidden>; ST=None; L=None; O=None; CN=*.www.wikipedia.org
*  start date: Nov 11 12:18:32 2020 GMT
*  expire date: Nov 11 12:18:32 2021 GMT
*  subjectAltName: host "www.wikipedia.org" matched cert's "www.wikipedia.org"
*  issuer: C=<hidden>; ST=<hidden>; L=<hidden>; O=<hidden>; CN=<hidden>; emailAddress=<hidden>
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* Using Stream ID: 1 (easy handle 0x55df610ea580)
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
> GET / HTTP/2
> Host: www.wikipedia.org
> User-Agent: curl/7.58.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
* TLSv1.3 (IN), TLS Unknown, Unknown (23):
* http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [Accept-Ranges], value: [bytes]
* TLSv1.3 (OUT), TLS Unknown, Unknown (23):
* HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
* Connection #0 to host www.wikipedia.org left intact
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

where 192.168.178.2 is the IP of my proxy. I am using a self-signed CA cert for testing, the proxy generates certs for the requested domains on the fly based on the CA cert. If I force curl to use HTTP1.1 then everything is fine (i received the target website content as expected):

$ curl --resolve www.wikipedia.org:443:192.168.178.59 https://www.wikipedia.org --cacert ca.crt --http1.1 -v

Inside the Cowboy-based proxy, upon receiving a request, I use HTTPoison to make the request to the target domain and just relay the response back to client (after removing Content-Length) using the standard :cowboy_req.reply function.

My question is, did I miss anything? Maybe I have to force HTTPoison to use HTTP1.1, if so then how?

Thanks a lot!

Marked As Solved

tduccuong

tduccuong

I solved the problem. Cowboy does not seem to like capital-case header keys, e.g., Set-Cookie, Content-Length. Lowercase the headers keys before feeding the headers to Cowboy makes it happy.

Where Next?

Popular in Questions Top

RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New

Other popular topics Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 55125 245
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New

We're in Beta

About us Mission Statement