request.go 21.1 KB
Newer Older
1 2 3 4 5 6 7 8 9
// 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.

// HTTP Request reading and parsing.

package http

import (
10
	"bufio"
11
	"bytes"
12
	"crypto/tls"
13
	"encoding/base64"
14
	"errors"
15 16 17
	"fmt"
	"io"
	"io/ioutil"
18 19
	"mime"
	"mime/multipart"
20
	"net/textproto"
21
	"net/url"
22
	"strings"
23 24 25
)

const (
26 27 28 29
	maxValueLength   = 4096
	maxHeaderLines   = 1024
	chunkSize        = 4 << 10  // 4 KB chunks
	defaultMaxMemory = 32 << 20 // 32 MB
30 31
)

32 33
// ErrMissingFile is returned by FormFile when the provided file field name
// is either not present in the request or not a file field.
34
var ErrMissingFile = errors.New("http: no such file")
35

Russ Cox's avatar
Russ Cox committed
36
// HTTP request parsing errors.
Russ Cox's avatar
Russ Cox committed
37
type ProtocolError struct {
38
	ErrorString string
Russ Cox's avatar
Russ Cox committed
39
}
Russ Cox's avatar
Russ Cox committed
40

41
func (err *ProtocolError) Error() string { return err.ErrorString }
42

Russ Cox's avatar
Russ Cox committed
43
var (
44 45 46 47 48
	ErrHeaderTooLong        = &ProtocolError{"header too long"}
	ErrShortBody            = &ProtocolError{"entity body too short"}
	ErrNotSupported         = &ProtocolError{"feature not supported"}
	ErrUnexpectedTrailer    = &ProtocolError{"trailer header without chunked transfer encoding"}
	ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
49 50
	ErrNotMultipart         = &ProtocolError{"request Content-Type isn't multipart/form-data"}
	ErrMissingBoundary      = &ProtocolError{"no multipart boundary param Content-Type"}
51 52
)

Russ Cox's avatar
Russ Cox committed
53
type badStringError struct {
54 55
	what string
	str  string
Russ Cox's avatar
Russ Cox committed
56 57
}

58
func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
Russ Cox's avatar
Russ Cox committed
59

