Separate Listen and Serve steps in net/http

352 views
Skip to first unread message

David Fifield

unread,
Mar 9, 2014, 6:01:41 AM3/9/14
to golan...@googlegroups.com
The net/http package's Server type has ListenAndServe and
ListenAndServeTLS methods that create a TCP listener and pass it into
Serve, which is an infinite loop. I wanted to be able to inspect the
created listener before it gets passed to Serve; specifically, I wanted
to find out the listener's address. The attached patch factors out
Listen and ListenTLS methods so you can inspect the listener before
calling Serve.

A separate Serve method already exists and allows you to pass in your
own listener. For plain HTTP it's no big deal to create your own
listener because ListenAndServe essentially just calls net.Listen.
https://code.google.com/p/go/source/browse/src/pkg/net/http/server.go?r=1849f83423ca#1684
However the HTTPS case is more complicated. It creates a slice for
certificates, load the certificate and key files, and sets up the
tls.Config NextProtos. The TLS setup exists only in ListenAndServeTLS;
there's no way to get the http package to set up a listener without it
also calling Serve. I can easily copy and paste the TLS setup (which is
what I am doing as a workaround), but that means my code will not notice
future TLS setup changes that happen in ListenAndServeTLS.
https://code.google.com/p/go/source/browse/src/pkg/net/http/server.go?r=1849f83423ca#1822

In summary, these methods already exist:
ListenAndServe
ListenAndServeTLS
Serve
The patch adds these two additional methods:
Listen
ListenTLS

My use case is running an HTTPS-based pluggable transport for Tor. Tor
tells the pluggable transport subprocess what address to listen on, and
the subprocess is supposed to report back with the actual address of the
listener. Tor's default behavior is to send "0.0.0.0:0" as the listening
address, meaning the subprocess should listen on an ephemeral port.
There's no way to find out what port the ":0" will become without
actually opening the listener, and currently the http package doesn't
provide a way to open a listener and do something with it before it is
passed to Serve.

David Fifield
http-separate-Listen-and-Serve.patch

Rob Pike

unread,
Mar 9, 2014, 7:09:32 AM3/9/14
to David Fifield, golan...@googlegroups.com
Thank you for your input, but please read
http://golang.org/doc/contribute.html to see how to contribute code to
the project. A patch to the mailing list is not the way. Also,
explained there, significant changes require discussion before
considering the code.

Moreover, the repository is in a feature freeze leading up to the Go
1.3 release, so we can't consider it now.

-rob

David Fifield

unread,
Mar 9, 2014, 1:36:48 PM3/9/14
to golan...@googlegroups.com
On Sun, Mar 09, 2014 at 10:09:32PM +1100, Rob Pike wrote:
> Thank you for your input, but please read
> http://golang.org/doc/contribute.html to see how to contribute code to
> the project. A patch to the mailing list is not the way. Also,
> explained there, significant changes require discussion before
> considering the code.

I meant my message to be the beginning of a mailing list discussion. The
patch was meant only as a concrete example of the kind of change I
proposed. (I had to write the patch anyway, to make sure the idea
actually worked for the program I'm writing.) I read the contribution
page carefully before writing, but I see now it wasn't clear what my
message was getting at.

I'm now using the workaround of copying code from ListenAndServeTLS,
which I can continue doing in case people don't like change.

David
Reply all
Reply to author
Forward
0 new messages