306 lines
7.3 KiB
Go
306 lines
7.3 KiB
Go
package router
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
type DefaultError uint32
|
|
|
|
const (
|
|
DefaultErrorBadRequest DefaultError = http.StatusBadRequest
|
|
DefaultErrorUnauthorized DefaultError = http.StatusUnauthorized
|
|
DefaultErrorMethodNotAllowed DefaultError = http.StatusMethodNotAllowed
|
|
DefaultErrorInternalServerError DefaultError = http.StatusInternalServerError
|
|
DefaultErrorNotImplemented DefaultError = http.StatusNotImplemented
|
|
)
|
|
|
|
func (e DefaultError) Error(Error) Error {
|
|
return e
|
|
}
|
|
|
|
func (e DefaultError) Status() (code int) {
|
|
return int(e)
|
|
}
|
|
|
|
func (e DefaultError) String() (out string) {
|
|
switch e {
|
|
case DefaultErrorBadRequest:
|
|
out = "bad request"
|
|
case DefaultErrorUnauthorized:
|
|
out = "user unauthorized"
|
|
case DefaultErrorMethodNotAllowed:
|
|
out = "method not allowed"
|
|
case DefaultErrorInternalServerError:
|
|
out = "internal server error"
|
|
case DefaultErrorNotImplemented:
|
|
out = "server not implemented"
|
|
default:
|
|
out = "unhandled error"
|
|
}
|
|
return
|
|
}
|
|
|
|
func (e DefaultError) Response() *GenericResponse {
|
|
body, err := json.Marshal(struct{ Error string }{Error: e.String()})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return &GenericResponse{
|
|
Status: e.Status(),
|
|
Header: Header{"Content-Type": []string{"text/javascript", "charInit=utf-8"}},
|
|
Body: body,
|
|
}
|
|
}
|
|
|
|
type DefaultErrorHandler struct {
|
|
DefaultError
|
|
}
|
|
|
|
func (*DefaultErrorHandler) Error(e Error) Error {
|
|
return &DefaultErrorHandler{DefaultError: e.(DefaultError)}
|
|
}
|
|
|
|
type DefaultRequestBuilder struct {
|
|
errorHandler Error
|
|
allowedMethods *[]string
|
|
url *url.URL
|
|
header struct {
|
|
*Header
|
|
fields header
|
|
}
|
|
values struct {
|
|
*Values
|
|
fields values
|
|
}
|
|
body struct {
|
|
*Body
|
|
fields body
|
|
}
|
|
}
|
|
|
|
// Leave commented to require services to create their own New method
|
|
// var _ RequestBuilder = (*DefaultRequestBuilder)(nil)
|
|
// func (*DefaultRequestBuilder) New() RequestBuilder {
|
|
// return NewDefaultRequestBuilder()
|
|
// }
|
|
|
|
func (*DefaultRequestBuilder) mustEmbedDefaultRequestBuilder() {}
|
|
|
|
func NewDefaultRequestBuilder() *DefaultRequestBuilder {
|
|
return &DefaultRequestBuilder{}
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) InitErrorHandler(errorHandler Error) *DefaultRequestBuilder {
|
|
rqb.errorHandler = errorHandler
|
|
return rqb
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) InitAllowedMethods(allowedMethods *[]string) *DefaultRequestBuilder {
|
|
rqb.allowedMethods = allowedMethods
|
|
return rqb
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) InitUrl(url *url.URL) *DefaultRequestBuilder {
|
|
rqb.url = url
|
|
return rqb
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) InitHeader(parsed *Header, fields header) *DefaultRequestBuilder {
|
|
rqb.header.Header = parsed
|
|
rqb.header.fields = fields
|
|
return rqb
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) InitValues(parsed *Values, fields values) *DefaultRequestBuilder {
|
|
rqb.values.Values = parsed
|
|
rqb.values.fields = fields
|
|
return rqb
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) InitBody(parsed *Body, fields body) *DefaultRequestBuilder {
|
|
rqb.body.Body = parsed
|
|
rqb.body.fields = fields
|
|
return rqb
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) Init() *DefaultRequestBuilder {
|
|
if rqb.errorHandler == nil {
|
|
rqb.errorHandler = &DefaultErrorHandler{}
|
|
}
|
|
if rqb.allowedMethods == nil {
|
|
amd := make([]string, 0)
|
|
rqb.allowedMethods = &amd
|
|
}
|
|
if rqb.url == nil {
|
|
u := url.URL{}
|
|
rqb.url = &u
|
|
}
|
|
if rqb.header.Header == nil || rqb.header.fields == nil {
|
|
hd := Header{"Content-Type": []string{"text/plain", "charset=utf-8"}}
|
|
rqb.header.Header = &hd
|
|
hfd := struct{ Header }{Header: hd}
|
|
rqb.header.fields = &hfd
|
|
}
|
|
if rqb.values.Values == nil || rqb.values.fields == nil {
|
|
vd := make(Values)
|
|
rqb.values.Values = &vd
|
|
vfd := struct{ Values }{Values: vd}
|
|
rqb.values.fields = &vfd
|
|
}
|
|
if rqb.body.Body == nil || rqb.body.fields == nil {
|
|
bd := make(Body, 0)
|
|
rqb.body.Body = &bd
|
|
bfd := struct{ Body }{Body: bd}
|
|
rqb.body.fields = &bfd
|
|
}
|
|
return rqb
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) SetAllowed(method string) (e Error) {
|
|
var ok bool
|
|
for _, m := range *rqb.allowedMethods {
|
|
if m == method {
|
|
ok = true
|
|
}
|
|
}
|
|
if !ok {
|
|
return rqb.errorHandler.Error(DefaultErrorMethodNotAllowed)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) SetUrl(url url.URL) (e Error) {
|
|
*rqb.url = url
|
|
return
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) SetHeader(header map[string][]string) (e Error) {
|
|
*rqb.header.Header = header
|
|
err := rqb.header.Header.Unmarshal(rqb.header.fields)
|
|
if err != nil {
|
|
return rqb.errorHandler.Error(DefaultErrorBadRequest)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) SetBody(body io.ReadCloser) (e Error) {
|
|
defer body.Close()
|
|
json.NewDecoder(body).Decode(rqb.body.fields)
|
|
return
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) SetValues(values map[string][]string) (e Error) {
|
|
*rqb.values.Values = values
|
|
err := rqb.values.Values.Unmarshal(rqb.values.fields)
|
|
if err != nil {
|
|
return rqb.errorHandler.Error(DefaultErrorBadRequest)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (rqb *DefaultRequestBuilder) Request() (req *GenericRequest) {
|
|
req = &GenericRequest{
|
|
Url: *rqb.url,
|
|
Header: *rqb.header.Header,
|
|
Values: *rqb.values.Values,
|
|
Body: *rqb.body.Body,
|
|
}
|
|
return
|
|
}
|
|
|
|
type DefaultResponseBuilder struct {
|
|
errorHandler Error
|
|
status *int
|
|
header struct {
|
|
*Header
|
|
fields header
|
|
}
|
|
body struct {
|
|
*Body
|
|
fields body
|
|
}
|
|
}
|
|
|
|
// Leave commented to require services to create their own New method
|
|
// var _ ResponseBuilder = (*DefaultResponseBuilder)(nil)
|
|
// func (rsb *DefaultResponseBuilder) New() ResponseBuilder {
|
|
// return NewDefaultResponseBuilder()
|
|
// }
|
|
|
|
func (*DefaultResponseBuilder) mustEmbedDefaultResponseBuilder() {}
|
|
|
|
func NewDefaultResponseBuilder() *DefaultResponseBuilder {
|
|
return &DefaultResponseBuilder{}
|
|
}
|
|
|
|
func (rsb *DefaultResponseBuilder) InitErrorHandler(errorHandler Error) *DefaultResponseBuilder {
|
|
rsb.errorHandler = errorHandler
|
|
return rsb
|
|
}
|
|
|
|
func (rsb *DefaultResponseBuilder) InitStatus(code *int) *DefaultResponseBuilder {
|
|
rsb.status = code
|
|
return rsb
|
|
}
|
|
|
|
func (rsb *DefaultResponseBuilder) InitHeader(parsed *Header, fields header) *DefaultResponseBuilder {
|
|
rsb.header.Header = parsed
|
|
rsb.header.fields = fields
|
|
return rsb
|
|
}
|
|
|
|
func (rsb *DefaultResponseBuilder) InitBody(parsed *Body, fields body) *DefaultResponseBuilder {
|
|
rsb.body.Body = parsed
|
|
rsb.body.fields = fields
|
|
return rsb
|
|
}
|
|
|
|
func (rsb *DefaultResponseBuilder) Init() *DefaultResponseBuilder {
|
|
if rsb.errorHandler == nil {
|
|
rsb.errorHandler = &DefaultErrorHandler{}
|
|
}
|
|
if rsb.status == nil {
|
|
c := http.StatusOK
|
|
rsb.status = &c
|
|
}
|
|
if rsb.header.Header == nil || rsb.header.fields == nil {
|
|
hd := Header{"Content-Type": []string{"text/plain", "charset=utf-8"}}
|
|
rsb.header.Header = &hd
|
|
hfd := struct{ Header }{Header: hd}
|
|
rsb.header.fields = &hfd
|
|
}
|
|
if rsb.body.Body == nil || rsb.body.fields == nil {
|
|
bd := make(Body, 0)
|
|
rsb.body.Body = &bd
|
|
bfd := struct{ Body }{Body: bd}
|
|
rsb.body.fields = &bfd
|
|
}
|
|
return rsb
|
|
}
|
|
|
|
func (rsb *DefaultResponseBuilder) SetHeader(header map[string][]string) (e Error) {
|
|
*rsb.header.Header = header
|
|
err := rsb.header.Header.Unmarshal(rsb.header.fields)
|
|
if err != nil {
|
|
return rsb.errorHandler.Error(DefaultErrorInternalServerError)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (rsb *DefaultResponseBuilder) SetBody(body []byte) (e Error) {
|
|
*rsb.body.Body = body
|
|
return
|
|
}
|
|
|
|
func (rsb *DefaultResponseBuilder) Response() (res *GenericResponse) {
|
|
res = &GenericResponse{
|
|
Status: *rsb.status,
|
|
Header: *rsb.header.Header,
|
|
Body: *rsb.body.Body,
|
|
}
|
|
return
|
|
}
|