Commit f589728f authored by Petar Maymounkov's avatar Petar Maymounkov Committed by Russ Cox

http: in ServerConn and ClientConn, rename Close to Hijack, add Close

R=rsc
CC=golang-dev
https://golang.org/cl/4372046
parent 361e4e5f
...@@ -20,8 +20,8 @@ var ( ...@@ -20,8 +20,8 @@ var (
// A ServerConn reads requests and sends responses over an underlying // A ServerConn reads requests and sends responses over an underlying
// connection, until the HTTP keepalive logic commands an end. ServerConn // connection, until the HTTP keepalive logic commands an end. ServerConn
// does not close the underlying connection. Instead, the user calls Close // also allows hijacking the underlying connection by calling Hijack
// and regains control over the connection. ServerConn supports pipe-lining, // to regain control over the connection. ServerConn supports pipe-lining,
// i.e. requests can be read out of sync (but in the same order) while the // i.e. requests can be read out of sync (but in the same order) while the
// respective responses are sent. // respective responses are sent.
type ServerConn struct { type ServerConn struct {
...@@ -45,11 +45,11 @@ func NewServerConn(c net.Conn, r *bufio.Reader) *ServerConn { ...@@ -45,11 +45,11 @@ func NewServerConn(c net.Conn, r *bufio.Reader) *ServerConn {
return &ServerConn{c: c, r: r, pipereq: make(map[*Request]uint)} return &ServerConn{c: c, r: r, pipereq: make(map[*Request]uint)}
} }
// Close detaches the ServerConn and returns the underlying connection as well // Hijack detaches the ServerConn and returns the underlying connection as well
// as the read-side bufio which may have some left over data. Close may be // as the read-side bufio which may have some left over data. Hijack may be
// called before Read has signaled the end of the keep-alive logic. The user // called before Read has signaled the end of the keep-alive logic. The user
// should not call Close while Read or Write is in progress. // should not call Hijack while Read or Write is in progress.
func (sc *ServerConn) Close() (c net.Conn, r *bufio.Reader) { func (sc *ServerConn) Hijack() (c net.Conn, r *bufio.Reader) {
sc.lk.Lock() sc.lk.Lock()
defer sc.lk.Unlock() defer sc.lk.Unlock()
c = sc.c c = sc.c
...@@ -59,6 +59,15 @@ func (sc *ServerConn) Close() (c net.Conn, r *bufio.Reader) { ...@@ -59,6 +59,15 @@ func (sc *ServerConn) Close() (c net.Conn, r *bufio.Reader) {
return return
} }
// Close calls Hijack and then also closes the underlying connection
func (sc *ServerConn) Close() os.Error {
c, _ := sc.Hijack()
if c != nil {
return c.Close()
}
return nil
}
// Read returns the next request on the wire. An ErrPersistEOF is returned if // Read returns the next request on the wire. An ErrPersistEOF is returned if
// it is gracefully determined that there are no more requests (e.g. after the // it is gracefully determined that there are no more requests (e.g. after the
// first request on an HTTP/1.0 connection, or after a Connection:close on a // first request on an HTTP/1.0 connection, or after a Connection:close on a
...@@ -199,9 +208,9 @@ func (sc *ServerConn) Write(req *Request, resp *Response) os.Error { ...@@ -199,9 +208,9 @@ func (sc *ServerConn) Write(req *Request, resp *Response) os.Error {
} }
// A ClientConn sends request and receives headers over an underlying // A ClientConn sends request and receives headers over an underlying
// connection, while respecting the HTTP keepalive logic. ClientConn is not // connection, while respecting the HTTP keepalive logic. ClientConn
// responsible for closing the underlying connection. One must call Close to // supports hijacking the connection calling Hijack to
// regain control of that connection and deal with it as desired. // regain control of the underlying net.Conn and deal with it as desired.
type ClientConn struct { type ClientConn struct {
lk sync.Mutex // read-write protects the following fields lk sync.Mutex // read-write protects the following fields
c net.Conn c net.Conn
...@@ -239,11 +248,11 @@ func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn { ...@@ -239,11 +248,11 @@ func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn {
return cc return cc
} }
// Close detaches the ClientConn and returns the underlying connection as well // Hijack detaches the ClientConn and returns the underlying connection as well
// as the read-side bufio which may have some left over data. Close may be // as the read-side bufio which may have some left over data. Hijack may be
// called before the user or Read have signaled the end of the keep-alive // called before the user or Read have signaled the end of the keep-alive
// logic. The user should not call Close while Read or Write is in progress. // logic. The user should not call Hijack while Read or Write is in progress.
func (cc *ClientConn) Close() (c net.Conn, r *bufio.Reader) { func (cc *ClientConn) Hijack() (c net.Conn, r *bufio.Reader) {
cc.lk.Lock() cc.lk.Lock()
defer cc.lk.Unlock() defer cc.lk.Unlock()
c = cc.c c = cc.c
...@@ -253,6 +262,15 @@ func (cc *ClientConn) Close() (c net.Conn, r *bufio.Reader) { ...@@ -253,6 +262,15 @@ func (cc *ClientConn) Close() (c net.Conn, r *bufio.Reader) {
return return
} }
// Close calls Hijack and then also closes the underlying connection
func (cc *ClientConn) Close() os.Error {
c, _ := cc.Hijack()
if c != nil {
return c.Close()
}
return nil
}
// Write writes a request. An ErrPersistEOF error is returned if the connection // Write writes a request. An ErrPersistEOF error is returned if the connection
// has been closed in an HTTP keepalive sense. If req.Close equals true, the // has been closed in an HTTP keepalive sense. If req.Close equals true, the
// keepalive connection is logically closed after this request and the opposing // keepalive connection is logically closed after this request and the opposing
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment