Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package httputil

import (
	
	
	
	
	
	
	
)

Deprecated: No longer used.
	ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"}
Deprecated: No longer used.
	ErrClosed = &http.ProtocolError{ErrorString: "connection closed by user"}
Deprecated: No longer used.
	ErrPipeline = &http.ProtocolError{ErrorString: "pipeline error"}
)
This is an API usage error - the local side is closed. ErrPersistEOF (above) reports that the remote side is closed.
var errClosed = errors.New("i/o operation on closed connection")
ServerConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use the Server in package net/http instead.
type ServerConn struct {
	mu              sync.Mutex // read-write protects the following fields
	c               net.Conn
	r               *bufio.Reader
	re, we          error // read/write errors
	lastbody        io.ReadCloser
	nread, nwritten int
	pipereq         map[*http.Request]uint

	pipe textproto.Pipeline
}
NewServerConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use the Server in package net/http instead.
func ( net.Conn,  *bufio.Reader) *ServerConn {
	if  == nil {
		 = bufio.NewReader()
	}
	return &ServerConn{c: , r: , pipereq: make(map[*http.Request]uint)}
}
Hijack detaches the ServerConn and returns the underlying connection as well 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 should not call Hijack while Read or Write is in progress.
func ( *ServerConn) () (net.Conn, *bufio.Reader) {
	.mu.Lock()
	defer .mu.Unlock()
	 := .c
	 := .r
	.c = nil
	.r = nil
	return , 
}
Close calls Hijack and then also closes the underlying connection.
func ( *ServerConn) () error {
	,  := .Hijack()
	if  != nil {
		return .Close()
	}
	return nil
}
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 first request on an HTTP/1.0 connection, or after a Connection:close on a HTTP/1.1 connection).
func ( *ServerConn) () (*http.Request, error) {
	var  *http.Request
	var  error
Ensure ordered execution of Reads and Writes
	 := .pipe.Next()
	.pipe.StartRequest()
	defer func() {
		.pipe.EndRequest()
		if  == nil {
			.pipe.StartResponse()
			.pipe.EndResponse()
Remember the pipeline id of this request
			.mu.Lock()
			.pipereq[] = 
			.mu.Unlock()
		}
	}()

	.mu.Lock()
	if .we != nil { // no point receiving if write-side broken or closed
		defer .mu.Unlock()
		return nil, .we
	}
	if .re != nil {
		defer .mu.Unlock()
		return nil, .re
	}
	if .r == nil { // connection closed by user in the meantime
		defer .mu.Unlock()
		return nil, errClosed
	}
	 := .r
	 := .lastbody
	.lastbody = nil
	.mu.Unlock()
Make sure body is fully consumed, even if user does not call body.Close
body.Close is assumed to be idempotent and multiple calls to it should return the error that its first invocation returned.
		 = .Close()
		if  != nil {
			.mu.Lock()
			defer .mu.Unlock()
			.re = 
			return nil, 
		}
	}

	,  = http.ReadRequest()
	.mu.Lock()
	defer .mu.Unlock()
	if  != nil {
A close from the opposing client is treated as a graceful close, even if there was some unparse-able data before the close.
			.re = ErrPersistEOF
			return nil, .re
		} else {
			.re = 
			return , 
		}
	}
	.lastbody = .Body
	.nread++
	if .Close {
		.re = ErrPersistEOF
		return , .re
	}
	return , 
}
Pending returns the number of unanswered requests that have been received on the connection.
func ( *ServerConn) () int {
	.mu.Lock()
	defer .mu.Unlock()
	return .nread - .nwritten
}
Write writes resp in response to req. To close the connection gracefully, set the Response.Close field to true. Write should be considered operational until it returns an error, regardless of any errors returned on the Read side.
func ( *ServerConn) ( *http.Request,  *http.Response) error {
Retrieve the pipeline ID of this request/response pair
	.mu.Lock()
	,  := .pipereq[]
	delete(.pipereq, )
	if ! {
		.mu.Unlock()
		return ErrPipeline
	}
	.mu.Unlock()
Ensure pipeline order
	.pipe.StartResponse()
	defer .pipe.EndResponse()

	.mu.Lock()
	if .we != nil {
		defer .mu.Unlock()
		return .we
	}
	if .c == nil { // connection closed by user in the meantime
		defer .mu.Unlock()
		return ErrClosed
	}
	 := .c
	if .nread <= .nwritten {
		defer .mu.Unlock()
		return errors.New("persist server pipe count")
	}
After signaling a keep-alive close, any pipelined unread requests will be lost. It is up to the user to drain them before signaling.
		.re = ErrPersistEOF
	}
	.mu.Unlock()

	 := .Write()
	.mu.Lock()
	defer .mu.Unlock()
	if  != nil {
		.we = 
		return 
	}
	.nwritten++

	return nil
}
ClientConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use Client or Transport in package net/http instead.
type ClientConn struct {
	mu              sync.Mutex // read-write protects the following fields
	c               net.Conn
	r               *bufio.Reader
	re, we          error // read/write errors
	lastbody        io.ReadCloser
	nread, nwritten int
	pipereq         map[*http.Request]uint

	pipe     textproto.Pipeline
	writeReq func(*http.Request, io.Writer) error
}
NewClientConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use the Client or Transport in package net/http instead.
func ( net.Conn,  *bufio.Reader) *ClientConn {
	if  == nil {
		 = bufio.NewReader()
	}
	return &ClientConn{
		c:        ,
		r:        ,
		pipereq:  make(map[*http.Request]uint),
		writeReq: (*http.Request).Write,
	}
}
NewProxyClientConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use the Client or Transport in package net/http instead.
Hijack detaches the ClientConn and returns the underlying connection as well 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 logic. The user should not call Hijack while Read or Write is in progress.
func ( *ClientConn) () ( net.Conn,  *bufio.Reader) {
	.mu.Lock()
	defer .mu.Unlock()
	 = .c
	 = .r
	.c = nil
	.r = nil
	return
}
Close calls Hijack and then also closes the underlying connection.
func ( *ClientConn) () error {
	,  := .Hijack()
	if  != nil {
		return .Close()
	}
	return nil
}
Write writes a request. An ErrPersistEOF error is returned if the connection has been closed in an HTTP keep-alive sense. If req.Close equals true, the keep-alive connection is logically closed after this request and the opposing server is informed. An ErrUnexpectedEOF indicates the remote closed the underlying TCP connection, which is usually considered as graceful close.
func ( *ClientConn) ( *http.Request) error {
	var  error
Ensure ordered execution of Writes
	 := .pipe.Next()
	.pipe.StartRequest()
	defer func() {
		.pipe.EndRequest()
		if  != nil {
			.pipe.StartResponse()
			.pipe.EndResponse()
Remember the pipeline id of this request
			.mu.Lock()
			.pipereq[] = 
			.mu.Unlock()
		}
	}()

	.mu.Lock()
	if .re != nil { // no point sending if read-side closed or broken
		defer .mu.Unlock()
		return .re
	}
	if .we != nil {
		defer .mu.Unlock()
		return .we
	}
	if .c == nil { // connection closed by user in the meantime
		defer .mu.Unlock()
		return errClosed
	}
	 := .c
We write the EOF to the write-side error, because there still might be some pipelined reads
		.we = ErrPersistEOF
	}
	.mu.Unlock()

	 = .writeReq(, )
	.mu.Lock()
	defer .mu.Unlock()
	if  != nil {
		.we = 
		return 
	}
	.nwritten++

	return nil
}
Pending returns the number of unanswered requests that have been sent on the connection.
func ( *ClientConn) () int {
	.mu.Lock()
	defer .mu.Unlock()
	return .nwritten - .nread
}
Read reads the next response from the wire. A valid response might be returned together with an ErrPersistEOF, which means that the remote requested that this be the last request serviced. Read can be called concurrently with Write, but not with another Read.
Retrieve the pipeline ID of this request/response pair
	.mu.Lock()
	,  := .pipereq[]
	delete(.pipereq, )
	if ! {
		.mu.Unlock()
		return nil, ErrPipeline
	}
	.mu.Unlock()
Ensure pipeline order
	.pipe.StartResponse()
	defer .pipe.EndResponse()

	.mu.Lock()
	if .re != nil {
		defer .mu.Unlock()
		return nil, .re
	}
	if .r == nil { // connection closed by user in the meantime
		defer .mu.Unlock()
		return nil, errClosed
	}
	 := .r
	 := .lastbody
	.lastbody = nil
	.mu.Unlock()
Make sure body is fully consumed, even if user does not call body.Close
body.Close is assumed to be idempotent and multiple calls to it should return the error that its first invocation returned.
		 = .Close()
		if  != nil {
			.mu.Lock()
			defer .mu.Unlock()
			.re = 
			return nil, 
		}
	}

	,  = http.ReadResponse(, )
	.mu.Lock()
	defer .mu.Unlock()
	if  != nil {
		.re = 
		return , 
	}
	.lastbody = .Body

	.nread++

	if .Close {
		.re = ErrPersistEOF // don't send any more requests
		return , .re
	}
	return , 
}
Do is convenience method that writes a request and reads a response.
func ( *ClientConn) ( *http.Request) (*http.Response, error) {
	 := .Write()
	if  != nil {
		return nil, 
	}
	return .Read()