60 61
// Headers that Request.Write handles itself and should be skipped.
var reqWriteExcludeHeader = map[string]bool{
62
	"Host":              true, // not in Header map anyway
63 64 65 66
	"User-Agent":        true,
	"Content-Length":    true,
	"Transfer-Encoding": true,
	"Trailer":           true,
67
}
68

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
69 70
// A Request represents an HTTP request received by a server
// or to be sent by a client.
Russ Cox's avatar
Russ Cox committed
71
type Request struct {
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
72 73
	Method string // GET, POST, PUT, etc.
	URL    *url.URL
74 75 76

	// The protocol version for incoming requests.
	// Outgoing requests always use HTTP/1.1.
77 78 79
	Proto      string // "HTTP/1.0"
	ProtoMajor int    // 1
	ProtoMinor int    // 0
Russ Cox's avatar
Russ Cox committed
80

Russ Cox's avatar
Russ Cox committed
81
	// A header maps request lines to their values.
Russ Cox's avatar
Russ Cox committed
82 83 84
	// If the header says
	//
	//	accept-encoding: gzip, deflate
Andrew Gerrand's avatar
Andrew Gerrand committed
85
	//	Accept-Language: en-us
Russ Cox's avatar
Russ Cox committed
86 87 88 89
	//	Connection: keep-alive
	//
	// then
	//
90 91 92 93
	//	Header = map[string][]string{
	//		"Accept-Encoding": {"gzip, deflate"},
	//		"Accept-Language": {"en-us"},
	//		"Connection": {"keep-alive"},
Russ Cox's avatar
Russ Cox committed
94 95 96 97 98 99
	//	}
	//
	// HTTP defines that header names are case-insensitive.
	// The request parser implements this by canonicalizing the
	// name, making the first character and any characters
	// following a hyphen uppercase and the rest lowercase.
100
	Header Header
Russ Cox's avatar
Russ Cox committed
101

David Symonds's avatar
David Symonds committed
102
	// The message body.
103
	Body io.ReadCloser
David Symonds's avatar
David Symonds committed
104

105 106
	// ContentLength records the length of the associated content.
	// The value -1 indicates that the length is unknown.
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
107 108 109
	// Values >= 0 indicate that the given number of bytes may
	// be read from Body.
	// For outgoing requests, a value of 0 means unknown if Body is not nil.
110 111
	ContentLength int64

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
112 113 114 115 116
	// TransferEncoding lists the transfer encodings from outermost to
	// innermost. An empty list denotes the "identity" encoding.
	// TransferEncoding can usually be ignored; chunked encoding is
	// automatically added and removed as necessary when sending and
	// receiving requests.
117 118
	TransferEncoding []string

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
119 120
	// Close indicates whether to close the connection after
	// replying to this request.
121
	Close bool
Russ Cox's avatar
Russ Cox committed
122 123 124 125

	// The host on which the URL is sought.
	// Per RFC 2616, this is either the value of the Host: header
	// or the host name given in the URL itself.
126
	Host string
Russ Cox's avatar
Russ Cox committed
127

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
128 129 130 131
	// Form contains the parsed form data, including both the URL
	// field's query parameters and the POST or PUT form data.
	// This field is only available after ParseForm is called.
	// The HTTP client ignores Form and uses Body instead.
Rob Pike's avatar
Rob Pike committed
132
	Form url.Values
133

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
134 135 136
	// MultipartForm is the parsed multipart form, including file uploads.
	// This field is only available after ParseMultipartForm is called.
	// The HTTP client ignores MultipartForm and uses Body instead.
137 138
	MultipartForm *multipart.Form

139 140 141
	// Trailer maps trailer keys to values.  Like for Header, if the
	// response has multiple trailer lines with the same key, they will be
	// concatenated, delimited by commas.
142 143
	// For server requests, Trailer is only populated after Body has been
	// closed or fully consumed.
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
144
	// Trailer support is only partially complete.
145
	Trailer Header
146 147 148 149 150 151 152

	// RemoteAddr allows HTTP servers and other software to record
	// the network address that sent the request, usually for
	// logging. This field is not filled in by ReadRequest and
	// has no defined format. The HTTP server in this package
	// sets RemoteAddr to an "IP:port" address before invoking a
	// handler.
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
153
	// This field is ignored by the HTTP client.
154 155
	RemoteAddr string

156 157 158 159 160 161
	// RequestURI is the unmodified Request-URI of the
	// Request-Line (RFC 2616, Section 5.1) as sent by the client
	// to a server. Usually the URL field should be used instead.
	// It is an error to set this field in an HTTP client request.
	RequestURI string

162 163 164 165 166 167
	// TLS allows HTTP servers and other software to record
	// information about the TLS connection on which the request
	// was received. This field is not filled in by ReadRequest.
	// The HTTP server in this package sets the field for
	// TLS-enabled connections before invoking a handler;
	// otherwise it leaves the field nil.
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
168
	// This field is ignored by the HTTP client.
169
	TLS *tls.ConnectionState
170 171
}

Russ Cox's avatar
Russ Cox committed
172 173
// ProtoAtLeast returns whether the HTTP protocol used
// in the request is at least major.minor.
Russ Cox's avatar
Russ Cox committed
174 175
func (r *Request) ProtoAtLeast(major, minor int) bool {
	return r.ProtoMajor > major ||
176
		r.ProtoMajor == major && r.ProtoMinor >= minor
Russ Cox's avatar
Russ Cox committed
177 178
}

179 180 181 182 183 184 185 186 187 188
// UserAgent returns the client's User-Agent, if sent in the request.
func (r *Request) UserAgent() string {
	return r.Header.Get("User-Agent")
}

// Cookies parses and returns the HTTP cookies sent with the request.
func (r *Request) Cookies() []*Cookie {
	return readCookies(r.Header, "")
}

Russ Cox's avatar
Russ Cox committed
189
var ErrNoCookie = errors.New("http: named cookie not present")
190 191 192

