~ubuntu-branches/ubuntu/saucy/golang/saucy

« back to all changes in this revision

Viewing changes to src/pkg/net/http/request.go

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2013-07-08 05:52:37 UTC
  • mfrom: (29.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20130708055237-at01839e0hp8z3ni
Tags: 2:1.1-1ubuntu1
016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
        "mime/multipart"
20
20
        "net/textproto"
21
21
        "net/url"
 
22
        "strconv"
22
23
        "strings"
23
24
)
24
25
 
47
48
        ErrUnexpectedTrailer    = &ProtocolError{"trailer header without chunked transfer encoding"}
48
49
        ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
49
50
        ErrNotMultipart         = &ProtocolError{"request Content-Type isn't multipart/form-data"}
50
 
        ErrMissingBoundary      = &ProtocolError{"no multipart boundary param Content-Type"}
 
51
        ErrMissingBoundary      = &ProtocolError{"no multipart boundary param in Content-Type"}
51
52
)
52
53
 
53
54
type badStringError struct {
70
71
// or to be sent by a client.
71
72
type Request struct {
72
73
        Method string // GET, POST, PUT, etc.
73
 
        URL    *url.URL
 
74
 
 
75
        // URL is created from the URI supplied on the Request-Line
 
76
        // as stored in RequestURI.
 
77
        //
 
78
        // For most requests, fields other than Path and RawQuery
 
79
        // will be empty. (See RFC 2616, Section 5.1.2)
 
80
        URL *url.URL
74
81
 
75
82
        // The protocol version for incoming requests.
76
83
        // Outgoing requests always use HTTP/1.1.
123
130
        // The host on which the URL is sought.
124
131
        // Per RFC 2616, this is either the value of the Host: header
125
132
        // or the host name given in the URL itself.
 
133
        // It may be of the form "host:port".
126
134
        Host string
127
135
 
128
136
        // Form contains the parsed form data, including both the URL
131
139
        // The HTTP client ignores Form and uses Body instead.
132
140
        Form url.Values
133
141
 
 
142
        // PostForm contains the parsed form data from POST or PUT
 
143
        // body parameters.
 
144
        // This field is only available after ParseForm is called.
 
145
        // The HTTP client ignores PostForm and uses Body instead.
 
146
        PostForm url.Values
 
147
 
134
148
        // MultipartForm is the parsed multipart form, including file uploads.
135
149
        // This field is only available after ParseMultipartForm is called.
136
150
        // The HTTP client ignores MultipartForm and uses Body instead.
269
283
        return def
270
284
}
271
285
 
272
 
const defaultUserAgent = "Go http package"
 
286
const defaultUserAgent = "Go 1.1 package http"
273
287
 
274
288
// Write writes an HTTP/1.1 request -- header and body -- in wire format.
275
289
// This method consults the following fields of the request:
317
331
        }
318
332
        // TODO(bradfitz): escape at least newlines in ruri?
319
333
 
320
 
        bw := bufio.NewWriter(w)
321
 
        fmt.Fprintf(bw, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), ruri)
 
334
        // Wrap the writer in a bufio Writer if it's not already buffered.
 
335
        // Don't always call NewWriter, as that forces a bytes.Buffer
 
336
        // and other small bufio Writers to have a minimum 4k buffer
 
337
        // size.
 
338
        var bw *bufio.Writer
 
339
        if _, ok := w.(io.ByteWriter); !ok {
 
340
                bw = bufio.NewWriter(w)
 
341
                w = bw
 
342
        }
 
343
 
 
344
        fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), ruri)
322
345
 
323
346
        // Header lines
324
 
        fmt.Fprintf(bw, "Host: %s\r\n", host)
 
347
        fmt.Fprintf(w, "Host: %s\r\n", host)
325
348
 
326
349
        // Use the defaultUserAgent unless the Header contains one, which
327
350
        // may be blank to not send the header.
332
355
                }
333
356
        }
334
357
        if userAgent != "" {
335
 
                fmt.Fprintf(bw, "User-Agent: %s\r\n", userAgent)
 
358
                fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent)
336
359
        }
337
360
 
338
361
        // Process Body,ContentLength,Close,Trailer
340
363
        if err != nil {
341
364
                return err
342
365
        }
343
 
        err = tw.WriteHeader(bw)
 
366
        err = tw.WriteHeader(w)
344
367
        if err != nil {
345
368
                return err
346
369
        }
347
370
 
348
371
        // TODO: split long values?  (If so, should share code with Conn.Write)
