Documentation
¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Check ¶
func Check(w http.ResponseWriter, r *http.Request) (done bool)
Check evaluates request preconditions and return true when a precondition resulted in sending http.StatusNotModified or http.StatusPreconditionFailed.
This method relies on ETag and Last-Modified headers being already set on the http.ResponseWriter.
Example (IfMatch) ¶
package main import ( "fmt" "net/http" "net/http/httptest" "github.com/bsm/conditional" ) func main() { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // set ETag and/or Last-Modified headers w.Header().Set("ETag", `"strong"`) w.Header().Set("Last-Modified", "Fri, 05 Jan 2018 11:25:15 GMT") // perform conditional check if conditional.Check(w, r) { return } w.WriteHeader(http.StatusNoContent) })) defer srv.Close() client := new(http.Client) // make a plain GET request req, err := http.NewRequest("GET", srv.URL, nil) if err != nil { panic(err) } res, err := client.Do(req) if err != nil { panic(err) } fmt.Println(res.Status) // => 204 No Content // now, try it with a matching "If-Match" req, err = http.NewRequest("GET", srv.URL, nil) if err != nil { panic(err) } req.Header.Set("If-Match", `"strong"`) res, err = client.Do(req) if err != nil { panic(err) } fmt.Println(res.Status) // => 204 No Content // finally, try it with a non-matching "If-Match" req, err = http.NewRequest("GET", srv.URL, nil) if err != nil { panic(err) } req.Header.Set("If-Match", `"OTHER-TAG"`) res, err = client.Do(req) if err != nil { panic(err) } fmt.Println(res.Status) // => 412 Precondition Failed }
Output: 204 No Content 204 No Content 412 Precondition Failed
Example (IfModifiedSince) ¶
package main import ( "fmt" "net/http" "net/http/httptest" "github.com/bsm/conditional" ) func main() { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // set ETag and/or Last-Modified headers w.Header().Set("ETag", `"strong"`) w.Header().Set("Last-Modified", "Fri, 05 Jan 2018 11:25:15 GMT") // perform conditional check if conditional.Check(w, r) { return } w.WriteHeader(http.StatusNoContent) })) defer srv.Close() client := new(http.Client) // make a plain GET request req, err := http.NewRequest("GET", srv.URL, nil) if err != nil { panic(err) } res, err := client.Do(req) if err != nil { panic(err) } fmt.Println(res.Status) // => 204 No Content // now, try it with a matchingg "If-Modified-Since" req, err = http.NewRequest("GET", srv.URL, nil) if err != nil { panic(err) } req.Header.Set("If-Modified-Since", "Fri, 05 Jan 2018 11:25:15 GMT") res, err = client.Do(req) if err != nil { panic(err) } fmt.Println(res.Status) // => 304 Not Modified }
Output: 204 No Content 304 Not Modified
Example (IfNoneMatch) ¶
package main import ( "fmt" "net/http" "net/http/httptest" "github.com/bsm/conditional" ) func main() { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // set ETag and/or Last-Modified headers w.Header().Set("ETag", `"strong"`) w.Header().Set("Last-Modified", "Fri, 05 Jan 2018 11:25:15 GMT") // perform conditional check if conditional.Check(w, r) { return } w.WriteHeader(http.StatusNoContent) })) defer srv.Close() client := new(http.Client) // make a plain GET request req, err := http.NewRequest("GET", srv.URL, nil) if err != nil { panic(err) } res, err := client.Do(req) if err != nil { panic(err) } fmt.Println(res.Status) // => 204 No Content // now, try it with a matching "If-None-Match" req, err = http.NewRequest("GET", srv.URL, nil) if err != nil { panic(err) } req.Header.Set("If-None-Match", `"strong"`) res, err = client.Do(req) if err != nil { panic(err) } fmt.Println(res.Status) // => 304 Not Modified }
Output: 204 No Content 304 Not Modified
func CheckStatus ¶
func CheckStatus(w http.ResponseWriter, r *http.Request) (code int)
CheckStatus behaves like Check, but returns the http status code that was used for the response instead of a boolean.
http.StatusNotModified http.StatusPreconditionFailed 0 = response header was not written
func Evaluate ¶
Evaluate evaluates request preconditions and return the appropriate http status code, which is one of the following:
http.StatusNotModified - content was not modified http.StatusPreconditionFailed - requested content was modified meanwhile 0 - otherwise.
Unlike Check it does not automatically write a response to the client. Like Check, it relies on ETag and Last-Modified headers being already set.
func NotModified ¶
func NotModified(w http.ResponseWriter)
NotModified writes a http.StatusNotModified response to the user following instructions from RFC 7232 section 4.1:
a sender SHOULD NOT generate representation metadata other than the above listed fields unless said metadata exists for the purpose of guiding cache updates (e.g., Last-Modified might be useful if the response does not have an ETag field).
Types ¶
type ETag ¶
type ETag string
ETag represents an ETag string.
func ScanETag ¶
ScanETag determines if a syntactically valid ETag is present at s. If so, the ETag and remaining text after consuming ETag is returned. Otherwise, it returns "", "".
Taken from https://golang.org/src/net/http/fs.go. Copyright 2009 The Go Authors. All rights reserved.
func (ETag) IsStrongMatch ¶
IsStrongMatch returns true if tag matches other strong tag.
func (ETag) IsWeakMatch ¶
IsWeakMatch returns true if tag matches other tag.