Created
July 8, 2016 15:49
-
-
Save jdkruzr/f6a8cf479fa7217af87767273aa2a61c to your computer and use it in GitHub Desktop.
This file contains 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
package main | |
import ( | |
"fmt" | |
"html/template" | |
"log" | |
"net/http" | |
"strings" | |
"time" | |
"crypto/md5" | |
"io" | |
"os" | |
"strconv" | |
"sync" | |
"crypto/rand" | |
"encoding/base64" | |
"net/url" | |
) | |
type Manager struct { | |
cookieName string //private cookiename | |
lock sync.Mutex //protects session | |
provider Provider | |
maxlifetime int64 | |
} | |
type Provider interface { | |
SessionInit(sid string) (Session, error) | |
SessionRead(sid string) (Session, error) | |
SessionDestroy(sid string) error | |
SessionGC(maxLifeTime int64) | |
} | |
type Session interface { | |
Set(key, value interface{}) error //set session value | |
Get(key interface{}) interface{} //get session value | |
Delete(key interface{}) error //delete session value | |
SessionID() string | |
} | |
var provides = make(map[string]Provider) | |
//Register makes a session provider available by the provided name. | |
//If a Register is called twice with the same name or the driver is nil, | |
//it panics. | |
func Register(name string, provider Provider) { | |
if provider == nil { | |
panic("session: Register provider is nil") | |
} | |
if _, dup := provides[name]; dup { | |
panic("session: Register called twice for provider " + name) | |
} | |
provides[name] = provider | |
} | |
func (manager *Manager) sessionId() string { | |
b := make([]byte, 32) | |
if _, err := io.ReadFull(rand.Reader, b); err != nil { | |
return "" | |
} | |
return base64.URLEncoding.EncodeToString(b) | |
} | |
func NewManager(provideName, cookieName string, maxlifetime int64) (*Manager, error) { | |
provider, ok := provides[provideName] | |
if !ok { | |
return nil, fmt.Errorf("session: unknown provide %q (forgotten import?)", provideName) | |
} | |
return &Manager{provider: provider, cookieName: cookieName, maxlifetime: maxlifetime}, nil | |
} | |
func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (session Session) { | |
manager.lock.Lock() | |
defer manager.lock.Unlock() | |
cookie, err := r.Cookie(manager.cookieName) | |
if err != nil || cookie.Value == "" { | |
sid := manager.sessionId() | |
session, _ = manager.provider.SessionInit(sid) | |
cookie := http.Cookie{Name: manager.cookieName, Value: url.QueryEscape(sid), Path: "/", HttpOnly: true, MaxAge: int(manager.maxlifetime)} | |
http.SetCookie(w, &cookie) | |
} else { | |
sid, _ := url.QueryUnescape(cookie.Value) | |
session, _ = manager.provider.SessionRead(sid) | |
} | |
return | |
} | |
func sayhelloName(w http.ResponseWriter, r *http.Request) { | |
r.ParseForm() //parse URL parameters and then the contents of the POST | |
fmt.Println("path: ", r.URL.Path) | |
fmt.Println("scheme: ", r.URL.Scheme) | |
fmt.Println(r.Form, "\n") | |
fmt.Println(r.Form["url_long"]) | |
for k, v := range r.Form { | |
fmt.Println("key: ", k) | |
fmt.Println("val: ", strings.Join(v, "")) | |
} | |
fmt.Fprintf(w, "Hello @radiofreekruzr!") // Write this to response | |
} | |
func login(w http.ResponseWriter, r *http.Request) { | |
sess := globalSessions.SessionStart(w, r) | |
r.ParseForm() | |
if r.Method == "GET" { | |
t, _ := template.ParseFiles("login.gtpl") | |
w.Header().Set("Content-Type", "text/html") | |
t.Execute(w, sess.Get("username")) | |
} else { | |
sess.Set("username", r.Form["username"]) | |
http.Redirect(w, r, "/", 302) | |
} | |
} | |
func upload(w http.ResponseWriter, r *http.Request) { | |
fmt.Println("method: ", r.Method) | |
if r.Method == "GET" { | |
crutime := time.Now().Unix() | |
h := md5.New() | |
io.WriteString(h, strconv.FormatInt(crutime, 10)) | |
token := fmt.Sprintf("%x", h.Sum(nil)) | |
t, _ := template.ParseFiles("upload.gtpl") | |
t.Execute(w, token) | |
} else { | |
r.ParseMultipartForm(32 << 20) | |
file, handler, err := r.FormFile("uploadfile") | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
defer file.Close() | |
fmt.Fprintf(w, "%v", handler.Header) | |
f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
defer file.Close() | |
io.Copy(f, file) | |
} | |
} | |
func count(w http.ResponseWriter, r *http.Request) { | |
sess := globalSessions.SessionStart(w, r) | |
createtime := sess.Get("createtime") | |
if createtime == nil { | |
sess.Set("createtime", time.Now().Unix()) | |
} else if (createtime.(int64) + 360) < (time.Now().Unix()) { | |
globalSessions.SessionDestroy(w, r) | |
sess = globalSessions.SessionStart(w, r) | |
} | |
ct := sess.Get("countnum") | |
if ct == nil { | |
sess.Set("countnum", 1) | |
} else { | |
sess.Set("countnum", (ct.(int) + 1)) | |
} | |
t, _ := template.ParseFiles("count.gtpl") | |
w.Header().Set("Content-Type", "text/html") | |
t.Execute(w, sess.Get("countnum")) | |
} | |
//Destroy sessionid | |
func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request){ | |
cookie, err := r.Cookie(manager.cookieName) | |
if err != nil || cookie.Value == "" { | |
return | |
} else { | |
manager.lock.Lock() | |
defer manager.lock.Unlock() | |
manager.provider.SessionDestroy(cookie.Value) | |
expiration := time.Now() | |
cookie := http.Cookie{Name: manager.cookieName, Path: "/", HttpOnly: true, Expires: expiration, MaxAge: -1} | |
http.SetCookie(w, &cookie) | |
} | |
} | |
func (manager *Manager) GC() { | |
manager.lock.Lock() | |
defer manager.lock.Unlock() | |
manager.provider.SessionGC(manager.maxlifetime) | |
time.AfterFunc(time.Duration(manager.maxlifetime), func() { manager.GC() }) | |
} | |
func main() { | |
var globalSessions *session.Manager | |
// Then, initialize the session manager | |
func init() { | |
globalSessions = NewManager("memory","gosessionid",3600) | |
} | |
go globalSessions.GC() | |
http.HandleFunc("/", sayhelloName) | |
http.HandleFunc("/login", login) | |
http.HandleFunc("/upload", upload) | |
err := http.ListenAndServe(":3001", nil) | |
if err != nil { | |
log.Fatal("ListenAndServe: ", err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's the error when I compile:
[Fri Jul 08 11:44:37 jtd@gruis ~/work-go/playground]$ go build forms.go
command-line-arguments
./forms.go:187: syntax error: unexpected init, expecting (
./forms.go:188: syntax error: unexpected globalSessions
./forms.go:191: syntax error: non-declaration statement outside function body