chunked.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // Taken from $GOROOT/src/pkg/net/http/chunked
  2. // needed to write https responses to client.
  3. package goproxy
  4. import (
  5. "io"
  6. "strconv"
  7. )
  8. // newChunkedWriter returns a new chunkedWriter that translates writes into HTTP
  9. // "chunked" format before writing them to w. Closing the returned chunkedWriter
  10. // sends the final 0-length chunk that marks the end of the stream.
  11. //
  12. // newChunkedWriter is not needed by normal applications. The http
  13. // package adds chunking automatically if handlers don't set a
  14. // Content-Length header. Using newChunkedWriter inside a handler
  15. // would result in double chunking or chunking with a Content-Length
  16. // length, both of which are wrong.
  17. func newChunkedWriter(w io.Writer) io.WriteCloser {
  18. return &chunkedWriter{w}
  19. }
  20. // Writing to chunkedWriter translates to writing in HTTP chunked Transfer
  21. // Encoding wire format to the underlying Wire chunkedWriter.
  22. type chunkedWriter struct {
  23. Wire io.Writer
  24. }
  25. // Write the contents of data as one chunk to Wire.
  26. // NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has
  27. // a bug since it does not check for success of io.WriteString
  28. func (cw *chunkedWriter) Write(data []byte) (n int, err error) {
  29. // Don't send 0-length data. It looks like EOF for chunked encoding.
  30. if len(data) == 0 {
  31. return 0, nil
  32. }
  33. head := strconv.FormatInt(int64(len(data)), 16) + "\r\n"
  34. if _, err = io.WriteString(cw.Wire, head); err != nil {
  35. return 0, err
  36. }
  37. if n, err = cw.Wire.Write(data); err != nil {
  38. return
  39. }
  40. if n != len(data) {
  41. err = io.ErrShortWrite
  42. return
  43. }
  44. _, err = io.WriteString(cw.Wire, "\r\n")
  45. return
  46. }
  47. func (cw *chunkedWriter) Close() error {
  48. _, err := io.WriteString(cw.Wire, "0\r\n")
  49. return err
  50. }