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() *Response { body, err := json.Marshal(struct{ Error string }{Error: e.String()}) if err != nil { panic(err) } return &Response{ Status: e.Status(), Header: Header{"Content-Type": []string{"text/javascript", "charset=utf-8"}}, Body: body, } } type DefaultErrorHandler struct { DefaultError } func (eh *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) SetErrorHandler(errorHandler Error) *DefaultRequestBuilder { rqb.errorHandler = errorHandler return rqb } func (rqb *DefaultRequestBuilder) SetAllowedMethods(allowedMethods *[]string) *DefaultRequestBuilder { rqb.allowedMethods = allowedMethods return rqb } func (rqb *DefaultRequestBuilder) SetUrl(url *url.URL) *DefaultRequestBuilder { rqb.url = url return rqb } func (rqb *DefaultRequestBuilder) SetHeader(parsed *Header, fields header) *DefaultRequestBuilder { rqb.header.Header = parsed rqb.header.fields = fields return rqb } func (rqb *DefaultRequestBuilder) SetValues(parsed *Values, fields values) *DefaultRequestBuilder { rqb.values.Values = parsed rqb.values.fields = fields return rqb } func (rqb *DefaultRequestBuilder) SetBody(parsed *Body, fields body) *DefaultRequestBuilder { rqb.body.Body = parsed rqb.body.fields = fields return rqb } func (rqb *DefaultRequestBuilder) SetDefaults() *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) Allowed(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) Url(url url.URL) (e Error) { *rqb.url = url return } func (rqb *DefaultRequestBuilder) Header(header Header) (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) Body(body io.ReadCloser) (e Error) { defer body.Close() json.NewDecoder(body).Decode(rqb.body.fields) return } func (rqb *DefaultRequestBuilder) Values(values Values) (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 *request) { req = &request{ Url: *rqb.url, Header: *rqb.header.Header, Values: *rqb.values.Values, Body: *rqb.body.Body, } return }