# π HTTP(S) proxies
<div class="book-article-intro">
<img src="../img/proxy_llama_http.jpeg" alt="artistical representation of rama http proxy as llamas spread across the globe">
<div>
HTTP(S) proxies forward HTTP requests. The request from the client is the same as a regular HTTP request except the full URL is passed, instead of just the path. Some web proxies allow the HTTP CONNECT method to set up forwarding of arbitrary data through the connection; a common policy is to only forward port 443 to allow HTTPS traffic.
<p>β <a href="https://en.wikipedia.org/wiki/Proxy_server#Web_proxy_servers">Wikipedia</a></p>
</div>
</div>
[Examples](https://github.com/plabayo/rama/tree/main/examples):
- [/examples/http_connect_proxy.rs](https://github.com/plabayo/rama/tree/main/examples/http_connect_proxy.rs):
Spawns a minimal http proxy which accepts http/1.1 and h2 connections alike,
and proxies them to the target host.
- [/examples/https_connect_proxy.rs](https://github.com/plabayo/rama/tree/main/examples/https_connect_proxy.rs):
Spawns a minimal https connect proxy which accepts http/1.1 and h2 connections alike,
and proxies them to the target host through a TLS tunnel.
## Description
<div class="book-article-image-center">
```dot process
digraph {
pad=0.2;
"client" -> "proxy (rama)" [dir=both]
"proxy (rama)" -> "server A" [dir=both]
"proxy (rama)" -> "server B" [dir=both]
}
```
</div>
You'll notice that the above graph is the exact same one used in
[the Reverse Proxies chapter](./reverse.md). In an abstract topology sense
this is expected, however there are typically differences:
- The client, proxy and server are typically in 3 different intranets,
with communication going typically over the intranet;
- The use cases of a reverse proxy are very wide, while
those of the http proxy are pretty specific.
The most common use case of an http(s) proxy is to
conceal the MAC (~L3) and IP address (~L4) of the client, and have the request
originate instead from the http(s) proxy.
```
HTTP Proxy relaying HTTPS requests
------------------------------------
ββββββββββ ββββββββββββββββ ββββββββββββββββββββββ
β Client ββββββββΆβ HTTP Proxy ββββββββΆβ Target Server (TLS)β
ββββββββββ ββββββββββββββββ ββββββββββββββββββββββ
β β β
β 1. TCP connect to proxy (e.g., :3128) β
ββββββββββββββββββΆβ β
β β β
β 2. Send HTTP CONNECT request β
β e.g., β
β CONNECT example.com:443 HTTP/1.1 β
β Host: example.com:443 β
ββββββββββββββββββΆβ β
β β β
β 3. Proxy establishes TCP to server β
β βββββββββββββββββββββββββΆβ
β β β
β 4. Proxy replies with 200 OK β
βββββββββββββββββββ β
β β β
β 5. TLS handshake begins (client β server)β
βββββββββββββββββββββββββββββββββββββββββββΆβ
β β β
β 6. Encrypted HTTP(S) traffic relayed β
βββββββββββββββββββββββββββββββββββββββββββΆβ
```
> Flow of a regular "HTTP CONNECT" proxy.
In case the client request is encrypted (TLS) it will typically make a
plaintext (http/1.1) request with the "CONNECT" method to the proxy,
whom on the behalve of the client will establish an encrypted tunnel
to the target (server), from there it will:
- either just copy the data between the two connections as they are;
- or it might act as [a MITM proxy](./mitm.md) and actually read and
possibly even modify the incoming (http) request prior to sending
it to the target client. In this case it might even act
as [a distortion proxy](./distort.md).
In case we are dealing with TLS-encrypted traffic it does mean that the client
most likely will have to accept/approve the authority of the proxy's TLS certification,
given it will not match the expected target (server) TLS certificate. Depending on the
client's network policies this might be handled automatically due to the use
of a non-public [root certificate](https://en.wikipedia.org/wiki/Root_certificate).
```plaintext
HTTP Proxy relaying HTTP requests
-----------------------------------
ββββββββββ ββββββββββββββββββ ββββββββββββββββββββββ
β Client ββββββββΆβ HTTP Proxy ββββββββΆβ Target HTTP Server β
ββββββββββ ββββββββββββββββββ ββββββββββββββββββββββ
β β β
β 1. TCP connect to proxy (:3128) β
βββββββββββββββββββΆβ β
β β β
β 2. Send full HTTP request via proxy β
β e.g., β
β GET http://example.com HTTP/1.1 β
β Host: example.com β
βββββββββββββββββββΆβ β
β β β
β 3. Proxy parses and forwards request β
β ββββββββββββββββββββββββΆ β
β β β
β 4. Target server replies with HTTP β
β ββββββββββββββββββββββββ β
β β β
β 5. Proxy may log, modify, or inject β
β β β
β 6. Proxy sends HTTP response to client β
ββββββββββββββββββββ β
β β β
β 7. Subsequent requests/responses relayed β
ββββββββββββββββββββΆββββββββββββββββββββββββΆβ
```
Plain text (http) requests are typically immediately made with the Host/Authorization
headers being equal to the desired target server. Which once again looks a lot more
like logic that a [reverse proxy](./reverse.md) would also do among one of its many tasks.
As such HTTP traffic can always be logged, modified or injected by any intermediate party,
including your HTTP proxy.
See the official RFCs for more information regarding HTTP semantics and
protocol specifications.
```plaintext
HTTP Proxy MITM'ing HTTPS requests
------------------------------------
ββββββββββ ββββββββββββββββββββββ ββββββββββββββββββββββ
β Client ββββββββΆβ HTTP Proxy (MITM) ββββββββΆβ Target Server (TLS)β
ββββββββββ ββββββββββββββββββββββ ββββββββββββββββββββββ
β β β
β 1. TCP connect β β
β to proxy (:3128)β β
βββββββββββββββββββββΆβ β
β β β
β 2. Send CONNECT β β
β example.com:443 β β
βββββββββββββββββββββΆβ β
β β β
β β 3. Proxy replies β
β ββββββββββββββββββ β with 200 OK β
β β β
β β 4. TLS handshake β
ββββββββββββββββββββΆ β with proxy β
β β (fake cert) β
β β β
β 5. Proxy connects β β
β to target:443 βββββββββββββββββββββββββββΆβ
β 6. Proxy performs β β
β TLS to server βββββββββββββββββββββββββββΆβ
β β β
β β
β 7. Encrypted HTTPS β
β relayed via MITM β
β β
βββββββββββββββββββββΆβββββββββββββββββββββββββββΆβ
```
> Flow a MITM proxy handling HTTPS traffic
>
> step (4) to (6) can be done before step (3).
> However rrama by default does these `proxy β server` steps
> lazilly only when the first actual http(s) request is received.