Modify HTTP request before it is parsed in plugin

(comp500) #1

I’m planning to make a http plugin for caddy that implements the SSTP protocol, which runs over HTTPS. As the handshake is http, it can be put on the same server, as a http plugin, rather than a standalone server.

However, the net/http package doesn’t parse the handshake properly, and drops it with a 400 (Bad Request) status. As far as I know, this is because the SSTP handshake sends a Content-Length (as per the SSTP specification) of 18446744073709551615. This creates an error within net/http as it is greater than an int64, so it can’t read it.

Is it possible to modify the HTTP request before net/http parses it (but after tls decryption occurs), so that it can be changed to something that is parseable by net/http?

After it is parsed, I presume that a Hijacker can be used to then parse this within the plugin as SSTP. I’ve already written a mostly working (but dependant on pppd, which I intend to implement in pure Go) server, which doesn’t use net/http.

(Matt Holt) #2

You can write a net.Listener plugin/middleware. I’m mobile but it’s in the code and the docs somewhere. I think it’s called ListenerMiddleware. Check the github wiki too!

(comp500) #3

I see, thanks. Is it called before TLS runs on each connection, or after?

This suggests (unless I am mistaken) that it’s done on top of the TCP listener, rather than the TLS server, which works for the proxyprotocol plugin but not for modifying the actual HTTP request itself.

(comp500) #4

I tested it, and it appears to run before TLS decryption. This won’t work, as it needs to be decrypted so that the HTTP request can be rewritten. If I disable TLS, it displays the correct HTTP request data, but that defeats the point of making it a Caddy plugin.

Is there a way to modify it after this decryption?

(Matt Holt) #5

I will have to look again when my computer is back from the shop. I’m pretty sure there is a way to do this, but if not, maybe we can look into it.

(comp500) #6

I’ve written the code to modify it as ListenerMiddleware, and it works well with HTTP requests. I’ve also tested it with TLS behind stunnel, and it works with SSTP clients.

Did you get your computer back from the shop? It would be great to have a way to do this using Caddy’s TLS implementation.

Another idea that I have to use this kind of middleware is to multiplex HTTP requests with other protocols using SNI, like the net plugin but with multiple individual upstreams on the same port. I currently use SNI multiplexing on my server with stunnel, as many firewalls only allow TLS on port 443. It’s probably not the best way to implement it though, as it would be a http plugin. Do you have any thoughts on this idea?

(system) #7

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.