A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://golang.org/src/net/http/request.go below:

- The Go Programming Language

Source file src/net/http/request.go
     1  
     2  
     3  
     4  
     5  
     6  
     7  package http
     8  
     9  import (
    10  	"bufio"
    11  	"bytes"
    12  	"context"
    13  	"crypto/tls"
    14  	"encoding/base64"
    15  	"errors"
    16  	"fmt"
    17  	"io"
    18  	"maps"
    19  	"mime"
    20  	"mime/multipart"
    21  	"net/http/httptrace"
    22  	"net/http/internal/ascii"
    23  	"net/textproto"
    24  	"net/url"
    25  	urlpkg "net/url"
    26  	"strconv"
    27  	"strings"
    28  	"sync"
    29  	_ "unsafe" 
    30  
    31  	"golang.org/x/net/http/httpguts"
    32  	"golang.org/x/net/idna"
    33  )
    34  
    35  const (
    36  	defaultMaxMemory = 32 << 20 
    37  )
    38  
    39  
    40  
    41  var ErrMissingFile = errors.New("http: no such file")
    42  
    43  
    44  
    45  
    46  
    47  type ProtocolError struct {
    48  	ErrorString string
    49  }
    50  
    51  func (pe *ProtocolError) Error() string { return pe.ErrorString }
    52  
    53  
    54  func (pe *ProtocolError) Is(err error) bool {
    55  	return pe == ErrNotSupported && err == errors.ErrUnsupported
    56  }
    57  
    58  var (
    59  	
    60  	
    61  	
    62  	
    63  	
    64  	
    65  	ErrNotSupported = &ProtocolError{"feature not supported"}
    66  
    67  	
    68  	
    69  	
    70  	ErrUnexpectedTrailer = &ProtocolError{"trailer header without chunked transfer encoding"}
    71  
    72  	
    73  	
    74  	ErrMissingBoundary = &ProtocolError{"no multipart boundary param in Content-Type"}
    75  
    76  	
    77  	
    78  	ErrNotMultipart = &ProtocolError{"request Content-Type isn't multipart/form-data"}
    79  
    80  	
    81  	
    82  	
    83  	ErrHeaderTooLong = &ProtocolError{"header too long"}
    84  
    85  	
    86  	
    87  	
    88  	ErrShortBody = &ProtocolError{"entity body too short"}
    89  
    90  	
    91  	
    92  	
    93  	ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
    94  )
    95  
    96  func badStringError(what, val string) error { return fmt.Errorf("%s %q", what, val) }
    97  
    98  
    99  var reqWriteExcludeHeader = map[string]bool{
   100  	"Host":              true, 
   101  	"User-Agent":        true,
   102  	"Content-Length":    true,
   103  	"Transfer-Encoding": true,
   104  	"Trailer":           true,
   105  }
   106  
   107  
   108  
   109  
   110  
   111  
   112  
   113  type Request struct {
   114  	
   115  	
   116  	Method string
   117  
   118  	
   119  	
   120  	
   121  	
   122  	
   123  	
   124  	
   125  	
   126  	
   127  	
   128  	
   129  	
   130  	URL *url.URL
   131  
   132  	
   133  	
   134  	
   135  	
   136  	
   137  	Proto      string 
   138  	ProtoMajor int    
   139  	ProtoMinor int    
   140  
   141  	
   142  	
   143  	
   144  	
   145  	
   146  	
   147  	
   148  	
   149  	
   150  	
   151  	
   152  	
   153  	
   154  	
   155  	
   156  	
   157  	
   158  	
   159  	
   160  	
   161  	
   162  	
   163  	
   164  	
   165  	
   166  	
   167  	
   168  	
   169  	
   170  	
   171  	
   172  	Header Header
   173  
   174  	
   175  	
   176  	
   177  	
   178  	
   179  	
   180  	
   181  	
   182  	
   183  	
   184  	
   185  	
   186  	
   187  	
   188  	Body io.ReadCloser
   189  
   190  	
   191  	
   192  	
   193  	
   194  	
   195  	
   196  	GetBody func() (io.ReadCloser, error)
   197  
   198  	
   199  	
   200  	
   201  	
   202  	
   203  	
   204  	
   205  	ContentLength int64
   206  
   207  	
   208  	
   209  	
   210  	
   211  	
   212  	TransferEncoding []string
   213  
   214  	
   215  	
   216  	
   217  	
   218  	
   219  	
   220  	
   221  	
   222  	
   223  	
   224  	Close bool
   225  
   226  	
   227  	
   228  	
   229  	
   230  	
   231  	
   232  	
   233  	
   234  	
   235  	
   236  	
   237  	
   238  	
   239  	
   240  	
   241  	
   242  	
   243  	
   244  	
   245  	Host string
   246  
   247  	
   248  	
   249  	
   250  	
   251  	Form url.Values
   252  
   253  	
   254  	
   255  	
   256  	
   257  	
   258  	PostForm url.Values
   259  
   260  	
   261  	
   262  	
   263  	MultipartForm *multipart.Form
   264  
   265  	
   266  	
   267  	
   268  	
   269  	
   270  	
   271  	
   272  	
   273  	
   274  	
   275  	
   276  	
   277  	
   278  	
   279  	
   280  	
   281  	
   282  	
   283  	Trailer Header
   284  
   285  	
   286  	
   287  	
   288  	
   289  	
   290  	
   291  	
   292  	RemoteAddr string
   293  
   294  	
   295  	
   296  	
   297  	
   298  	RequestURI string
   299  
   300  	
   301  	
   302  	
   303  	
   304  	
   305  	
   306  	
   307  	TLS *tls.ConnectionState
   308  
   309  	
   310  	
   311  	
   312  	
   313  	
   314  	
   315  	
   316  	
   317  	
   318  	Cancel <-chan struct{}
   319  
   320  	
   321  	
   322  	
   323  	Response *Response
   324  
   325  	
   326  	
   327  	Pattern string
   328  
   329  	
   330  	
   331  	
   332  	
   333  	ctx context.Context
   334  
   335  	
   336  	pat         *pattern          
   337  	matches     []string          
   338  	otherValues map[string]string 
   339  }
   340  
   341  
   342  
   343  
   344  
   345  
   346  
   347  
   348  
   349  
   350  
   351  
   352  func (r *Request) Context() context.Context {
   353  	if r.ctx != nil {
   354  		return r.ctx
   355  	}
   356  	return context.Background()
   357  }
   358  
   359  
   360  
   361  
   362  
   363  
   364  
   365  
   366  
   367  
   368  func (r *Request) WithContext(ctx context.Context) *Request {
   369  	if ctx == nil {
   370  		panic("nil context")
   371  	}
   372  	r2 := new(Request)
   373  	*r2 = *r
   374  	r2.ctx = ctx
   375  	return r2
   376  }
   377  
   378  
   379  
   380  
   381  
   382  
   383  
   384  
   385  
   386  func (r *Request) Clone(ctx context.Context) *Request {
   387  	if ctx == nil {
   388  		panic("nil context")
   389  	}
   390  	r2 := new(Request)
   391  	*r2 = *r
   392  	r2.ctx = ctx
   393  	r2.URL = cloneURL(r.URL)
   394  	r2.Header = r.Header.Clone()
   395  	r2.Trailer = r.Trailer.Clone()
   396  	if s := r.TransferEncoding; s != nil {
   397  		s2 := make([]string, len(s))
   398  		copy(s2, s)
   399  		r2.TransferEncoding = s2
   400  	}
   401  	r2.Form = cloneURLValues(r.Form)
   402  	r2.PostForm = cloneURLValues(r.PostForm)
   403  	r2.MultipartForm = cloneMultipartForm(r.MultipartForm)
   404  
   405  	
   406  	if s := r.matches; s != nil {
   407  		s2 := make([]string, len(s))
   408  		copy(s2, s)
   409  		r2.matches = s2
   410  	}
   411  	r2.otherValues = maps.Clone(r.otherValues)
   412  	return r2
   413  }
   414  
   415  
   416  
   417  func (r *Request) ProtoAtLeast(major, minor int) bool {
   418  	return r.ProtoMajor > major ||
   419  		r.ProtoMajor == major && r.ProtoMinor >= minor
   420  }
   421  
   422  
   423  func (r *Request) UserAgent() string {
   424  	return r.Header.Get("User-Agent")
   425  }
   426  
   427  
   428  func (r *Request) Cookies() []*Cookie {
   429  	return readCookies(r.Header, "")
   430  }
   431  
   432  
   433  
   434  func (r *Request) CookiesNamed(name string) []*Cookie {
   435  	if name == "" {
   436  		return []*Cookie{}
   437  	}
   438  	return readCookies(r.Header, name)
   439  }
   440  
   441  
   442  var ErrNoCookie = errors.New("http: named cookie not present")
   443  
   444  
   445  
   446  
   447  
   448  func (r *Request) Cookie(name string) (*Cookie, error) {
   449  	if name == "" {
   450  		return nil, ErrNoCookie
   451  	}
   452  	for _, c := range readCookies(r.Header, name) {
   453  		return c, nil
   454  	}
   455  	return nil, ErrNoCookie
   456  }
   457  
   458  
   459  
   460  
   461  
   462  
   463  
   464  func (r *Request) AddCookie(c *Cookie) {
   465  	s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value, c.Quoted))
   466  	if c := r.Header.Get("Cookie"); c != "" {
   467  		r.Header.Set("Cookie", c+"; "+s)
   468  	} else {
   469  		r.Header.Set("Cookie", s)
   470  	}
   471  }
   472  
   473  
   474  
   475  
   476  
   477  
   478  
   479  
   480  
   481  func (r *Request) Referer() string {
   482  	return r.Header.Get("Referer")
   483  }
   484  
   485  
   486  
   487  
   488  var multipartByReader = &multipart.Form{
   489  	Value: make(map[string][]string),
   490  	File:  make(map[string][]*multipart.FileHeader),
   491  }
   492  
   493  
   494  
   495  
   496  
   497  func (r *Request) MultipartReader() (*multipart.Reader, error) {
   498  	if r.MultipartForm == multipartByReader {
   499  		return nil, errors.New("http: MultipartReader called twice")
   500  	}
   501  	if r.MultipartForm != nil {
   502  		return nil, errors.New("http: multipart handled by ParseMultipartForm")
   503  	}
   504  	r.MultipartForm = multipartByReader
   505  	return r.multipartReader(true)
   506  }
   507  
   508  func (r *Request) multipartReader(allowMixed bool) (*multipart.Reader, error) {
   509  	v := r.Header.Get("Content-Type")
   510  	if v == "" {
   511  		return nil, ErrNotMultipart
   512  	}
   513  	if r.Body == nil {
   514  		return nil, errors.New("missing form body")
   515  	}
   516  	d, params, err := mime.ParseMediaType(v)
   517  	if err != nil || !(d == "multipart/form-data" || allowMixed && d == "multipart/mixed") {
   518  		return nil, ErrNotMultipart
   519  	}
   520  	boundary, ok := params["boundary"]
   521  	if !ok {
   522  		return nil, ErrMissingBoundary
   523  	}
   524  	return multipart.NewReader(r.Body, boundary), nil
   525  }
   526  
   527  
   528  
   529  func (r *Request) isH2Upgrade() bool {
   530  	return r.Method == "PRI" && len(r.Header) == 0 && r.URL.Path == "*" && r.Proto == "HTTP/2.0"
   531  }
   532  
   533  
   534  func valueOrDefault(value, def string) string {
   535  	if value != "" {
   536  		return value
   537  	}
   538  	return def
   539  }
   540  
   541  
   542  
   543  
   544  
   545  const defaultUserAgent = "Go-http-client/1.1"
   546  
   547  
   548  
   549  
   550  
   551  
   552  
   553  
   554  
   555  
   556  
   557  
   558  
   559  
   560  
   561  func (r *Request) Write(w io.Writer) error {
   562  	return r.write(w, false, nil, nil)
   563  }
   564  
   565  
   566  
   567  
   568  
   569  
   570  
   571  func (r *Request) WriteProxy(w io.Writer) error {
   572  	return r.write(w, true, nil, nil)
   573  }
   574  
   575  
   576  
   577  var errMissingHost = errors.New("http: Request.Write on Request with no Host or URL set")
   578  
   579  
   580  
   581  
   582  func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitForContinue func() bool) (err error) {
   583  	trace := httptrace.ContextClientTrace(r.Context())
   584  	if trace != nil && trace.WroteRequest != nil {
   585  		defer func() {
   586  			trace.WroteRequest(httptrace.WroteRequestInfo{
   587  				Err: err,
   588  			})
   589  		}()
   590  	}
   591  	closed := false
   592  	defer func() {
   593  		if closed {
   594  			return
   595  		}
   596  		if closeErr := r.closeBody(); closeErr != nil && err == nil {
   597  			err = closeErr
   598  		}
   599  	}()
   600  
   601  	
   602  	
   603  	
   604  	
   605  	host := r.Host
   606  	if host == "" {
   607  		if r.URL == nil {
   608  			return errMissingHost
   609  		}
   610  		host = r.URL.Host
   611  	}
   612  	host, err = httpguts.PunycodeHostPort(host)
   613  	if err != nil {
   614  		return err
   615  	}
   616  	
   617  	
   618  	
   619  	
   620  	
   621  	if !httpguts.ValidHostHeader(host) {
   622  		
   623  		
   624  		
   625  		
   626  		
   627  		
   628  		
   629  		
   630  		
   631  		
   632  		
   633  		
   634  		if !usingProxy {
   635  			host = ""
   636  		} else {
   637  			return errors.New("http: invalid Host header")
   638  		}
   639  	}
   640  
   641  	
   642  	
   643  	
   644  	host = removeZone(host)
   645  
   646  	ruri := r.URL.RequestURI()
   647  	if usingProxy && r.URL.Scheme != "" && r.URL.Opaque == "" {
   648  		ruri = r.URL.Scheme + "://" + host + ruri
   649  	} else if r.Method == "CONNECT" && r.URL.Path == "" {
   650  		
   651  		ruri = host
   652  		if r.URL.Opaque != "" {
   653  			ruri = r.URL.Opaque
   654  		}
   655  	}
   656  	if stringContainsCTLByte(ruri) {
   657  		return errors.New("net/http: can't write control character in Request.URL")
   658  	}
   659  	
   660  	
   661  	
   662  
   663  	
   664  	
   665  	
   666  	
   667  	var bw *bufio.Writer
   668  	if _, ok := w.(io.ByteWriter); !ok {
   669  		bw = bufio.NewWriter(w)
   670  		w = bw
   671  	}
   672  
   673  	_, err = fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(r.Method, "GET"), ruri)
   674  	if err != nil {
   675  		return err
   676  	}
   677  
   678  	
   679  	_, err = fmt.Fprintf(w, "Host: %s\r\n", host)
   680  	if err != nil {
   681  		return err
   682  	}
   683  	if trace != nil && trace.WroteHeaderField != nil {
   684  		trace.WroteHeaderField("Host", []string{host})
   685  	}
   686  
   687  	
   688  	
   689  	userAgent := defaultUserAgent
   690  	if r.Header.has("User-Agent") {
   691  		userAgent = r.Header.Get("User-Agent")
   692  	}
   693  	if userAgent != "" {
   694  		userAgent = headerNewlineToSpace.Replace(userAgent)
   695  		userAgent = textproto.TrimString(userAgent)
   696  		_, err = fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent)
   697  		if err != nil {
   698  			return err
   699  		}
   700  		if trace != nil && trace.WroteHeaderField != nil {
   701  			trace.WroteHeaderField("User-Agent", []string{userAgent})
   702  		}
   703  	}
   704  
   705  	
   706  	tw, err := newTransferWriter(r)
   707  	if err != nil {
   708  		return err
   709  	}
   710  	err = tw.writeHeader(w, trace)
   711  	if err != nil {
   712  		return err
   713  	}
   714  
   715  	err = r.Header.writeSubset(w, reqWriteExcludeHeader, trace)
   716  	if err != nil {
   717  		return err
   718  	}
   719  
   720  	if extraHeaders != nil {
   721  		err = extraHeaders.write(w, trace)
   722  		if err != nil {
   723  			return err
   724  		}
   725  	}
   726  
   727  	_, err = io.WriteString(w, "\r\n")
   728  	if err != nil {
   729  		return err
   730  	}
   731  
   732  	if trace != nil && trace.WroteHeaders != nil {
   733  		trace.WroteHeaders()
   734  	}
   735  
   736  	
   737  	if waitForContinue != nil {
   738  		if bw, ok := w.(*bufio.Writer); ok {
   739  			err = bw.Flush()
   740  			if err != nil {
   741  				return err
   742  			}
   743  		}
   744  		if trace != nil && trace.Wait100Continue != nil {
   745  			trace.Wait100Continue()
   746  		}
   747  		if !waitForContinue() {
   748  			closed = true
   749  			r.closeBody()
   750  			return nil
   751  		}
   752  	}
   753  
   754  	if bw, ok := w.(*bufio.Writer); ok && tw.FlushHeaders {
   755  		if err := bw.Flush(); err != nil {
   756  			return err
   757  		}
   758  	}
   759  
   760  	
   761  	closed = true
   762  	err = tw.writeBody(w)
   763  	if err != nil {
   764  		if tw.bodyReadError == err {
   765  			err = requestBodyReadError{err}
   766  		}
   767  		return err
   768  	}
   769  
   770  	if bw != nil {
   771  		return bw.Flush()
   772  	}
   773  	return nil
   774  }
   775  
   776  
   777  
   778  
   779  type requestBodyReadError struct{ error }
   780  
   781  func idnaASCII(v string) (string, error) {
   782  	
   783  	
   784  	
   785  	
   786  	
   787  	
   788  	
   789  	
   790  	
   791  	if ascii.Is(v) {
   792  		return v, nil
   793  	}
   794  	return idna.Lookup.ToASCII(v)
   795  }
   796  
   797  
   798  
   799  func removeZone(host string) string {
   800  	if !strings.HasPrefix(host, "[") {
   801  		return host
   802  	}
   803  	i := strings.LastIndex(host, "]")
   804  	if i < 0 {
   805  		return host
   806  	}
   807  	j := strings.LastIndex(host[:i], "%")
   808  	if j < 0 {
   809  		return host
   810  	}
   811  	return host[:j] + host[i:]
   812  }
   813  
   814  
   815  
   816  
   817  func ParseHTTPVersion(vers string) (major, minor int, ok bool) {
   818  	switch vers {
   819  	case "HTTP/1.1":
   820  		return 1, 1, true
   821  	case "HTTP/1.0":
   822  		return 1, 0, true
   823  	}
   824  	if !strings.HasPrefix(vers, "HTTP/") {
   825  		return 0, 0, false
   826  	}
   827  	if len(vers) != len("HTTP/X.Y") {
   828  		return 0, 0, false
   829  	}
   830  	if vers[6] != '.' {
   831  		return 0, 0, false
   832  	}
   833  	maj, err := strconv.ParseUint(vers[5:6], 10, 0)
   834  	if err != nil {
   835  		return 0, 0, false
   836  	}
   837  	min, err := strconv.ParseUint(vers[7:8], 10, 0)
   838  	if err != nil {
   839  		return 0, 0, false
   840  	}
   841  	return int(maj), int(min), true
   842  }
   843  
   844  func validMethod(method string) bool {
   845  	
   858  	return isToken(method)
   859  }
   860  
   861  
   862  func NewRequest(method, url string, body io.Reader) (*Request, error) {
   863  	return NewRequestWithContext(context.Background(), method, url, body)
   864  }
   865  
   866  
   867  
   868  
   869  
   870  
   871  
   872  
   873  
   874  
   875  
   876  
   877  
   878  
   879  
   880  
   881  
   882  
   883  
   884  
   885  
   886  
   887  
   888  
   889  func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) {
   890  	if method == "" {
   891  		
   892  		
   893  		
   894  		method = "GET"
   895  	}
   896  	if !validMethod(method) {
   897  		return nil, fmt.Errorf("net/http: invalid method %q", method)
   898  	}
   899  	if ctx == nil {
   900  		return nil, errors.New("net/http: nil Context")
   901  	}
   902  	u, err := urlpkg.Parse(url)
   903  	if err != nil {
   904  		return nil, err
   905  	}
   906  	rc, ok := body.(io.ReadCloser)
   907  	if !ok && body != nil {
   908  		rc = io.NopCloser(body)
   909  	}
   910  	
   911  	u.Host = removeEmptyPort(u.Host)
   912  	req := &Request{
   913  		ctx:        ctx,
   914  		Method:     method,
   915  		URL:        u,
   916  		Proto:      "HTTP/1.1",
   917  		ProtoMajor: 1,
   918  		ProtoMinor: 1,
   919  		Header:     make(Header),
   920  		Body:       rc,
   921  		Host:       u.Host,
   922  	}
   923  	if body != nil {
   924  		switch v := body.(type) {
   925  		case *bytes.Buffer:
   926  			req.ContentLength = int64(v.Len())
   927  			buf := v.Bytes()
   928  			req.GetBody = func() (io.ReadCloser, error) {
   929  				r := bytes.NewReader(buf)
   930  				return io.NopCloser(r), nil
   931  			}
   932  		case *bytes.Reader:
   933  			req.ContentLength = int64(v.Len())
   934  			snapshot := *v
   935  			req.GetBody = func() (io.ReadCloser, error) {
   936  				r := snapshot
   937  				return io.NopCloser(&r), nil
   938  			}
   939  		case *strings.Reader:
   940  			req.ContentLength = int64(v.Len())
   941  			snapshot := *v
   942  			req.GetBody = func() (io.ReadCloser, error) {
   943  				r := snapshot
   944  				return io.NopCloser(&r), nil
   945  			}
   946  		default:
   947  			
   948  			
   949  			
   950  			
   951  			
   952  		}
   953  		
   954  		
   955  		
   956  		
   957  		
   958  		
   959  		
   960  		
   961  		if req.GetBody != nil && req.ContentLength == 0 {
   962  			req.Body = NoBody
   963  			req.GetBody = func() (io.ReadCloser, error) { return NoBody, nil }
   964  		}
   965  	}
   966  
   967  	return req, nil
   968  }
   969  
   970  
   971  
   972  
   973  func (r *Request) BasicAuth() (username, password string, ok bool) {
   974  	auth := r.Header.Get("Authorization")
   975  	if auth == "" {
   976  		return "", "", false
   977  	}
   978  	return parseBasicAuth(auth)
   979  }
   980  
   981  
   982  
   983  
   984  
   985  
   986  
   987  
   988  
   989  
   990  
   991  
   992  
   993  func parseBasicAuth(auth string) (username, password string, ok bool) {
   994  	const prefix = "Basic "
   995  	
   996  	if len(auth) < len(prefix) || !ascii.EqualFold(auth[:len(prefix)], prefix) {
   997  		return "", "", false
   998  	}
   999  	c, err := base64.StdEncoding.DecodeString(auth[len(prefix):])
  1000  	if err != nil {
  1001  		return "", "", false
  1002  	}
  1003  	cs := string(c)
  1004  	username, password, ok = strings.Cut(cs, ":")
  1005  	if !ok {
  1006  		return "", "", false
  1007  	}
  1008  	return username, password, true
  1009  }
  1010  
  1011  
  1012  
  1013  
  1014  
  1015  
  1016  
  1017  
  1018  
  1019  
  1020  
  1021  
  1022  func (r *Request) SetBasicAuth(username, password string) {
  1023  	r.Header.Set("Authorization", "Basic "+basicAuth(username, password))
  1024  }
  1025  
  1026  
  1027  func parseRequestLine(line string) (method, requestURI, proto string, ok bool) {
  1028  	method, rest, ok1 := strings.Cut(line, " ")
  1029  	requestURI, proto, ok2 := strings.Cut(rest, " ")
  1030  	if !ok1 || !ok2 {
  1031  		return "", "", "", false
  1032  	}
  1033  	return method, requestURI, proto, true
  1034  }
  1035  
  1036  var textprotoReaderPool sync.Pool
  1037  
  1038  func newTextprotoReader(br *bufio.Reader) *textproto.Reader {
  1039  	if v := textprotoReaderPool.Get(); v != nil {
  1040  		tr := v.(*textproto.Reader)
  1041  		tr.R = br
  1042  		return tr
  1043  	}
  1044  	return textproto.NewReader(br)
  1045  }
  1046  
  1047  func putTextprotoReader(r *textproto.Reader) {
  1048  	r.R = nil
  1049  	textprotoReaderPool.Put(r)
  1050  }
  1051  
  1052  
  1053  
  1054  
  1055  
  1056  
  1057  
  1058  func ReadRequest(b *bufio.Reader) (*Request, error) {
  1059  	req, err := readRequest(b)
  1060  	if err != nil {
  1061  		return nil, err
  1062  	}
  1063  
  1064  	delete(req.Header, "Host")
  1065  	return req, nil
  1066  }
  1067  
  1068  
  1069  
  1070  
  1071  
  1072  
  1073  
  1074  
  1075  
  1076  
  1077  
  1078  
  1079  func readRequest(b *bufio.Reader) (req *Request, err error) {
  1080  	tp := newTextprotoReader(b)
  1081  	defer putTextprotoReader(tp)
  1082  
  1083  	req = new(Request)
  1084  
  1085  	
  1086  	var s string
  1087  	if s, err = tp.ReadLine(); err != nil {
  1088  		return nil, err
  1089  	}
  1090  	defer func() {
  1091  		if err == io.EOF {
  1092  			err = io.ErrUnexpectedEOF
  1093  		}
  1094  	}()
  1095  
  1096  	var ok bool
  1097  	req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s)
  1098  	if !ok {
  1099  		return nil, badStringError("malformed HTTP request", s)
  1100  	}
  1101  	if !validMethod(req.Method) {
  1102  		return nil, badStringError("invalid method", req.Method)
  1103  	}
  1104  	rawurl := req.RequestURI
  1105  	if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok {
  1106  		return nil, badStringError("malformed HTTP version", req.Proto)
  1107  	}
  1108  
  1109  	
  1110  	
  1111  	
  1112  	
  1113  	
  1114  	
  1115  	
  1116  	
  1117  	
  1118  	justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/")
  1119  	if justAuthority {
  1120  		rawurl = "http://" + rawurl
  1121  	}
  1122  
  1123  	if req.URL, err = url.ParseRequestURI(rawurl); err != nil {
  1124  		return nil, err
  1125  	}
  1126  
  1127  	if justAuthority {
  1128  		
  1129  		req.URL.Scheme = ""
  1130  	}
  1131  
  1132  	
  1133  	mimeHeader, err := tp.ReadMIMEHeader()
  1134  	if err != nil {
  1135  		return nil, err
  1136  	}
  1137  	req.Header = Header(mimeHeader)
  1138  	if len(req.Header["Host"]) > 1 {
  1139  		return nil, fmt.Errorf("too many Host headers")
  1140  	}
  1141  
  1142  	
  1143  	
  1144  	
  1145  	
  1146  	
  1147  	
  1148  	
  1149  	req.Host = req.URL.Host
  1150  	if req.Host == "" {
  1151  		req.Host = req.Header.get("Host")
  1152  	}
  1153  
  1154  	fixPragmaCacheControl(req.Header)
  1155  
  1156  	req.Close = shouldClose(req.ProtoMajor, req.ProtoMinor, req.Header, false)
  1157  
  1158  	err = readTransfer(req, b)
  1159  	if err != nil {
  1160  		return nil, err
  1161  	}
  1162  
  1163  	if req.isH2Upgrade() {
  1164  		
  1165  		req.ContentLength = -1
  1166  
  1167  		
  1168  		
  1169  		
  1170  		
  1171  		req.Close = true
  1172  	}
  1173  	return req, nil
  1174  }
  1175  
  1176  
  1177  
  1178  
  1179  
  1180  
  1181  
  1182  
  1183  
  1184  
  1185  
  1186  func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser {
  1187  	if n < 0 { 
  1188  		n = 0
  1189  	}
  1190  	return &maxBytesReader{w: w, r: r, i: n, n: n}
  1191  }
  1192  
  1193  
  1194  type MaxBytesError struct {
  1195  	Limit int64
  1196  }
  1197  
  1198  func (e *MaxBytesError) Error() string {
  1199  	
  1200  	return "http: request body too large"
  1201  }
  1202  
  1203  type maxBytesReader struct {
  1204  	w   ResponseWriter
  1205  	r   io.ReadCloser 
  1206  	i   int64         
  1207  	n   int64         
  1208  	err error         
  1209  }
  1210  
  1211  func (l *maxBytesReader) Read(p []byte) (n int, err error) {
  1212  	if l.err != nil {
  1213  		return 0, l.err
  1214  	}
  1215  	if len(p) == 0 {
  1216  		return 0, nil
  1217  	}
  1218  	
  1219  	
  1220  	
  1221  	
  1222  	if int64(len(p))-1 > l.n {
  1223  		p = p[:l.n+1]
  1224  	}
  1225  	n, err = l.r.Read(p)
  1226  
  1227  	if int64(n) <= l.n {
  1228  		l.n -= int64(n)
  1229  		l.err = err
  1230  		return n, err
  1231  	}
  1232  
  1233  	n = int(l.n)
  1234  	l.n = 0
  1235  
  1236  	
  1237  	
  1238  	
  1239  	
  1240  	
  1241  	
  1242  	
  1243  	type requestTooLarger interface {
  1244  		requestTooLarge()
  1245  	}
  1246  	if res, ok := l.w.(requestTooLarger); ok {
  1247  		res.requestTooLarge()
  1248  	}
  1249  	l.err = &MaxBytesError{l.i}
  1250  	return n, l.err
  1251  }
  1252  
  1253  func (l *maxBytesReader) Close() error {
  1254  	return l.r.Close()
  1255  }
  1256  
  1257  func copyValues(dst, src url.Values) {
  1258  	for k, vs := range src {
  1259  		dst[k] = append(dst[k], vs...)
  1260  	}
  1261  }
  1262  
  1263  func parsePostForm(r *Request) (vs url.Values, err error) {
  1264  	if r.Body == nil {
  1265  		err = errors.New("missing form body")
  1266  		return
  1267  	}
  1268  	ct := r.Header.Get("Content-Type")
  1269  	
  1270  	
  1271  	if ct == "" {
  1272  		ct = "application/octet-stream"
  1273  	}
  1274  	ct, _, err = mime.ParseMediaType(ct)
  1275  	switch {
  1276  	case ct == "application/x-www-form-urlencoded":
  1277  		var reader io.Reader = r.Body
  1278  		maxFormSize := int64(1<<63 - 1)
  1279  		if _, ok := r.Body.(*maxBytesReader); !ok {
  1280  			maxFormSize = int64(10 << 20) 
  1281  			reader = io.LimitReader(r.Body, maxFormSize+1)
  1282  		}
  1283  		b, e := io.ReadAll(reader)
  1284  		if e != nil {
  1285  			if err == nil {
  1286  				err = e
  1287  			}
  1288  			break
  1289  		}
  1290  		if int64(len(b)) > maxFormSize {
  1291  			err = errors.New("http: POST too large")
  1292  			return
  1293  		}
  1294  		vs, e = url.ParseQuery(string(b))
  1295  		if err == nil {
  1296  			err = e
  1297  		}
  1298  	case ct == "multipart/form-data":
  1299  		
  1300  		
  1301  		
  1302  		
  1303  		
  1304  		
  1305  	}
  1306  	return
  1307  }
  1308  
  1309  
  1310  
  1311  
  1312  
  1313  
  1314  
  1315  
  1316  
  1317  
  1318  
  1319  
  1320  
  1321  
  1322  
  1323  
  1324  
  1325  
  1326  
  1327  func (r *Request) ParseForm() error {
  1328  	var err error
  1329  	if r.PostForm == nil {
  1330  		if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
  1331  			r.PostForm, err = parsePostForm(r)
  1332  		}
  1333  		if r.PostForm == nil {
  1334  			r.PostForm = make(url.Values)
  1335  		}
  1336  	}
  1337  	if r.Form == nil {
  1338  		if len(r.PostForm) > 0 {
  1339  			r.Form = make(url.Values)
  1340  			copyValues(r.Form, r.PostForm)
  1341  		}
  1342  		var newValues url.Values
  1343  		if r.URL != nil {
  1344  			var e error
  1345  			newValues, e = url.ParseQuery(r.URL.RawQuery)
  1346  			if err == nil {
  1347  				err = e
  1348  			}
  1349  		}
  1350  		if newValues == nil {
  1351  			newValues = make(url.Values)
  1352  		}
  1353  		if r.Form == nil {
  1354  			r.Form = newValues
  1355  		} else {
  1356  			copyValues(r.Form, newValues)
  1357  		}
  1358  	}
  1359  	return err
  1360  }
  1361  
  1362  
  1363  
  1364  
  1365  
  1366  
  1367  
  1368  
  1369  
  1370  func (r *Request) ParseMultipartForm(maxMemory int64) error {
  1371  	if r.MultipartForm == multipartByReader {
  1372  		return errors.New("http: multipart handled by MultipartReader")
  1373  	}
  1374  	var parseFormErr error
  1375  	if r.Form == nil {
  1376  		
  1377  		
  1378  		parseFormErr = r.ParseForm()
  1379  	}
  1380  	if r.MultipartForm != nil {
  1381  		return nil
  1382  	}
  1383  
  1384  	mr, err := r.multipartReader(false)
  1385  	if err != nil {
  1386  		return err
  1387  	}
  1388  
  1389  	f, err := mr.ReadForm(maxMemory)
  1390  	if err != nil {
  1391  		return err
  1392  	}
  1393  
  1394  	if r.PostForm == nil {
  1395  		r.PostForm = make(url.Values)
  1396  	}
  1397  	for k, v := range f.Value {
  1398  		r.Form[k] = append(r.Form[k], v...)
  1399  		
  1400  		r.PostForm[k] = append(r.PostForm[k], v...)
  1401  	}
  1402  
  1403  	r.MultipartForm = f
  1404  
  1405  	return parseFormErr
  1406  }
  1407  
  1408  
  1409  
  1410  
  1411  
  1412  
  1413  
  1414  
  1415  
  1416  
  1417  
  1418  
  1419  func (r *Request) FormValue(key string) string {
  1420  	if r.Form == nil {
  1421  		r.ParseMultipartForm(defaultMaxMemory)
  1422  	}
  1423  	if vs := r.Form[key]; len(vs) > 0 {
  1424  		return vs[0]
  1425  	}
  1426  	return ""
  1427  }
  1428  
  1429  
  1430  
  1431  
  1432  
  1433  
  1434  func (r *Request) PostFormValue(key string) string {
  1435  	if r.PostForm == nil {
  1436  		r.ParseMultipartForm(defaultMaxMemory)
  1437  	}
  1438  	if vs := r.PostForm[key]; len(vs) > 0 {
  1439  		return vs[0]
  1440  	}
  1441  	return ""
  1442  }
  1443  
  1444  
  1445  
  1446  func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
  1447  	if r.MultipartForm == multipartByReader {
  1448  		return nil, nil, errors.New("http: multipart handled by MultipartReader")
  1449  	}
  1450  	if r.MultipartForm == nil {
  1451  		err := r.ParseMultipartForm(defaultMaxMemory)
  1452  		if err != nil {
  1453  			return nil, nil, err
  1454  		}
  1455  	}
  1456  	if r.MultipartForm != nil && r.MultipartForm.File != nil {
  1457  		if fhs := r.MultipartForm.File[key]; len(fhs) > 0 {
  1458  			f, err := fhs[0].Open()
  1459  			return f, fhs[0], err
  1460  		}
  1461  	}
  1462  	return nil, nil, ErrMissingFile
  1463  }
  1464  
  1465  
  1466  
  1467  
  1468  
  1469  func (r *Request) PathValue(name string) string {
  1470  	if i := r.patIndex(name); i >= 0 {
  1471  		return r.matches[i]
  1472  	}
  1473  	return r.otherValues[name]
  1474  }
  1475  
  1476  
  1477  
  1478  func (r *Request) SetPathValue(name, value string) {
  1479  	if i := r.patIndex(name); i >= 0 {
  1480  		r.matches[i] = value
  1481  	} else {
  1482  		if r.otherValues == nil {
  1483  			r.otherValues = map[string]string{}
  1484  		}
  1485  		r.otherValues[name] = value
  1486  	}
  1487  }
  1488  
  1489  
  1490  
  1491  func (r *Request) patIndex(name string) int {
  1492  	
  1493  	
  1494  	if r.pat == nil {
  1495  		return -1
  1496  	}
  1497  	i := 0
  1498  	for _, seg := range r.pat.segments {
  1499  		if seg.wild && seg.s != "" {
  1500  			if name == seg.s {
  1501  				return i
  1502  			}
  1503  			i++
  1504  		}
  1505  	}
  1506  	return -1
  1507  }
  1508  
  1509  func (r *Request) expectsContinue() bool {
  1510  	return hasToken(r.Header.get("Expect"), "100-continue")
  1511  }
  1512  
  1513  func (r *Request) wantsHttp10KeepAlive() bool {
  1514  	if r.ProtoMajor != 1 || r.ProtoMinor != 0 {
  1515  		return false
  1516  	}
  1517  	return hasToken(r.Header.get("Connection"), "keep-alive")
  1518  }
  1519  
  1520  func (r *Request) wantsClose() bool {
  1521  	if r.Close {
  1522  		return true
  1523  	}
  1524  	return hasToken(r.Header.get("Connection"), "close")
  1525  }
  1526  
  1527  func (r *Request) closeBody() error {
  1528  	if r.Body == nil {
  1529  		return nil
  1530  	}
  1531  	return r.Body.Close()
  1532  }
  1533  
  1534  func (r *Request) isReplayable() bool {
  1535  	if r.Body == nil || r.Body == NoBody || r.GetBody != nil {
  1536  		switch valueOrDefault(r.Method, "GET") {
  1537  		case "GET", "HEAD", "OPTIONS", "TRACE":
  1538  			return true
  1539  		}
  1540  		
  1541  		
  1542  		
  1543  		if r.Header.has("Idempotency-Key") || r.Header.has("X-Idempotency-Key") {
  1544  			return true
  1545  		}
  1546  	}
  1547  	return false
  1548  }
  1549  
  1550  
  1551  
  1552  func (r *Request) outgoingLength() int64 {
  1553  	if r.Body == nil || r.Body == NoBody {
  1554  		return 0
  1555  	}
  1556  	if r.ContentLength != 0 {
  1557  		return r.ContentLength
  1558  	}
  1559  	return -1
  1560  }
  1561  
  1562  
  1563  
  1564  
  1565  
  1566  
  1567  
  1568  
  1569  func requestMethodUsuallyLacksBody(method string) bool {
  1570  	switch method {
  1571  	case "GET", "HEAD", "DELETE", "OPTIONS", "PROPFIND", "SEARCH":
  1572  		return true
  1573  	}
  1574  	return false
  1575  }
  1576  
  1577  
  1578  
  1579  func (r *Request) requiresHTTP1() bool {
  1580  	return hasToken(r.Header.Get("Connection"), "upgrade") &&
  1581  		ascii.EqualFold(r.Header.Get("Upgrade"), "websocket")
  1582  }
  1583  

View as plain text


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4