2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// 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.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-13 22:03:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// HTTP server. See RFC 7230 through 7235.  
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  http  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"bufio" 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-02 13:00:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/tls" 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-02 14:55:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"internal/godebug" 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"log" 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 19:25:56 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"math/rand" 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net" 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net/textproto" 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-08 15:41:54 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-21 15:30:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									urlpkg  "net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path" 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-22 08:18:45 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"runtime" 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-25 22:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sort" 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync/atomic" 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-02 13:00:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-19 02:13:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-01 10:12:30 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"golang.org/x/net/http/httpguts" 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 20:11:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Errors used by the HTTP server.  
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
									
										
										
										
											2016-04-30 20:11:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// ErrBodyNotAllowed is returned by ResponseWriter.Write calls 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// when the HTTP method or response code does not permit a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// body. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ErrBodyNotAllowed  =  errors . New ( "http: request method or response status code does not allow body" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ErrHijacked is returned by ResponseWriter.Write calls when 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the underlying connection has been hijacked using the 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-16 10:27:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Hijacker interface. A zero-byte write on a hijacked 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// connection will return ErrHijacked without any other side 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// effects. 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 20:11:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ErrHijacked  =  errors . New ( "http: connection has been hijacked" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ErrContentLength is returned by ResponseWriter.Write calls 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// when a Handler set a Content-Length response header with a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// declared size and then attempted to write more bytes than 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// declared. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ErrContentLength  =  errors . New ( "http: wrote more than the declared Content-Length" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-06 16:32:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Deprecated: ErrWriteAfterFlush is no longer returned by 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// anything in the net/http package. Callers should not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// compare errors against this variable. 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 20:11:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ErrWriteAfterFlush  =  errors . New ( "unused" ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-12-17 20:53:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// A Handler responds to an HTTP request.  
						 
					
						
							
								
									
										
										
										
											2010-02-12 14:27:44 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ServeHTTP should write reply headers and data to the ResponseWriter  
						 
					
						
							
								
									
										
										
										
											2015-12-17 20:53:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// and then return. Returning signals that the request is finished; it  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is not valid to use the ResponseWriter or read from the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Request.Body after or concurrently with the completion of the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ServeHTTP call.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Depending on the HTTP client software, HTTP protocol version, and  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// any intermediaries between the client and the Go server, it may not  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// be possible to read from the Request.Body after writing to the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ResponseWriter. Cautious handlers should read the Request.Body  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// first, and then reply.  
						 
					
						
							
								
									
										
										
										
											2014-09-19 13:53:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2016-04-05 15:59:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Except for reading the body, handlers should not modify the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// provided Request.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2014-09-19 13:53:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If ServeHTTP panics, the server (the caller of ServeHTTP) assumes  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// that the effect of the panic was isolated to the active request.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It recovers the panic, logs a stack trace to the server error log,  
						 
					
						
							
								
									
										
										
										
											2017-07-14 15:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// and either closes the network connection or sends an HTTP/2  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// RST_STREAM, depending on the HTTP protocol. To abort a handler so  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the client sees an interrupted response but the server doesn't log  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// an error, panic with the value ErrAbortHandler.  
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  Handler  interface  {  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ServeHTTP ( ResponseWriter ,  * Request ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// A ResponseWriter interface is used by an HTTP handler to  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// construct an HTTP response.  
						 
					
						
							
								
									
										
										
										
											2015-12-17 20:53:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// A ResponseWriter may not be used after the Handler.ServeHTTP method  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// has returned.  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  ResponseWriter  interface  {  
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Header returns the header map that will be sent by 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 15:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// WriteHeader. The Header map also is the mechanism with which 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Handlers can set HTTP trailers. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Changing the header map after a call to WriteHeader (or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Write) has no effect unless the modified headers are 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// trailers. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There are two ways to set Trailers. The preferred way is to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// predeclare in the headers which trailers you will later 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// send by setting the "Trailer" header to the names of the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// trailer keys which will come later. In this case, those 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// keys of the Header map are treated as if they were 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// trailers. See the example. The second way, for trailer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// keys not known to the Handler until after the first Write, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is to prefix the Header map keys with the TrailerPrefix 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// constant value. See TrailerPrefix. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-29 20:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// To suppress automatic response headers (such as "Date"), set 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 15:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// their value to nil. 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-09 09:41:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Header ( )  Header 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Write writes the data to the connection as part of an HTTP reply. 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-10 16:09:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If WriteHeader has not yet been called, Write calls 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// WriteHeader(http.StatusOK) before writing the data. If the Header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// does not contain a Content-Type line, Write adds a Content-Type set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to the result of passing the initial 512 bytes of written data to 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-29 20:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// DetectContentType. Additionally, if the total size of all written 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// data is under a few KB and there are no Flush calls, the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Content-Length header is added automatically. 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-10 16:09:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Depending on the HTTP protocol version and the client, calling 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Write or WriteHeader may prevent future reads on the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Request.Body. For HTTP/1.x requests, handlers should read any 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// needed request body data before writing the response. Once the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// headers have been flushed (due to either an explicit Flusher.Flush 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// call or writing enough data to trigger a flush), the request body 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// may be unavailable. For HTTP/2 requests, the Go HTTP server permits 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// handlers to continue to read the request body while concurrently 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// writing the response. However, such behavior may not be supported 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// by all HTTP/2 clients. Handlers should read before writing if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// possible to maximize compatibility. 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Write ( [ ] byte )  ( int ,  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-07 20:08:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// WriteHeader sends an HTTP response header with the provided 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// status code. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If WriteHeader is not called explicitly, the first call to Write 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// will trigger an implicit WriteHeader(http.StatusOK). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Thus explicit calls to WriteHeader are mainly used to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// send error codes. 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-07 20:08:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The provided code must be a valid HTTP 1xx-5xx status code. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Only one header may be written. Go does not currently 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// support sending user-defined 1xx informational headers, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// with the exception of 100-continue response header that the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Server sends automatically when the Request.Body is read. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WriteHeader ( statusCode  int ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-09 10:24:50 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-09 10:24:50 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The Flusher interface is implemented by ResponseWriters that allow  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// an HTTP handler to flush buffered data to the client.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2016-04-15 21:56:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The default HTTP/1.x and HTTP/2 ResponseWriter implementations  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// support Flusher, but ResponseWriter wrappers may not. Handlers  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// should always test for this ability at runtime.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2011-03-09 10:24:50 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Note that even for ResponseWriters that support Flush,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// if the client is connected through an HTTP proxy,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the buffered data may not reach the client until the response  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// completes.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Flusher  interface  {  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Flush sends any buffered data to the client. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Flush ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-06 18:59:50 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 12:04:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The Hijacker interface is implemented by ResponseWriters that allow  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// an HTTP handler to take over the connection.  
						 
					
						
							
								
									
										
										
										
											2016-04-15 21:56:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The default ResponseWriter for HTTP/1.x connections supports  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Hijacker, but HTTP/2 connections intentionally do not.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ResponseWriter wrappers may also not support Hijacker. Handlers  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// should always test for this ability at runtime.  
						 
					
						
							
								
									
										
										
										
											2011-03-06 18:59:50 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  Hijacker  interface  {  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Hijack lets the caller take over the connection. 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-13 21:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// After a call to Hijack the HTTP server library 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// will not do anything else with the connection. 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 12:11:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// It becomes the caller's responsibility to manage 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// and close the connection. 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 12:11:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The returned net.Conn may have read or write deadlines 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// already set, depending on the configuration of the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Server. It is the caller's responsibility to set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// or clear those deadlines as needed. 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-13 21:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The returned bufio.Reader may contain unprocessed buffered 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// data from the client. 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-21 18:52:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-29 19:45:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// After a call to Hijack, the original Request.Body must not 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-15 20:10:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// be used. The original Request's Context remains valid and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is not canceled until the Request's ServeHTTP method 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// returns. 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Hijack ( )  ( net . Conn ,  * bufio . ReadWriter ,  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The CloseNotifier interface is implemented by ResponseWriters which  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// allow detecting when the underlying connection has gone away.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This mechanism can be used to cancel long operations on the server  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// if the client has disconnected before the response is ready.  
						 
					
						
							
								
									
										
										
										
											2018-07-13 19:31:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Deprecated: the CloseNotifier interface predates Go's context package.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// New code should use Request.Context instead.  
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  CloseNotifier  interface  {  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// CloseNotify returns a channel that receives at most a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// single value (true) when the client connection has gone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// away. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 20:38:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// CloseNotify may wait to notify until Request.Body has been 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// fully read. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// After the Handler has returned, there is no guarantee 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that the channel receives a value. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If the protocol is HTTP/1.1 and CloseNotify is called while 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// processing an idempotent request (such a GET) while 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// HTTP/1.1 pipelining is in use, the arrival of a subsequent 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 20:38:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// pipelined request may cause a value to be sent on the 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// returned channel. In practice HTTP/1.1 pipelining is not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// enabled in browsers and not seen often in the wild. If this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is a problem, use HTTP/2 or only use CloseNotify on methods 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// such as POST. 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CloseNotify ( )  <- chan  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-11 05:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ServerContextKey is a context key. It can be used in HTTP 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-26 03:30:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// handlers with Context.Value to access the server that 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-11 05:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// started the handler. The associated value will be of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// type *Server. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ServerContextKey  =  & contextKey { "http-server" } 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 21:11:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// LocalAddrContextKey is a context key. It can be used in 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-26 03:30:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP handlers with Context.Value to access the local 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-05 13:27:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// address the connection arrived on. 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 21:11:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// The associated value will be of type net.Addr. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LocalAddrContextKey  =  & contextKey { "local-addr" } 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-11 05:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// A conn represents the server side of an HTTP connection.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  conn  struct  {  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// server is the server on which the connection arrived. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Immutable; never nil. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									server  * Server 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// cancelCtx cancels the connection-level context. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cancelCtx  context . CancelFunc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// rwc is the underlying network connection. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This is never wrapped by other types and is the value given out 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to CloseNotifier callers. It is usually of type *net.TCPConn or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// *tls.Conn. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rwc  net . Conn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// remoteAddr is rwc.RemoteAddr().String(). It is not populated synchronously 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// inside the Listener's Accept goroutine, as some implementations block. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// It is populated immediately inside the (*conn).serve goroutine. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This is the value of a Handler's (*Request).RemoteAddr. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									remoteAddr  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// tlsState is the TLS connection state when using TLS. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// nil means not TLS. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tlsState  * tls . ConnectionState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// werr is set to the first write error to rwc. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// It is set via checkConnErrorWriter{w}, where bufw writes. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									werr  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// r is bufr's read source. It's a wrapper around rwc that provides 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// io.LimitedReader-style limiting (while reading request headers) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// and functionality to support CloseNotifier. See *connReader docs. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r  * connReader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// bufr reads from r. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bufr  * bufio . Reader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// bufw writes to checkConnErrorWriter{c}, which populates werr on error. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bufw  * bufio . Writer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// lastMethod is the method of the most recent request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// on this connection, if any. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lastMethod  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									curReq  atomic . Value  // of *response (which has a Request in it) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-28 21:01:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									curState  struct {  atomic  uint64  }  // packed (unixtime<<8|uint8(ConnState)) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// mu guards hijackedv 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mu  sync . Mutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// hijackedv is whether this connection has been hijacked 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// by a Handler with the Hijacker interface. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// It is guarded by mu. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hijackedv  bool 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * conn )  hijacked ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  c . hijackedv 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// c.mu must be held.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * conn )  hijackLocked ( )  ( rwc  net . Conn ,  buf  * bufio . ReadWriter ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . hijackedv  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  ErrHijacked 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . r . abortPendingRead ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . hijackedv  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rwc  =  c . rwc 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rwc . SetDeadline ( time . Time { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									buf  =  bufio . NewReadWriter ( c . bufr ,  bufio . NewWriter ( rwc ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-13 21:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . r . hasByte  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  err  :=  c . bufr . Peek ( c . bufr . Buffered ( )  +  1 ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  fmt . Errorf ( "unexpected Peek failure reading buffered byte: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 13:31:34 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . setState ( rwc ,  StateHijacked ,  runHooks ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// This should be >= 512 bytes for DetectContentType,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but otherwise it's somewhat arbitrary.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  bufferBeforeChunkingSize  =  2048  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// chunkWriter writes to a response's conn buffer, and is the writer  
						 
					
						
							
								
									
										
										
										
											2020-07-09 18:49:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// wrapped by the response.w buffered writer.  
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// chunkWriter also is responsible for finalizing the Header, including  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// conditionally setting the Content-Type and setting a Content-Length  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// in cases where the handler's final output is smaller than the buffer  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// size. It also conditionally adds chunk headers, when in chunking mode.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// See the comment above (*response).Write for the entire write flow.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  chunkWriter  struct  {  
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  * response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// header is either nil or a deep clone of res.handlerHeader 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-08 15:25:28 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// at the time of res.writeHeader, if res.writeHeader is 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// called and extra buffering is being done to calculate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Content-Type and/or Content-Length. 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									header  Header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// wroteHeader tells whether the header's been written to "the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// wire" (or rather: w.conn.buf). this is unlike 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// (*response).wroteHeader, which tells only whether it was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// logically written. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wroteHeader  bool 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set by the writeHeader method: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chunking  bool  // using chunked transfer encoding for reply body 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									crlf        =  [ ] byte ( "\r\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									colonSpace  =  [ ] byte ( ": " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cw  * chunkWriter )  Write ( p  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! cw . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cw . writeHeader ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: treat HEAD requests like GET requests
A response to a HEAD request is supposed to look the same as a
response to a GET request, just without a body.
HEAD requests are incredibly rare in the wild.
The Go net/http package has so far treated HEAD requests
specially: a Write on our default ResponseWriter returned
ErrBodyNotAllowed, telling handlers that something was wrong.
This was to optimize the fast path for HEAD requests, but:
1) because HEAD requests are incredibly rare, they're not
   worth having a fast path for.
2) Letting the http.Handler handle but do nop Writes is still
   very fast.
3) this forces ugly error handling into the application.
   e.g. https://code.google.com/p/go/source/detail?r=6f596be7a31e
   and related.
4) The net/http package nowadays does Content-Type sniffing,
   but you don't get that for HEAD.
5) The net/http package nowadays does Content-Length counting
   for small (few KB) responses, but not for HEAD.
6) ErrBodyNotAllowed was useless. By the time you received it,
   you had probably already done all your heavy computation
   and I/O to calculate what to write.