// Cookie returns the named cookie provided in the request or
// ErrNoCookie if not found.
193
func (r *Request) Cookie(name string) (*Cookie, error) {
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
	for _, c := range readCookies(r.Header, name) {
		return c, nil
	}
	return nil, ErrNoCookie
}

// AddCookie adds a cookie to the request.  Per RFC 6265 section 5.4,
// AddCookie does not attach more than one Cookie header field.  That
// means all cookies, if any, are written into the same line,
// separated by semicolon.
func (r *Request) AddCookie(c *Cookie) {
	s := fmt.Sprintf("%s=%s", sanitizeName(c.Name), sanitizeValue(c.Value))
	if c := r.Header.Get("Cookie"); c != "" {
		r.Header.Set("Cookie", c+"; "+s)
	} else {
		r.Header.Set("Cookie", s)
	}
}

// Referer returns the referring URL, if sent in the request.
//
// Referer is misspelled as in the request itself, a mistake from the
// earliest days of HTTP.  This value can also be fetched from the
// Header map as Header["Referer"]; the benefit of making it available
// as a method is that the compiler can diagnose programs that use the
// alternate (correct English) spelling req.Referrer() but cannot
// diagnose programs that use Header["Referrer"].
func (r *Request) Referer() string {
	return r.Header.Get("Referer")
}

225 226 227 228 229 230 231 232
// multipartByReader is a sentinel value.
// Its presence in Request.MultipartForm indicates that parsing of the request
// body has been handed off to a MultipartReader instead of ParseMultipartFrom.
var multipartByReader = &multipart.Form{
	Value: make(map[string][]string),
	File:  make(map[string][]*multipart.FileHeader),
}

233 234
// MultipartReader returns a MIME multipart reader if this is a
// multipart/form-data POST request, else returns nil and an error.
235 236
// Use this function instead of ParseMultipartForm to
// process the request body as a stream.
237
func (r *Request) MultipartReader() (*multipart.Reader, error) {
238
	if r.MultipartForm == multipartByReader {
239
		return nil, errors.New("http: MultipartReader called twice")
240 241
	}
	if r.MultipartForm != nil {
242
		return nil, errors.New("http: multipart handled by ParseMultipartForm")
243 244 245 246 247
	}
	r.MultipartForm = multipartByReader
	return r.multipartReader()
}

248
func (r *Request) multipartReader() (*multipart.Reader, error) {
249 250
	v := r.Header.Get("Content-Type")
	if v == "" {
251 252
		return nil, ErrNotMultipart
	}
253 254
	d, params, err := mime.ParseMediaType(v)
	if err != nil || d != "multipart/form-data" {
255 256 257 258 259 260 261 262 263
		return nil, ErrNotMultipart
	}
	boundary, ok := params["boundary"]
	if !ok {
		return nil, ErrMissingBoundary
	}
	return multipart.NewReader(r.Body, boundary), nil
}

Steve Newman's avatar
Steve Newman committed
264 265 266
// Return value if nonempty, def otherwise.
func valueOrDefault(value, def string) string {
	if value != "" {
267
		return value
Steve Newman's avatar
Steve Newman committed
268
	}
269
	return def
Steve Newman's avatar
Steve Newman committed
270 271
}

Russ Cox's avatar
Russ Cox committed
272
const defaultUserAgent = "Go http package"
Steve Newman's avatar
Steve Newman committed
273

274
// Write writes an HTTP/1.1 request -- header and body -- in wire format.
275
// This method consults the following fields of the request:
276
//	Host
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
277
//	URL
278
//	Method (defaults to "GET")
279
//	Header
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
280 281
//	ContentLength
//	TransferEncoding
282 283
//	Body
//
284 285 286
// If Body is present, Content-Length is <= 0 and TransferEncoding
// hasn't been set to "identity", Write adds "Transfer-Encoding:
// chunked" to the header. Body is closed after it is sent.
287 288
func (r *Request) Write(w io.Writer) error {
	return r.write(w, false, nil)
289 290 291
}

