Skip to content

Instantly share code, notes, and snippets.

@tristanwietsma
Created May 15, 2014 04:15
Show Gist options
  • Star 78 You must be signed in to star a gist
  • Fork 25 You must be signed in to fork a gist
  • Save tristanwietsma/8444cf3cb5a1ac496203 to your computer and use it in GitHub Desktop.
Save tristanwietsma/8444cf3cb5a1ac496203 to your computer and use it in GitHub Desktop.
Golang web server example
package main
import (
"encoding/base64"
"net/http"
"strings"
)
type handler func(w http.ResponseWriter, r *http.Request)
func BasicAuth(pass handler) handler {
return func(w http.ResponseWriter, r *http.Request) {
auth := strings.SplitN(r.Header["Authorization"][0], " ", 2)
if len(auth) != 2 || auth[0] != "Basic" {
http.Error(w, "bad syntax", http.StatusBadRequest)
return
}
payload, _ := base64.StdEncoding.DecodeString(auth[1])
pair := strings.SplitN(string(payload), ":", 2)
if len(pair) != 2 || !Validate(pair[0], pair[1]) {
http.Error(w, "authorization failed", http.StatusUnauthorized)
return
}
pass(w, r)
}
}
func Validate(username, password string) bool {
if username == "username" && password == "password" {
return true
}
return false
}
package main
import (
"log"
"net/http"
)
func main() {
// public views
http.HandleFunc("/", HandleIndex)
// private views
http.HandleFunc("/post", PostOnly(BasicAuth(HandlePost)))
http.HandleFunc("/json", GetOnly(BasicAuth(HandleJSON)))
log.Fatal(http.ListenAndServe(":8080", nil))
}
package main
import (
"encoding/json"
"io"
"log"
"net/http"
)
func HandleIndex(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "hello, world\n")
}
func HandlePost(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
log.Println(r.PostForm)
io.WriteString(w, "post\n")
}
type Result struct {
FirstName string `json:"first"`
LastName string `json:"last"`
}
func HandleJSON(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
result, _ := json.Marshal(Result{"tee", "dub"})
io.WriteString(w, string(result))
}
curl http://0.0.0.0:8080
curl -u username:password -d "param1=value1&param2=value2" http://0.0.0.0:8080/post
curl -u username:password http://0.0.0.0:8080/json
package main
import (
"net/http"
)
func GetOnly(h handler) handler {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
h(w, r)
return
}
http.Error(w, "get only", http.StatusMethodNotAllowed)
}
}
func PostOnly(h handler) handler {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
h(w, r)
return
}
http.Error(w, "post only", http.StatusMethodNotAllowed)
}
}
@donatj
Copy link

donatj commented Feb 25, 2015

Instead of defining your own handler type why not just use http.HandlerFunc?

eg:

func BasicAuth(pass http.HandlerFunc) http.HandlerFunc {

Copy link

ghost commented Feb 20, 2016

Why to reinvent the wheel?

type handler func(w http.ResponseWriter, r *http.Request)

 func BasicAuth(pass handler) handler {

    return func(w http.ResponseWriter, r *http.Request) {

        username, password, _ := r.BasicAuth()

        if username != "username" || password != "password" {
            http.Error(w, "authorization failed", http.StatusUnauthorized)
            return
        }
        pass(w, r)
    }
 }

would be sufficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment