1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
18 // Deprecated: No longer used.
19 ErrPersistEOF
= &http
.ProtocolError
{ErrorString
: "persistent connection closed"}
21 // Deprecated: No longer used.
22 ErrClosed
= &http
.ProtocolError
{ErrorString
: "connection closed by user"}
24 // Deprecated: No longer used.
25 ErrPipeline
= &http
.ProtocolError
{ErrorString
: "pipeline error"}
28 // This is an API usage error - the local side is closed.
29 // ErrPersistEOF (above) reports that the remote side is closed.
30 var errClosed
= errors
.New("i/o operation on closed connection")
32 // ServerConn is an artifact of Go's early HTTP implementation.
33 // It is low-level, old, and unused by Go's current HTTP stack.
34 // We should have deleted it before Go 1.
36 // Deprecated: Use the Server in package net/http instead.
37 type ServerConn
struct {
38 mu sync
.Mutex
// read-write protects the following fields
41 re
, we error
// read/write errors
42 lastbody io
.ReadCloser
44 pipereq
map[*http
.Request
]uint
46 pipe textproto
.Pipeline
49 // NewServerConn is an artifact of Go's early HTTP implementation.
50 // It is low-level, old, and unused by Go's current HTTP stack.
51 // We should have deleted it before Go 1.
53 // Deprecated: Use the Server in package net/http instead.
54 func NewServerConn(c net
.Conn
, r
*bufio
.Reader
) *ServerConn
{
56 r
= bufio
.NewReader(c
)
58 return &ServerConn
{c
: c
, r
: r
, pipereq
: make(map[*http
.Request
]uint)}
61 // Hijack detaches the ServerConn and returns the underlying connection as well
62 // as the read-side bufio which may have some left over data. Hijack may be
63 // called before Read has signaled the end of the keep-alive logic. The user
64 // should not call Hijack while Read or Write is in progress.
65 func (sc
*ServerConn
) Hijack() (net
.Conn
, *bufio
.Reader
) {
75 // Close calls Hijack and then also closes the underlying connection.
76 func (sc
*ServerConn
) Close() error
{
84 // Read returns the next request on the wire. An ErrPersistEOF is returned if
85 // it is gracefully determined that there are no more requests (e.g. after the
86 // first request on an HTTP/1.0 connection, or after a Connection:close on a
87 // HTTP/1.1 connection).
88 func (sc
*ServerConn
) Read() (*http
.Request
, error
) {
92 // Ensure ordered execution of Reads and Writes
94 sc
.pipe
.StartRequest(id
)
96 sc
.pipe
.EndRequest(id
)
98 sc
.pipe
.StartResponse(id
)
99 sc
.pipe
.EndResponse(id
)
101 // Remember the pipeline id of this request
109 if sc
.we
!= nil { // no point receiving if write-side broken or closed
117 if sc
.r
== nil { // connection closed by user in the meantime
119 return nil, errClosed
122 lastbody
:= sc
.lastbody
126 // Make sure body is fully consumed, even if user does not call body.Close
128 // body.Close is assumed to be idempotent and multiple calls to
129 // it should return the error that its first invocation
131 err
= lastbody
.Close()
140 req
, err
= http
.ReadRequest(r
)
144 if err
== io
.ErrUnexpectedEOF
{
145 // A close from the opposing client is treated as a
146 // graceful close, even if there was some unparse-able
147 // data before the close.
148 sc
.re
= ErrPersistEOF
155 sc
.lastbody
= req
.Body
158 sc
.re
= ErrPersistEOF
164 // Pending returns the number of unanswered requests
165 // that have been received on the connection.
166 func (sc
*ServerConn
) Pending() int {
169 return sc
.nread
- sc
.nwritten
172 // Write writes resp in response to req. To close the connection gracefully, set the
173 // Response.Close field to true. Write should be considered operational until
174 // it returns an error, regardless of any errors returned on the Read side.
175 func (sc
*ServerConn
) Write(req
*http
.Request
, resp
*http
.Response
) error
{
177 // Retrieve the pipeline ID of this request/response pair
179 id
, ok
:= sc
.pipereq
[req
]
180 delete(sc
.pipereq
, req
)
187 // Ensure pipeline order
188 sc
.pipe
.StartResponse(id
)
189 defer sc
.pipe
.EndResponse(id
)
196 if sc
.c
== nil { // connection closed by user in the meantime
201 if sc
.nread
<= sc
.nwritten
{
203 return errors
.New("persist server pipe count")
206 // After signaling a keep-alive close, any pipelined unread
207 // requests will be lost. It is up to the user to drain them
209 sc
.re
= ErrPersistEOF
225 // ClientConn is an artifact of Go's early HTTP implementation.
226 // It is low-level, old, and unused by Go's current HTTP stack.
227 // We should have deleted it before Go 1.
229 // Deprecated: Use Client or Transport in package net/http instead.
230 type ClientConn
struct {
231 mu sync
.Mutex
// read-write protects the following fields
234 re
, we error
// read/write errors
235 lastbody io
.ReadCloser
237 pipereq
map[*http
.Request
]uint
239 pipe textproto
.Pipeline
240 writeReq
func(*http
.Request
, io
.Writer
) error
243 // NewClientConn is an artifact of Go's early HTTP implementation.
244 // It is low-level, old, and unused by Go's current HTTP stack.
245 // We should have deleted it before Go 1.
247 // Deprecated: Use the Client or Transport in package net/http instead.
248 func NewClientConn(c net
.Conn
, r
*bufio
.Reader
) *ClientConn
{
250 r
= bufio
.NewReader(c
)
255 pipereq
: make(map[*http
.Request
]uint),
256 writeReq
: (*http
.Request
).Write
,
260 // NewProxyClientConn is an artifact of Go's early HTTP implementation.
261 // It is low-level, old, and unused by Go's current HTTP stack.
262 // We should have deleted it before Go 1.
264 // Deprecated: Use the Client or Transport in package net/http instead.
265 func NewProxyClientConn(c net
.Conn
, r
*bufio
.Reader
) *ClientConn
{
266 cc
:= NewClientConn(c
, r
)
267 cc
.writeReq
= (*http
.Request
).WriteProxy
271 // Hijack detaches the ClientConn and returns the underlying connection as well
272 // as the read-side bufio which may have some left over data. Hijack may be
273 // called before the user or Read have signaled the end of the keep-alive
274 // logic. The user should not call Hijack while Read or Write is in progress.
275 func (cc
*ClientConn
) Hijack() (c net
.Conn
, r
*bufio
.Reader
) {
285 // Close calls Hijack and then also closes the underlying connection.
286 func (cc
*ClientConn
) Close() error
{
294 // Write writes a request. An ErrPersistEOF error is returned if the connection
295 // has been closed in an HTTP keep-alive sense. If req.Close equals true, the
296 // keep-alive connection is logically closed after this request and the opposing
297 // server is informed. An ErrUnexpectedEOF indicates the remote closed the
298 // underlying TCP connection, which is usually considered as graceful close.
299 func (cc
*ClientConn
) Write(req
*http
.Request
) error
{
302 // Ensure ordered execution of Writes
304 cc
.pipe
.StartRequest(id
)
306 cc
.pipe
.EndRequest(id
)
308 cc
.pipe
.StartResponse(id
)
309 cc
.pipe
.EndResponse(id
)
311 // Remember the pipeline id of this request
319 if cc
.re
!= nil { // no point sending if read-side closed or broken
327 if cc
.c
== nil { // connection closed by user in the meantime
333 // We write the EOF to the write-side error, because there
334 // still might be some pipelined reads
335 cc
.we
= ErrPersistEOF
339 err
= cc
.writeReq(req
, c
)
351 // Pending returns the number of unanswered requests
352 // that have been sent on the connection.
353 func (cc
*ClientConn
) Pending() int {
356 return cc
.nwritten
- cc
.nread
359 // Read reads the next response from the wire. A valid response might be
360 // returned together with an ErrPersistEOF, which means that the remote
361 // requested that this be the last request serviced. Read can be called
362 // concurrently with Write, but not with another Read.
363 func (cc
*ClientConn
) Read(req
*http
.Request
) (resp
*http
.Response
, err error
) {
364 // Retrieve the pipeline ID of this request/response pair
366 id
, ok
:= cc
.pipereq
[req
]
367 delete(cc
.pipereq
, req
)
370 return nil, ErrPipeline
374 // Ensure pipeline order
375 cc
.pipe
.StartResponse(id
)
376 defer cc
.pipe
.EndResponse(id
)
383 if cc
.r
== nil { // connection closed by user in the meantime
385 return nil, errClosed
388 lastbody
:= cc
.lastbody
392 // Make sure body is fully consumed, even if user does not call body.Close
394 // body.Close is assumed to be idempotent and multiple calls to
395 // it should return the error that its first invocation
397 err
= lastbody
.Close()
406 resp
, err
= http
.ReadResponse(r
, req
)
413 cc
.lastbody
= resp
.Body
418 cc
.re
= ErrPersistEOF
// don't send any more requests
424 // Do is convenience method that writes a request and reads a response.
425 func (cc
*ClientConn
) Do(req
*http
.Request
) (*http
.Response
, error
) {