// WriteProxy is like Write but writes the request in the form
292 293
// expected by an HTTP proxy.  In particular, WriteProxy writes the
// initial Request-URI line of the request with an absolute URI, per
294 295 296 297 298
// section 5.1.2 of RFC 2616, including the scheme and host.
// In either case, WriteProxy also writes a Host header, using
// either r.Host or r.URL.Host.
func (r *Request) WriteProxy(w io.Writer) error {
	return r.write(w, true, nil)
299 300
}

301
// extraHeaders may be nil
302
func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header) error {
303 304
	host := req.Host
	if host == "" {
305
		if req.URL == nil {
306
			return errors.New("http: Request.Write on Request with no Host or URL set")
307
		}
308 309 310
		host = req.URL.Host
	}

311 312 313
	ruri := req.URL.RequestURI()
	if usingProxy && req.URL.Scheme != "" && req.URL.Opaque == "" {
		ruri = req.URL.Scheme + "://" + host + ruri
314 315 316
	} else if req.Method == "CONNECT" && req.URL.Path == "" {
		// CONNECT requests normally give just the host and port, not a full URL.
		ruri = host
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
317
	}
318
	// TODO(bradfitz): escape at least newlines in ruri?
319

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
320
	bw := bufio.NewWriter(w)
321
	fmt.Fprintf(bw, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), ruri)
322 323

	// Header lines
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
324
	fmt.Fprintf(bw, "Host: %s\r\n", host)
325 326 327 328 329 330 331 332 333 334

	// Use the defaultUserAgent unless the Header contains one, which
	// may be blank to not send the header.
	userAgent := defaultUserAgent
	if req.Header != nil {
		if ua := req.Header["User-Agent"]; len(ua) > 0 {
			userAgent = ua[0]
		}
	}
	if userAgent != "" {
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
335
		fmt.Fprintf(bw, "User-Agent: %s\r\n", userAgent)
Steve Newman's avatar
Steve Newman committed
336 337
	}

338 339 340 341 342
	// Process Body,ContentLength,Close,Trailer
	tw, err := newTransferWriter(req)
	if err != nil {
		return err
	}
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
343
	err = tw.WriteHeader(bw)
344 345
	if err != nil {
		return err
346 347
	}

Steve Newman's avatar
Steve Newman committed
348
	// TODO: split long values?  (If so, should share code with Conn.Write)
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
349
	err = req.Header.WriteSubset(bw, reqWriteExcludeHeader)
350 351 352
	if err != nil {
		return err
	}
Steve Newman's avatar
Steve Newman committed
353

354 355 356 357 358 359 360
	if extraHeaders != nil {
		err = extraHeaders.Write(bw)
		if err != nil {
			return err
		}
	}

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
361
	io.WriteString(bw, "\r\n")
Steve Newman's avatar
Steve Newman committed
362

363
	// Write body and trailer
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
364
	err = tw.WriteBody(bw)
365 366
	if err != nil {
		return err
Steve Newman's avatar
Steve Newman committed
367
	}
368 369

	return bw.Flush()
Steve Newman's avatar
Steve Newman committed
370 371
}

372 373 374 375
// Convert decimal at s[i:len(s)] to integer,
// returning value, string position where the digits stopped,
// and whether there was a valid number (digits, not too big).
func atoi(s string, i int) (n, i1 int, ok bool) {
376
	const Big = 1000000
377
	if i >= len(s) || s[i] < '0' || s[i] > '9' {
378
		return 0, 0, false
379
	}
380
	n = 0
381
	for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
382
		n = n*10 + int(s[i]-'0')
383
		if n > Big {
384
			return 0, 0, false
385 386
		}
	}
387
	return n, i, true
388 389
}

