Fragment Description:



A too often ignored function of the 'http' package:
ServeContent().
Signature:
func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker) 'ServeContent' replies to the request using the content in the provided ReadSeeker.
The main benefit of 'ServeContent' over 'io.Copy' is that it handles Range requests properly, sets the MIME type, and handles If-Modified-Since requests.
Launch the program and try:
$ curl -H 'Range:
bytes=5-' http://localhost:8080

httpServeContent

Last update, on 2015, Fri 9 Oct, 16:15:39

/* ... <== see fragment description ... */

package main

import (
    "log"
    "net/http"
    "strings"
    "time"
)

func main() {
    log.Printf("Running on :8080 ...")
    err := http.ListenAndServe("127.0.0.1:8080",
        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            http.ServeContent(w, r, "foo.txt", time.Now(),
                strings.NewReader("I am some content.\n"))
        }))
    log.Fatal(err)
}

/* Expected Output:
I am some content.
*/
/*
To be noted:
If the response's Content-Type header is not set, ServeContent first tries to deduce the type from name's file extension and, if that fails, falls back to reading the first block of the content and passing it to DetectContentType. The name is otherwise unused; in particular it can be empty and is never sent in the response.
If modtime is not the zero time, ServeContent includes it in a Last-Modified header in the response. If the request includes an If-Modified-Since header, ServeContent uses modtime to decide whether the content needs to be sent at all.
The content's Seek method must work: ServeContent uses a seek to the end of the content to determine its size.
If the caller has set w's ETag header, ServeContent uses it to handle requests using If-Range and If-None-Match.
Note that *os.File implements the io.ReadSeeker interface.
*/



Comments