The Go Programming Language

Source file src/pkg/http/chunked.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package http
     6	
     7	import (
     8		"io"
     9		"log"
    10		"os"
    11		"strconv"
    12		"bufio"
    13	)
    14	
    15	// NewChunkedWriter returns a new writer that translates writes into HTTP
    16	// "chunked" format before writing them to w. Closing the returned writer
    17	// sends the final 0-length chunk that marks the end of the stream.
    18	//
    19	// NewChunkedWriter is not needed by normal applications. The http
    20	// package adds chunking automatically if handlers don't set a
    21	// Content-Length header. Using NewChunkedWriter inside a handler
    22	// would result in double chunking or chunking with a Content-Length
    23	// length, both of which are wrong.
    24	func NewChunkedWriter(w io.Writer) io.WriteCloser {
    25		if _, bad := w.(*response); bad {
    26			log.Printf("warning: using NewChunkedWriter in an http.Handler; expect corrupt output")
    27		}
    28		return &chunkedWriter{w}
    29	}
    30	
    31	// Writing to ChunkedWriter translates to writing in HTTP chunked Transfer
    32	// Encoding wire format to the underlying Wire writer.
    33	type chunkedWriter struct {
    34		Wire io.Writer
    35	}
    36	
    37	// Write the contents of data as one chunk to Wire.
    38	// NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has
    39	// a bug since it does not check for success of io.WriteString
    40	func (cw *chunkedWriter) Write(data []byte) (n int, err os.Error) {
    41	
    42		// Don't send 0-length data. It looks like EOF for chunked encoding.
    43		if len(data) == 0 {
    44			return 0, nil
    45		}
    46	
    47		head := strconv.Itob(len(data), 16) + "\r\n"
    48	
    49		if _, err = io.WriteString(cw.Wire, head); err != nil {
    50			return 0, err
    51		}
    52		if n, err = cw.Wire.Write(data); err != nil {
    53			return
    54		}
    55		if n != len(data) {
    56			err = io.ErrShortWrite
    57			return
    58		}
    59		_, err = io.WriteString(cw.Wire, "\r\n")
    60	
    61		return
    62	}
    63	
    64	func (cw *chunkedWriter) Close() os.Error {
    65		_, err := io.WriteString(cw.Wire, "0\r\n")
    66		return err
    67	}
    68	
    69	// NewChunkedReader returns a new reader that translates the data read from r
    70	// out of HTTP "chunked" format before returning it. 
    71	// The reader returns os.EOF when the final 0-length chunk is read.
    72	//
    73	// NewChunkedReader is not needed by normal applications. The http package
    74	// automatically decodes chunking when reading response bodies.
    75	func NewChunkedReader(r *bufio.Reader) io.Reader {
    76		return &chunkedReader{r: r}
    77	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.