requestBodyLimitHit bool
 
        handlerDone bool // set true when the handler exits
+
+       // Buffers for Date and Content-Length
+       dateBuf [len(TimeFormat)]byte
+       clenBuf [10]byte
 }
 
 // requestTooLarge is called by maxBytesReader when too much input has
 // It is like time.RFC1123 but hard codes GMT as the time zone.
 const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
 
+// appendTime is a non-allocating version of []byte(time.Now().UTC().Format(TimeFormat))
+func appendTime(b []byte, t time.Time) []byte {
+       const days = "SunMonTueWedThuFriSat"
+       const months = "JanFebMarAprMayJunJulAugSepOctNovDec"
+
+       yy, mm, dd := t.Date()
+       hh, mn, ss := t.Clock()
+       day := days[3*t.Weekday():]
+       mon := months[3*(mm-1):]
+
+       return append(b,
+               day[0], day[1], day[2], ',', ' ',
+               byte('0'+dd/10), byte('0'+dd%10), ' ',
+               mon[0], mon[1], mon[2], ' ',
+               byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ',
+               byte('0'+hh/10), byte('0'+hh%10), ':',
+               byte('0'+mn/10), byte('0'+mn%10), ':',
+               byte('0'+ss/10), byte('0'+ss%10), ' ',
+               'G', 'M', 'T')
+}
+
 var errTooLarge = errors.New("http: request too large")
 
 // Read next request from connection.
 // the response Header map and all its 1-element slices.
 type extraHeader struct {
        contentType      string
-       contentLength    string
        connection       string
-       date             string
        transferEncoding string
+       date             []byte // written if not nil
+       contentLength    []byte // written if not nil
 }
 
 // Sorted the same as extraHeader.Write's loop.
 var extraHeaderKeys = [][]byte{
-       []byte("Content-Type"), []byte("Content-Length"),
-       []byte("Connection"), []byte("Date"), []byte("Transfer-Encoding"),
+       []byte("Content-Type"),
+       []byte("Connection"),
+       []byte("Transfer-Encoding"),
 }
 
-// The value receiver, despite copying 5 strings to the stack,
-// prevents an extra allocation. The escape analysis isn't smart
-// enough to realize this doesn't mutate h.
-func (h extraHeader) Write(w io.Writer) {
-       for i, v := range []string{h.contentType, h.contentLength, h.connection, h.date, h.transferEncoding} {
+var (
+       headerContentLength = []byte("Content-Length: ")
+       headerDate          = []byte("Date: ")
+)
+
+// Write writes the headers described in h to w.
+//
+// This method has a value receiver, despite the somewhat large size
+// of h, because it prevents an allocation. The escape analysis isn't
+// smart enough to realize this function doesn't mutate h.
+func (h extraHeader) Write(w *bufio.Writer) {
+       if h.date != nil {
+               w.Write(headerDate)
+               w.Write(h.date)
+               w.Write(crlf)
+       }
+       if h.contentLength != nil {
+               w.Write(headerContentLength)
+               w.Write(h.contentLength)
+               w.Write(crlf)
+       }
+       for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
                if v != "" {
                        w.Write(extraHeaderKeys[i])
                        w.Write(colonSpace)
-                       io.WriteString(w, v)
+                       w.WriteString(v)
                        w.Write(crlf)
                }
        }
        // "keep-alive" connections alive.
        if w.handlerDone && header.get("Content-Length") == "" && w.req.Method != "HEAD" {
                w.contentLength = int64(len(p))
-               setHeader.contentLength = strconv.Itoa(len(p))
+               setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
        }
 
        // If this was an HTTP/1.0 request with keep-alive and we sent a
        }
 
        if _, ok := header["Date"]; !ok {
-               setHeader.date = time.Now().UTC().Format(TimeFormat)
+               setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now())
        }
 
        te := header.get("Transfer-Encoding")
 
        io.WriteString(w.conn.buf, statusLine(w.req, code))
        cw.header.WriteSubset(w.conn.buf, excludeHeader)
-       setHeader.Write(w.conn.buf)
+       setHeader.Write(w.conn.buf.Writer)
        w.conn.buf.Write(crlf)
 }