So, this change makes HEAD requests like GET requests.
We now count content-length and sniff content-type for HEAD
requests. If you Write, it doesn't return an error.
If you want a fast-path in your code for HEAD, you have to do
it early and set all the response headers yourself. Just like
before. If you choose not to Write in HEAD requests, be sure
to set Content-Length if you know it. We won't write
"Content-Length: 0" because you might've just chosen to not
write (or you don't know your Content-Length in advance).
Fixes #5454
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/12583043
											 
										 
										
											2013-08-06 18:33:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cw . res . req . Method  ==  "HEAD"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Eat writes. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  len ( p ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cw . chunking  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  fmt . Fprintf ( cw . res . conn . bufw ,  "%x\r\n" ,  len ( p ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 20:26:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cw . res . conn . rwc . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									n ,  err  =  cw . res . conn . bufw . Write ( p ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cw . chunking  &&  err  ==  nil  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  cw . res . conn . bufw . Write ( crlf ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 20:26:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cw . res . conn . rwc . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cw  * chunkWriter )  flush ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! cw . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cw . writeHeader ( nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cw . res . conn . bufw . Flush ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cw  * chunkWriter )  close ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! cw . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cw . writeHeader ( nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cw . chunking  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bw  :=  cw . res . conn . bufw  // conn's bufio writer 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// zero chunk to mark EOF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bw . WriteString ( "0\r\n" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 15:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  trailers  :=  cw . res . finalTrailers ( ) ;  trailers  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											trailers . Write ( bw )  // the writer handles noting errors 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// final blank line after the trailers (whether 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// present or not) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bw . WriteString ( "\r\n" ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// A response represents the server side of an HTTP response.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  response  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-04-05 15:59:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									conn              * conn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req               * Request  // request for this response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reqBody           io . ReadCloser 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cancelCtx         context . CancelFunc  // when ServeHTTP exits 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wroteHeader       bool                // reply header has been (logically) written 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wroteContinue     bool                // 100 Continue response was written 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wants10KeepAlive  bool                // HTTP/1.0 w/ Connection "keep-alive" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wantsClose        bool                // HTTP request has Connection "close" 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 13:27:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// canWriteContinue is a boolean value accessed as an atomic int32 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that says whether or not a 100 Continue header can be written 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to the connection. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// writeContinueMu must be held while writing the header. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// These two fields together synchronize the body reader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// (the expectContinueReader, which wants to write 100 Continue) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// against the main writer. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canWriteContinue  atomicBool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeContinueMu   sync . Mutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w   * bufio . Writer  // buffers output in chunks to chunkWriter 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 13:13:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cw  chunkWriter 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// handlerHeader is the Header that Handlers get access to, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// which may be retained and mutated even after WriteHeader. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// handlerHeader is copied into cw.header at WriteHeader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// time, and privately mutated thereafter. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									handlerHeader  Header 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									calledHeader   bool  // handler accessed handlerHeader via Header 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									written        int64  // number of bytes written in body 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									contentLength  int64  // explicitly-declared Content-Length; or -1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									status         int    // status code passed to WriteHeader 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-27 21:55:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// close connection after this reply.  set on request and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// updated after response from handler if there's a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// "Connection: keep-alive" response header and a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Content-Length. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									closeAfterReply  bool 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 12:17:21 +04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// requestBodyLimitHit is set by requestTooLarge when 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// maxBytesReader hits its max size. It is checked in 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-22 02:58:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// WriteHeader, to make sure we don't consume the 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 12:17:21 +04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// remaining request body to try to advance to the next HTTP 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:40:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// request. Instead, when this is set, we stop reading 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 12:17:21 +04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// subsequent requests on this connection and stop reading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// input from it. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestBodyLimitHit  bool 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// trailers are the headers to be sent after the handler 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// finishes writing the body. This field is initialized from 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// the Trailer response header when the response header is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// written. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									trailers  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-18 11:43:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									handlerDone  atomicBool  // set true when the handler exits 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-28 16:46:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Buffers for Date, Content-Length, and status code 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dateBuf    [ len ( TimeFormat ) ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									clenBuf    [ 10 ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									statusBuf  [ 3 ] byte 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// closeNotifyCh is the channel returned by CloseNotify. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO(bradfitz): this is currently (for Go 1.8) always 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// non-nil. Make this lazily-created again as it used to be? 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									closeNotifyCh   chan  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									didCloseNotify  int32  // atomic (only 0->1 winner should send) 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 12:17:21 +04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 15:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// that, if present, signals that the map entry is actually for  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the response trailers, and not the response headers. The prefix  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is stripped after the ServeHTTP call finishes and the values are  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// sent in the trailers.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This mechanism is intended only for trailers that are not known  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// prior to the headers being written. If the set of trailers is fixed  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// or known before the header is written, the normal Go trailers mechanism  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is preferred:  
						 
					
						
							
								
									
										
										
										
											2021-12-20 16:31:45 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//    https://pkg.go.dev/net/http#ResponseWriter  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    https://pkg.go.dev/net/http#example-ResponseWriter-Trailers  
						 
					
						
							
								
									
										
										
										
											2016-11-01 15:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  TrailerPrefix  =  "Trailer:"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// finalTrailers is called after the Handler exits and returns a non-nil  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// value if the Handler set any trailers.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * response )  finalTrailers ( )  Header  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  t  Header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  k ,  vv  :=  range  w . handlerHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . HasPrefix ( k ,  TrailerPrefix )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  t  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t  =  make ( Header ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t [ strings . TrimPrefix ( k ,  TrailerPrefix ) ]  =  vv 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  k  :=  range  w . trailers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  t  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t  =  make ( Header ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  v  :=  range  w . handlerHeader [ k ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Add ( k ,  v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-18 11:43:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  atomicBool  int32  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( b  * atomicBool )  isSet ( )  bool  {  return  atomic . LoadInt32 ( ( * int32 ) ( b ) )  !=  0  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( b  * atomicBool )  setTrue ( )     {  atomic . StoreInt32 ( ( * int32 ) ( b ) ,  1 )  }  
						 
					
						
							
								
									
										
										
										
											2020-07-13 13:27:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( b  * atomicBool )  setFalse ( )    {  atomic . StoreInt32 ( ( * int32 ) ( b ) ,  0 )  }  
						 
					
						
							
								
									
										
										
										
											2016-01-18 11:43:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// declareTrailer is called for each Trailer header when the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// response header is written. It notes that a header will need to be  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// written in the trailers at the end of the response.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * response )  declareTrailer ( k  string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									k  =  CanonicalHeaderKey ( k ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-02 12:57:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! httpguts . ValidTrailerHeader ( k )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Forbidden by RFC 7230, section 4.1.2 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . trailers  =  append ( w . trailers ,  k ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 12:17:21 +04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// requestTooLarge is called by maxBytesReader when too much input has  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// been read from the client.  
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  requestTooLarge ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . closeAfterReply  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . requestBodyLimitHit  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! w . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Header ( ) . Set ( "Connection" ,  "close" ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 12:17:21 +04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-07-23 11:59:49 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// needsSniff reports whether a Content-Type still needs to be sniffed.  
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  needsSniff ( )  bool  {  
						 
					
						
							
								
									
										
										
										
											2013-10-15 08:22:04 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  haveType  :=  w . handlerHeader [ "Content-Type" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ! w . cw . wroteHeader  &&  ! haveType  &&  w . written  <  sniffLen 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:02:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// writerOnly hides an io.Writer value's optional ReadFrom method  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// from io.Copy.  
						 
					
						
							
								
									
										
										
										
											2011-05-25 10:15:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  writerOnly  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									io . Writer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:02:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ReadFrom is here to optimize copying from an *os.File regular file  
						 
					
						
							
								
									
										
										
										
											2020-09-01 00:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// to a *net.TCPConn with sendfile, or from a supported src type such  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// as a *net.TCPConn on Linux with splice.  
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  ReadFrom ( src  io . Reader )  ( n  int64 ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2020-09-01 00:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bufp  :=  copyBufPool . Get ( ) . ( * [ ] byte ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buf  :=  * bufp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  copyBufPool . Put ( bufp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:02:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Our underlying w.conn.rwc is usually a *TCPConn (with its 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-01 00:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// own ReadFrom method). If not, just fall back to the normal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// copy method. 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:02:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rf ,  ok  :=  w . conn . rwc . ( io . ReaderFrom ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-01 00:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  io . CopyBuffer ( writerOnly { w } ,  src ,  buf ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:02:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 13:53:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Copy the first sniffLen bytes before switching to ReadFrom. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This ensures we don't start writing the response before the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// source is available (see golang.org/issue/5660) and provides 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// enough bytes to perform Content-Type sniffing when required. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! w . cw . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n0 ,  err  :=  io . CopyBuffer ( writerOnly { w } ,  io . LimitReader ( src ,  sniffLen ) ,  buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  +=  n0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  ||  n0  <  sniffLen  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  n ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-01 00:38:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . w . Flush ( )   // get rid of any previous writes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . cw . flush ( )  // make sure Header is written; flush data to rwc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Now that cw has been flushed, its chunking field is guaranteed initialized. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! w . cw . chunking  &&  w . bodyAllowed ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 14:02:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										n0 ,  err  :=  rf . ReadFrom ( src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  +=  n0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . written  +=  n0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  n ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 10:15:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 13:53:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									n0 ,  err  :=  io . CopyBuffer ( writerOnly { w } ,  src ,  buf ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									n  +=  n0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  n ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 10:15:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												net/http: fix Transport races & deadlocks
Thanks to Dustin Sallings for exposing the most frustrating
bug ever, and for providing repro cases (which formed the
basis of the new tests in this CL), and to Dave Cheney and
Dmitry Vyukov for help debugging and fixing.
This CL depends on submited pollster CLs ffd1e075c260 (Unix)
and 14b544194509 (Windows), as well as unsubmitted 6852085.
Some operating systems (OpenBSD, NetBSD, ?) may still require
more pollster work, fixing races (Issue 4434 and
http://goo.gl/JXB6W).
Tested on linux-amd64 and darwin-amd64, both with GOMAXPROCS 1
and 4 (all combinations of which previously failed differently)
Fixes #4191
Update #4434 (related fallout from this bug)
R=dave, bradfitz, dsallings, rsc, fullung
CC=golang-dev
https://golang.org/cl/6851061
											 
										 
										
											2012-11-26 13:31:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// debugServerConnections controls whether all server connections are wrapped  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// with a verbose logging wrapper.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  debugServerConnections  =  false  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Create new connection from rwc.  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  newConn ( rwc  net . Conn )  * conn  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c  :=  & conn { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										server :  srv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rwc :     rwc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
											
												net/http: fix Transport races & deadlocks
Thanks to Dustin Sallings for exposing the most frustrating
bug ever, and for providing repro cases (which formed the
basis of the new tests in this CL), and to Dave Cheney and
Dmitry Vyukov for help debugging and fixing.
This CL depends on submited pollster CLs ffd1e075c260 (Unix)
and 14b544194509 (Windows), as well as unsubmitted 6852085.
Some operating systems (OpenBSD, NetBSD, ?) may still require
more pollster work, fixing races (Issue 4434 and
http://goo.gl/JXB6W).
Tested on linux-amd64 and darwin-amd64, both with GOMAXPROCS 1
and 4 (all combinations of which previously failed differently)
Fixes #4191
Update #4434 (related fallout from this bug)
R=dave, bradfitz, dsallings, rsc, fullung
CC=golang-dev
https://golang.org/cl/6851061
											 
										 
										
											2012-11-26 13:31:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  debugServerConnections  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . rwc  =  newLoggingConn ( "server" ,  c . rwc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  readResult  struct  {  
						 
					
						
							
								
									
										
										
										
											2020-04-30 09:03:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_    incomparable 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									n    int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									b    byte  // byte read, if n == 1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// connReader is the io.Reader wrapper used by *conn. It combines a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// selectively-activated io.LimitedReader (to bound request header  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// read sizes) with support for selectively keeping an io.Reader.Read  
						 
					
						
							
								
									
										
										
										
											2015-12-23 23:56:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// call blocked in a background goroutine to wait for activity and  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// trigger a CloseNotifier channel.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  connReader  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									conn  * conn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mu       sync . Mutex  // guards following 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hasByte  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									byteBuf  [ 1 ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cond     * sync . Cond 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									inRead   bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									aborted  bool   // set true before conn.rwc deadline is set to past 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									remain   int64  // bytes remaining 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( cr  * connReader )  lock ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cr . cond  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cr . cond  =  sync . NewCond ( & cr . mu ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cr  * connReader )  unlock ( )  {  cr . mu . Unlock ( )  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cr  * connReader )  startBackgroundRead ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  cr . unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cr . inRead  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "invalid concurrent Body.Read call" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 20:41:14 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cr . hasByte  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cr . inRead  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-04 21:03:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cr . conn . rwc . SetReadDeadline ( time . Time { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									go  cr . backgroundRead ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cr  * connReader )  backgroundRead ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n ,  err  :=  cr . conn . rwc . Read ( cr . byteBuf [ : ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  n  ==  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cr . hasByte  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-13 19:31:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// We were past the end of the previous request's body already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// (since we wouldn't be in a background read otherwise), so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this is a pipelined HTTP request. Prior to Go 1.11 we used to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// send on the CloseNotify channel and cancel the context here, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// but the behavior was documented as only "may", and we only 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// did that because that's how CloseNotify accidentally behaved 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// in very early Go releases prior to context support. Once we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// added context support, people used a Handler's 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Request.Context() and passed it along. Having that context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// cancel on pipelined HTTP requests caused problems. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Fortunately, almost nothing uses HTTP/1.x pipelining. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Unfortunately, apt-get does, or sometimes does. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// New Go 1.11 behavior: don't fire CloseNotify or cancel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// contexts on pipelined requests. Shouldn't affect people, but 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// fixes cases like Issue 23921. This does mean that a client 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// closing their TCP connection after sending a pipelined 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// request won't cancel the context, but we'll catch that on any 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// write failure (in checkConnErrorWriter.Write). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If the server never writes, yes, there are still contrived 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// server & client behaviors where this fails to ever cancel the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// context, but that's kinda why HTTP/1.x pipelining died 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// anyway. 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ne ,  ok  :=  err . ( net . Error ) ;  ok  &&  cr . aborted  &&  ne . Timeout ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Ignore this error. It's the expected error from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// another goroutine calling abortPendingRead. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cr . handleReadError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . aborted  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . inRead  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . cond . Broadcast ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cr  * connReader )  abortPendingRead ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  cr . unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! cr . inRead  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . aborted  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . conn . rwc . SetReadDeadline ( aLongTimeAgo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  cr . inRead  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cr . cond . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . conn . rwc . SetReadDeadline ( time . Time { } ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cr  * connReader )  setReadLimit ( remain  int64 )  {  cr . remain  =  remain  }  
						 
					
						
							
								
									
										
										
										
											2016-03-31 00:06:27 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( cr  * connReader )  setInfiniteReadLimit ( )      {  cr . remain  =  maxInt64  }  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( cr  * connReader )  hitReadLimit ( )  bool         {  return  cr . remain  <=  0  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-09 17:56:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// handleReadError is called whenever a Read from the client returns a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// non-nil error.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The provided non-nil err is almost always io.EOF or a "use of  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// closed network connection". In any case, the error is not  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// particularly interesting, except perhaps for debugging during  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// development. Any error means the connection is dead and we should  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// down its context.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It may be called from multiple goroutines.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cr  * connReader )  handleReadError ( _  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cr . conn . cancelCtx ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . closeNotify ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// may be called from multiple goroutines.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cr  * connReader )  closeNotify ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res ,  _  :=  cr . conn . curReq . Load ( ) . ( * response ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 20:21:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  res  !=  nil  &&  atomic . CompareAndSwapInt32 ( & res . didCloseNotify ,  0 ,  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res . closeNotifyCh  <-  true 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( cr  * connReader )  Read ( p  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cr . lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cr . inRead  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cr . unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-29 18:56:59 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  cr . conn . hijacked ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											panic ( "invalid Body.Read call. After hijacked, the original Request must not be used" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										panic ( "invalid concurrent Body.Read call" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cr . hitReadLimit ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cr . unlock ( ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ,  io . EOF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( p )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cr . unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  nil 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  int64 ( len ( p ) )  >  cr . remain  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p  =  p [ : cr . remain ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cr . hasByte  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p [ 0 ]  =  cr . byteBuf [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cr . hasByte  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cr . unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ,  nil 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cr . inRead  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n ,  err  =  cr . conn . rwc . Read ( p ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cr . lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . inRead  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cr . handleReadError ( err ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cr . remain  -=  int64 ( n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cr . unlock ( ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cr . cond . Broadcast ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  n ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bufioReaderPool    sync . Pool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bufioWriter2kPool  sync . Pool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bufioWriter4kPool  sync . Pool 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-09-03 01:19:51 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  copyBufPool  =  sync . Pool {  
						 
					
						
							
								
									
										
										
										
											2021-12-01 12:15:45 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									New :  func ( )  any  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-03 01:19:51 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										b  :=  make ( [ ] byte ,  32 * 1024 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & b 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  bufioWriterPool ( size  int )  * sync . Pool  {  
						 
					
						
							
								
									
										
										
										
											2013-03-27 13:35:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  size  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  2  <<  10 : 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & bufioWriter2kPool 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-27 13:35:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  4  <<  10 : 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & bufioWriter4kPool 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-27 13:35:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-10 19:22:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newBufioReader ( r  io . Reader )  * bufio . Reader  {  
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  v  :=  bufioReaderPool . Get ( ) ;  v  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										br  :=  v . ( * bufio . Reader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										br . Reset ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  br 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-09 21:03:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Note: if this reader size is ever changed, update 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 11:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// TestHandlerBodyClose's assumptions. 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  bufio . NewReader ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-10 19:22:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  putBufioReader ( br  * bufio . Reader )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									br . Reset ( nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bufioReaderPool . Put ( br ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-10 19:22:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newBufioWriterSize ( w  io . Writer ,  size  int )  * bufio . Writer  {  
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pool  :=  bufioWriterPool ( size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  pool  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  v  :=  pool . Get ( ) ;  v  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bw  :=  v . ( * bufio . Writer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bw . Reset ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  bw 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  bufio . NewWriterSize ( w ,  size ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-10 19:22:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  putBufioWriter ( bw  * bufio . Writer )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bw . Reset ( nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 15:52:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  pool  :=  bufioWriterPool ( bw . Available ( ) ) ;  pool  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pool . Put ( bw ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-09 10:55:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// DefaultMaxHeaderBytes is the maximum permitted size of the headers  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// in an HTTP request.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This can be overridden by setting Server.MaxHeaderBytes.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  DefaultMaxHeaderBytes  =  1  <<  20  // 1 MB  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( srv  * Server )  maxHeaderBytes ( )  int  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  srv . MaxHeaderBytes  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  srv . MaxHeaderBytes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  DefaultMaxHeaderBytes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  initialReadLimitSize ( )  int64  {  
						 
					
						
							
								
									
										
										
										
											2014-03-03 18:58:28 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  int64 ( srv . maxHeaderBytes ( ) )  +  4096  // bufio slop 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 08:45:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// tlsHandshakeTimeout returns the time limit permitted for the TLS  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// handshake, or zero for unlimited.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It returns the minimum of any positive ReadHeaderTimeout,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ReadTimeout, or WriteTimeout.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( srv  * Server )  tlsHandshakeTimeout ( )  time . Duration  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ret  time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  [ ... ] time . Duration { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										srv . ReadHeaderTimeout , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										srv . ReadTimeout , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										srv . WriteTimeout , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  v  <=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ret  ==  0  ||  v  <  ret  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ret  =  v 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-17 00:50:41 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// wrapper around io.ReadCloser which on first read, sends an  
						 
					
						
							
								
									
										
										
										
											2010-06-16 10:15:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// HTTP/1.1 100 Continue header  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  expectContinueReader  struct  {  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									resp        * response 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-16 10:15:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									readCloser  io . ReadCloser 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-27 13:08:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									closed      atomicBool 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 13:27:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sawEOF      atomicBool 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-16 10:15:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ecr  * expectContinueReader )  Read ( p  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2020-08-27 13:08:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ecr . closed . isSet ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-10 01:42:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ,  ErrBodyReadAfterClose 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-14 10:40:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 13:27:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w  :=  ecr . resp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! w . wroteContinue  &&  w . canWriteContinue . isSet ( )  &&  ! w . conn . hijacked ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . wroteContinue  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeContinueMu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . canWriteContinue . isSet ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . conn . bufw . WriteString ( "HTTP/1.1 100 Continue\r\n\r\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . conn . bufw . Flush ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . canWriteContinue . setFalse ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeContinueMu . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-16 10:15:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 09:15:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									n ,  err  =  ecr . readCloser . Read ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  io . EOF  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 13:27:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ecr . sawEOF . setTrue ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 09:15:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-16 10:15:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ecr  * expectContinueReader )  Close ( )  error  {  
						 
					
						
							
								
									
										
										
										
											2020-08-27 13:08:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ecr . closed . setTrue ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-16 10:15:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ecr . readCloser . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-26 18:55:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TimeFormat is the time format to use when generating times in HTTP  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// headers. It is like time.RFC1123 but hard-codes GMT as the time  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// zone. The time being formatted must be in UTC for Format to  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// generate the correct format.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// For parsing this time format, see ParseTime.  
						 
					
						
							
								
									
										
										
										
											2010-09-02 14:21:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  TimeFormat  =  "Mon, 02 Jan 2006 15:04:05 GMT"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-09-22 19:53:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat))  
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  appendTime ( b  [ ] byte ,  t  time . Time )  [ ] byte  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  days  =  "SunMonTueWedThuFriSat" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  months  =  "JanFebMarAprMayJunJulAugSepOctNovDec" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-09-22 19:53:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t  =  t . UTC ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									yy ,  mm ,  dd  :=  t . Date ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hh ,  mn ,  ss  :=  t . Clock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									day  :=  days [ 3 * t . Weekday ( ) : ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mon  :=  months [ 3 * ( mm - 1 ) : ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  append ( b , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										day [ 0 ] ,  day [ 1 ] ,  day [ 2 ] ,  ',' ,  ' ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byte ( '0' + dd / 10 ) ,  byte ( '0' + dd % 10 ) ,  ' ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mon [ 0 ] ,  mon [ 1 ] ,  mon [ 2 ] ,  ' ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byte ( '0' + yy / 1000 ) ,  byte ( '0' + ( yy / 100 ) % 10 ) ,  byte ( '0' + ( yy / 10 ) % 10 ) ,  byte ( '0' + yy % 10 ) ,  ' ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byte ( '0' + hh / 10 ) ,  byte ( '0' + hh % 10 ) ,  ':' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byte ( '0' + mn / 10 ) ,  byte ( '0' + mn % 10 ) ,  ':' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byte ( '0' + ss / 10 ) ,  byte ( '0' + ss % 10 ) ,  ' ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										'G' ,  'M' ,  'T' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  errTooLarge  =  errors . New ( "http: request too large" )  
						 
					
						
							
								
									
										
										
										
											2011-08-09 10:55:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Read next request from connection.  
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * conn )  readRequest ( ctx  context . Context )  ( w  * response ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . hijacked ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-09 12:07:39 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  ErrHijacked 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-03 14:16:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:52:45 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wholeReqDeadline  time . Time  // or zero if none 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hdrDeadline       time . Time  // or zero if none 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t0  :=  time . Now ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 09:54:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  d  :=  c . server . readHeaderTimeout ( ) ;  d  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hdrDeadline  =  t0 . Add ( d ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 09:54:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  d  :=  c . server . ReadTimeout ;  d  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										wholeReqDeadline  =  t0 . Add ( d ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:52:45 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . rwc . SetReadDeadline ( hdrDeadline ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 09:54:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  d  :=  c . server . WriteTimeout ;  d  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:52:45 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . rwc . SetWriteDeadline ( time . Now ( ) . Add ( d ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . r . setReadLimit ( c . server . initialReadLimitSize ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-25 11:31:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . lastMethod  ==  "POST"  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-13 22:03:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// RFC 7230 section 3 tolerance for old buggy clients. 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										peek ,  _  :=  c . bufr . Peek ( 4 )  // ReadRequest will get err below 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . bufr . Discard ( numLeadingCRorLF ( peek ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-25 11:31:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-12 17:19:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  :=  readRequest ( c . bufr ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  c . r . hitReadLimit ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-09 10:55:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  errTooLarge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-09 12:07:39 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-27 10:28:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! http1ServerSupportsRequest ( req )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 13:02:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  statusError { StatusHTTPVersionNotSupported ,  "unsupported protocol version" } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-27 10:28:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-06-25 11:31:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . lastMethod  =  req . Method 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . r . setInfiniteReadLimit ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-12-16 18:51:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hosts ,  haveHost  :=  req . Header [ "Host" ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-30 22:11:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									isH2Upgrade  :=  req . isH2Upgrade ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 23:42:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  req . ProtoAtLeast ( 1 ,  1 )  &&  ( ! haveHost  ||  len ( hosts )  ==  0 )  &&  ! isH2Upgrade  &&  req . Method  !=  "CONNECT"  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-16 18:51:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  badRequestError ( "missing required Host header" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-07 19:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( hosts )  ==  1  &&  ! httpguts . ValidHostHeader ( hosts [ 0 ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-16 18:51:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  badRequestError ( "malformed Host header" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-17 19:25:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  k ,  vv  :=  range  req . Header  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-07 19:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! httpguts . ValidHeaderFieldName ( k )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-17 19:25:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  badRequestError ( "invalid header name" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  v  :=  range  vv  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-07 19:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! httpguts . ValidHeaderFieldValue ( v )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-17 19:25:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nil ,  badRequestError ( "invalid header value" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-16 18:51:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									delete ( req . Header ,  "Host" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-09 17:24:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx ,  cancelCtx  :=  context . WithCancel ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . ctx  =  ctx 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-10 08:17:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . RemoteAddr  =  c . remoteAddr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . TLS  =  c . tlsState 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 11:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  body ,  ok  :=  req . Body . ( * body ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										body . doEarlyClose  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-10 08:17:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Adjust the read deadline if necessary. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! hdrDeadline . Equal ( wholeReqDeadline )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . rwc . SetReadDeadline ( wholeReqDeadline ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w  =  & response { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										conn :           c , 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cancelCtx :      cancelCtx , 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req :            req , 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-03 12:04:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reqBody :        req . Body , 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										handlerHeader :  make ( Header ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentLength :  - 1 , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										closeNotifyCh :  make ( chan  bool ,  1 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-05 15:59:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// We populate these ahead of time so we're not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// reading from req.Header after their Handler starts 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// and maybe mutates it (Issue 14940) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wants10KeepAlive :  req . wantsHttp10KeepAlive ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wantsClose :        req . wantsClose ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-30 22:11:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isH2Upgrade  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . closeAfterReply  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . cw . res  =  w 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-10 19:22:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . w  =  newBufioWriterSize ( & w . cw ,  bufferBeforeChunkingSize ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  w ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-27 10:28:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// http1ServerSupportsRequest reports whether Go's HTTP/1.x server  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// supports the given request.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  http1ServerSupportsRequest ( req  * Request )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  req . ProtoMajor  ==  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Accept "PRI * HTTP/2.0" upgrade requests, so Handlers can 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// wire up their own HTTP/2 upgrades. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  req . ProtoMajor  ==  2  &&  req . ProtoMinor  ==  0  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Method  ==  "PRI"  &&  req . RequestURI  ==  "*"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Reject HTTP/0.x, and all other HTTP/2+ requests (which 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// aren't encoded in ASCII anyway). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-09 09:41:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  Header ( )  Header  {  
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . cw . header  ==  nil  &&  w . wroteHeader  &&  ! w . cw . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Accessing the header between logically writing it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// and physically writing it means we need to allocate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// a clone to snapshot the logically written state. 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-24 14:59:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . cw . header  =  w . handlerHeader . Clone ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . calledHeader  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  w . handlerHeader 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// maxPostHandlerReadBytes is the max number of Request.Body bytes not  
						 
					
						
							
								
									
										
										
										
											2011-12-10 13:02:23 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// consumed by a handler that the server will read from the client  
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// in order to keep a connection alive. If there are more bytes than  
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// this then the server to be paranoid instead sends a "Connection:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// close" response.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This number is approximately what a typical machine's TCP buffer  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// size is anyway.  (if we have the bytes on the machine, we might as  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// well read them)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  maxPostHandlerReadBytes  =  256  <<  10  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-11-27 22:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  checkWriteHeaderCode ( code  int )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Issue 22880: require valid WriteHeader status codes. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// For now we only enforce that it's three digits. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// In the future we might block things over 599 (600 and above aren't defined 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-01 17:29:59 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// at https://httpwg.org/specs/rfc7231.html#status.codes) 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-27 22:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// and we might block under 200 (once we have more mature 1xx support). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// But for now any three digits. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We used to send "HTTP/1.1 000 0" on the wire in responses but there's 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// no equivalent bogus thing we can realistically send in HTTP/2, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// so we'll consistently panic instead and help people find their bugs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// early. (We can't return an error from WriteHeader even if we wanted to.) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  code  <  100  ||  code  >  999  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( fmt . Sprintf ( "invalid WriteHeader code %v" ,  code ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-23 17:28:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// relevantCaller searches the call stack for the first function outside of net/http.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The purpose of this function is to provide more helpful error messages.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  relevantCaller ( )  runtime . Frame  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pc  :=  make ( [ ] uintptr ,  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  :=  runtime . Callers ( 1 ,  pc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									frames  :=  runtime . CallersFrames ( pc [ : n ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  frame  runtime . Frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										frame ,  more  :=  frames . Next ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! strings . HasPrefix ( frame . Function ,  "net/http." )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! more  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  WriteHeader ( code  int )  {  
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . conn . hijacked ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-23 17:28:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										caller  :=  relevantCaller ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . conn . server . logf ( "http: response.WriteHeader on hijacked connection from %s (%s:%d)" ,  caller . Function ,  path . Base ( caller . File ) ,  caller . Line ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-03 14:16:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . wroteHeader  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-23 17:28:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										caller  :=  relevantCaller ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . conn . server . logf ( "http: superfluous response.WriteHeader call from %s (%s:%d)" ,  caller . Function ,  path . Base ( caller . File ) ,  caller . Line ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-04 22:26:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									checkWriteHeaderCode ( code ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . wroteHeader  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . status  =  code 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . calledHeader  &&  w . cw . header  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-24 14:59:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . cw . header  =  w . handlerHeader . Clone ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cl  :=  w . handlerHeader . get ( "Content-Length" ) ;  cl  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										v ,  err  :=  strconv . ParseInt ( cl ,  10 ,  64 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  nil  &&  v  >=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . contentLength  =  v 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 12:12:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . conn . server . logf ( "http: invalid Content-Length of %q" ,  cl ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . handlerHeader . Del ( "Content-Length" ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This type is used to avoid extra allocations from cloning and/or populating  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the response Header map and all its 1-element slices.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  extraHeader  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									contentType       string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									connection        string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									transferEncoding  string 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									date              [ ] byte  // written if not nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									contentLength     [ ] byte  // written if not nil 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Sorted the same as extraHeader.Write's loop.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  extraHeaderKeys  =  [ ] [ ] byte {  
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ ] byte ( "Content-Type" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ ] byte ( "Connection" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ ] byte ( "Transfer-Encoding" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									headerContentLength  =  [ ] byte ( "Content-Length: " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									headerDate           =  [ ] byte ( "Date: " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Write writes the headers described in h to w.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This method has a value receiver, despite the somewhat large size  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// of h, because it prevents an allocation. The escape analysis isn't  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// smart enough to realize this function doesn't mutate h.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  extraHeader )  Write ( w  * bufio . Writer )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  h . date  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Write ( headerDate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Write ( h . date ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Write ( crlf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  h . contentLength  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Write ( headerContentLength ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Write ( h . contentLength ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Write ( crlf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  v  :=  range  [ ] string { h . contentType ,  h . connection ,  h . transferEncoding }  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  v  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . Write ( extraHeaderKeys [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . Write ( colonSpace ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . WriteString ( v ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . Write ( crlf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// writeHeader finalizes the header sent to the client and writes it  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// to cw.res.conn.bufw.  
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// p is not written by writeHeader, but is the first chunk of the body  
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// that will be written. It is sniffed for a Content-Type if none is  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// set explicitly. It's also used to set the Content-Length, if the  
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// total body size was small and the handler has already finished  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// running.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cw  * chunkWriter )  writeHeader ( p  [ ] byte )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cw . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cw . wroteHeader  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w  :=  cw . res 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									keepAlivesEnabled  :=  w . conn . server . doKeepAlives ( ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: treat HEAD requests like GET requests
A response to a HEAD request is supposed to look the same as a
response to a GET request, just without a body.
HEAD requests are incredibly rare in the wild.
The Go net/http package has so far treated HEAD requests
specially: a Write on our default ResponseWriter returned
ErrBodyNotAllowed, telling handlers that something was wrong.
This was to optimize the fast path for HEAD requests, but:
1) because HEAD requests are incredibly rare, they're not
   worth having a fast path for.
2) Letting the http.Handler handle but do nop Writes is still
   very fast.
3) this forces ugly error handling into the application.
   e.g. https://code.google.com/p/go/source/detail?r=6f596be7a31e
   and related.
4) The net/http package nowadays does Content-Type sniffing,
   but you don't get that for HEAD.
5) The net/http package nowadays does Content-Length counting
   for small (few KB) responses, but not for HEAD.
6) ErrBodyNotAllowed was useless. By the time you received it,
   you had probably already done all your heavy computation
   and I/O to calculate what to write.
So, this change makes HEAD requests like GET requests.
We now count content-length and sniff content-type for HEAD
requests. If you Write, it doesn't return an error.
If you want a fast-path in your code for HEAD, you have to do
it early and set all the response headers yourself. Just like
before. If you choose not to Write in HEAD requests, be sure
to set Content-Length if you know it. We won't write
"Content-Length: 0" because you might've just chosen to not
write (or you don't know your Content-Length in advance).
Fixes #5454
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/12583043
											 
										 
										
											2013-08-06 18:33:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									isHEAD  :=  w . req . Method  ==  "HEAD" 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// header is written out to w.conn.buf below. Depending on the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// state of the handler, we either own the map or not. If we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// don't own it, the exclude map is created lazily for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// WriteSubset to remove headers. The setHeader struct holds 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// headers we need to add. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									header  :=  cw . header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									owned  :=  header  !=  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! owned  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										header  =  w . handlerHeader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  excludeHeader  map [ string ] bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									delHeader  :=  func ( key  string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  owned  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											header . Del ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  _ ,  ok  :=  header [ key ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  excludeHeader  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											excludeHeader  =  make ( map [ string ] bool ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										excludeHeader [ key ]  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  setHeader  extraHeader 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 15:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Don't write out the fake "Trailer:foo" keys. See TrailerPrefix. 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									trailers  :=  false 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-01 15:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  k  :=  range  cw . header  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . HasPrefix ( k ,  TrailerPrefix )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  excludeHeader  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												excludeHeader  =  make ( map [ string ] bool ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											excludeHeader [ k ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											trailers  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  cw . header [ "Trailer" ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										trailers  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										foreachHeaderElement ( v ,  cw . res . declareTrailer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-05-01 07:02:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									te  :=  header . get ( "Transfer-Encoding" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hasTE  :=  te  !=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If the handler is done but never sent a Content-Length 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// response header and this is our first (and last) write, set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// it, even to zero. This helps HTTP/1.0 clients keep their 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// "keep-alive" connections alive. 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-16 11:43:52 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Exceptions: 304/204/1xx responses never get Content-Length, and if 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-15 17:40:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// it was a HEAD request, we don't know the difference between 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 0 actual bytes and 0 bytes because the handler noticed it 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// was a HEAD request and chose not to write anything. So for 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-15 17:40:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HEAD, the handler should either write the Content-Length or 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// write non-zero bytes. If it's actually 0 bytes and the 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-15 17:40:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// handler never looked at the Request.Method, we just don't 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// send a Content-Length header. 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-01 07:02:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Further, we don't send an automatic Content-Length if they 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set a Transfer-Encoding, because they're generally incompatible. 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-18 11:43:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . handlerDone . isSet ( )  &&  ! trailers  &&  ! hasTE  &&  bodyAllowedForStatus ( w . status )  &&  header . get ( "Content-Length" )  ==  ""  &&  ( ! isHEAD  ||  len ( p )  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . contentLength  =  int64 ( len ( p ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										setHeader . contentLength  =  strconv . AppendInt ( cw . res . clenBuf [ : 0 ] ,  int64 ( len ( p ) ) ,  10 ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If this was an HTTP/1.0 request with keep-alive and we sent a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Content-Length back, we can make this a keep-alive response ... 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-05 15:59:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . wants10KeepAlive  &&  keepAlivesEnabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sentLength  :=  header . get ( "Content-Length" )  !=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  sentLength  &&  header . get ( "Connection" )  ==  "keep-alive"  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . closeAfterReply  =  false 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-15 10:24:47 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check for an explicit (and valid) Content-Length header. 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hasCL  :=  w . contentLength  !=  - 1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-05-11 15:01:28 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . wants10KeepAlive  &&  ( isHEAD  ||  hasCL  ||  ! bodyAllowedForStatus ( w . status ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  connectionHeaderSet  :=  header [ "Connection" ] 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! connectionHeaderSet  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											setHeader . connection  =  "keep-alive" 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-05 15:59:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ! w . req . ProtoAtLeast ( 1 ,  1 )  ||  w . wantsClose  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . closeAfterReply  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  header . get ( "Connection" )  ==  "close"  ||  ! keepAlivesEnabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . closeAfterReply  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-14 10:40:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 09:15:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If the client wanted a 100-continue but we never sent it to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// them (or, more strictly: we never finished reading their 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// request body), don't reuse this connection because it's now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// in an unknown state: we might be sending this response at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the same time the client is now sending its request body 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// after a timeout.  (Some HTTP clients send Expect: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 100-continue but knowing that some servers don't support 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// it, the clients set a timer and send the body later anyway) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If we haven't seen EOF, we can't skip over the unread body 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// because we don't know if the next bytes on the wire will be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the body-following-the-timer or the subsequent request. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// See Issue 11549. 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 13:27:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ecr ,  ok  :=  w . req . Body . ( * expectContinueReader ) ;  ok  &&  ! ecr . sawEOF . isSet ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-05 09:15:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . closeAfterReply  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-14 10:40:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Per RFC 2616, we should consume the request body before 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// replying, if the handler hasn't already done so. But we 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// don't want to do an unbounded amount of reading here for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// DoS reasons, so we only try up to a threshold. 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-10 16:09:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// TODO(bradfitz): where does RFC 2616 say that? See Issue 15527 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// about HTTP/1.x Handlers concurrently reading and writing, like 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// HTTP/2 handlers can do. Maybe this code should be relaxed? 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . req . ContentLength  !=  0  &&  ! w . closeAfterReply  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-29 18:10:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  discard ,  tooBig  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  bdy  :=  w . req . Body . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  * expectContinueReader : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  bdy . resp . wroteContinue  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												discard  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  * body : 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-03 10:04:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bdy . mu . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-29 18:10:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  bdy . closed : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! bdy . sawEOF  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Body was closed in handler with non-EOF error. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													w . closeAfterReply  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-03 10:04:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  bdy . unreadDataSizeLocked ( )  >=  maxPostHandlerReadBytes : 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-24 14:22:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												tooBig  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-29 18:10:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												discard  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-24 14:22:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-03 10:04:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bdy . mu . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-29 18:10:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											discard  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  discard  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-16 00:49:02 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											_ ,  err  :=  io . CopyN ( io . Discard ,  w . reqBody ,  maxPostHandlerReadBytes + 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-29 18:10:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  err  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// There must be even more data left over. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tooBig  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ErrBodyReadAfterClose : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Body was already consumed and closed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  io . EOF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// The remaining body was just consumed, close it. 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 20:38:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												err  =  w . reqBody . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-29 18:10:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													w . closeAfterReply  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-06 20:35:29 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Some other kind of error occurred, like a read timeout, or 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-29 18:10:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// corrupt chunked encoding. In any case, whatever remains 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// on the wire must not be parsed as another HTTP request. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												w . closeAfterReply  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 17:34:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-14 10:40:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-29 18:10:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  tooBig  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . requestTooLarge ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											delHeader ( "Connection" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											setHeader . connection  =  "close" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-14 10:40:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 11:35:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									code  :=  w . status 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-16 15:39:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  bodyAllowedForStatus ( code )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-15 01:01:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// If no content type, apply sniffing algorithm to body. 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-31 23:38:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  haveType  :=  header [ "Content-Type" ] 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 00:23:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If the Content-Encoding was set and is non-blank, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// we shouldn't sniff the body. See Issue 31753. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ce  :=  header . Get ( "Content-Encoding" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hasCE  :=  len ( ce )  >  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! hasCE  &&  ! haveType  &&  ! hasTE  &&  len ( p )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-31 17:09:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											setHeader . contentType  =  DetectContentType ( p ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-16 15:39:59 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  k  :=  range  suppressedHeaders ( code )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											delHeader ( k ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-05 16:26:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! header . has ( "Date" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-19 20:15:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										setHeader . date  =  appendTime ( cw . res . dateBuf [ : 0 ] ,  time . Now ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  hasCL  &&  hasTE  &&  te  !=  "identity"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TODO: return an error if WriteHeader gets a return parameter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// For now just ignore the Content-Length. 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 12:12:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . conn . server . logf ( "http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d" , 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											te ,  w . contentLength ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delHeader ( "Content-Length" ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hasCL  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 14:03:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . req . Method  ==  "HEAD"  ||  ! bodyAllowedForStatus ( code )  ||  code  ==  StatusNoContent  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Response has no body. 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delHeader ( "Transfer-Encoding" ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  hasCL  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 14:03:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Content-Length has been provided, so no chunking is to be done. 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delHeader ( "Transfer-Encoding" ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  w . req . ProtoAtLeast ( 1 ,  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-19 22:33:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// HTTP/1.1 or greater: Transfer-Encoding has been set to identity, and no 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-29 13:53:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// content-length has been provided. The connection must be closed after the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// reply is written, and no chunking is to be done. This is the setup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// recommended in the Server-Sent Events candidate recommendation 11, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// section 8. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  hasTE  &&  te  ==  "identity"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cw . chunking  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . closeAfterReply  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-27 14:03:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											delHeader ( "Transfer-Encoding" ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-29 13:53:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// HTTP/1.1 or greater: use chunked transfer encoding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// to avoid closing the connection at EOF. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cw . chunking  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											setHeader . transferEncoding  =  "chunked" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-15 10:52:42 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  hasTE  &&  te  ==  "chunked"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We will send the chunked Transfer-Encoding header later. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												delHeader ( "Transfer-Encoding" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-29 13:53:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// HTTP version < 1.1: cannot do chunked transfer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// encoding and we don't know the Content-Length so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// signal EOF by closing connection. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . closeAfterReply  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delHeader ( "Transfer-Encoding" )  // in case already set 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-19 10:05:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Cannot use Content-Length with non-identity Transfer-Encoding. 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cw . chunking  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delHeader ( "Content-Length" ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-19 10:05:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! w . req . ProtoAtLeast ( 1 ,  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-09 12:07:39 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-23 11:19:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-24 00:40:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Only override the Connection header if it is not a successful 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// protocol switch response and if KeepAlives are not enabled. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// See https://golang.org/issue/36381. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									delConnectionHeader  :=  w . closeAfterReply  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( ! keepAlivesEnabled  ||  ! hasToken ( cw . header . get ( "Connection" ) ,  "close" ) )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										! isProtocolSwitchResponse ( w . status ,  header ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  delConnectionHeader  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-02 16:27:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delHeader ( "Connection" ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-06 18:37:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  w . req . ProtoAtLeast ( 1 ,  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											setHeader . connection  =  "close" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-23 11:19:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-28 16:46:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									writeStatusLine ( w . conn . bufw ,  w . req . ProtoAtLeast ( 1 ,  1 ) ,  code ,  w . statusBuf [ : ] ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cw . header . WriteSubset ( w . conn . bufw ,  excludeHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									setHeader . Write ( w . conn . bufw ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . conn . bufw . Write ( crlf ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-28 13:07:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// foreachHeaderElement splits v according to the "#rule" construction  
						 
					
						
							
								
									
										
										
										
											2018-02-13 22:03:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// in RFC 7230 section 7 and calls fn for each non-empty element.  
						 
					
						
							
								
									
										
										
										
											2014-12-29 19:32:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  foreachHeaderElement ( v  string ,  fn  func ( string ) )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v  =  textproto . TrimString ( v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  v  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! strings . Contains ( v ,  "," )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fn ( v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  f  :=  range  strings . Split ( v ,  "," )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  f  =  textproto . TrimString ( f ) ;  f  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fn ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-13 22:03:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// writeStatusLine writes an HTTP/1.x Status-Line (RFC 7230 Section 3.1.2)  
						 
					
						
							
								
									
										
										
										
											2017-04-28 16:46:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// to bw. is11 is whether the HTTP request is HTTP/1.1. false means HTTP/1.0.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// code is the response status code.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// scratch is an optional scratch buffer. If it has at least capacity 3, it's used.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  writeStatusLine ( bw  * bufio . Writer ,  is11  bool ,  code  int ,  scratch  [ ] byte )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  is11  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bw . WriteString ( "HTTP/1.1 " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bw . WriteString ( "HTTP/1.0 " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  text ,  ok  :=  statusText [ code ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bw . Write ( strconv . AppendInt ( scratch [ : 0 ] ,  int64 ( code ) ,  10 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bw . WriteByte ( ' ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bw . WriteString ( text ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bw . WriteString ( "\r\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// don't worry about performance 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fmt . Fprintf ( bw ,  "%03d status code %d\r\n" ,  code ,  code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-02-17 15:44:42 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// bodyAllowed reports whether a Write is allowed for this response type.  
						 
					
						
							
								
									
										
										
										
											2011-06-09 18:10:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// It's illegal to call this before the header has been flushed.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * response )  bodyAllowed ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! w . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-16 11:43:52 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  bodyAllowedForStatus ( w . status ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-09 18:10:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The Life Of A Write is like this:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Handler starts. No header has been sent. The handler can either  
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// write a header, or just start writing. Writing before sending a header  
						 
					
						
							
								
									
										
										
										
											2013-03-20 16:32:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// sends an implicitly empty 200 OK header.  
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If the handler didn't declare a Content-Length up front, we either  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// go into chunking mode or, if the handler finishes running before  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the chunking buffer size, we compute a Content-Length and send that  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// in the header instead.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Likewise, if the handler didn't set a Content-Type, we sniff that  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// from the initial chunk of output.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The Writers are wired together like:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2022-01-29 19:07:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  1. *response (the ResponseWriter) ->  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes ->  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//     and which writes the chunk headers, if needed ->  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  4. conn.bufw, a *bufio.Writer of default (4kB) bytes, writing to ->  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  5. checkConnErrorWriter{c}, which notes any non-nil error on Write  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//     and populates c.werr with it if so, but otherwise writes to ->  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  6. the rwc, the net.Conn.  
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TODO(bradfitz): short-circuit some of the buffering when the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// initial header contains both a Content-Type and Content-Length.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Also short-circuit in (1) when the header's been sent and not in  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// chunking mode, writing directly to (4) instead, if (2) has no  
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// buffered data. More generally, we could short-circuit from (1) to  
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// (3) even in chunking mode if the write size from (1) is over some  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// threshold and nothing is in (2).  The answer might be mostly making  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// with this instead.  
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  Write ( data  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2013-08-19 22:56:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  w . write ( len ( data ) ,  data ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * response )  WriteString ( data  string )  ( n  int ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  w . write ( len ( data ) ,  nil ,  data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// either dataB or dataS is non-zero.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * response )  write ( lenData  int ,  dataB  [ ] byte ,  dataS  string )  ( n  int ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . conn . hijacked ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-11 09:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  lenData  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-23 17:28:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											caller  :=  relevantCaller ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . conn . server . logf ( "http: response.Write on hijacked connection from %s (%s:%d)" ,  caller . Function ,  path . Base ( caller . File ) ,  caller . Line ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-11 09:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ,  ErrHijacked 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 13:27:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . canWriteContinue . isSet ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Body reader wants to write 100 Continue but hasn't yet. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Tell it not to. The store must be done while holding the lock 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// because the lock makes sure that there is not an active write 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this very moment. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeContinueMu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . canWriteContinue . setFalse ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . writeContinueMu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! w . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . WriteHeader ( StatusOK ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-19 22:56:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  lenData  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-09 12:07:39 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-09 18:10:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! w . bodyAllowed ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-03 16:09:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ,  ErrBodyNotAllowed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-19 22:56:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . written  +=  int64 ( lenData )  // ignoring errors, for errorKludge 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . contentLength  !=  - 1  &&  w . written  >  w . contentLength  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  ErrContentLength 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-19 22:56:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  dataB  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  w . w . Write ( dataB ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  w . w . WriteString ( dataS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  finishRequest ( )  {  
						 
					
						
							
								
									
										
										
										
											2016-01-18 11:43:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . handlerDone . setTrue ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! w . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . WriteHeader ( StatusOK ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . w . Flush ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-10 19:22:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									putBufioWriter ( w . w ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . cw . close ( ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . conn . bufw . Flush ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . conn . r . abortPendingRead ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-14 09:46:40 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Close the body (regardless of w.closeAfterReply) so we can 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// re-use its bufio.Reader later safely. 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-03 12:04:20 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . reqBody . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-14 09:46:40 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-28 15:21:54 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . req . MultipartForm  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . req . MultipartForm . RemoveAll ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 11:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// shouldReuseConnection reports whether the underlying TCP connection can be reused.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It must only be called after the handler is done executing.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * response )  shouldReuseConnection ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . closeAfterReply  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// The request or something set while executing the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// handler indicated we shouldn't reuse this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// connection. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: treat HEAD requests like GET requests
A response to a HEAD request is supposed to look the same as a
response to a GET request, just without a body.
HEAD requests are incredibly rare in the wild.
The Go net/http package has so far treated HEAD requests
specially: a Write on our default ResponseWriter returned
ErrBodyNotAllowed, telling handlers that something was wrong.
This was to optimize the fast path for HEAD requests, but:
1) because HEAD requests are incredibly rare, they're not
   worth having a fast path for.
2) Letting the http.Handler handle but do nop Writes is still
   very fast.
3) this forces ugly error handling into the application.
   e.g. https://code.google.com/p/go/source/detail?r=6f596be7a31e
   and related.
4) The net/http package nowadays does Content-Type sniffing,
   but you don't get that for HEAD.
5) The net/http package nowadays does Content-Length counting
   for small (few KB) responses, but not for HEAD.
6) ErrBodyNotAllowed was useless. By the time you received it,
   you had probably already done all your heavy computation
   and I/O to calculate what to write.
So, this change makes HEAD requests like GET requests.
We now count content-length and sniff content-type for HEAD
requests. If you Write, it doesn't return an error.
If you want a fast-path in your code for HEAD, you have to do
it early and set all the response headers yourself. Just like
before. If you choose not to Write in HEAD requests, be sure
to set Content-Length if you know it. We won't write
"Content-Length: 0" because you might've just chosen to not
write (or you don't know your Content-Length in advance).
Fixes #5454
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/12583043
											 
										 
										
											2013-08-06 18:33:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . req . Method  !=  "HEAD"  &&  w . contentLength  !=  - 1  &&  w . bodyAllowed ( )  &&  w . contentLength  !=  w . written  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Did not write enough. Avoid getting out of sync. 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 11:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-03 12:22:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-15 17:51:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There was some error writing to the underlying connection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// during the request, so don't re-use this conn. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . conn . werr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 11:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-15 17:51:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 11:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-24 14:22:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . closedRequestBodyEarly ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 11:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-24 14:22:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  closedRequestBodyEarly ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									body ,  ok  :=  w . req . Body . ( * body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ok  &&  body . didEarlyClose ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  Flush ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! w . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . WriteHeader ( StatusOK ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 18:06:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . w . Flush ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . cw . flush ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 18:06:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:40:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * conn )  finalFlush ( )  {  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . bufr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Steal the bufio.Reader (~4KB worth of memory) and its associated 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// reader for a future connection. 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										putBufioReader ( c . bufr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . bufr  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . bufw  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . bufw . Flush ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 20:02:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Steal the bufio.Writer (~4KB worth of memory) and its associated 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// writer for a future connection. 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										putBufioWriter ( c . bufw ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . bufw  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:40:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Close the connection.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * conn )  close ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . finalFlush ( ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . rwc . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-12 15:20:18 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// rstAvoidanceDelay is the amount of time we sleep after closing the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// write side of a TCP connection before closing the entire socket.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// By sleeping, we increase the chances that the client sees our FIN  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and processes its final data before they process the subsequent RST  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// from closing a connection with known unread data.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This RST seems to occur mostly on BSD systems. (And Windows?)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This timeout is somewhat arbitrary (~latency around the planet).  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  rstAvoidanceDelay  =  500  *  time . Millisecond  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-09-24 17:01:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  closeWriter  interface  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CloseWrite ( )  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  _  closeWriter  =  ( * net . TCPConn ) ( nil )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-12 15:20:18 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// closeWrite flushes any outstanding data and sends a FIN packet (if  
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// client is connected via TCP), signalling that we're done. We then  
						 
					
						
							
								
									
										
										
										
											2014-09-24 17:01:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// pause for a bit, hoping the client processes it before any  
						 
					
						
							
								
									
										
										
										
											2012-11-12 15:20:18 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// subsequent RST.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2015-07-10 17:17:11 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// See https://golang.org/issue/3595  
						 
					
						
							
								
									
										
										
										
											2012-11-12 15:20:18 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * conn )  closeWriteAndWait ( )  {  
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:40:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . finalFlush ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-24 17:01:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  tcp ,  ok  :=  c . rwc . ( closeWriter ) ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:40:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tcp . CloseWrite ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-12 15:20:18 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									time . Sleep ( rstAvoidanceDelay ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:40:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-08 12:39:56 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// validNextProto reports whether the proto is a valid ALPN protocol name.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Everything is valid except the empty string and built-in protocol types,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// so that those can't be overridden with alternate implementations.  
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  validNextProto ( proto  string )  bool  {  
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  proto  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  "" ,  "http/1.1" ,  "http/1.0" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 13:31:34 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									runHooks   =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									skipHooks  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * conn )  setState ( nc  net . Conn ,  state  ConnState ,  runHook  bool )  {  
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srv  :=  c . server 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  state  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  StateNew : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										srv . trackConn ( c ,  true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  StateHijacked ,  StateClosed : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										srv . trackConn ( c ,  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-28 21:01:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  state  >  0xff  ||  state  <  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "internal error" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									packedState  :=  uint64 ( time . Now ( ) . Unix ( ) << 8 )  |  uint64 ( state ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									atomic . StoreUint64 ( & c . curState . atomic ,  packedState ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 13:31:34 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! runHook  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  hook  :=  srv . ConnState ;  hook  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-27 18:29:00 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hook ( nc ,  state ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-28 21:01:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * conn )  getState ( )  ( state  ConnState ,  unixSec  int64 )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									packedState  :=  atomic . LoadUint64 ( & c . curState . atomic ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ConnState ( packedState  &  0xff ) ,  int64 ( packedState  >>  8 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-12-16 18:51:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// badRequestError is a literal string (used by in the server in HTML,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// unescaped) to tell the user why their request was bad. It should  
						 
					
						
							
								
									
										
										
										
											2016-02-24 11:55:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// be plain text without user info or other embedded errors.  
						 
					
						
							
								
									
										
										
										
											2020-10-13 13:02:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  badRequestError ( e  string )  error  {  return  statusError { StatusBadRequest ,  e }  }  
						 
					
						
							
								
									
										
										
										
											2015-12-16 18:51:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 13:02:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// statusError is an error used to respond to a request with an HTTP status.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The text should be plain text without user info or other embedded errors.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  statusError  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									code  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									text  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( e  statusError )  Error ( )  string  {  return  StatusText ( e . code )  +  ": "  +  e . text  }  
						 
					
						
							
								
									
										
										
										
											2015-12-16 18:51:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 22:49:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ErrAbortHandler is a sentinel panic value to abort a handler.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// While any panic from ServeHTTP aborts the response to the client,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// panicking with ErrAbortHandler also suppresses logging of a stack  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// trace to the server's error log.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  ErrAbortHandler  =  errors . New ( "net/http: abort Handler" )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 22:21:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// isCommonNetReadError reports whether err is a common error  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// encountered during reading a request off the network when the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// client has gone away or had its read fail somehow. This is used to  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// determine which logs are interesting enough to log about.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isCommonNetReadError ( err  error )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  io . EOF  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  neterr ,  ok  :=  err . ( net . Error ) ;  ok  &&  neterr . Timeout ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  oe ,  ok  :=  err . ( * net . OpError ) ;  ok  &&  oe . Op  ==  "read"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Serve a new connection.  
						 
					
						
							
								
									
										
										
										
											2016-04-11 05:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( c  * conn )  serve ( ctx  context . Context )  {  
						 
					
						
							
								
									
										
										
										
											2015-10-14 14:25:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . remoteAddr  =  c . rwc . RemoteAddr ( ) . String ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-18 23:47:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  =  context . WithValue ( ctx ,  LocalAddrContextKey ,  c . rwc . LocalAddr ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 20:23:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  inFlightResponse  * response 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-02 12:00:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 22:49:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  recover ( ) ;  err  !=  nil  &&  err  !=  ErrAbortHandler  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-14 10:15:38 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  size  =  64  <<  10 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-21 15:14:38 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											buf  :=  make ( [ ] byte ,  size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf  =  buf [ : runtime . Stack ( buf ,  false ) ] 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 12:12:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											c . server . logf ( "http: panic serving %v: %v\n%s" ,  c . remoteAddr ,  err ,  buf ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-02 12:00:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 20:23:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  inFlightResponse  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											inFlightResponse . cancelCtx ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-21 15:14:38 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! c . hijacked ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 20:23:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  inFlightResponse  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												inFlightResponse . conn . r . abortPendingRead ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												inFlightResponse . reqBody . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-21 15:14:38 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											c . close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 13:31:34 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											c . setState ( c . rwc ,  StateClosed ,  runHooks ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-19 14:19:59 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-02 12:00:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-19 19:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  tlsConn ,  ok  :=  c . rwc . ( * tls . Conn ) ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 08:45:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tlsTO  :=  c . server . tlsHandshakeTimeout ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  tlsTO  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dl  :=  time . Now ( ) . Add ( tlsTO ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . rwc . SetReadDeadline ( dl ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . rwc . SetWriteDeadline ( dl ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:52:45 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-01 12:18:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  tlsConn . HandshakeContext ( ctx ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-25 02:02:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// If the handshake failed due to the client not speaking 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// TLS, assume they're speaking plaintext HTTP and write a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// 400 response on the TLS conn's underlying net.Conn. 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 08:21:44 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  re ,  ok  :=  err . ( tls . RecordHeaderError ) ;  ok  &&  re . Conn  !=  nil  &&  tlsRecordHeaderLooksLikeHTTP ( re . RecordHeader )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												io . WriteString ( re . Conn ,  "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												re . Conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 12:12:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											c . server . logf ( "http: TLS handshake error from %s: %v" ,  c . rwc . RemoteAddr ( ) ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-18 12:59:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 08:45:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Restore Conn-level deadlines. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  tlsTO  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . rwc . SetReadDeadline ( time . Time { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . rwc . SetWriteDeadline ( time . Time { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-19 19:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . tlsState  =  new ( tls . ConnectionState ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* c . tlsState  =  tlsConn . ConnectionState ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  proto  :=  c . tlsState . NegotiatedProtocol ;  validNextProto ( proto )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  fn  :=  c . server . TLSNextProto [ proto ] ;  fn  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												h  :=  initALPNRequest { ctx ,  tlsConn ,  serverHandler { c . server } } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 13:31:34 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Mark freshly created HTTP/2 as active and prevent any server state hooks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// from being run on these connections. This prevents closeIdleConns from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// closing such connections. See issue https://golang.org/issue/39776. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												c . setState ( c . rwc ,  StateActive ,  skipHooks ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fn ( c . server ,  tlsConn ,  h ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-19 19:56:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP/1.x from here on. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-11 05:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx ,  cancelCtx  :=  context . WithCancel ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . cancelCtx  =  cancelCtx 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  cancelCtx ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c . r  =  & connReader { conn :  c } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . bufr  =  newBufioReader ( c . r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . bufw  =  newBufioWriterSize ( checkConnErrorWriter { c } ,  4 << 10 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w ,  err  :=  c . readRequest ( ctx ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  c . r . remain  !=  c . server . initialReadLimitSize ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-03 18:58:28 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// If we read any bytes off the wire, we're active. 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 13:31:34 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											c . setState ( c . rwc ,  StateActive ,  runHooks ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-03 18:58:28 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 22:21:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  errorHeaders  =  "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-11 15:52:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  err  ==  errTooLarge : 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-09 10:55:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Their HTTP client may or may not be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// able to read this if we're 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// responding to them and hanging up 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// while they're still writing their 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// request. Undefined behavior. 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 22:21:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												const  publicErr  =  "431 Request Header Fields Too Large" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Fprintf ( c . rwc ,  "HTTP/1.1 " + publicErr + errorHeaders + publicErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-12 15:20:18 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												c . closeWriteAndWait ( ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-11 15:52:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  isUnsupportedTEError ( err ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Respond as per RFC 7230 Section 3.3.1 which says, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//      A server that receives a request message with a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//      transfer coding it does not understand SHOULD 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//      respond with 501 (Unimplemented). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												code  :=  StatusNotImplemented 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We purposefully aren't echoing back the transfer-encoding's value, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// so as to mitigate the risk of cross side scripting by an attacker. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Fprintf ( c . rwc ,  "HTTP/1.1 %d %s%sUnsupported transfer encoding" ,  code ,  StatusText ( code ) ,  errorHeaders ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  isCommonNetReadError ( err ) : 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  // don't reply 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 22:21:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-11 15:52:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 13:02:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  v ,  ok  :=  err . ( statusError ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													fmt . Fprintf ( c . rwc ,  "HTTP/1.1 %d %s: %s%s%d %s: %s" ,  v . code ,  StatusText ( v . code ) ,  v . text ,  errorHeaders ,  v . code ,  StatusText ( v . code ) ,  v . text ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-11 15:52:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-13 13:02:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												publicErr  :=  "400 Bad Request" 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-11 15:52:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												fmt . Fprintf ( c . rwc ,  "HTTP/1.1 " + publicErr + errorHeaders + publicErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 14:09:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expect 100 Continue support 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req  :=  w . req 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  req . expectsContinue ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-10 22:25:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  req . ProtoAtLeast ( 1 ,  1 )  &&  req . ContentLength  !=  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 14:09:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Wrap the Body reader with one that replies on the connection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												req . Body  =  & expectContinueReader { readCloser :  req . Body ,  resp :  w } 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-13 13:27:22 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												w . canWriteContinue . setTrue ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 14:09:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-28 11:07:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  req . Header . get ( "Expect" )  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											w . sendExpectationFailed ( ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 14:09:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . curReq . Store ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  requestBodyRemains ( req . Body )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											registerOnHitEOF ( req . Body ,  w . conn . r . startBackgroundRead ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . conn . r . startBackgroundRead ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-27 21:55:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// HTTP cannot have multiple simultaneous active requests.[*] 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Until the server replies to this request, it can't read another, 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-07 00:40:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// so we might as well run the handler in this goroutine. 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// [*] Not strictly true: HTTP pipelining. We could let them all process 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-27 21:55:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// in parallel even if their responses need to be serialized. 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// But we're not going to implement HTTP pipelining because it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// was never deployed in the wild and the answer is HTTP/2. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 20:23:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										inFlightResponse  =  w 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										serverHandler { c . server } . ServeHTTP ( w ,  w . req ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 20:23:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										inFlightResponse  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 12:31:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . cancelCtx ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  c . hijacked ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-09 12:07:39 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . finishRequest ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-24 11:53:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! w . shouldReuseConnection ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-24 14:22:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  w . requestBodyLimitHit  ||  w . closedRequestBodyEarly ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-12 15:20:18 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												c . closeWriteAndWait ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:40:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 13:31:34 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . setState ( c . rwc ,  StateIdle ,  runHooks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . curReq . Store ( ( * response ) ( nil ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 18:43:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! w . conn . server . doKeepAlives ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// We're in shutdown mode. We might've replied 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// to the user without "Connection: close" and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// they might think they can send another 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// request, but such is life with HTTP/1.1. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  d  :=  c . server . idleTimeout ( ) ;  d  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c . rwc . SetReadDeadline ( time . Now ( ) . Add ( d ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  err  :=  c . bufr . Peek ( 4 ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . rwc . SetReadDeadline ( time . Time { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-03 14:16:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  sendExpectationFailed ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO(bradfitz): let ServeHTTP handlers handle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// requests with non-standard expectation[s]? Seems 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// theoretical at best, and doesn't fit into the 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// current ServeHTTP model anyway. We'd need to 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// make the ResponseWriter an optional 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// "ExpectReplier" interface or something. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-13 22:03:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For now we'll just obey RFC 7231 5.1.1 which says 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// "A server that receives an Expect field-value other 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// than 100-continue MAY respond with a 417 (Expectation 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Failed) status code to indicate that the unexpected 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// expectation cannot be met." 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . Header ( ) . Set ( "Connection" ,  "close" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . WriteHeader ( StatusExpectationFailed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . finishRequest ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 12:04:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and a Hijacker.  
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( w  * response )  Hijack ( )  ( rwc  net . Conn ,  buf  * bufio . ReadWriter ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-01-18 11:43:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . handlerDone . isSet ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "net/http: Hijack called after ServeHTTP finished" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-11 10:03:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . cw . flush ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c  :=  w . conn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  c . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-12-26 11:52:14 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Release the bufioWriter that writes to the chunk writer, it is not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// used after a connection has been hijacked. 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rwc ,  buf ,  err  =  c . hijackLocked ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-26 11:52:14 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										putBufioWriter ( w . w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . w  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rwc ,  buf ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-05 19:25:43 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  * response )  CloseNotify ( )  <- chan  bool  {  
						 
					
						
							
								
									
										
										
										
											2016-01-18 11:43:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  w . handlerDone . isSet ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "net/http: CloseNotify called after ServeHTTP finished" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  w . closeNotifyCh 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 20:38:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  registerOnHitEOF ( rc  io . ReadCloser ,  fn  func ( ) )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  v  :=  rc . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * expectContinueReader : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										registerOnHitEOF ( v . readCloser ,  fn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * body : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										v . registerOnHitEOF ( fn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "unexpected type "  +  fmt . Sprintf ( "%T" ,  rc ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// requestBodyRemains reports whether future calls to Read  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// on rc might yield more data.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  requestBodyRemains ( rc  io . ReadCloser )  bool  {  
						 
					
						
							
								
									
										
										
										
											2016-10-22 09:47:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  rc  ==  NoBody  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 20:38:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  v  :=  rc . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * expectContinueReader : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  requestBodyRemains ( v . readCloser ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  * body : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  v . bodyRemains ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "unexpected type "  +  fmt . Sprintf ( "%T" ,  rc ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The HandlerFunc type is an adapter to allow the use of  
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ordinary functions as HTTP handlers. If f is a function  
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// with the appropriate signature, HandlerFunc(f) is a  
						 
					
						
							
								
									
										
										
										
											2015-12-17 20:53:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Handler that calls f.  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  HandlerFunc  func ( ResponseWriter ,  * Request )  
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-18 21:53:18 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ServeHTTP calls f(w, r).  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( f  HandlerFunc )  ServeHTTP ( w  ResponseWriter ,  r  * Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f ( w ,  r ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Helper handlers  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-20 10:22:09 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Error replies to the request with the specified error message and HTTP code.  
						 
					
						
							
								
									
										
										
										
											2016-04-11 11:15:00 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// It does not otherwise end the request; the caller should ensure no further  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// writes are done to w.  
						 
					
						
							
								
									
										
										
										
											2013-08-01 12:05:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The error message should be plain text.  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  Error ( w  ResponseWriter ,  error  string ,  code  int )  {  
						 
					
						
							
								
									
										
										
										
											2011-03-09 09:41:01 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . Header ( ) . Set ( "Content-Type" ,  "text/plain; charset=utf-8" ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-02 11:01:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . Header ( ) . Set ( "X-Content-Type-Options" ,  "nosniff" ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . WriteHeader ( code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fmt . Fprintln ( w ,  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-20 10:22:09 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// NotFound replies to the request with an HTTP 404 not found error.  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  NotFound ( w  ResponseWriter ,  r  * Request )  {  Error ( w ,  "404 page not found" ,  StatusNotFound )  }  
						 
					
						
							
								
									
										
										
										
											2010-03-20 10:22:09 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// NotFoundHandler returns a simple request handler  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// that replies to each request with a ``404 page not found'' reply.  
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  NotFoundHandler ( )  Handler  {  return  HandlerFunc ( NotFound )  }  
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-13 10:39:11 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// StripPrefix returns a handler that serves HTTP requests by removing the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// given prefix from the request URL's Path (and RawPath if set) and invoking  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the handler h. StripPrefix handles a request for a path that doesn't begin  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// with prefix by replying with an HTTP 404 not found error. The prefix must  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// match exactly: if the prefix in the request contains escaped characters  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the reply is also an HTTP 404 not found error.  
						 
					
						
							
								
									
										
										
										
											2011-06-27 11:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  StripPrefix ( prefix  string ,  h  Handler )  Handler  {  
						 
					
						
							
								
									
										
										
										
											2013-03-18 13:44:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  prefix  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  h 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-27 11:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  HandlerFunc ( func ( w  ResponseWriter ,  r  * Request )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-13 10:39:11 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p  :=  strings . TrimPrefix ( r . URL . Path ,  prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rp  :=  strings . TrimPrefix ( r . URL . RawPath ,  prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( p )  <  len ( r . URL . Path )  &&  ( r . URL . RawPath  ==  ""  ||  len ( rp )  <  len ( r . URL . RawPath ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 10:57:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r2  :=  new ( Request ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* r2  =  * r 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r2 . URL  =  new ( url . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* r2 . URL  =  * r . URL 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 21:21:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r2 . URL . Path  =  p 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-13 10:39:11 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r2 . URL . RawPath  =  rp 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 10:57:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											h . ServeHTTP ( w ,  r2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-18 13:44:20 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-27 11:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											NotFound ( w ,  r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: improve signature of Redirect, NewRequest
In CL https://golang.org/cl/4893043 (6 years ago), a new package named
"url" was created (it is currently known as "net/url"). During that
change, some identifier name collisions were introduced, and two
parameters in net/http were renamed to "urlStr".
Since that time, Go has continued to put high emphasis on the quality
and readability of the documentation. Sometimes, that means making small
sacrifices in the implementation details of a package to ensure that
the godoc reads better, since that's what the majority of users interact
with. See https://golang.org/s/style#named-result-parameters:
> Clarity of docs is always more important than saving a line or two
> in your function.
I think the "urlStr" parameter name is suboptimal for godoc purposes,
and just "url" would be better.
During the review of https://golang.org/cl/4893043, it was also noted
by @rsc that having to rename parameters named "url" was suboptimal:
> It's unfortunate that naming the package url means
> you can't have a parameter or variable named url.
However, at the time, the name of the url package was still being
decided, and uri was an alternative name under consideration.
The reason urlStr was chosen is because it was a lesser evil
compared to naming the url package uri instead:
> Let's not get hung up on URI vs. URL, but I'd like s/uri/urlStr/ even for just
> that the "i" in "uri" looks very similar to the "l" in "url" in many fonts.
> Please let's go with urlStr instead of uri.
Now that we have the Go 1 compatibility guarantee, the name of the
net/url package is fixed. However, it's possible to improve the
signature of Redirect, NewRequest functions in net/http package
for godoc purposes by creating a package global alias to url.Parse,
and renaming urlStr parameter to url in the exported funcs. This CL
does so.
Updates #21077.
Change-Id: Ibcc10e3825863a663e6ad91b6eb47b1862a299a6
Reviewed-on: https://go-review.googlesource.com/49930
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
											 
										 
										
											2017-07-19 00:41:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Redirect replies to the request with a redirect to url,  
						 
					
						
							
								
									
										
										
										
											2009-04-14 20:31:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// which may be a path relative to the request path.  
						 
					
						
							
								
									
										
										
										
											2015-10-16 13:26:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The provided code should be in the 3xx range and is usually  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// StatusMovedPermanently, StatusFound or StatusSeeOther.  
						 
					
						
							
								
									
										
										
										
											2018-05-04 13:05:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If the Content-Type header has not been set, Redirect sets it  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to "text/html; charset=utf-8" and writes a small HTML body.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Setting the Content-Type header to any value, including nil,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// disables that behavior.  
						 
					
						
							
								
									
										
											 
										
											
												net/http: improve signature of Redirect, NewRequest
In CL https://golang.org/cl/4893043 (6 years ago), a new package named
"url" was created (it is currently known as "net/url"). During that
change, some identifier name collisions were introduced, and two
parameters in net/http were renamed to "urlStr".
Since that time, Go has continued to put high emphasis on the quality
and readability of the documentation. Sometimes, that means making small
sacrifices in the implementation details of a package to ensure that
the godoc reads better, since that's what the majority of users interact
with. See https://golang.org/s/style#named-result-parameters:
> Clarity of docs is always more important than saving a line or two
> in your function.
I think the "urlStr" parameter name is suboptimal for godoc purposes,
and just "url" would be better.
During the review of https://golang.org/cl/4893043, it was also noted
by @rsc that having to rename parameters named "url" was suboptimal:
> It's unfortunate that naming the package url means
> you can't have a parameter or variable named url.
However, at the time, the name of the url package was still being
decided, and uri was an alternative name under consideration.
The reason urlStr was chosen is because it was a lesser evil
compared to naming the url package uri instead:
> Let's not get hung up on URI vs. URL, but I'd like s/uri/urlStr/ even for just
> that the "i" in "uri" looks very similar to the "l" in "url" in many fonts.
> Please let's go with urlStr instead of uri.
Now that we have the Go 1 compatibility guarantee, the name of the
net/url package is fixed. However, it's possible to improve the
signature of Redirect, NewRequest functions in net/http package
for godoc purposes by creating a package global alias to url.Parse,
and renaming urlStr parameter to url in the exported funcs. This CL
does so.
Updates #21077.
Change-Id: Ibcc10e3825863a663e6ad91b6eb47b1862a299a6
Reviewed-on: https://go-review.googlesource.com/49930
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
											 
										 
										
											2017-07-19 00:41:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  Redirect ( w  ResponseWriter ,  r  * Request ,  url  string ,  code  int )  {  
						 
					
						
							
								
									
										
										
										
											2019-10-21 15:30:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  u ,  err  :=  urlpkg . Parse ( url ) ;  err  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-13 22:03:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// If url was relative, make its path absolute by 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// combining with request path. 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-13 22:03:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// The client would probably do this for us, 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// but doing it ourselves is more reliable. 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-13 22:03:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// See RFC 7231, section 7.1.2 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-02 13:40:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  u . Scheme  ==  ""  &&  u . Host  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											oldpath  :=  r . URL . Path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  oldpath  ==  ""  {  // should not happen, but avoid a crash if it does 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												oldpath  =  "/" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// no leading http://server 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: improve signature of Redirect, NewRequest
In CL https://golang.org/cl/4893043 (6 years ago), a new package named
"url" was created (it is currently known as "net/url"). During that
change, some identifier name collisions were introduced, and two
parameters in net/http were renamed to "urlStr".
Since that time, Go has continued to put high emphasis on the quality
and readability of the documentation. Sometimes, that means making small
sacrifices in the implementation details of a package to ensure that
the godoc reads better, since that's what the majority of users interact
with. See https://golang.org/s/style#named-result-parameters:
> Clarity of docs is always more important than saving a line or two
> in your function.
I think the "urlStr" parameter name is suboptimal for godoc purposes,
and just "url" would be better.
During the review of https://golang.org/cl/4893043, it was also noted
by @rsc that having to rename parameters named "url" was suboptimal:
> It's unfortunate that naming the package url means
> you can't have a parameter or variable named url.
However, at the time, the name of the url package was still being
decided, and uri was an alternative name under consideration.
The reason urlStr was chosen is because it was a lesser evil
compared to naming the url package uri instead:
> Let's not get hung up on URI vs. URL, but I'd like s/uri/urlStr/ even for just
> that the "i" in "uri" looks very similar to the "l" in "url" in many fonts.
> Please let's go with urlStr instead of uri.
Now that we have the Go 1 compatibility guarantee, the name of the
net/url package is fixed. However, it's possible to improve the
signature of Redirect, NewRequest functions in net/http package
for godoc purposes by creating a package global alias to url.Parse,
and renaming urlStr parameter to url in the exported funcs. This CL
does so.
Updates #21077.
Change-Id: Ibcc10e3825863a663e6ad91b6eb47b1862a299a6
Reviewed-on: https://go-review.googlesource.com/49930
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
											 
										 
										
											2017-07-19 00:41:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  url  ==  ""  ||  url [ 0 ]  !=  '/'  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// make relative path absolute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												olddir ,  _  :=  path . Split ( oldpath ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: improve signature of Redirect, NewRequest
In CL https://golang.org/cl/4893043 (6 years ago), a new package named
"url" was created (it is currently known as "net/url"). During that
change, some identifier name collisions were introduced, and two
parameters in net/http were renamed to "urlStr".
Since that time, Go has continued to put high emphasis on the quality
and readability of the documentation. Sometimes, that means making small
sacrifices in the implementation details of a package to ensure that
the godoc reads better, since that's what the majority of users interact
with. See https://golang.org/s/style#named-result-parameters:
> Clarity of docs is always more important than saving a line or two
> in your function.
I think the "urlStr" parameter name is suboptimal for godoc purposes,
and just "url" would be better.
During the review of https://golang.org/cl/4893043, it was also noted
by @rsc that having to rename parameters named "url" was suboptimal:
> It's unfortunate that naming the package url means
> you can't have a parameter or variable named url.
However, at the time, the name of the url package was still being
decided, and uri was an alternative name under consideration.
The reason urlStr was chosen is because it was a lesser evil
compared to naming the url package uri instead:
> Let's not get hung up on URI vs. URL, but I'd like s/uri/urlStr/ even for just
> that the "i" in "uri" looks very similar to the "l" in "url" in many fonts.
> Please let's go with urlStr instead of uri.
Now that we have the Go 1 compatibility guarantee, the name of the
net/url package is fixed. However, it's possible to improve the
signature of Redirect, NewRequest functions in net/http package
for godoc purposes by creating a package global alias to url.Parse,
and renaming urlStr parameter to url in the exported funcs. This CL
does so.
Updates #21077.
Change-Id: Ibcc10e3825863a663e6ad91b6eb47b1862a299a6
Reviewed-on: https://go-review.googlesource.com/49930
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
											 
										 
										
											2017-07-19 00:41:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												url  =  olddir  +  url 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-15 18:40:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-11 04:30:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  query  string 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-05 15:49:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  i  :=  strings . Index ( url ,  "?" ) ;  i  !=  - 1  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: improve signature of Redirect, NewRequest
In CL https://golang.org/cl/4893043 (6 years ago), a new package named
"url" was created (it is currently known as "net/url"). During that
change, some identifier name collisions were introduced, and two
parameters in net/http were renamed to "urlStr".
Since that time, Go has continued to put high emphasis on the quality
and readability of the documentation. Sometimes, that means making small
sacrifices in the implementation details of a package to ensure that
the godoc reads better, since that's what the majority of users interact
with. See https://golang.org/s/style#named-result-parameters:
> Clarity of docs is always more important than saving a line or two
> in your function.
I think the "urlStr" parameter name is suboptimal for godoc purposes,
and just "url" would be better.
During the review of https://golang.org/cl/4893043, it was also noted
by @rsc that having to rename parameters named "url" was suboptimal:
> It's unfortunate that naming the package url means
> you can't have a parameter or variable named url.
However, at the time, the name of the url package was still being
decided, and uri was an alternative name under consideration.
The reason urlStr was chosen is because it was a lesser evil
compared to naming the url package uri instead:
> Let's not get hung up on URI vs. URL, but I'd like s/uri/urlStr/ even for just
> that the "i" in "uri" looks very similar to the "l" in "url" in many fonts.
> Please let's go with urlStr instead of uri.
Now that we have the Go 1 compatibility guarantee, the name of the
net/url package is fixed. However, it's possible to improve the
signature of Redirect, NewRequest functions in net/http package
for godoc purposes by creating a package global alias to url.Parse,
and renaming urlStr parameter to url in the exported funcs. This CL
does so.
Updates #21077.
Change-Id: Ibcc10e3825863a663e6ad91b6eb47b1862a299a6
Reviewed-on: https://go-review.googlesource.com/49930
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
											 
										 
										
											2017-07-19 00:41:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												url ,  query  =  url [ : i ] ,  url [ i : ] 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-11 04:30:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// clean up but preserve trailing slash 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: improve signature of Redirect, NewRequest
In CL https://golang.org/cl/4893043 (6 years ago), a new package named
"url" was created (it is currently known as "net/url"). During that
change, some identifier name collisions were introduced, and two
parameters in net/http were renamed to "urlStr".
Since that time, Go has continued to put high emphasis on the quality
and readability of the documentation. Sometimes, that means making small
sacrifices in the implementation details of a package to ensure that
the godoc reads better, since that's what the majority of users interact
with. See https://golang.org/s/style#named-result-parameters:
> Clarity of docs is always more important than saving a line or two
> in your function.
I think the "urlStr" parameter name is suboptimal for godoc purposes,
and just "url" would be better.
During the review of https://golang.org/cl/4893043, it was also noted
by @rsc that having to rename parameters named "url" was suboptimal:
> It's unfortunate that naming the package url means
> you can't have a parameter or variable named url.
However, at the time, the name of the url package was still being
decided, and uri was an alternative name under consideration.
The reason urlStr was chosen is because it was a lesser evil
compared to naming the url package uri instead:
> Let's not get hung up on URI vs. URL, but I'd like s/uri/urlStr/ even for just
> that the "i" in "uri" looks very similar to the "l" in "url" in many fonts.
> Please let's go with urlStr instead of uri.
Now that we have the Go 1 compatibility guarantee, the name of the
net/url package is fixed. However, it's possible to improve the
signature of Redirect, NewRequest functions in net/http package
for godoc purposes by creating a package global alias to url.Parse,
and renaming urlStr parameter to url in the exported funcs. This CL
does so.
Updates #21077.
Change-Id: Ibcc10e3825863a663e6ad91b6eb47b1862a299a6
Reviewed-on: https://go-review.googlesource.com/49930
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
											 
										 
										
											2017-07-19 00:41:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											trailing  :=  strings . HasSuffix ( url ,  "/" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											url  =  path . Clean ( url ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  trailing  &&  ! strings . HasSuffix ( url ,  "/" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												url  +=  "/" 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: improve signature of Redirect, NewRequest
In CL https://golang.org/cl/4893043 (6 years ago), a new package named
"url" was created (it is currently known as "net/url"). During that
change, some identifier name collisions were introduced, and two
parameters in net/http were renamed to "urlStr".
Since that time, Go has continued to put high emphasis on the quality
and readability of the documentation. Sometimes, that means making small
sacrifices in the implementation details of a package to ensure that
the godoc reads better, since that's what the majority of users interact
with. See https://golang.org/s/style#named-result-parameters:
> Clarity of docs is always more important than saving a line or two
> in your function.
I think the "urlStr" parameter name is suboptimal for godoc purposes,
and just "url" would be better.
During the review of https://golang.org/cl/4893043, it was also noted
by @rsc that having to rename parameters named "url" was suboptimal:
> It's unfortunate that naming the package url means
> you can't have a parameter or variable named url.
However, at the time, the name of the url package was still being
decided, and uri was an alternative name under consideration.
The reason urlStr was chosen is because it was a lesser evil
compared to naming the url package uri instead:
> Let's not get hung up on URI vs. URL, but I'd like s/uri/urlStr/ even for just
> that the "i" in "uri" looks very similar to the "l" in "url" in many fonts.
> Please let's go with urlStr instead of uri.
Now that we have the Go 1 compatibility guarantee, the name of the
net/url package is fixed. However, it's possible to improve the
signature of Redirect, NewRequest functions in net/http package
for godoc purposes by creating a package global alias to url.Parse,
and renaming urlStr parameter to url in the exported funcs. This CL
does so.
Updates #21077.
Change-Id: Ibcc10e3825863a663e6ad91b6eb47b1862a299a6
Reviewed-on: https://go-review.googlesource.com/49930
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
											 
										 
										
											2017-07-19 00:41:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											url  +=  query 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-15 18:40:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-30 11:42:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h  :=  w . Header ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-04 13:05:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// RFC 7231 notes that a short HTML body is usually included in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the response because older user agents may not understand 301/307. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Do it only if the request didn't already have a Content-Type header. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_ ,  hadCT  :=  h [ "Content-Type" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h . Set ( "Location" ,  hexEscapeNonASCII ( url ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! hadCT  &&  ( r . Method  ==  "GET"  ||  r . Method  ==  "HEAD" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-30 11:42:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										h . Set ( "Content-Type" ,  "text/html; charset=utf-8" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-18 23:59:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . WriteHeader ( code ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-21 01:53:13 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-04 13:05:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Shouldn't send the body for POST or HEAD; that leaves GET. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! hadCT  &&  r . Method  ==  "GET"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										body  :=  "<a href=\""  +  htmlEscape ( url )  +  "\">"  +  statusText [ code ]  +  "</a>.\n" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fmt . Fprintln ( w ,  body ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-03 15:19:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  htmlReplacer  =  strings . NewReplacer (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"&" ,  "&" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"<" ,  "<" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									">" ,  ">" , 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-12 09:35:43 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// """ is shorter than """. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									` " ` ,  """ , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// "'" is shorter than "'" and apos was not in HTML until HTML5. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"'" ,  "'" , 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-03 15:19:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-11 17:15:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  htmlEscape ( s  string )  string  {  
						 
					
						
							
								
									
										
										
										
											2011-10-03 15:19:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  htmlReplacer . Replace ( s ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-14 20:31:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Redirect to a fixed URL  
						 
					
						
							
								
									
										
										
										
											2009-05-12 15:41:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  redirectHandler  struct  {  
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									url   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									code  int 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-12 15:41:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-10-06 19:41:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( rh  * redirectHandler )  ServeHTTP ( w  ResponseWriter ,  r  * Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Redirect ( w ,  r ,  rh . url ,  rh . code ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-14 20:31:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// RedirectHandler returns a request handler that redirects  
						 
					
						
							
								
									
										
										
										
											2009-05-12 15:41:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// each request it receives to the given url using the given  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// status code.  
						 
					
						
							
								
									
										
										
										
											2015-10-16 13:26:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The provided code should be in the 3xx range and is usually  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// StatusMovedPermanently, StatusFound or StatusSeeOther.  
						 
					
						
							
								
									
										
										
										
											2009-05-12 15:41:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  RedirectHandler ( url  string ,  code  int )  Handler  {  
						 
					
						
							
								
									
										
										
										
											2009-11-09 12:07:39 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  & redirectHandler { url ,  code } 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ServeMux is an HTTP request multiplexer.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It matches the URL of each incoming request against a list of registered  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// patterns and calls the handler for the pattern that  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// most closely matches the URL.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2012-06-28 15:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Patterns name fixed, rooted paths, like "/favicon.ico",  
						 
					
						
							
								
									
										
										
										
											2011-02-01 13:58:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// or rooted subtrees, like "/images/" (note the trailing slash).  
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Longer patterns take precedence over shorter ones, so that  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// if there are handlers registered for both "/images/"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and "/images/thumbnails/", the latter handler will be  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// called for paths beginning "/images/thumbnails/" and the  
						 
					
						
							
								
									
										
										
										
											2012-06-28 15:18:35 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// former will receive requests for any other paths in the  
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// "/images/" subtree.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2013-09-12 11:20:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Note that since a pattern ending in a slash names a rooted subtree,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the pattern "/" matches all paths not matched by other registered  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// patterns, not just the URL with Path == "/".  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2015-12-17 02:34:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If a subtree has been registered and a request is received naming the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// subtree root without its trailing slash, ServeMux redirects that  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// request to the subtree root (adding the trailing slash). This behavior can  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// be overridden with a separate registration for the path without  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the trailing slash. For example, registering "/images/" causes ServeMux  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to redirect a request for "/images" to "/images/", unless "/images" has  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// been registered separately.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2011-02-01 13:58:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Patterns may optionally begin with a host name, restricting matches to  
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// URLs on that host only. Host-specific patterns take precedence over  
						 
					
						
							
								
									
										
										
										
											2011-02-01 13:58:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// general patterns, so that a handler might register for the two patterns  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// "/codesearch" and "codesearch.google.com/" without also taking over  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// requests for "http://www.google.com/".  
						 
					
						
							
								
									
										
										
										
											2009-04-07 00:40:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2018-06-23 22:32:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ServeMux also takes care of sanitizing the URL request path and the Host  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// header, stripping the port number and redirecting any request containing . or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// .. elements or repeated slashes to an equivalent, cleaner URL.  
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  ServeMux  struct  {  
						 
					
						
							
								
									
										
										
										
											2012-05-28 10:58:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mu     sync . RWMutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m      map [ string ] muxEntry 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-25 22:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									es     [ ] muxEntry  // slice of entries sorted from longest to shortest. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hosts  bool        // whether any patterns contain hostnames 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  muxEntry  struct  {  
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h        Handler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pattern  string 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// NewServeMux allocates and returns a new ServeMux.  
						 
					
						
							
								
									
										
										
										
											2016-03-16 20:14:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  NewServeMux ( )  * ServeMux  {  return  new ( ServeMux )  }  
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// DefaultServeMux is the default ServeMux used by Serve.  
						 
					
						
							
								
									
										
										
										
											2016-03-16 20:14:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  DefaultServeMux  =  & defaultServeMux  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  defaultServeMux  ServeMux  
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-31 04:19:06 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// cleanPath returns the canonical path for p, eliminating . and .. elements.  
						 
					
						
							
								
									
										
										
										
											2009-04-07 00:40:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  cleanPath ( p  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  p  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-09 12:07:39 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  "/" 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-07 00:40:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  p [ 0 ]  !=  '/'  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-09 21:23:52 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p  =  "/"  +  p 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-07 00:40:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									np  :=  path . Clean ( p ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-07 00:40:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// path.Clean removes trailing slash except for root; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// put the trailing slash back if necessary. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  p [ len ( p ) - 1 ]  ==  '/'  &&  np  !=  "/"  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-05 21:06:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Fast path for common case of p being the string we want: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( p )  ==  len ( np ) + 1  &&  strings . HasPrefix ( p ,  np )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											np  =  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											np  +=  "/" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-07 00:40:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  np 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-07 00:40:07 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 21:55:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// stripHostPort returns h without any trailing ":<port>".  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  stripHostPort ( h  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If no port on host, return unchanged 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 10:46:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! strings . Contains ( h ,  ":" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 21:55:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  h 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									host ,  _ ,  err  :=  net . SplitHostPort ( h ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  h  // on error, return unchanged 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-12 10:02:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Find a handler on a handler map given a path string.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Most-specific (longest) pattern wins.  
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( mux  * ServeMux )  match ( path  string )  ( h  Handler ,  pattern  string )  {  
						 
					
						
							
								
									
										
										
										
											2017-03-12 10:02:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check for exact match first. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v ,  ok  :=  mux . m [ path ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  v . h ,  v . pattern 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-25 22:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check for longest valid match.  mux.es contains all patterns 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that end in / sorted from longest to shortest. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  e  :=  range  mux . es  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . HasPrefix ( path ,  e . pattern )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  e . h ,  e . pattern 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-25 22:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil ,  "" 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// redirectToPathSlash determines if the given path needs appending "/" to it.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This occurs when a handler for path + "/" was already registered, but  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// not for path itself. If the path needs appending to, it creates a new  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// URL, setting the path to u.Path + "/" and returning true to indicate so.  
						 
					
						
							
								
									
										
										
										
											2017-12-18 15:17:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( mux  * ServeMux )  redirectToPathSlash ( host ,  path  string ,  u  * url . URL )  ( * url . URL ,  bool )  {  
						 
					
						
							
								
									
										
										
										
											2018-05-21 12:57:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mux . mu . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									shouldRedirect  :=  mux . shouldRedirectRLocked ( host ,  path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mux . mu . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! shouldRedirect  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  u ,  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									path  =  path  +  "/" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u  =  & url . URL { Path :  path ,  RawQuery :  u . RawQuery } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  u ,  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-21 12:57:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// shouldRedirectRLocked reports whether the given path and host should be redirected to  
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// path+"/". This should happen if a handler is registered for path+"/" but  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// not path -- see comments at ServeMux.  
						 
					
						
							
								
									
										
										
										
											2018-05-21 12:57:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( mux  * ServeMux )  shouldRedirectRLocked ( host ,  path  string )  bool  {  
						 
					
						
							
								
									
										
										
										
											2017-12-18 15:17:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p  :=  [ ] string { path ,  host  +  path } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  c  :=  range  p  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  exist  :=  mux . m [ c ] ;  exist  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-18 15:17:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									n  :=  len ( path ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-11 09:58:16 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  n  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-18 15:17:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  c  :=  range  p  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  exist  :=  mux . m [ c + "/" ] ;  exist  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-11 09:58:16 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  path [ n - 1 ]  !=  '/' 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-18 15:17:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Handler returns the handler to use for the given request,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// consulting r.Method, r.Host, and r.URL.Path. It always returns  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// a non-nil handler. If the path is not in its canonical form, the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// handler will be an internally-generated handler that redirects  
						 
					
						
							
								
									
										
										
										
											2017-03-15 21:55:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// to the canonical path. If the host contains a port, it is ignored  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// when matching handlers.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The path and host are used unchanged for CONNECT requests.  
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Handler also returns the registered pattern that matches the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// request or, in the case of internally-generated redirects,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the pattern that will match after following the redirect.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If there is no registered handler that applies to the request,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Handler returns a ``page not found'' handler and an empty pattern.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( mux  * ServeMux )  Handler ( r  * Request )  ( h  Handler ,  pattern  string )  {  
						 
					
						
							
								
									
										
										
										
											2017-12-01 00:59:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 21:55:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// CONNECT requests are not canonicalized. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  r . Method  ==  "CONNECT"  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// If r.URL.Path is /tree and its handler is not registered, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the /tree -> /tree/ redirect applies to CONNECT requests 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// but the path canonicalization does not. 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-18 15:17:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  u ,  ok  :=  mux . redirectToPathSlash ( r . URL . Host ,  r . URL . Path ,  r . URL ) ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  RedirectHandler ( u . String ( ) ,  StatusMovedPermanently ) ,  u . Path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 21:55:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  mux . handler ( r . Host ,  r . URL . Path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// All other requests have any port stripped and path cleaned 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// before passing to mux.handler. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									host  :=  stripHostPort ( r . Host ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									path  :=  cleanPath ( r . URL . Path ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If the given path is /tree and its handler is not registered, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// redirect for /tree/. 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-18 15:17:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  u ,  ok  :=  mux . redirectToPathSlash ( host ,  path ,  r . URL ) ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  RedirectHandler ( u . String ( ) ,  StatusMovedPermanently ) ,  u . Path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 21:55:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  path  !=  r . URL . Path  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  pattern  =  mux . handler ( host ,  path ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-26 20:10:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										u  :=  & url . URL { Path :  path ,  RawQuery :  r . URL . RawQuery } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  RedirectHandler ( u . String ( ) ,  StatusMovedPermanently ) ,  pattern 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-15 21:55:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  mux . handler ( host ,  r . URL . Path ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-01 13:58:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// handler is the main implementation of Handler.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The path is known to be in canonical form, except for CONNECT methods.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( mux  * ServeMux )  handler ( host ,  path  string )  ( h  Handler ,  pattern  string )  {  
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mux . mu . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  mux . mu . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Host-specific pattern takes precedence over generic ones 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-28 10:58:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  mux . hosts  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										h ,  pattern  =  mux . match ( host  +  path ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-28 10:58:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  h  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										h ,  pattern  =  mux . match ( path ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  h  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										h ,  pattern  =  NotFoundHandler ( ) ,  "" 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-01 13:58:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ServeHTTP dispatches the request to the handler whose  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// pattern most closely matches the request URL.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( mux  * ServeMux )  ServeHTTP ( w  ResponseWriter ,  r  * Request )  {  
						 
					
						
							
								
									
										
										
										
											2012-12-11 12:07:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  r . RequestURI  ==  "*"  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-06 18:37:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  r . ProtoAtLeast ( 1 ,  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . Header ( ) . Set ( "Connection" ,  "close" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-11 12:07:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . WriteHeader ( StatusBadRequest ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-31 12:16:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h ,  _  :=  mux . Handler ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h . ServeHTTP ( w ,  r ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Handle registers the handler for the given pattern.  
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If a handler already exists for pattern, Handle panics.  
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( mux  * ServeMux )  Handle ( pattern  string ,  handler  Handler )  {  
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mux . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  mux . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-01 13:58:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  pattern  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-21 00:35:31 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										panic ( "http: invalid pattern" ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  handler  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "http: nil handler" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-03 02:08:02 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  exist  :=  mux . m [ pattern ] ;  exist  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 13:50:00 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										panic ( "http: multiple registrations for "  +  pattern ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-16 20:14:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  mux . m  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mux . m  =  make ( map [ string ] muxEntry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-25 22:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									e  :=  muxEntry { h :  handler ,  pattern :  pattern } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mux . m [ pattern ]  =  e 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  pattern [ len ( pattern ) - 1 ]  ==  '/'  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mux . es  =  appendSorted ( mux . es ,  e ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-28 10:58:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  pattern [ 0 ]  !=  '/'  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mux . hosts  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-25 22:03:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  appendSorted ( es  [ ] muxEntry ,  e  muxEntry )  [ ] muxEntry  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  :=  len ( es ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									i  :=  sort . Search ( n ,  func ( i  int )  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  len ( es [ i ] . pattern )  <  len ( e . pattern ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  i  ==  n  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  append ( es ,  e ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// we now know that i points at where we want to insert 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									es  =  append ( es ,  muxEntry { } )  // try to grow the slice in place, any entry works. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									copy ( es [ i + 1 : ] ,  es [ i : ] )       // Move shorter entries down 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									es [ i ]  =  e 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  es 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-29 10:02:37 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// HandleFunc registers the handler function for the given pattern.  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( mux  * ServeMux )  HandleFunc ( pattern  string ,  handler  func ( ResponseWriter ,  * Request ) )  {  
						 
					
						
							
								
									
										
										
										
											2018-03-09 01:31:50 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  handler  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "http: nil handler" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-29 10:02:37 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mux . Handle ( pattern ,  HandlerFunc ( handler ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Handle registers the handler for the given pattern  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// in the DefaultServeMux.  
						 
					
						
							
								
									
										
										
										
											2011-02-22 11:16:25 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The documentation for ServeMux explains how patterns are matched.  
						 
					
						
							
								
									
										
										
										
											2009-12-15 15:35:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  Handle ( pattern  string ,  handler  Handler )  {  DefaultServeMux . Handle ( pattern ,  handler )  }  
						 
					
						
							
								
									
										
										
										
											2009-02-02 18:01:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-29 10:02:37 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// HandleFunc registers the handler function for the given pattern  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// in the DefaultServeMux.  
						 
					
						
							
								
									
										
										
										
											2011-02-22 11:16:25 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The documentation for ServeMux explains how patterns are matched.  
						 
					
						
							
								
									
										
										
										
											2010-09-29 14:30:12 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  HandleFunc ( pattern  string ,  handler  func ( ResponseWriter ,  * Request ) )  {  
						 
					
						
							
								
									
										
										
										
											2010-03-29 10:02:37 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DefaultServeMux . HandleFunc ( pattern ,  handler ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Serve accepts incoming HTTP connections on the listener l,  
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// creating a new service goroutine for each. The service goroutines  
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// read requests and then call handler to reply to them.  
						 
					
						
							
								
									
										
										
										
											2018-07-23 18:31:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The handler is typically nil, in which case the DefaultServeMux is used.  
						 
					
						
							
								
									
										
										
										
											2018-07-23 18:31:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// HTTP/2 support is only enabled if the Listener returns *tls.Conn  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// connections and they were configured with "h2" in the TLS  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Config.NextProtos.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2018-07-24 00:24:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Serve always returns a non-nil error.  
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  Serve ( l  net . Listener ,  handler  Handler )  error  {  
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srv  :=  & Server { Handler :  handler } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  srv . Serve ( l ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-23 21:45:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ServeTLS accepts incoming HTTPS connections on the listener l,  
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// creating a new service goroutine for each. The service goroutines  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// read requests and then call handler to reply to them.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The handler is typically nil, in which case the DefaultServeMux is used.  
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Additionally, files containing a certificate and matching private key  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// for the server must be provided. If the certificate is signed by a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// certificate authority, the certFile should be the concatenation  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// of the server's certificate, any intermediates, and the CA's certificate.  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ServeTLS always returns a non-nil error.  
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ServeTLS ( l  net . Listener ,  handler  Handler ,  certFile ,  keyFile  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv  :=  & Server { Handler :  handler } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  srv . ServeTLS ( l ,  certFile ,  keyFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// A Server defines parameters for running an HTTP server.  
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The zero value for Server is a valid configuration.  
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  Server  struct  {  
						 
					
						
							
								
									
										
										
										
											2019-08-23 15:02:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Addr optionally specifies the TCP address for the server to listen on, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// in the form "host:port". If empty, ":http" (port 80) is used. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The service names are defined in RFC 6335 and assigned by IANA. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// See net.Dial for details of the address format. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Addr  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-05 21:31:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Handler  Handler  // handler to invoke, http.DefaultServeMux if nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TLSConfig optionally provides a TLS configuration for use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// by ServeTLS and ListenAndServeTLS. Note that this value is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// cloned by ServeTLS and ListenAndServeTLS, so it's not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// possible to modify the configuration with methods like 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// tls.Config.SetSessionTicketKeys. To use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// SetSessionTicketKeys, use Server.Serve with a TLS Listener 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// instead. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									TLSConfig  * tls . Config 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ReadTimeout is the maximum duration for reading the entire 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 09:54:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// request, including the body. A zero or negative value means 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// there will be no timeout. 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Because ReadTimeout does not let Handlers make per-request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// decisions on each request body's acceptable deadline or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// upload rate, most users will prefer to use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ReadHeaderTimeout. It is valid to use them both. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ReadTimeout  time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ReadHeaderTimeout is the amount of time allowed to read 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// request headers. The connection's read deadline is reset 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// after reading the headers and the Handler can decide what 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-18 08:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// is considered too slow for the body. If ReadHeaderTimeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is zero, the value of ReadTimeout is used. If both are 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// zero, there is no timeout. 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ReadHeaderTimeout  time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// WriteTimeout is the maximum duration before timing out 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// writes of the response. It is reset whenever a new 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// request's header is read. Like ReadTimeout, it does not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// let Handlers make decisions on a per-request basis. 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 09:54:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// A zero or negative value means there will be no timeout. 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									WriteTimeout  time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// IdleTimeout is the maximum amount of time to wait for the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// next request when keep-alives are enabled. If IdleTimeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is zero, the value of ReadTimeout is used. If both are 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-18 08:30:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// zero, there is no timeout. 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									IdleTimeout  time . Duration 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 17:29:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// MaxHeaderBytes controls the maximum number of bytes the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// server will read parsing the request header's keys and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// values, including the request line. It does not limit the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// size of the request body. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If zero, DefaultMaxHeaderBytes is used. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MaxHeaderBytes  int 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TLSNextProto optionally specifies a function to take over 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// ownership of the provided TLS connection when an ALPN 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// protocol upgrade has occurred. The map key is the protocol 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// name negotiated. The Handler argument should be used to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// handle HTTP requests and will initialize the Request's TLS 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-01 23:21:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// and RemoteAddr if not already set. The connection is 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// automatically closed when the function returns. 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 20:28:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If TLSNextProto is not nil, HTTP/2 support is not enabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// automatically. 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									TLSNextProto  map [ string ] func ( * Server ,  * tls . Conn ,  Handler ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-27 18:29:00 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ConnState specifies an optional callback function that is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// called when a client connection changes state. See the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ConnState type and associated constants for details. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ConnState  func ( net . Conn ,  ConnState ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 12:12:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// ErrorLog specifies an optional logger for errors accepting 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-08 15:38:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// connections, unexpected behavior from handlers, and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// underlying FileSystem errors. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If nil, logging is done via the log package's standard logger. 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 12:12:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ErrorLog  * log . Logger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 14:58:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// BaseContext optionally specifies a function that returns 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the base context for incoming requests on this server. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The provided Listener is the specific Listener that's 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// about to start accepting requests. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If BaseContext is nil, the default is context.Background(). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If non-nil, it must return a non-nil context. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BaseContext  func ( net . Listener )  context . Context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ConnContext optionally specifies a function that modifies 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-10 13:44:56 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// the context used for a new connection c. The provided ctx 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 14:58:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// is derived from the base context and has a ServerContextKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// value. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ConnContext  func ( ctx  context . Context ,  c  net . Conn )  context . Context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-13 11:25:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									inShutdown  atomicBool  // true when server is in shutdown 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-13 19:21:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-10-14 20:41:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									disableKeepAlives  int32      // accessed atomically. 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 23:44:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nextProtoOnce      sync . Once  // guards setupHTTP2_* init 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nextProtoErr       error      // result of http2.ConfigureServer if used 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mu          sync . Mutex 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 17:20:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									listeners   map [ * net . Listener ] struct { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									activeConn  map [ * conn ] struct { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									doneChan    chan  struct { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 16:03:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									onShutdown  [ ] func ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  getDoneChan ( )  <- chan  struct { }  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s . getDoneChanLocked ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  getDoneChanLocked ( )  chan  struct { }  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s . doneChan  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . doneChan  =  make ( chan  struct { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s . doneChan 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  closeDoneChanLocked ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ch  :=  s . getDoneChanLocked ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  <- ch : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Already closed. Don't close again. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Safe to close here. We're the only closer, guarded 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// by s.mu. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( ch ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 21:35:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Close immediately closes all active net.Listeners and any  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// connections in state StateNew, StateActive, or StateIdle. For a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// graceful shutdown, use Shutdown.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Close does not attempt to close (and does not even know about)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// any hijacked connections, such as WebSockets.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Close returns any error returned from closing the Server's  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// underlying Listener(s).  
						 
					
						
							
								
									
										
										
										
											2016-11-23 16:29:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  Close ( )  error  {  
						 
					
						
							
								
									
										
										
										
											2020-03-13 19:21:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srv . inShutdown . setTrue ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 16:29:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srv . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  srv . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv . closeDoneChanLocked ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  :=  srv . closeListenersLocked ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  c  :=  range  srv . activeConn  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . rwc . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 16:29:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delete ( srv . activeConn ,  c ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 19:25:56 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// shutdownPollIntervalMax is the max polling interval when checking  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// quiescence during Server.Shutdown. Polling starts with a small  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// interval and backs off to the max.  
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Ideally we could find a solution that doesn't involve polling,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but which also doesn't have a high runtime cost (and doesn't  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// involve any contentious mutexes), but that is left as an  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// exercise for the reader.  
						 
					
						
							
								
									
										
										
										
											2020-10-22 19:25:56 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  shutdownPollIntervalMax  =  500  *  time . Millisecond  
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Shutdown gracefully shuts down the server without interrupting any  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// active connections. Shutdown works by first closing all open  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// listeners, then closing all idle connections, and then waiting  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// indefinitely for connections to return to idle and then shut down.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If the provided context expires before the shutdown is complete,  
						 
					
						
							
								
									
										
										
										
											2017-02-17 11:57:46 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Shutdown returns the context's error, otherwise it returns any  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// error returned from closing the Server's underlying Listener(s).  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// When Shutdown is called, Serve, ListenAndServe, and  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ListenAndServeTLS immediately return ErrServerClosed. Make sure the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// program doesn't exit and waits instead for Shutdown to return.  
						 
					
						
							
								
									
										
										
										
											2016-11-10 21:35:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Shutdown does not attempt to close nor wait for hijacked  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// connections such as WebSockets. The caller of Shutdown should  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// separately notify such long-lived connections of shutdown and wait  
						 
					
						
							
								
									
										
										
										
											2017-08-27 11:30:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// for them to close, if desired. See RegisterOnShutdown for a way to  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// register shutdown notification functions.  
						 
					
						
							
								
									
										
										
										
											2017-12-04 19:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Once Shutdown has been called on a server, it may not be reused;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// future calls to methods such as Serve will return ErrServerClosed.  
						 
					
						
							
								
									
										
										
										
											2016-11-23 16:29:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  Shutdown ( ctx  context . Context )  error  {  
						 
					
						
							
								
									
										
										
										
											2020-03-13 19:21:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srv . inShutdown . setTrue ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 16:29:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srv . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lnerr  :=  srv . closeListenersLocked ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv . closeDoneChanLocked ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 16:03:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  f  :=  range  srv . onShutdown  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  f ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 16:29:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srv . mu . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 19:25:56 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pollIntervalBase  :=  time . Millisecond 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nextPollInterval  :=  func ( )  time . Duration  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Add 10% jitter. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										interval  :=  pollIntervalBase  +  time . Duration ( rand . Intn ( int ( pollIntervalBase / 10 ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Double and clamp for next time. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pollIntervalBase  *=  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  pollIntervalBase  >  shutdownPollIntervalMax  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pollIntervalBase  =  shutdownPollIntervalMax 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  interval 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									timer  :=  time . NewTimer ( nextPollInterval ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  timer . Stop ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-06 11:16:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  srv . closeIdleConns ( )  &&  srv . numListeners ( )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  lnerr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ctx . Err ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 19:25:56 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  <- timer . C : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											timer . Reset ( nextPollInterval ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 16:03:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// RegisterOnShutdown registers a function to call on Shutdown.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This can be used to gracefully shutdown connections that have  
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// undergone ALPN protocol upgrade or that have been hijacked.  
						 
					
						
							
								
									
										
										
										
											2017-05-23 16:03:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// This function should start protocol-specific graceful shutdown,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but should not wait for shutdown to complete.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( srv  * Server )  RegisterOnShutdown ( f  func ( ) )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv . onShutdown  =  append ( srv . onShutdown ,  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-06 11:16:34 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Server )  numListeners ( )  int  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  len ( s . listeners ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// closeIdleConns closes all idle connections and reports whether the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// server is quiescent.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  closeIdleConns ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									quiescent  :=  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  c  :=  range  s . activeConn  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-28 21:01:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										st ,  unixSec  :=  c . getState ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Issue 22682: treat StateNew connections as if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// they're idle if we haven't read the first request's 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// header in over 5 seconds. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  st  ==  StateNew  &&  unixSec  <  time . Now ( ) . Unix ( ) - 5  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											st  =  StateIdle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  st  !=  StateIdle  ||  unixSec  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Assume unixSec == 0 means it's a very new 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// connection, without state set yet. 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											quiescent  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c . rwc . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delete ( s . activeConn ,  c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  quiescent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  closeListenersLocked ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ln  :=  range  s . listeners  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 17:20:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  cerr  :=  ( * ln ) . Close ( ) ;  cerr  !=  nil  &&  err  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  cerr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-27 18:29:00 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// A ConnState represents the state of a client connection to a server.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It's used by the optional Server.ConnState hook.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  ConnState  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StateNew represents a new connection that is expected to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// send a request immediately. Connections begin at this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// state and then transition to either StateActive or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StateClosed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateNew  ConnState  =  iota 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StateActive represents a connection that has read 1 or more 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// bytes of a request. The Server.ConnState hook for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StateActive fires before the request has entered a handler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// and doesn't fire again until the request has been 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// handled. After the request is handled, the state 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// transitions to StateClosed, StateHijacked, or StateIdle. 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-13 19:36:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For HTTP/2, StateActive fires on the transition from zero 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to one active request, and only transitions away once all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// active requests are complete. That means that ConnState 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-27 12:49:13 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// cannot be used to do per-request work; ConnState only notes 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-13 19:36:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// the overall state of the connection. 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-27 18:29:00 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StateActive 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StateIdle represents a connection that has finished 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// handling a request and is in the keep-alive state, waiting 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// for a new request. Connections transition from StateIdle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to either StateActive or StateClosed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateIdle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StateHijacked represents a hijacked connection. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This is a terminal state. It does not transition to StateClosed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateHijacked 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StateClosed represents a closed connection. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This is a terminal state. Hijacked connections do not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// transition to StateClosed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateClosed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  stateName  =  map [ ConnState ] string {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateNew :       "new" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateActive :    "active" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateIdle :      "idle" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateHijacked :  "hijacked" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StateClosed :    "closed" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  ConnState )  String ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  stateName [ c ] 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// serverHandler delegates to either the server's Handler or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// DefaultServeMux and also handles "OPTIONS *" requests.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  serverHandler  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv  * Server 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sh  serverHandler )  ServeHTTP ( rw  ResponseWriter ,  req  * Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									handler  :=  sh . srv . Handler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  handler  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										handler  =  DefaultServeMux 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  req . RequestURI  ==  "*"  &&  req . Method  ==  "OPTIONS"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										handler  =  globalOptionsHandler { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 07:43:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 14:29:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  req . URL  !=  nil  &&  strings . Contains ( req . URL . RawQuery ,  ";" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 07:43:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  allowQuerySemicolonsInUse  int32 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req  =  req . WithContext ( context . WithValue ( req . Context ( ) ,  silenceSemWarnContextKey ,  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											atomic . StoreInt32 ( & allowQuerySemicolonsInUse ,  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  atomic . LoadInt32 ( & allowQuerySemicolonsInUse )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sh . srv . logf ( "http: URL query contains semicolon, which is no longer a supported separator; parts of the query may be stripped when parsed; see golang.org/issue/25192" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-07 14:29:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-09 07:43:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									handler . ServeHTTP ( rw ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  silenceSemWarnContextKey  =  & contextKey { "silence-semicolons" }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// AllowQuerySemicolons returns a handler that serves requests by converting any  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// unescaped semicolons in the URL query to ampersands, and invoking the handler h.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This restores the pre-Go 1.17 behavior of splitting query parameters on both  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// semicolons and ampersands. (See golang.org/issue/25192). Note that this  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// behavior doesn't match that of many proxies, and the mismatch can lead to  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// security issues.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// AllowQuerySemicolons should be invoked before Request.ParseForm is called.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  AllowQuerySemicolons ( h  Handler )  Handler  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  HandlerFunc ( func ( w  ResponseWriter ,  r  * Request )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  silenceSemicolonsWarning ,  ok  :=  r . Context ( ) . Value ( silenceSemWarnContextKey ) . ( func ( ) ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											silenceSemicolonsWarning ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . Contains ( r . URL . RawQuery ,  ";" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r2  :=  new ( Request ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* r2  =  * r 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r2 . URL  =  new ( url . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* r2 . URL  =  * r . URL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r2 . URL . RawQuery  =  strings . ReplaceAll ( r . URL . RawQuery ,  ";" ,  "&" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											h . ServeHTTP ( w ,  r2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											h . ServeHTTP ( w ,  r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ListenAndServe listens on the TCP network address srv.Addr and then  
						 
					
						
							
								
									
										
										
										
											2015-08-20 11:56:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// calls Serve to handle requests on incoming connections.  
						 
					
						
							
								
									
										
										
										
											2015-12-09 17:41:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Accepted connections are configured to enable TCP keep-alives.  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2015-08-20 11:56:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If srv.Addr is blank, ":http" is used.  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ListenAndServe always returns a non-nil error. After Shutdown or Close,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the returned error is ErrServerClosed.  
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  ListenAndServe ( )  error  {  
						 
					
						
							
								
									
										
										
										
											2017-12-04 19:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  srv . shuttingDown ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ErrServerClosed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									addr  :=  srv . Addr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  addr  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addr  =  ":http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-09 15:05:09 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ln ,  err  :=  net . Listen ( "tcp" ,  addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 08:50:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  srv . Serve ( ln ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-11-03 11:00:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  testHookServerServe  func ( * Server ,  net . Listener )  // used if non-nil  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-27 16:39:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// shouldDoServeHTTP2 reports whether Server.Serve should configure  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// automatic HTTP/2. (which sets up the srv.TLSNextProto map)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( srv  * Server )  shouldConfigureHTTP2ForServe ( )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  srv . TLSConfig  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Compatibility with Go 1.6: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If there's no TLSConfig, it's possible that the user just 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// didn't set it on the http.Server, but did pass it to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// tls.NewListener and passed that listener to Serve. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// So we should configure HTTP/2 (to set up srv.TLSNextProto) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// in case the listener returns an "h2" *tls.Conn. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The user specified a TLSConfig on their http.Server. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// In this, case, only configure HTTP/2 if their tls.Config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// explicitly mentions "h2". Otherwise http2.ConfigureServer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// would modify the tls.Config to add it, but they probably already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// passed this tls.Config to tls.NewListener. And if they did, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// it's too late anyway to fix it. It would only be potentially racy. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// See Issue 15908. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  strSliceContains ( srv . TLSConfig . NextProtos ,  http2NextProtoTLS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ErrServerClosed is returned by the Server's Serve, ServeTLS, ListenAndServe,  
						 
					
						
							
								
									
										
										
										
											2017-02-14 08:11:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// and ListenAndServeTLS methods after a call to Shutdown or Close.  
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  ErrServerClosed  =  errors . New ( "http: Server closed" )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Serve accepts incoming connections on the Listener l, creating a  
						 
					
						
							
								
									
										
										
										
											2015-08-20 11:56:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// new service goroutine for each. The service goroutines read requests and  
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// then call srv.Handler to reply to them.  
						 
					
						
							
								
									
										
										
										
											2016-06-27 16:39:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2018-07-23 18:31:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// HTTP/2 support is only enabled if the Listener returns *tls.Conn  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// connections and they were configured with "h2" in the TLS  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Config.NextProtos.  
						 
					
						
							
								
									
										
										
										
											2016-06-27 16:39:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2017-12-04 19:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Serve always returns a non-nil error and closes l.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// After Shutdown or Close, the returned error is ErrServerClosed.  
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  Serve ( l  net . Listener )  error  {  
						 
					
						
							
								
									
										
										
										
											2015-11-03 11:00:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  fn  :=  testHookServerServe ;  fn  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 20:25:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fn ( srv ,  l )  // call hook with unwrapped listener 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-03 11:00:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 20:25:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 14:58:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									origListener  :=  l 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 20:25:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									l  =  & onceCloseListener { Listener :  l } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  l . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 23:44:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  srv . setupHTTP2_Serve ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-20 22:57:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-27 16:39:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-04 19:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! srv . trackListener ( & l ,  true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ErrServerClosed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 17:20:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  srv . trackListener ( & l ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 14:58:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									baseCtx  :=  context . Background ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  srv . BaseContext  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										baseCtx  =  srv . BaseContext ( origListener ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  baseCtx  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											panic ( "BaseContext returned a nil context" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 17:26:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  tempDelay  time . Duration  // how long to sleep on accept failure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-11 05:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  context . WithValue ( baseCtx ,  ServerContextKey ,  srv ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 17:26:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rw ,  err  :=  l . Accept ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  <- srv . getDoneChan ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ErrServerClosed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 17:26:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ne ,  ok  :=  err . ( net . Error ) ;  ok  &&  ne . Temporary ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-14 15:04:29 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  tempDelay  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													tempDelay  =  5  *  time . Millisecond 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													tempDelay  *=  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  max  :=  1  *  time . Second ;  tempDelay  >  max  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													tempDelay  =  max 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 17:26:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												srv . logf ( "http: Accept error: %v; retrying in %v" ,  err ,  tempDelay ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-14 15:04:29 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												time . Sleep ( tempDelay ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-03 12:23:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 17:26:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 22:25:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										connCtx  :=  ctx 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 14:58:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  cc  :=  srv . ConnContext ;  cc  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 22:25:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											connCtx  =  cc ( connCtx ,  rw ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  connCtx  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 14:58:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												panic ( "ConnContext returned nil" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-14 15:04:29 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tempDelay  =  0 
							 
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c  :=  srv . newConn ( rw ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 13:31:34 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										c . setState ( c . rwc ,  StateNew ,  runHooks )  // before Serve can return 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 22:25:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										go  c . serve ( connCtx ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ServeTLS accepts incoming connections on the Listener l, creating a  
						 
					
						
							
								
									
										
										
										
											2018-07-23 18:31:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// new service goroutine for each. The service goroutines perform TLS  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// setup and then read requests, calling srv.Handler to reply to them.  
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2018-07-23 18:31:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Files containing a certificate and matching private key for the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// server must be provided if neither the Server's  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TLSConfig.Certificates nor TLSConfig.GetCertificate are populated.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If the certificate is signed by a certificate authority, the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// certFile should be the concatenation of the server's certificate,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// any intermediates, and the CA's certificate.  
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ServeTLS always returns a non-nil error. After Shutdown or Close, the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// returned error is ErrServerClosed.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( srv  * Server )  ServeTLS ( l  net . Listener ,  certFile ,  keyFile  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Setup HTTP/2 before srv.Serve, to initialize srv.TLSConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// before we clone it and create the TLS Listener. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  srv . setupHTTP2_ServeTLS ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									config  :=  cloneTLSConfig ( srv . TLSConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! strSliceContains ( config . NextProtos ,  "http/1.1" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config . NextProtos  =  append ( config . NextProtos ,  "http/1.1" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configHasCert  :=  len ( config . Certificates )  >  0  ||  config . GetCertificate  !=  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! configHasCert  ||  certFile  !=  ""  ||  keyFile  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config . Certificates  =  make ( [ ] tls . Certificate ,  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config . Certificates [ 0 ] ,  err  =  tls . LoadX509KeyPair ( certFile ,  keyFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tlsListener  :=  tls . NewListener ( l ,  config ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  srv . Serve ( tlsListener ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 17:20:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// trackListener adds or removes a net.Listener to the set of tracked  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// listeners.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// We store a pointer to interface in the map set, in case the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// net.Listener is not comparable. This is safe because we only call  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// trackListener via Serve and can track+defer untrack the same  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// pointer to local variable there. We never need to compare a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Listener from another caller.  
						 
					
						
							
								
									
										
										
										
											2017-12-04 19:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It reports whether the server is still up (not Shutdown or Closed).  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  trackListener ( ln  * net . Listener ,  add  bool )  bool  {  
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s . listeners  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 17:20:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s . listeners  =  make ( map [ * net . Listener ] struct { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  add  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-04 19:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  s . shuttingDown ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s . listeners [ ln ]  =  struct { } { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delete ( s . listeners ,  ln ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-04 19:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  trackConn ( c  * conn ,  add  bool )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s . activeConn  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . activeConn  =  make ( map [ * conn ] struct { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  add  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . activeConn [ c ]  =  struct { } { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delete ( s . activeConn ,  c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-23 06:04:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Server )  idleTimeout ( )  time . Duration  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s . IdleTimeout  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  s . IdleTimeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s . ReadTimeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  readHeaderTimeout ( )  time . Duration  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s . ReadHeaderTimeout  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  s . ReadHeaderTimeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s . ReadTimeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Server )  doKeepAlives ( )  bool  {  
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  atomic . LoadInt32 ( & s . disableKeepAlives )  ==  0  &&  ! s . shuttingDown ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Server )  shuttingDown ( )  bool  {  
						 
					
						
							
								
									
										
										
										
											2020-03-13 19:21:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  s . inShutdown . isSet ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// By default, keep-alives are always enabled. Only very  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// resource-constrained environments or servers in the process of  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// shutting down should disable them.  
						 
					
						
							
								
									
										
										
										
											2015-07-31 23:25:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  SetKeepAlivesEnabled ( v  bool )  {  
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  v  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-31 23:25:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										atomic . StoreInt32 ( & srv . disableKeepAlives ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 03:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									atomic . StoreInt32 ( & srv . disableKeepAlives ,  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Close idle HTTP/1 conns: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv . closeIdleConns ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-09 23:47:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// TODO: Issue 26303: close HTTP/2 conns as soon as they become idle. 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-28 07:40:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 12:15:45 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Server )  logf ( format  string ,  args  ... any )  {  
						 
					
						
							
								
									
										
										
										
											2014-02-28 12:12:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s . ErrorLog  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . ErrorLog . Printf ( format ,  args ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Printf ( format ,  args ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-08 15:38:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// logf prints to the ErrorLog of the *Server associated with request r  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// via ServerContextKey. If there's no associated server, or if ErrorLog  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is nil, logging is done via the log package's standard logger.  
						 
					
						
							
								
									
										
										
										
											2021-12-01 12:15:45 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  logf ( r  * Request ,  format  string ,  args  ... any )  {  
						 
					
						
							
								
									
										
										
										
											2017-08-08 15:38:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s ,  _  :=  r . Context ( ) . Value ( ServerContextKey ) . ( * Server ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s  !=  nil  &&  s . ErrorLog  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . ErrorLog . Printf ( format ,  args ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Printf ( format ,  args ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ListenAndServe listens on the TCP network address addr and then calls  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Serve with handler to handle requests on incoming connections.  
						 
					
						
							
								
									
										
										
										
											2015-12-09 17:41:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Accepted connections are configured to enable TCP keep-alives.  
						 
					
						
							
								
									
										
										
										
											2009-03-11 12:51:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The handler is typically nil, in which case the DefaultServeMux is used.  
						 
					
						
							
								
									
										
										
										
											2015-08-20 11:56:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ListenAndServe always returns a non-nil error.  
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ListenAndServe ( addr  string ,  handler  Handler )  error  {  
						 
					
						
							
								
									
										
										
										
											2011-02-10 14:36:22 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									server  :=  & Server { Addr :  addr ,  Handler :  handler } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  server . ListenAndServe ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-24 15:26:55 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2010-07-02 13:00:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-02 16:43:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ListenAndServeTLS acts identically to ListenAndServe, except that it  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// expects HTTPS connections. Additionally, files containing a certificate and  
						 
					
						
							
								
									
										
										
										
											2011-06-20 12:19:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// matching private key for the server must be provided. If the certificate  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is signed by a certificate authority, the certFile should be the concatenation  
						 
					
						
							
								
									
										
										
										
											2015-06-24 13:57:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// of the server's certificate, any intermediates, and the CA's certificate.  
						 
					
						
							
								
									
										
										
										
											2015-12-09 17:41:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ListenAndServeTLS ( addr ,  certFile ,  keyFile  string ,  handler  Handler )  error  {  
						 
					
						
							
								
									
										
										
										
											2011-06-20 12:19:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									server  :=  & Server { Addr :  addr ,  Handler :  handler } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  server . ListenAndServeTLS ( certFile ,  keyFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ListenAndServeTLS listens on the TCP network address srv.Addr and  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// then calls ServeTLS to handle requests on incoming TLS connections.  
						 
					
						
							
								
									
										
										
										
											2015-12-09 17:41:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Accepted connections are configured to enable TCP keep-alives.  
						 
					
						
							
								
									
										
										
										
											2011-06-20 12:19:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2015-06-24 13:57:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Filenames containing a certificate and matching private key for the  
						 
					
						
							
								
									
										
										
										
											2016-02-08 23:23:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// server must be provided if neither the Server's TLSConfig.Certificates  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// nor TLSConfig.GetCertificate are populated. If the certificate is  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// signed by a certificate authority, the certFile should be the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// concatenation of the server's certificate, any intermediates, and  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the CA's certificate.  
						 
					
						
							
								
									
										
										
										
											2011-06-20 12:19:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If srv.Addr is blank, ":https" is used.  
						 
					
						
							
								
									
										
										
										
											2015-08-20 11:56:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2018-07-23 18:31:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ListenAndServeTLS always returns a non-nil error. After Shutdown or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Close, the returned error is ErrServerClosed.  
						 
					
						
							
								
									
										
										
										
											2012-01-30 11:58:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  ListenAndServeTLS ( certFile ,  keyFile  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2017-12-04 19:34:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  srv . shuttingDown ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ErrServerClosed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-30 11:58:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									addr  :=  srv . Addr 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-20 12:19:26 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  addr  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addr  =  ":https" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-03 11:00:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-09 15:05:09 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ln ,  err  :=  net . Listen ( "tcp" ,  addr ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-02 13:00:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-05 09:21:25 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  ln . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 08:50:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  srv . ServeTLS ( ln ,  certFile ,  keyFile ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-02 13:00:18 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// setupHTTP2_ServeTLS conditionally configures HTTP/2 on  
						 
					
						
							
								
									
										
										
										
											2018-11-22 11:46:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// srv and reports whether there was an error setting it up. If it is  
						 
					
						
							
								
									
										
										
										
											2016-07-26 23:44:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// not configured for policy reasons, nil is returned.  
						 
					
						
							
								
									
										
										
										
											2017-03-13 07:43:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  setupHTTP2_ServeTLS ( )  error  {  
						 
					
						
							
								
									
										
										
										
											2015-11-03 11:00:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srv . nextProtoOnce . Do ( srv . onceSetNextProtoDefaults ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  srv . nextProtoErr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 23:44:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// setupHTTP2_Serve is called from (*Server).Serve and conditionally  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// configures HTTP/2 on srv using a more conservative policy than  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:09:59 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// setupHTTP2_ServeTLS because Serve is called after tls.Listen,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and may be called concurrently. See shouldConfigureHTTP2ForServe.  
						 
					
						
							
								
									
										
										
										
											2016-07-26 23:44:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The tests named TestTransportAutomaticHTTP2* and  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TestConcurrentServerServe in server_test.go demonstrate some  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// of the supported use cases and motivations.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( srv  * Server )  setupHTTP2_Serve ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srv . nextProtoOnce . Do ( srv . onceSetNextProtoDefaults_Serve ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  srv . nextProtoErr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( srv  * Server )  onceSetNextProtoDefaults_Serve ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  srv . shouldConfigureHTTP2ForServe ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										srv . onceSetNextProtoDefaults ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-11-03 11:00:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// onceSetNextProtoDefaults configures HTTP/2, if the user hasn't  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// configured otherwise. (by setting srv.TLSNextProto non-nil)  
						 
					
						
							
								
									
										
										
										
											2016-07-26 23:44:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// It must only be called via srv.nextProtoOnce (use srv.setupHTTP2_*).  
						 
					
						
							
								
									
										
										
										
											2015-11-03 11:00:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( srv  * Server )  onceSetNextProtoDefaults ( )  {  
						 
					
						
							
								
									
										
										
										
											2021-08-02 14:55:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  omitBundledHTTP2  ||  godebug . Get ( "http2server" )  ==  "0"  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-07 23:43:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-14 20:41:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Enable HTTP/2 by default if the user hasn't otherwise 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// configured their TLSNextProto map. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  srv . TLSNextProto  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 10:13:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										conf  :=  & http2Server { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											NewWriteScheduler :  func ( )  http2WriteScheduler  {  return  http2NewPriorityWriteScheduler ( nil )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										srv . nextProtoErr  =  http2ConfigureServer ( srv ,  conf ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-14 20:41:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TimeoutHandler returns a Handler that runs h with the given time limit.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The new Handler calls h.ServeHTTP to handle each request, but if a  
						 
					
						
							
								
									
										
										
										
											2013-01-03 10:06:04 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// call runs for longer than its time limit, the handler responds with  
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// a 503 Service Unavailable error and the given message in its body.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (If msg is empty, a suitable default message will be sent.)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// After such a timeout, writes by h to its ResponseWriter will return  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ErrHandlerTimeout.  
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2019-10-25 18:58:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TimeoutHandler supports the Pusher interface but does not support  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Hijacker or Flusher interfaces.  
						 
					
						
							
								
									
										
										
										
											2011-11-30 12:01:46 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TimeoutHandler ( h  Handler ,  dt  time . Duration ,  msg  string )  Handler  {  
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  & timeoutHandler { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										handler :  h , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										body :     msg , 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-29 12:06:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dt :       dt , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ErrHandlerTimeout is returned on ResponseWriter Write calls  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// in handlers which have timed out.  
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  ErrHandlerTimeout  =  errors . New ( "http: Handler timeout" )  
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  timeoutHandler  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									handler  Handler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									body     string 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-29 12:06:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dt       time . Duration 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 21:58:42 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// When set, no context will be created and this context will 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-29 12:06:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// be used instead. 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 21:58:42 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testContext  context . Context 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * timeoutHandler )  errorBody ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  h . body  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  h . body 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( h  * timeoutHandler )  ServeHTTP ( w  ResponseWriter ,  r  * Request )  {  
						 
					
						
							
								
									
										
										
										
											2017-06-21 21:58:42 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  h . testContext 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ctx  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  cancelCtx  context . CancelFunc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctx ,  cancelCtx  =  context . WithTimeout ( r . Context ( ) ,  h . dt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  cancelCtx ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-29 12:06:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 21:58:42 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r  =  r . WithContext ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									done  :=  make ( chan  struct { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tw  :=  & timeoutWriter { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-10 19:11:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w :    w , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										h :    make ( Header ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req :  r , 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 12:15:45 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									panicChan  :=  make ( chan  any ,  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-01 14:24:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  p  :=  recover ( ) ;  p  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												panicChan  <-  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										h . handler . ServeHTTP ( tw ,  r ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										close ( done ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-01 14:24:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  p  :=  <- panicChan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( p ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  <- done : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tw . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  tw . mu . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dst  :=  w . Header ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  k ,  vv  :=  range  tw . h  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dst [ k ]  =  vv 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-06 10:23:49 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! tw . wroteHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tw . code  =  StatusOK 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . WriteHeader ( tw . code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Write ( tw . wbuf . Bytes ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-21 21:58:42 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tw . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  tw . mu . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:27:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  err  :=  ctx . Err ( ) ;  err  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  context . DeadlineExceeded : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . WriteHeader ( StatusServiceUnavailable ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											io . WriteString ( w ,  h . errorBody ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tw . err  =  ErrHandlerTimeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w . WriteHeader ( StatusServiceUnavailable ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tw . err  =  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  timeoutWriter  struct  {  
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w     ResponseWriter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h     Header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wbuf  bytes . Buffer 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-10 19:11:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req   * Request 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mu           sync . Mutex 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:27:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err          error 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									wroteHeader  bool 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									code         int 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-17 11:06:30 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  _  Pusher  =  ( * timeoutWriter ) ( nil )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Push implements the Pusher interface.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( tw  * timeoutWriter )  Push ( target  string ,  opts  * PushOptions )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  pusher ,  ok  :=  tw . w . ( Pusher ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  pusher . Push ( target ,  opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ErrNotSupported 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( tw  * timeoutWriter )  Header ( )  Header  {  return  tw . h  }  
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-01 22:04:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( tw  * timeoutWriter )  Write ( p  [ ] byte )  ( int ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tw . mu . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-08-19 18:45:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  tw . mu . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:27:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  tw . err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ,  tw . err 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! tw . wroteHeader  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-10 19:11:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tw . writeHeaderLocked ( StatusOK ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  tw . wbuf . Write ( p ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-10 19:11:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( tw  * timeoutWriter )  writeHeaderLocked ( code  int )  {  
						 
					
						
							
								
									
										
										
										
											2017-11-27 22:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									checkWriteHeaderCode ( code ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-10 19:11:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:27:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  tw . err  !=  nil : 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-10 19:11:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  tw . wroteHeader : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  tw . req  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											caller  :=  relevantCaller ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logf ( tw . req ,  "http: superfluous response.WriteHeader call from %s (%s:%d)" ,  caller . Function ,  path . Base ( caller . File ) ,  caller . Line ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tw . wroteHeader  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tw . code  =  code 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 01:04:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-10 19:11:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( tw  * timeoutWriter )  WriteHeader ( code  int )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tw . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  tw . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tw . writeHeaderLocked ( code ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 12:53:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
											
												net/http: fix Transport races & deadlocks
Thanks to Dustin Sallings for exposing the most frustrating
bug ever, and for providing repro cases (which formed the
basis of the new tests in this CL), and to Dave Cheney and
Dmitry Vyukov for help debugging and fixing.
This CL depends on submited pollster CLs ffd1e075c260 (Unix)
and 14b544194509 (Windows), as well as unsubmitted 6852085.
Some operating systems (OpenBSD, NetBSD, ?) may still require
more pollster work, fixing races (Issue 4434 and
http://goo.gl/JXB6W).
Tested on linux-amd64 and darwin-amd64, both with GOMAXPROCS 1
and 4 (all combinations of which previously failed differently)
Fixes #4191
Update #4434 (related fallout from this bug)
R=dave, bradfitz, dsallings, rsc, fullung
CC=golang-dev
https://golang.org/cl/6851061
											 
										 
										
											2012-11-26 13:31:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-12 20:25:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// onceCloseListener wraps a net.Listener, protecting it from  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// multiple Close calls.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  onceCloseListener  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									net . Listener 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									once      sync . Once 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									closeErr  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( oc  * onceCloseListener )  Close ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									oc . once . Do ( oc . close ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  oc . closeErr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( oc  * onceCloseListener )  close ( )  {  oc . closeErr  =  oc . Listener . Close ( )  }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-11 12:07:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// globalOptionsHandler responds to "OPTIONS *" requests.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  globalOptionsHandler  struct { }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( globalOptionsHandler )  ServeHTTP ( w  ResponseWriter ,  r  * Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . Header ( ) . Set ( "Content-Length" ,  "0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  r . ContentLength  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Read up to 4KB of OPTIONS body (as mentioned in the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// spec as being reserved for future use), but anything 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// over that is considered a waste of server resources 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// (or an attack) and we abort and close the connection, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// courtesy of MaxBytesReader's EOF behavior. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mb  :=  MaxBytesReader ( w ,  r . Body ,  4 << 10 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-16 00:49:02 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										io . Copy ( io . Discard ,  mb ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-11 12:07:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// initALPNRequest is an HTTP handler that initializes certain  
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// uninitialized fields in its *Request. Such partially-initialized  
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Requests come from ALPN protocol handlers.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  initALPNRequest  struct  {  
						 
					
						
							
								
									
										
										
										
											2019-06-07 17:56:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  context . Context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c    * tls . Conn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h    serverHandler 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-07 17:56:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// BaseContext is an exported but unadvertised http.Handler method  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// recognized by x/net/http2 to pass down a context; the TLSNextProto  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// API predates context support so we shoehorn through the only  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// interface we have available.  
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( h  initALPNRequest )  BaseContext ( )  context . Context  {  return  h . ctx  }  
						 
					
						
							
								
									
										
										
										
											2019-06-07 17:56:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 17:48:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( h  initALPNRequest )  ServeHTTP ( rw  ResponseWriter ,  req  * Request )  {  
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  req . TLS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . TLS  =  & tls . ConnectionState { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* req . TLS  =  h . c . ConnectionState ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  req . Body  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-22 09:47:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req . Body  =  NoBody 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-04 13:55:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  req . RemoteAddr  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . RemoteAddr  =  h . c . RemoteAddr ( ) . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h . h . ServeHTTP ( rw ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												net/http: fix Transport races & deadlocks
Thanks to Dustin Sallings for exposing the most frustrating
bug ever, and for providing repro cases (which formed the
basis of the new tests in this CL), and to Dave Cheney and
Dmitry Vyukov for help debugging and fixing.
This CL depends on submited pollster CLs ffd1e075c260 (Unix)
and 14b544194509 (Windows), as well as unsubmitted 6852085.
Some operating systems (OpenBSD, NetBSD, ?) may still require
more pollster work, fixing races (Issue 4434 and
http://goo.gl/JXB6W).
Tested on linux-amd64 and darwin-amd64, both with GOMAXPROCS 1
and 4 (all combinations of which previously failed differently)
Fixes #4191
Update #4434 (related fallout from this bug)
R=dave, bradfitz, dsallings, rsc, fullung
CC=golang-dev
https://golang.org/cl/6851061
											 
										 
										
											2012-11-26 13:31:02 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// loggingConn is used for debugging.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  loggingConn  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									name  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									net . Conn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uniqNameMu    sync . Mutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uniqNameNext  =  make ( map [ string ] int ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newLoggingConn ( baseName  string ,  c  net . Conn )  net . Conn  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uniqNameMu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  uniqNameMu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uniqNameNext [ baseName ] ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & loggingConn { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										name :  fmt . Sprintf ( "%s-%d" ,  baseName ,  uniqNameNext [ baseName ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Conn :  c , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * loggingConn )  Write ( p  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Printf ( "%s.Write(%d) = ...." ,  c . name ,  len ( p ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n ,  err  =  c . Conn . Write ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Printf ( "%s.Write(%d) = %d, %v" ,  c . name ,  len ( p ) ,  n ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * loggingConn )  Read ( p  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Printf ( "%s.Read(%d) = ...." ,  c . name ,  len ( p ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n ,  err  =  c . Conn . Read ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Printf ( "%s.Read(%d) = %d, %v" ,  c . name ,  len ( p ) ,  n ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * loggingConn )  Close ( )  ( err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Printf ( "%s.Close() = ..." ,  c . name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  c . Conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log . Printf ( "%s.Close() = %v" ,  c . name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-10-15 17:51:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// checkConnErrorWriter writes to c.rwc and records any write errors to c.werr.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It only contains one field (and a pointer field at that), so it  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// fits in an interface value without an extra allocation.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  checkConnErrorWriter  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c  * conn 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( w  checkConnErrorWriter )  Write ( p  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
									
										
											 
										
											
												net/http: rework CloseNotifier implementation, clarify expectations in docs
CloseNotifier wasn't well specified previously. This CL simplifies its
implementation, clarifies the public documentation on CloseNotifier,
clarifies internal documentation on conn, and fixes two CloseNotifier
bugs in the process.
The main change, though, is tightening the rules and expectations for using
CloseNotifier:
* the caller must consume the Request.Body first (old rule, unwritten)
* the received value is the "true" value (old rule, unwritten)
* no promises for channel sends after Handler returns (old rule, unwritten)
* a subsequent pipelined request fires the CloseNotifier (new behavior;
  previously it never fired and thus effectively deadlocked as in #13165)
* advise that it should only be used without HTTP/1.1 pipelining (use HTTP/2
  or non-idempotent browsers). Not that browsers actually use pipelining.
The main implementation change is that each Handler now gets its own
CloseNotifier channel value, rather than sharing one between the whole
conn. This means Handlers can't affect subsequent requests. This is
how HTTP/2's Server works too. The old docs never clarified a behavior
either way. The other side effect of each request getting its own
CloseNotifier channel is that one handler can't "poison" the
underlying conn preventing subsequent requests on the same connection
from using CloseNotifier (this is #9763).
In the old implementation, once any request on a connection used
ClosedNotifier, the conn's underlying bufio.Reader source was switched
from the TCPConn to the read side of the pipe being fed by a
never-ending copy. Since it was impossible to abort that never-ending
copy, we could never get back to a fresh state where it was possible
to return the underlying TCPConn to callers of Hijack. Now, instead of
a never-ending Copy, the background goroutine doing a Read from the
TCPConn (or *tls.Conn) only reads a single byte. That single byte
can be in the request body, a socket timeout error, io.EOF error, or
the first byte of the second body. In any case, the new *connReader
type stitches sync and async reads together like an io.MultiReader. To
clarify the flow of Read data and combat the complexity of too many
wrapper Reader types, the *connReader absorbs the io.LimitReader
previously used for bounding request header reads.  The
liveSwitchReader type is removed. (an unused switchWriter type is also
removed)
Many fields on *conn are also documented more fully.
Fixes #9763 (CloseNotify + Hijack together)
Fixes #13165 (deadlock with CloseNotify + pipelined requests)
Change-Id: I40abc0a1992d05b294d627d1838c33cbccb9dd65
Reviewed-on: https://go-review.googlesource.com/17750
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											 
										 
										
											2015-12-01 19:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									n ,  err  =  w . c . rwc . Write ( p ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-15 17:51:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  &&  w . c . werr  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . c . werr  =  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 11:45:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w . c . cancelCtx ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-15 17:51:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2015-06-25 11:31:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  numLeadingCRorLF ( v  [ ] byte )  ( n  int )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  b  :=  range  v  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  b  ==  '\r'  ||  b  ==  '\n'  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											n ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2015-11-03 11:00:37 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  strSliceContains ( ss  [ ] string ,  s  string )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  v  :=  range  ss  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  v  ==  s  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2018-03-15 08:21:44 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// tlsRecordHeaderLooksLikeHTTP reports whether a TLS record header  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// looks like it might've been a misdirected plaintext HTTP request.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  tlsRecordHeaderLooksLikeHTTP ( hdr  [ 5 ] byte )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  string ( hdr [ : ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  "GET /" ,  "HEAD " ,  "POST " ,  "PUT /" ,  "OPTIO" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-08-31 20:35:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MaxBytesHandler returns a Handler that runs h with its ResponseWriter and Request.Body wrapped by a MaxBytesReader.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  MaxBytesHandler ( h  Handler ,  n  int64 )  Handler  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  HandlerFunc ( func ( w  ResponseWriter ,  r  * Request )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r2  :=  * r 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r2 . Body  =  MaxBytesReader ( w ,  r . Body ,  n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										h . ServeHTTP ( w ,  & r2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}