David Symonds's avatar
David Symonds committed
390
// ParseHTTPVersion parses a HTTP version string.
391
// "HTTP/1.0" returns (1, 0, true).
David Symonds's avatar
David Symonds committed
392
func ParseHTTPVersion(vers string) (major, minor int, ok bool) {
393
	if len(vers) < 5 || vers[0:5] != "HTTP/" {
394
		return 0, 0, false
395
	}
396
	major, i, ok := atoi(vers, 5)
397
	if !ok || i >= len(vers) || vers[i] != '.' {
398
		return 0, 0, false
399
	}
400
	minor, i, ok = atoi(vers, i+1)
401
	if !ok || i != len(vers) {
402
		return 0, 0, false
403
	}
404
	return major, minor, true
405 406
}

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
407
// NewRequest returns a new Request given a method, URL, and optional body.
408
func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
Rob Pike's avatar
Rob Pike committed
409
	u, err := url.Parse(urlStr)
Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
	if err != nil {
		return nil, err
	}
	rc, ok := body.(io.ReadCloser)
	if !ok && body != nil {
		rc = ioutil.NopCloser(body)
	}
	req := &Request{
		Method:     method,
		URL:        u,
		Proto:      "HTTP/1.1",
		ProtoMajor: 1,
		ProtoMinor: 1,
		Header:     make(Header),
		Body:       rc,
		Host:       u.Host,
	}
427 428 429 430 431 432
	if body != nil {
		switch v := body.(type) {
		case *strings.Reader:
			req.ContentLength = int64(v.Len())
		case *bytes.Buffer:
			req.ContentLength = int64(v.Len())
433
		}
434 435
	}

Brad Fitzpatrick's avatar
Brad Fitzpatrick committed
436 437 438
	return req, nil
}

439 440 441 442 443 444 445
// SetBasicAuth sets the request's Authorization header to use HTTP
// Basic Authentication with the provided username and password.
//
// With HTTP Basic Authentication the provided username and password
// are not encrypted.
func (r *Request) SetBasicAuth(username, password string) {
	s := username + ":" + password
446
	r.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(s)))
447 448
}

Russ Cox's avatar
Russ Cox committed
449
// ReadRequest reads and parses a request from b.
450
func ReadRequest(b *bufio.Reader) (req *Request, err error) {
451 452

	tp := textproto.NewReader(b)
453
	req = new(Request)
454 455

	// First line: GET /index.html HTTP/1.0
456
	var s string
457
	if s, err = tp.ReadLine(); err != nil {
458 459 460
		return nil, err
	}
	defer func() {
461
		if err == io.EOF {
462 463
			err = io.ErrUnexpectedEOF
		}
464
	}()
465

466
	var f []string
467
	if f = strings.SplitN(s, " ", 3); len(f) < 3 {
468
		return nil, &badStringError{"malformed HTTP request", s}
469
	}
470 471
	req.Method, req.RequestURI, req.Proto = f[0], f[1], f[2]
	rawurl := req.RequestURI
472
	var ok bool
David Symonds's avatar
David Symonds committed
473
	if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok {
474
		return nil, &badStringError{"malformed HTTP version", req.Proto}
475 476
	}

477 478 479 480 481 482 483 484 485 486 487 488 489 490
	// CONNECT requests are used two different ways, and neither uses a full URL:
	// The standard use is to tunnel HTTPS through an HTTP proxy.
	// It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is
	// just the authority section of a URL. This information should go in req.URL.Host.
	//
	// The net/rpc package also uses CONNECT, but there the parameter is a path
	// that starts with a slash. It can be parsed with the regular URL parser,
	// and the path will end up in req.URL.Path, where it needs to be in order for
	// RPC to work.
	justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/")
	if justAuthority {
		rawurl = "http://" + rawurl
	}

Russ Cox's avatar
Russ Cox committed
491
	if req.URL, err = url.ParseRequestURI(rawurl); err != nil {
Russ Cox's avatar
Russ Cox committed
492
		return nil, err
493 494
	}

495 496 497 498 499
	if justAuthority {
		// Strip the bogus "http://" back off.
		req.URL.Scheme = ""
	}

500
	// Subsequent lines: Key: value.
501 502 503
	mimeHeader, err := tp.ReadMIMEHeader()
	if err != nil {
		return nil, err
504
	}
505
	req.Header = Header(mimeHeader)
506 507 508 509 510 511 512 513

	// RFC2616: Must treat
	//	GET /index.html HTTP/1.1
	//	Host: www.google.com
	// and
	//	GET http://www.google.com/index.html HTTP/1.1
	//	Host: doesntmatter
	// the same.  In the second case, any Host line is ignored.
Russ Cox's avatar
Russ Cox committed
514
	req.Host = req.URL.Host
515
	if req.Host == "" {
516
		req.Host = req.Header.Get("Host")
517
	}
518
	req.Header.Del("Host")
519

520
	fixPragmaCacheControl(req.Header)
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547

	// TODO: Parse specific header values:
	//	Accept
	//	Accept-Encoding
	//	Accept-Language
	//	Authorization
	//	Cache-Control
	//	Connection
	//	Date
	//	Expect
	//	From
	//	If-Match
	//	If-Modified-Since
	//	If-None-Match
	//	If-Range
	//	If-Unmodified-Since
	//	Max-Forwards
	//	Proxy-Authorization
	//	Referer [sic]
	//	TE (transfer-codings)
	//	Trailer
	//	Transfer-Encoding
	//	Upgrade
	//	User-Agent
	//	Via
	//	Warning

548 549 550
	err = readTransfer(req, b)
	if err != nil {
		return nil, err
David Symonds's avatar
David Symonds committed
551 552
	}

553
	return req, nil
554
}
555

