Webcounter with cookies

This commit is contained in:
Meutel 2017-07-28 20:47:26 +02:00
parent b9344dcf82
commit 4dc2e681c4
3 changed files with 92 additions and 0 deletions

1
.gitignore vendored
View File

@ -59,3 +59,4 @@ tpl-ex2/tpl-ex2
tpl-ex3/tpl-ex3
form-ex1/form-ex1
form-ex2/form-ex2
webcounter/webcounter

83
webcounter/main.go Normal file
View File

@ -0,0 +1,83 @@
package main
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
"hash"
"html/template"
"log"
"net/http"
"strconv"
"strings"
)
var TPL *template.Template
const (
SECRET = "QDFuO2FyRHhGKEg5QlI4XDMlM2sK"
COUNTER_COOKIE string = "counter"
)
func displayPage(res http.ResponseWriter, req *http.Request) {
count, cookie := updateCounter(req)
http.SetCookie(res, cookie)
TPL.Execute(res, count)
}
func updateCounter(req *http.Request) (uint64, *http.Cookie) {
count := fromCookie(req)
count++
val := toCookieVal(count)
cookie := &http.Cookie{
Name: COUNTER_COOKIE,
Value: val,
}
return count, cookie
}
func fromCookie(req *http.Request) uint64 {
cookie, err := req.Cookie(COUNTER_COOKIE)
if err != nil {
return 0
}
sp := strings.Split(cookie.Value, "|")
if len(sp) != 2 {
return 0
}
c, err := strconv.Atoi(sp[0])
if err != nil {
return 0
}
if !checkMac(sp[0], sp[1]) {
return 0
}
return uint64(c)
}
func checkMac(val string, macStr string) bool {
var mac []byte
fmt.Sscanf(macStr, "%x", &mac)
return hmac.Equal(mac, cookieHash(val).Sum(nil))
}
func cookieHash(val string) hash.Hash {
mac := hmac.New(sha256.New, []byte(SECRET))
mac.Write([]byte(val))
return mac
}
func toCookieVal(count uint64) string {
val := strconv.FormatUint(count, 10)
return val + "|" + fmt.Sprintf("%x", cookieHash(val).Sum(nil))
}
func main() {
var err error
TPL, err = template.ParseFiles("tpl.html")
if err != nil {
log.Fatalln(err)
}
http.HandleFunc("/", displayPage)
http.ListenAndServe(":9000", nil)
}

8
webcounter/tpl.html Normal file
View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head><title>Webcounter</title></head>
<body>
<p>Number of visits: {{ . }}</p>
</body>
</html>