349
 
        err = req.Header.WriteSubset(bw, reqWriteExcludeHeader)
 
372
        err = req.Header.WriteSubset(w, reqWriteExcludeHeader)
350
373
        if err != nil {
351
374
                return err
352
375
        }
353
376
 
354
377
        if extraHeaders != nil {
355
 
                err = extraHeaders.Write(bw)
 
378
                err = extraHeaders.Write(w)
356
379
                if err != nil {
357
380
                        return err
358
381
                }
359
382
        }
360
383
 
361
 
        io.WriteString(bw, "\r\n")
 
384
        io.WriteString(w, "\r\n")
362
385
 
363
386
        // Write body and trailer
364
 
        err = tw.WriteBody(bw)
 
387
        err = tw.WriteBody(w)
365
388
        if err != nil {
366
389
                return err
367
390
        }
368
391
 
369
 
        return bw.Flush()
370
 
}
371
 
 
372
 
// Convert decimal at s[i:len(s)] to integer,
373
 
// returning value, string position where the digits stopped,
374
 
// and whether there was a valid number (digits, not too big).
375
 
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
 
392
        if bw != nil {
 
393
                return bw.Flush()
 
394
        }
 
395
        return nil
388
396
}
389
397
 
390
398
// ParseHTTPVersion parses a HTTP version string.
391
399
// "HTTP/1.0" returns (1, 0, true).
392
400
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) {
 
401
        const Big = 1000000 // arbitrary upper bound
 
402
        switch vers {
 
403
        case "HTTP/1.1":
 
404
                return 1, 1, true
 
405
        case "HTTP/1.0":
 
406
                return 1, 0, true
 
407
        }
 
408
        if !strings.HasPrefix(vers, "HTTP/") {
 
409
                return 0, 0, false
 
410
        }
 
411
        dot := strings.Index(vers, ".")
 
412
        if dot < 0 {
 
413
                return 0, 0, false
 
414
        }
 
415
        major, err := strconv.Atoi(vers[5:dot])
 
416
        if err != nil || major < 0 || major > Big {
 
417
                return 0, 0, false
 
418
        }
 
419
        minor, err = strconv.Atoi(vers[dot+1:])
 
420
        if err != nil || minor < 0 || minor > Big {
402
421
                return 0, 0, false
403
422
        }
404
423
        return major, minor, true
426
445
        }
427
446
        if body != nil {
428
447
                switch v := body.(type) {
 
448
                case *bytes.Buffer:
 
449
                        req.ContentLength = int64(v.Len())
 
450
                case *bytes.Reader:
 
451
                        req.ContentLength = int64(v.Len())
429
452
                case *strings.Reader:
430
453
                        req.ContentLength = int64(v.Len())
431
 
                case *bytes.Buffer:
432
 
                        req.ContentLength = int64(v.Len())
433
454
                }
434
455
        }
435
456
 
446
467
        r.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(s)))
447
468
}
448
469
 
 
470
// parseRequestLine parses "GET /foo HTTP/1.1" into its three parts.
 
471
func parseRequestLine(line string) (method, requestURI, proto string, ok bool) {
 
472
        s1 := strings.Index(line, " ")
 
473
        s2 := strings.Index(line[s1+1:], " ")
 
474
        if s1 < 0 || s2 < 0 {
 
475
                return
 
476
        }
 
477
        s2 += s1 + 1
 
478
        return line[:s1], line[s1+1 : s2], line[s2+1:], true
 
479
}
 
480
 
 
481
// TODO(bradfitz): use a sync.Cache when available
 
482
var textprotoReaderCache = make(chan *textproto.Reader, 4)
 
483
 
 
484
func newTextprotoReader(br *bufio.Reader) *textproto.Reader {
 
485
        select {
 
486
        case r := <-textprotoReaderCache:
 
487
                r.R = br
 
488
                return r
 
489
        default:
 
490
                return textproto.NewReader(br)
 
491
        }
 
492
}
 
493
 
 
494
func putTextprotoReader(r *textproto.Reader) {
 
495
        r.R = nil
 
496
        select {
 
497
        case textprotoReaderCache <- r:
 
498
        default:
 
499
        }
 
500
}
 
501
 
449
502
// ReadRequest reads and parses a request from b.
450
503
func ReadRequest(b *bufio.Reader) (req *Request, err error) {
451
504
 
452
 
        tp := textproto.NewReader(b)
 
505
        tp := newTextprotoReader(b)
453
506
        req = new(Request)
454
507
 
455
508
        // First line: GET /index.html HTTP/1.0
458
511
                return nil, err
459
512
        }
