Created
November 28, 2018 21:18
-
-
Save lmas/95f3e991d49f69bcdfa34b21777908ea to your computer and use it in GitHub Desktop.
Some simple http utils (http handlers with errors, secure cookies)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ( | |
"net/http" | |
"time" | |
"github.com/gorilla/securecookie" | |
) | |
type WebError struct { | |
Code int | |
Err error | |
} | |
func (e WebError) Error() string { | |
return e.Err.Error() | |
} | |
func (e WebError) Status() int { | |
return e.Code | |
} | |
type H func(w http.ResponseWriter, r *http.Request) error | |
func Handler(h H) http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
w.Header().Set("Content-Type", "text/html; charset=utf-8") // default | |
err := h(w, r) | |
if err != nil { | |
switch e := err.(type) { | |
case WebError: | |
http.Error(w, e.Error(), e.Status()) | |
default: | |
log.Printf("server error: %s\n", err) | |
http.Error(w, "internal server error", http.StatusInternalServerError) | |
} | |
} | |
}) | |
} | |
func WebClientAddr(r *http.Request) string { | |
addr := r.Header.Get("x-forwarded-for") // Possible proxy addr | |
if addr == "" { | |
addr = r.RemoteAddr // fallback | |
} | |
return addr | |
} | |
//////////////////////////////////////////////////////////////////////////////// | |
const ( | |
cookieName = "session" | |
cookieExpire = 24 * time.Hour | |
) | |
var ( | |
hashKey = securecookie.GenerateRandomKey(64) | |
blockKey = securecookie.GenerateRandomKey(32) | |
cookieEncoder = securecookie.New(hashKey, blockKey).MaxAge(int(cookieExpire.Seconds())) | |
) | |
func defaultCookie() *http.Cookie { | |
return &http.Cookie{ | |
Name: cookieName, | |
Path: "/", | |
SameSite: http.SameSiteStrictMode, // Prevents CSRF | |
HttpOnly: true, | |
//Secure: true, // NOTE: only works when we run the site behind TLS | |
// NOTE: don't forget to set these values on the new cookie | |
//Value: token, | |
//Expires: time.Now().Add(expire), | |
//MaxAge: int(expire.Seconds()), | |
} | |
} | |
func SetCookie(w http.ResponseWriter, data string) { | |
cookie := defaultCookie() | |
if data != "" { | |
val, err := cookieEncoder.Encode(cookieName, data) | |
if err != nil { | |
// silently ignore errors, no cookies will be set. sue me | |
// this should never happen with a string? | |
return | |
} | |
cookie.Value = val | |
cookie.Expires = time.Now().Add(cookieExpire) | |
cookie.MaxAge = int(cookieExpire.Seconds()) | |
} | |
http.SetCookie(w, cookie) | |
} | |
func GetCookie(r *http.Request) string { | |
cookie, err := r.Cookie(cookieName) | |
if err != nil { | |
return "" | |
} | |
var data string | |
err = cookieEncoder.Decode(cookieName, cookie.Value, &data) | |
if err != nil { | |
return "" | |
} | |
return data | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment