diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..08e0cf8d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "src/app/spreed-speakfreely-server/sleepy"] + path = src/app/spreed-speakfreely-server/sleepy + url = https://github.com/strukturag/sleepy.git + branch = gorillasupport diff --git a/src/app/spreed-speakfreely-server/main.go b/src/app/spreed-speakfreely-server/main.go index fb1a68d8..b6289833 100644 --- a/src/app/spreed-speakfreely-server/main.go +++ b/src/app/spreed-speakfreely-server/main.go @@ -310,7 +310,8 @@ func runner(runtime phoenix.Runtime) error { r.HandleFunc("/{room}", httputils.MakeGzipHandler(roomHandler)) // Add API end points. - api := sleepy.NewAPI(r.PathPrefix("/api/v1/").Subrouter()) + api := sleepy.NewAPI() + api.SetMux(r.PathPrefix("/api/v1/").Subrouter()) api.AddResource(&Rooms{}, "/rooms") api.AddResourceWithWrapper(&Tokens{tokenProvider}, httputils.MakeGzipHandler, "/tokens") if statsEnabled { diff --git a/src/app/spreed-speakfreely-server/rooms.go b/src/app/spreed-speakfreely-server/rooms.go index ec19e3fd..c5e49120 100644 --- a/src/app/spreed-speakfreely-server/rooms.go +++ b/src/app/spreed-speakfreely-server/rooms.go @@ -23,6 +23,7 @@ package main import ( "fmt" "net/http" + "net/url" ) type Room struct { @@ -33,9 +34,9 @@ type Room struct { type Rooms struct { } -func (rooms *Rooms) Post(r *http.Request) (int, interface{}) { +func (rooms *Rooms) Post(values url.Values, headers http.Header) (int, interface{}, http.Header) { name := RandomString(11) - return 200, &Room{name, fmt.Sprintf("/%s", name)} + return 200, &Room{name, fmt.Sprintf("/%s", name)}, http.Header{"Content-Type": {"application/json"}} } diff --git a/src/app/spreed-speakfreely-server/sleepy b/src/app/spreed-speakfreely-server/sleepy new file mode 160000 index 00000000..e34a9e43 --- /dev/null +++ b/src/app/spreed-speakfreely-server/sleepy @@ -0,0 +1 @@ +Subproject commit e34a9e4393f8b4bb1caa738b3afe448522e478f8 diff --git a/src/app/spreed-speakfreely-server/sleepy/core.go b/src/app/spreed-speakfreely-server/sleepy/core.go deleted file mode 100644 index aca296df..00000000 --- a/src/app/spreed-speakfreely-server/sleepy/core.go +++ /dev/null @@ -1,136 +0,0 @@ -/* This is a modified version of https://github.com/dougblack/sleepy - * with support for Gorilla muxing and full http.Request in handler. - * - * sleepy is released under the MIT License. - */ -package sleepy - -import ( - "encoding/json" - "github.com/gorilla/mux" - "net/http" -) - -const ( - GET = "GET" - POST = "POST" - PUT = "PUT" - DELETE = "DELETE" -) - -// GetSupported is the interface that provides the Get -// method a resource must support to receive HTTP GETs. -type GetSupported interface { - Get(*http.Request) (int, interface{}) -} - -// PostSupported is the interface that provides the Post -// method a resource must support to receive HTTP POSTs. -type PostSupported interface { - Post(*http.Request) (int, interface{}) -} - -// PutSupported is the interface that provides the Put -// method a resource must support to receive HTTP PUTs. -type PutSupported interface { - Put(*http.Request) (int, interface{}) -} - -// DeleteSupported is the interface that provides the Delete -// method a resource must support to receive HTTP DELETEs. -type DeleteSupported interface { - Delete(*http.Request) (int, interface{}) -} - -// HandleSupported is the interface that provides a general -// use method to support custom request processing. -type HandleSupported interface { - Handle(http.ResponseWriter, *http.Request) (int, []byte) -} - -// An API manages a group of resources by routing requests -// to the correct method on a matching resource and marshalling -// the returned data to JSON for the HTTP response. -type API struct { - mux *mux.Router -} - -// NewAPI allocates and returns a new API. -func NewAPI(mux *mux.Router) *API { - return &API{mux} -} - -func (api *API) requestHandler(resource interface{}) http.HandlerFunc { - return func(rw http.ResponseWriter, request *http.Request) { - - request.ParseForm() - - var code int - var content []byte - var err error - - if hresource, ok := resource.(HandleSupported); ok { - - var handle func(http.ResponseWriter, *http.Request) (int, []byte) - handle = hresource.Handle - code, content = handle(rw, request) - - } else { - - var handler func(*http.Request) (int, interface{}) - var data interface{} - - switch request.Method { - case GET: - if resource, ok := resource.(GetSupported); ok { - handler = resource.Get - } - case POST: - if resource, ok := resource.(PostSupported); ok { - handler = resource.Post - } - case PUT: - if resource, ok := resource.(PutSupported); ok { - handler = resource.Put - } - case DELETE: - if resource, ok := resource.(DeleteSupported); ok { - handler = resource.Delete - } - } - - if handler == nil { - rw.WriteHeader(http.StatusMethodNotAllowed) - return - } - - code, data = handler(request) - rw.Header().Set("Content-Type", "application/json; charset=utf-8") - - content, err = json.MarshalIndent(data, "", "\t") - if err != nil { - rw.WriteHeader(http.StatusInternalServerError) - return - } - - } - - rw.WriteHeader(code) - rw.Write(content) - } -} - -// AddResource adds a new resource to an API. The API will route -// requests that match one of the given paths to the matching HTTP -// method on the resource. -func (api *API) AddResource(resource interface{}, paths ...string) { - for _, path := range paths { - api.mux.HandleFunc(path, api.requestHandler(resource)) - } -} - -func (api *API) AddResourceWithWrapper(resource interface{}, wrapper func(handler http.HandlerFunc) http.HandlerFunc, paths ...string) { - for _, path := range paths { - api.mux.HandleFunc(path, wrapper(api.requestHandler(resource))) - } -} diff --git a/src/app/spreed-speakfreely-server/stats.go b/src/app/spreed-speakfreely-server/stats.go index aa14eba5..cecf1030 100644 --- a/src/app/spreed-speakfreely-server/stats.go +++ b/src/app/spreed-speakfreely-server/stats.go @@ -21,8 +21,8 @@ package main import ( - "encoding/json" "net/http" + "net/url" "runtime" "time" ) @@ -72,23 +72,9 @@ type Stats struct { hub *Hub } -func (stats *Stats) Handle(rw http.ResponseWriter, r *http.Request) (int, []byte) { +func (stats *Stats) Get(values url.Values, headers http.Header) (int, interface{}, http.Header) { - if r.Method != "GET" { - return http.StatusMethodNotAllowed, nil - } - - details := r.FormValue("details") == "1" - - data := NewStat(details, stats.hub) - rw.Header().Set("Access-Control-Allow-Origin", "*") - rw.Header().Set("Content-Type", "application/json; charset=utf-8") - - content, err := json.MarshalIndent(data, "", "\t") - if err != nil { - return http.StatusInternalServerError, nil - } - - return 200, content + details := values.Get("details") == "1" + return 200, NewStat(details, stats.hub), http.Header{"Content-Type": {"application/json; charset=utf-8"}, "Access-Control-Allow-Origin": {"*"}} } diff --git a/src/app/spreed-speakfreely-server/token.go b/src/app/spreed-speakfreely-server/token.go deleted file mode 100644 index 98bd107b..00000000 --- a/src/app/spreed-speakfreely-server/token.go +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Spreed Speak Freely. - * Copyright (C) 2013-2014 struktur AG - * - * This file is part of Spreed Speak Freely. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ -package main - -type Token struct { - Token string `json:"token"` - Success bool `json:"success"` -} diff --git a/src/app/spreed-speakfreely-server/tokens.go b/src/app/spreed-speakfreely-server/tokens.go index 8fe86aff..1854415c 100644 --- a/src/app/spreed-speakfreely-server/tokens.go +++ b/src/app/spreed-speakfreely-server/tokens.go @@ -23,39 +23,37 @@ package main import ( "log" "net/http" + "net/url" "strings" ) +type Token struct { + Token string `json:"token"` + Success bool `json:"success"` +} + type Tokens struct { provider TokenProvider } -func (tokens Tokens) Post(r *http.Request) (int, interface{}) { +func (tokens Tokens) Post(values url.Values, headers http.Header) (int, interface{}, http.Header) { - r.ParseForm() - auth := r.FormValue("a") - - remoteAddr := r.RemoteAddr - if remoteAddr == "@" || remoteAddr == "127.0.0.1" { - if r.Header["X-Forwarded-For"][0] != "" { - remoteAddr = r.Header["X-Forwarded-For"][0] - } - } + auth := values.Get("a") if len(auth) > 100 { - return 413, NewApiError("auth_too_large", "Auth too large") + return 413, NewApiError("auth_too_large", "Auth too large"), nil } valid := tokens.provider(strings.ToLower(auth)) response := &Token{Token: valid} if valid != "" { - log.Printf("Good incoming token request: %s from %s\n", auth, remoteAddr) + log.Printf("Good incoming token request: %s\n", auth) response.Success = true } else { - log.Printf("Wrong incoming token request: %s from %s\n", auth, remoteAddr) + log.Printf("Wrong incoming token request: %s\n", auth) } - return 200, response + return 200, response, http.Header{"Content-Type": {"application/json"}} }