460
513
        defer func() {
 
514
                putTextprotoReader(tp)
461
515
                if err == io.EOF {
462
516
                        err = io.ErrUnexpectedEOF
463
517
                }
464
518
        }()
465
519
 
466
 
        var f []string
467
 
        if f = strings.SplitN(s, " ", 3); len(f) < 3 {
 
520
        var ok bool
 
521
        req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s)
 
522
        if !ok {
468
523
                return nil, &badStringError{"malformed HTTP request", s}
469
524
        }
470
 
        req.Method, req.RequestURI, req.Proto = f[0], f[1], f[2]
471
525
        rawurl := req.RequestURI
472
 
        var ok bool
473
526
        if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok {
474
527
                return nil, &badStringError{"malformed HTTP version", req.Proto}
475
528
        }
513
566
        // the same.  In the second case, any Host line is ignored.
514
567
        req.Host = req.URL.Host
515
568
        if req.Host == "" {
516
 
                req.Host = req.Header.Get("Host")
 
569
                req.Host = req.Header.get("Host")
517
570
        }
518
 
        req.Header.Del("Host")
 
571
        delete(req.Header, "Host")
519
572
 
520
573
        fixPragmaCacheControl(req.Header)
521
574
 
594
647
        return l.r.Close()
595
648
}
596
649
 
597
 
// ParseForm parses the raw query from the URL.
598
 
//
599
 
// For POST or PUT requests, it also parses the request body as a form.
 
650
func copyValues(dst, src url.Values) {
 
651
        for k, vs := range src {
 
652
                for _, value := range vs {
 
653
                        dst.Add(k, value)
 
654
                }
 
655
        }
 
656
}
 
657
 
 
658
func parsePostForm(r *Request) (vs url.Values, err error) {
 
659
        if r.Body == nil {
 
660
                err = errors.New("missing form body")
 
661
                return
 
662
        }
 
663
        ct := r.Header.Get("Content-Type")
 
664
        ct, _, err = mime.ParseMediaType(ct)
 
665
        switch {
 
666
        case ct == "application/x-www-form-urlencoded":
 
667
                var reader io.Reader = r.Body
 
668
                maxFormSize := int64(1<<63 - 1)
 
669
                if _, ok := r.Body.(*maxBytesReader); !ok {
 
670
                        maxFormSize = int64(10 << 20) // 10 MB is a lot of text.
 
671
                        reader = io.LimitReader(r.Body, maxFormSize+1)
 
672
                }
 
673
                b, e := ioutil.ReadAll(reader)
 
674
                if e != nil {
 
675
                        if err == nil {
 
676
                                err = e
 
677
                        }
 
678
                        break
 
679
                }
 
680
                if int64(len(b)) > maxFormSize {
 
681
                        err = errors.New("http: POST too large")
 
682
                        return
 
683
                }
 
684
                vs, e = url.ParseQuery(string(b))
 
685
                if err == nil {
 
686
                        err = e
 
687
                }
 
688
        case ct == "multipart/form-data":
 
689
                // handled by ParseMultipartForm (which is calling us, or should be)
 
690
                // TODO(bradfitz): there are too many possible
 
691
                // orders to call too many functions here.
 
692
                // Clean this up and write more tests.
 
693
                // request_test.go contains the start of this,
 
694
                // in TestRequestMultipartCallOrder.
 
695
        }
 
696
        return
 
697
}
 
698
 
 
699
// ParseForm parses the raw query from the URL and updates r.Form.
 
700
//
 
701
// For POST or PUT requests, it also parses the request body as a form and
 
702
// put the results into both r.PostForm and r.Form.
 
703
// POST and PUT body parameters take precedence over URL query string values
 
704
// in r.Form.
 
705
//
600
706
// If the request Body's size has not already been limited by MaxBytesReader,
601
707
// the size is capped at 10MB.
602
708
//
603
709
// ParseMultipartForm calls ParseForm automatically.
604
710
// It is idempotent.
605
 
