Must hold b.mu.
(p []byte)
| 768 | |
| 769 | // Must hold b.mu. |
| 770 | func (b *body) readLocked(p []byte) (n int, err error) { |
| 771 | if b.sawEOF { |
| 772 | return 0, io.EOF |
| 773 | } |
| 774 | n, err = b.src.Read(p) |
| 775 | |
| 776 | if err == io.EOF { |
| 777 | b.sawEOF = true |
| 778 | // Chunked case. Read the trailer. |
| 779 | if b.hdr != nil { |
| 780 | if e := b.readTrailer(); e != nil { |
| 781 | err = e |
| 782 | // Something went wrong in the trailer, we must not allow any |
| 783 | // further reads of any kind to succeed from body, nor any |
| 784 | // subsequent requests on the server connection. See |
| 785 | // golang.org/issue/12027 |
| 786 | b.sawEOF = false |
| 787 | b.closed = true |
| 788 | } |
| 789 | b.hdr = nil |
| 790 | } else { |
| 791 | // If the server declared the Content-Length, our body is a LimitedReader |
| 792 | // and we need to check whether this EOF arrived early. |
| 793 | if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 0 { |
| 794 | err = io.ErrUnexpectedEOF |
| 795 | } |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | // If we can return an EOF here along with the read data, do |
| 800 | // so. This is optional per the io.textprotoReader contract, but doing |
| 801 | // so helps the HTTP transport code recycle its connection |
| 802 | // earlier (since it will see this EOF itself), even if the |
| 803 | // client doesn't do future reads or Close. |
| 804 | if err == nil && n > 0 { |
| 805 | if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 { |
| 806 | err = io.EOF |
| 807 | b.sawEOF = true |
| 808 | } |
| 809 | } |
| 810 | |
| 811 | if b.sawEOF && b.onHitEOF != nil { |
| 812 | b.onHitEOF() |
| 813 | } |
| 814 | |
| 815 | return n, err |
| 816 | } |
| 817 | |
| 818 | var ( |
| 819 | singleCRLF = []byte("\r\n") |
no test coverage detected