Reverse proxy & feedback #3120
antoniosarosi
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I've been working on a little reverse proxy project over the last couple weeks, nothing serious, just for fun. Here are some issues I found specific to
hyperand this kind of projects:HTTP/1.1 Upgraded connections
There is an example of how connection upgrades work with
hyperhere, but it doesn't apply to reverse proxies, since they don't handle the upgraded connection themselves. Instead, they have to set up a tunnel and forward data from the client to the upstream server and viceversa. There is also an example of how to set up a tunnel here, this is used with theCONNECTheader by a forward proxy. The problem with a reverse proxy is that it cannot immediately upgrade the connection, it has to send the request to the upstream server and wait for theHTTP 101response, then upgrade the connection and send that response back to the client.The examples use
hyper::upgrade::onto upgrade on either a request or response. The issue is that upgrading on a request as a server requires giving up ownership on that request, because you need to spawn a Tokio task since thehyper::upgrade::onfuture will not resolve until you send anHTTP 101response back to the client. From this example:As a reverse proxy, you have to forward the incoming request to the upstream server and also upgrade on it, which you can't do easily because for both actions you need ownership on the request. So this is more or less what I ended up doing:
I found out while reading through the source code that
hyper::upgrade::onbasically calls this function:So I figured out I can do that manually and then await the
OnUpgradefutures like this:It works, but I'm not sure if it's okay to remove that extension from the request and response.
No access to the underlying socket
I implemented the
ForwardedHTTP header, for which I need to know my listening address and the client address. In previous versions (I'm using1.0.0-rc2) there was a methodremote_addr()on the request or an extension type, but it's not available anymore. I found this response to an issue from 2018, so that's what I did, I just made my own struct that implementsService:This is not a really a problem but it adds boilerplate, because if I could get the socket addresses from the request I wouldn't have to implement
Service, I could useservice_fnand a function.Body types
Other than that everything was great, I just missed some documentation on body types as some examples (http_proxy, web_api, echo) tend to use
BoxBodybut they don't explain why. I'm assuming it's becauseBoxBodycan represent both an incoming body and a complete body, so it's useful for echoing requests or sending a custom 404 response under the same return type. I'll update this discussion if I find more issues while implementing new features.Beta Was this translation helpful? Give feedback.
All reactions