func (r *Request) ParseForm() (err error) {
606
 
        if r.Form != nil {
607
 
                return
608
 
        }
609
 
        if r.URL != nil {
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
 
                        if _, ok := r.Body.(*maxBytesReader); !ok {
623
 
                                maxFormSize = int64(10 << 20) // 10 MB is a lot of text.
624
 
                                reader = io.LimitReader(r.Body, maxFormSize+1)
625
 
                        }
626
 
                        b, e := ioutil.ReadAll(reader)
627
 
                        if e != nil {
628
 
                                if err == nil {
629
 
                                        err = e
630
 
                                }
631
 
                                break
632
 
                        }
633
 
                        if int64(len(b)) > maxFormSize {
634
 
                                return errors.New("http: POST too large")
635
 
                        }
636
 
                        var newValues url.Values
637
 
                        newValues, e = url.ParseQuery(string(b))
 
711
func (r *Request) ParseForm() error {
 
712
        var err error
 
713
        if r.PostForm == nil {
 
714
                if r.Method == "POST" || r.Method == "PUT" {
 
715
                        r.PostForm, err = parsePostForm(r)
 
716
                }
 
717
                if r.PostForm == nil {
 
718
                        r.PostForm = make(url.Values)
 
719
                }
 
720
        }
 
721
        if r.Form == nil {
 
722
                if len(r.PostForm) > 0 {
 
723
                        r.Form = make(url.Values)
 
724
                        copyValues(r.Form, r.PostForm)
 
725
                }
 
726
                var newValues url.Values
 
727
                if r.URL != nil {
 
728
                        var e error
 
729
                        newValues, e = url.ParseQuery(r.URL.RawQuery)
638
730
                        if err == nil {
639
731
                                err = e
640
732
                        }
641
 
                        if r.Form == nil {
642
 
                                r.Form = make(url.Values)
643
 
                        }
644
 
                        // Copy values into r.Form. TODO: make this smoother.
645
 
                        for k, vs := range newValues {
646
 
                                for _, value := range vs {
647
 
                                        r.Form.Add(k, value)
648
 
                                }
649
 
                        }
650
 
                case ct == "multipart/form-data":
651
 
                        // handled by ParseMultipartForm (which is calling us, or should be)
652
 
                        // TODO(bradfitz): there are too many possible
653
 
                        // orders to call too many functions here.
654
 
                        // Clean this up and write more tests.
655
 
                        // request_test.go contains the start of this,
656
 
                        // in TestRequestMultipartCallOrder.
 
733
                }
 
734
                if newValues == nil {
 
735
                        newValues = make(url.Values)
 
736
                }
 
737
                if r.Form == nil {
 
738
                        r.Form = newValues
 
739
                } else {
 
740
                        copyValues(r.Form, newValues)
657
741
                }
658
742
        }
659
743
        return err
699
783
}
700
784
 
701
785
// FormValue returns the first value for the named component of the query.
 
786
// POST and PUT body parameters take precedence over URL query string values.
702
787
// FormValue calls ParseMultipartForm and ParseForm if necessary.
 
788
// To access multiple values of the same key use ParseForm.
703
789
func (r *Request) FormValue(key string) string {
704
790
        if r.Form == nil {
705
791
                r.ParseMultipartForm(defaultMaxMemory)
710
796
        return ""
711
797
}
712
798
 
 
799
// PostFormValue returns the first value for the named component of the POST
 
800
// or PUT request body. URL query parameters are ignored.
 
801
// PostFormValue calls ParseMultipartForm and ParseForm if necessary.
 
802
func (r *Request) PostFormValue(key string) string {
 
803
        if r.PostForm == nil {
 
804
                r.ParseMultipartForm(defaultMaxMemory)
 
805
        }
 
806
        if vs := r.PostForm[key]; len(vs) > 0 {
 
807
                return vs[0]
 
808
        }
 
809
        return ""
 
810
}
 
811
 
713
812
// FormFile returns the first file for the provided form key.
714
813
// FormFile calls ParseMultipartForm and ParseForm if necessary.
715
814
func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
732
831
}
733
832
 
734
833
func (r *Request) expectsContinue() bool {
735
 
        return strings.ToLower(r.Header.Get("Expect")) == "100-continue"
 
834
        return hasToken(r.Header.get("Expect"), "100-continue")
736
835
}
737
836
 
738
837
func (r *Request) wantsHttp10KeepAlive() bool {
739
838
        if r.ProtoMajor != 1 || r.ProtoMinor != 0 {
740
839
                return false
741
840
        }
742
 
        return strings.Contains(strings.ToLower(r.Header.Get("Connection")), "keep-alive")
 
841
        return hasToken(r.Header.get("Connection"), "keep-alive")
 
842
}
 
843
 
 
844
func (r *Request) wantsClose() bool {
 
845
        return hasToken(r.Header.get("Connection"), "close")
743
846
}