556
// MaxBytesReader is similar to io.LimitReader but is intended for
557
// limiting the size of incoming request bodies. In contrast to
558 559 560 561 562 563
// io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a
// non-EOF error for a Read beyond the limit, and Closes the
// underlying reader when its Close method is called.
//
// MaxBytesReader prevents clients from accidentally or maliciously
// sending a large request and wasting server resources.
564 565 566 567 568 569 570 571 572 573 574
func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser {
	return &maxBytesReader{w: w, r: r, n: n}
}

type maxBytesReader struct {
	w       ResponseWriter
	r       io.ReadCloser // underlying reader
	n       int64         // max bytes remaining
	stopped bool
}

575
func (l *maxBytesReader) Read(p []byte) (n int, err error) {
576 577 578 579 580 581 582
	if l.n <= 0 {
		if !l.stopped {
			l.stopped = true
			if res, ok := l.w.(*response); ok {
				res.requestTooLarge()
			}
		}
583
		return 0, errors.New("http: request body too large")
584 585 586 587 588 589 590 591 592
	}
	if int64(len(p)) > l.n {
		p = p[:l.n]
	}
	n, err = l.r.Read(p)
	l.n -= int64(n)
	return
}

593
func (l *maxBytesReader) Close() error {
594 595 596 597 598 599 600 601 602
	return l.r.Close()
}

// ParseForm parses the raw query from the URL.
//
// For POST or PUT requests, it also parses the request body as a form.
// If the request Body's size has not already been limited by MaxBytesReader,
// the size is capped at 10MB.
//
603
// ParseMultipartForm calls ParseForm automatically.
604
// It is idempotent.
605
func (r *Request) ParseForm() (err error) {
606
	if r.Form != nil {
607
		return
608
	}
609
	if r.URL != nil {
Rob Pike's avatar
Rob Pike committed
610
		r.Form, err = url.ParseQuery(r.URL.RawQuery)
611
	}
612
	if r.Method == "POST" || r.Method == "PUT" {
613
		if r.Body == nil {
614
			return errors.New("missing form body")
615
		}
616
		ct := r.Header.Get("Content-Type")
617
		ct, _, err = mime.ParseMediaType(ct)
618
		switch {
619
		case ct == "application/x-www-form-urlencoded":
620
			var reader io.Reader = r.Body
621
			maxFormSize := int64(1<<63 - 1)
622 623 624 625 626
			if _, ok := r.Body.(*maxBytesReader); !ok {
				maxFormSize = int64(10 << 20) // 10 MB is a lot of text.
				reader = io.LimitReader(r.Body, maxFormSize+1)
			}
			b, e := ioutil.ReadAll(reader)
627 628 629 630 631 632
			if e != nil {
				if err == nil {
					err = e
				}
				break
			}
633
			if int64(len(b)) > maxFormSize {
634
				return errors.New("http: POST too large")
635
			}
Rob Pike's avatar
Rob Pike committed
636 637
			var newValues url.Values
			newValues, e = url.ParseQuery(string(b))
638 639
			if err == nil {
				err = e
640
			}
641 642 643
			if r.Form == nil {
				r.Form = make(url.Values)
			}
Rob Pike's avatar
Rob Pike committed
644 645 646 647 648 649
			// Copy values into r.Form. TODO: make this smoother.
			for k, vs := range newValues {
				for _, value := range vs {
					r.Form.Add(k, value)
				}
			}
650 651 652 653 654 655 656
		case ct == "multipart/form-data":
			// handled by ParseMultipartForm (which is calling us, or should be)
			// TODO(bradfitz): there are too many possible
			// orders to call too many functions here.
			// Clean this up and write more tests.
			// request_test.go contains the start of this,
			// in TestRequestMultipartCallOrder.
657 658
		}
	}
659
	return err
660 661
}

