oauth2/server/server.go

76 lines
1.5 KiB
Go

package server
import (
"net/http"
"net/url"
"somehole.com/common/log"
)
type Request interface {
Parse(*url.Values) error
}
type EmptyRequest interface {
Request() Request
}
type Response interface {
Response() []byte
}
type ErrorResponse interface {
Ok() bool
HttpStatus() int
ErrorResponse() []byte
String() string
}
type server struct {
emptyReq EmptyRequest
allowed []string
logger log.Logger
do func(req Request) (res Response, errRes ErrorResponse)
}
func NewServer(req EmptyRequest, allowed []string, logger log.Logger, do func(req Request) (res Response, errRes ErrorResponse)) *server {
return &server{
emptyReq: req,
allowed: allowed,
logger: logger,
do: do,
}
}
type defaultError struct {
Error string `json:"error"`
}
func (srv *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
req := srv.emptyReq
request := req.Request()
var allowed bool
for _, method := range srv.allowed {
if method == r.Method {
allowed = true
break
}
}
if !allowed {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write(mustMarshalJson(&defaultError{Error: "method_not_allowed"}))
srv.logger.Logf(log.LevelError, "requested method (%s) not one of %v", r.Method, srv.allowed)
return
}
r.ParseForm()
request.Parse(&r.Form)
res, errRes := srv.do(request)
if !errRes.Ok() {
w.WriteHeader(errRes.HttpStatus())
w.Write(errRes.ErrorResponse())
srv.logger.Logf(log.LevelError, "request failed: %s", errRes.String())
}
w.WriteHeader(errRes.HttpStatus())
w.Write(res.Response())
}