()
| 838 | var errTrailerEOF = errors.New("http: unexpected EOF reading trailer") |
| 839 | |
| 840 | func (b *body) readTrailer() error { |
| 841 | // The common case, since nobody uses trailers. |
| 842 | buf, err := b.r.Peek(2) |
| 843 | if bytes.Equal(buf, singleCRLF) { |
| 844 | b.r.Discard(2) |
| 845 | return nil |
| 846 | } |
| 847 | if len(buf) < 2 { |
| 848 | return errTrailerEOF |
| 849 | } |
| 850 | if err != nil { |
| 851 | return err |
| 852 | } |
| 853 | |
| 854 | // Make sure there's a header terminator coming up, to prevent |
| 855 | // a DoS with an unbounded size Trailer. It's not easy to |
| 856 | // slip in a LimitReader here, as textproto.NewReader requires |
| 857 | // a concrete *bufio.textprotoReader. Also, we can't get all the way |
| 858 | // back up to our conn's LimitedReader that *might* be backing |
| 859 | // this bufio.textprotoReader. Instead, a hack: we iteratively Peek up |
| 860 | // to the bufio.textprotoReader's max size, looking for a double CRLF. |
| 861 | // This limits the trailer to the underlying buffer size, typically 4kB. |
| 862 | if !seeUpcomingDoubleCRLF(b.r) { |
| 863 | return errors.New("http: suspiciously long trailer after chunked body") |
| 864 | } |
| 865 | |
| 866 | hdr, err := textproto.NewReader(b.r).ReadMIMEHeader() |
| 867 | if err != nil { |
| 868 | if err == io.EOF { |
| 869 | return errTrailerEOF |
| 870 | } |
| 871 | return err |
| 872 | } |
| 873 | switch rr := b.hdr.(type) { |
| 874 | case *http.Request: |
| 875 | mergeSetHeader(&rr.Trailer, http.Header(hdr)) |
| 876 | case *http.Response: |
| 877 | mergeSetHeader(&rr.Trailer, http.Header(hdr)) |
| 878 | } |
| 879 | return nil |
| 880 | } |
| 881 | |
| 882 | func mergeSetHeader(dst *http.Header, src http.Header) { |
| 883 | if *dst == nil { |
no test coverage detected