662 663 664 665 666 667
// ParseMultipartForm parses a request body as multipart/form-data.
// The whole request body is parsed and up to a total of maxMemory bytes of
// its file parts are stored in memory, with the remainder stored on
// disk in temporary files.
// ParseMultipartForm calls ParseForm if necessary.
// After one call to ParseMultipartForm, subsequent calls have no effect.
668
func (r *Request) ParseMultipartForm(maxMemory int64) error {
669
	if r.MultipartForm == multipartByReader {
670
		return errors.New("http: multipart handled by MultipartReader")
671
	}
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
	if r.Form == nil {
		err := r.ParseForm()
		if err != nil {
			return err
		}
	}
	if r.MultipartForm != nil {
		return nil
	}

	mr, err := r.multipartReader()
	if err == ErrNotMultipart {
		return nil
	} else if err != nil {
		return err
	}

	f, err := mr.ReadForm(maxMemory)
	if err != nil {
		return err
	}
	for k, v := range f.Value {
		r.Form[k] = append(r.Form[k], v...)
	}
	r.MultipartForm = f

	return nil
}

701
// FormValue returns the first value for the named component of the query.
702
// FormValue calls ParseMultipartForm and ParseForm if necessary.
703 704
func (r *Request) FormValue(key string) string {
	if r.Form == nil {
705
		r.ParseMultipartForm(defaultMaxMemory)
706
	}
707
	if vs := r.Form[key]; len(vs) > 0 {
708
		return vs[0]
709
	}
710
	return ""
711
}
712

713 714
// FormFile returns the first file for the provided form key.
// FormFile calls ParseMultipartForm and ParseForm if necessary.
715
func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
716
	if r.MultipartForm == multipartByReader {
717
		return nil, nil, errors.New("http: multipart handled by MultipartReader")
718 719 720 721 722 723 724
	}
	if r.MultipartForm == nil {
		err := r.ParseMultipartForm(defaultMaxMemory)
		if err != nil {
			return nil, nil, err
		}
	}
725 726 727 728 729
	if r.MultipartForm != nil && r.MultipartForm.File != nil {
		if fhs := r.MultipartForm.File[key]; len(fhs) > 0 {
			f, err := fhs[0].Open()
			return f, fhs[0], err
		}
730 731 732 733
	}
	return nil, nil, ErrMissingFile
}

734
func (r *Request) expectsContinue() bool {
735
	return hasToken(r.Header.Get("Expect"), "100-continue")
736
}
737 738 739 740 741

func (r *Request) wantsHttp10KeepAlive() bool {
	if r.ProtoMajor != 1 || r.ProtoMinor != 0 {
		return false
	}
742 743 744 745 746 747 748 749 750 751 752 753 754
	return hasToken(r.Header.Get("Connection"), "keep-alive")
}

func (r *Request) wantsClose() bool {
	return hasToken(r.Header.Get("Connection"), "close")
}

func hasToken(s, token string) bool {
	if s == "" {
		return false
	}
	// TODO This is a poor implementation of the RFC. See http://golang.org/issue/3535
	return strings.Contains(strings.ToLower(s), token)
755
}