router/default.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
}