commit
486fa84f21
@ -0,0 +1 @@
|
||||
.idea/
|
@ -0,0 +1,160 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"git.nwestland.com/tools/nwjson"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCannotRead = errors.New("cannot read from body")
|
||||
ErrCannotWrite = errors.New("cannot write to body")
|
||||
ErrCannotConvertToBuffer = errors.New("cannot convert body to buffer")
|
||||
)
|
||||
|
||||
type body struct {
|
||||
parent any
|
||||
readerWriter any
|
||||
}
|
||||
|
||||
func newBody(parent any, readerWriter any) body {
|
||||
return body{
|
||||
parent: parent,
|
||||
readerWriter: readerWriter,
|
||||
}
|
||||
}
|
||||
|
||||
func (b body) Read(p []byte) (int, error) {
|
||||
if reader, ok := b.readerWriter.(io.Reader); ok {
|
||||
return reader.Read(p)
|
||||
}
|
||||
|
||||
return 0, ErrCannotRead
|
||||
}
|
||||
|
||||
func (b body) Bytes() []byte {
|
||||
if reader, ok := b.readerWriter.(io.Reader); ok {
|
||||
data, _ := io.ReadAll(reader)
|
||||
b.Close()
|
||||
return data
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b body) String() string {
|
||||
return string(b.Bytes())
|
||||
}
|
||||
|
||||
func (b body) Object() nwjson.Object {
|
||||
if reader, ok := b.readerWriter.(io.Reader); ok {
|
||||
return nwjson.ObjectFromStream(reader)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b body) Array() nwjson.Array {
|
||||
if reader, ok := b.readerWriter.(io.Reader); ok {
|
||||
return nwjson.ArrayFromStream(reader)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b body) UnmarshalJson(any any) error {
|
||||
if reader, ok := b.readerWriter.(io.Reader); ok {
|
||||
jd := json.NewDecoder(reader)
|
||||
err := jd.Decode(&any)
|
||||
|
||||
b.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
return ErrCannotRead
|
||||
}
|
||||
|
||||
func (b body) Write(p []byte) (int, error) {
|
||||
if writer, ok := b.readerWriter.(io.Writer); ok {
|
||||
return writer.Write(p)
|
||||
}
|
||||
|
||||
return 0, ErrCannotWrite
|
||||
}
|
||||
|
||||
func (b body) WriteString(s string) (int, error) {
|
||||
if writer, ok := b.readerWriter.(io.Writer); ok {
|
||||
return writer.Write([]byte(s))
|
||||
}
|
||||
|
||||
return 0, ErrCannotWrite
|
||||
}
|
||||
|
||||
func (b body) WriteJsonError(errText string, statusCode int) error {
|
||||
if response, ok := b.parent.(*Response); ok {
|
||||
defer response.SetStatusCode(statusCode)
|
||||
return b.MarshalJson(map[string]string{"Error": errText})
|
||||
}
|
||||
|
||||
return ErrCannotWrite
|
||||
}
|
||||
|
||||
func (b body) MarshalJson(any any) error {
|
||||
switch b.parent.(type) {
|
||||
case *Request:
|
||||
b.parent.(*Request).Headers.SetContentType("application/json")
|
||||
case *Response:
|
||||
b.parent.(*Response).Headers.SetContentType("application/json")
|
||||
}
|
||||
|
||||
if writer, ok := b.readerWriter.(io.Writer); ok {
|
||||
je := json.NewEncoder(writer)
|
||||
return je.Encode(any)
|
||||
}
|
||||
|
||||
return ErrCannotWrite
|
||||
}
|
||||
|
||||
func (b *body) Buffer() (*bytes.Buffer, error) {
|
||||
switch b.readerWriter.(type) {
|
||||
case *bytes.Buffer:
|
||||
return b.readerWriter.(*bytes.Buffer), nil
|
||||
case io.Reader:
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(b.readerWriter.(io.Reader))
|
||||
b.Close()
|
||||
b.readerWriter = buf
|
||||
return buf, nil
|
||||
default:
|
||||
return nil, ErrCannotConvertToBuffer
|
||||
}
|
||||
}
|
||||
|
||||
//TODO check if this is a good solution
|
||||
func (b *body) Len() int {
|
||||
var contentLength int
|
||||
switch b.parent.(type) {
|
||||
case *Request:
|
||||
contentLength = b.parent.(*Request).Headers.ContentLength()
|
||||
case *Response:
|
||||
contentLength = b.parent.(*Response).Headers.ContentLength()
|
||||
}
|
||||
|
||||
if contentLength == 0 {
|
||||
if buf, err := b.Buffer(); err == nil {
|
||||
return buf.Len()
|
||||
}
|
||||
}
|
||||
|
||||
return contentLength
|
||||
}
|
||||
|
||||
func (b body) Close() error {
|
||||
if readCloser, ok := b.readerWriter.(io.ReadCloser); ok {
|
||||
return readCloser.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var DefaultClient = NewClient()
|
||||
|
||||
type Client struct {
|
||||
httpClient *http.Client
|
||||
httpCookieJar http.CookieJar
|
||||
}
|
||||
|
||||
func NewClient() *Client {
|
||||
httpCookieJar, _ := cookiejar.New(nil)
|
||||
|
||||
return &Client{
|
||||
httpClient: &http.Client{
|
||||
Transport: &http.Transport{},
|
||||
Jar: httpCookieJar,
|
||||
},
|
||||
httpCookieJar: httpCookieJar,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Client) Do(request *Request) *Response {
|
||||
request.finalize()
|
||||
httpResponse, err := c.httpClient.Do(request.httpRequest)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return newResponseClient(httpResponse)
|
||||
}
|
||||
|
||||
func (c *Client) SetProxy(hostname string, port int) {
|
||||
proxyUrl, _ := url.Parse(fmt.Sprintf("%s:%d", hostname, port))
|
||||
c.httpClient.Transport.(*http.Transport).Proxy = http.ProxyURL(proxyUrl)
|
||||
}
|
||||
|
||||
func (c *Client) SetSSLChecks(enabled bool) {
|
||||
c.httpClient.Transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: !enabled}
|
||||
}
|
||||
|
||||
func (c *Client) SetTLSVersion(maxVersion uint16) {
|
||||
tlsConfig := &tls.Config{MaxVersion: maxVersion}
|
||||
c.httpClient.Transport.(*http.Transport).DialTLS = func(network, addr string) (net.Conn, error) {
|
||||
return tls.Dial(network, addr, tlsConfig)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) DisableHTTP2() {
|
||||
c.httpClient.Transport.(*http.Transport).TLSNextProto = make(map[string]func(authority string, c *tls.Conn) http.RoundTripper)
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package nwweb
|
||||
|
||||
import "git.nwestland.com/tools/nwjson"
|
||||
|
||||
type convertable struct {
|
||||
stringVal func(string) string
|
||||
}
|
||||
|
||||
func (c convertable) String(key string) string {
|
||||
return c.stringVal(key)
|
||||
}
|
||||
|
||||
func (c convertable) Bytes(key string) []byte {
|
||||
return stringToBytes(c.String(key))
|
||||
}
|
||||
|
||||
func (c convertable) Int(key string) int {
|
||||
return stringToInt(c.String(key))
|
||||
}
|
||||
|
||||
func (c convertable) Bool(key string) bool {
|
||||
return stringToBool(c.String(key))
|
||||
}
|
||||
|
||||
func (c convertable) Float32(key string) float32 {
|
||||
return stringToFloat32(c.String(key))
|
||||
}
|
||||
|
||||
func (c convertable) Float64(key string) float64 {
|
||||
return stringToFloat64(c.String(key))
|
||||
}
|
||||
|
||||
func (c convertable) Object(key string) nwjson.Object {
|
||||
return stringToObject(c.String(key))
|
||||
}
|
||||
|
||||
func (c convertable) Array(key string) nwjson.Array {
|
||||
return stringToArray(c.String(key))
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type form struct {
|
||||
convertable
|
||||
postForm url.Values
|
||||
httpRequest *http.Request
|
||||
}
|
||||
|
||||
func newForm(httpRequest *http.Request) form {
|
||||
if httpRequest.Form == nil {
|
||||
httpRequest.ParseForm()
|
||||
}
|
||||
|
||||
f := form{httpRequest: httpRequest}
|
||||
f.stringVal = func(key string) string {
|
||||
return f.httpRequest.Form.Get(key)
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *form) Set(key string, value any) {
|
||||
if f.postForm == nil {
|
||||
f.postForm = url.Values{}
|
||||
}
|
||||
|
||||
f.postForm.Set(key, anyToString(value))
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
module git.nwestland.com/tools/nwweb
|
||||
|
||||
go 1.18
|
||||
|
||||
require git.nwestland.com/tools/nwjson v0.0.0-20220420120036-0c00931366e7
|
@ -0,0 +1,2 @@
|
||||
git.nwestland.com/tools/nwjson v0.0.0-20220420120036-0c00931366e7 h1:f4eqAeUQ8B94VvXPdKy8lJW1Z0K/kgA0LdRD3ktRH90=
|
||||
git.nwestland.com/tools/nwjson v0.0.0-20220420120036-0c00931366e7/go.mod h1:eMzX1O7T63BIw+CigFeul8xaqrY8DDkHU83N4NTTTgc=
|
@ -0,0 +1,62 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type headers struct {
|
||||
httpObj any
|
||||
}
|
||||
|
||||
func newHeaders(httpObj any) headers {
|
||||
return headers{httpObj: httpObj}
|
||||
}
|
||||
|
||||
func (h headers) Get(key string) string {
|
||||
switch h.httpObj.(type) {
|
||||
case *http.Request:
|
||||
return h.httpObj.(*http.Request).Header.Get(key)
|
||||
case *http.Response:
|
||||
return h.httpObj.(*http.Response).Header.Get(key)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (h headers) ContentLength() int {
|
||||
return stringToInt(h.Get("Content-Length"))
|
||||
}
|
||||
|
||||
func (h headers) Set(key string, value any) {
|
||||
switch h.httpObj.(type) {
|
||||
case *http.Request:
|
||||
h.httpObj.(*http.Request).Header.Set(key, anyToString(value))
|
||||
case http.ResponseWriter:
|
||||
h.httpObj.(http.ResponseWriter).Header().Set(key, anyToString(value))
|
||||
}
|
||||
}
|
||||
|
||||
func (h headers) SetContentType(mimeType string) {
|
||||
h.Set("Content-Type", mimeType)
|
||||
}
|
||||
|
||||
func (h headers) SetContentLength(contentLength int) {
|
||||
switch h.httpObj.(type) {
|
||||
case *http.Request:
|
||||
h.httpObj.(*http.Request).ContentLength = int64(contentLength)
|
||||
//http.ResponseWriter automatically sets its content length
|
||||
}
|
||||
}
|
||||
|
||||
func (h headers) SetBasicAuth(username, password string) {
|
||||
h.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(username+":"+password)))
|
||||
}
|
||||
|
||||
func (h headers) SetBearerAuth(token string) {
|
||||
h.Set("Authorization", "Bearer "+token)
|
||||
}
|
||||
|
||||
func (h headers) SetUserAgent(userAgent string) {
|
||||
h.Set("User-Agent", userAgent)
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package nwweb
|
||||
|
||||
type IController interface {
|
||||
GetRoutes() []Route
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.nwestland.com/tools/nwjson"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
GET = "GET"
|
||||
HEAD = "HEAD"
|
||||
POST = "POST"
|
||||
PUT = "PUT"
|
||||
PATCH = "PATCH"
|
||||
DELETE = "DELETE"
|
||||
CONNECT = "CONNECT"
|
||||
OPTIONS = "OPTIONS"
|
||||
TRACE = "TRACE"
|
||||
)
|
||||
|
||||
const (
|
||||
TLS10 = 0x0301
|
||||
TLS11 = 0x0302
|
||||
TLS12 = 0x0303
|
||||
TLS13 = 0x0304
|
||||
SSL30 = 0x0300
|
||||
)
|
||||
|
||||
func stringToBytes(stringVal string) []byte {
|
||||
return []byte(stringVal)
|
||||
}
|
||||
|
||||
func stringToInt(stringVal string) (val int) {
|
||||
val, _ = strconv.Atoi(stringVal)
|
||||
return
|
||||
}
|
||||
|
||||
func stringToBool(stringVal string) (val bool) {
|
||||
val, _ = strconv.ParseBool(stringVal)
|
||||
return
|
||||
}
|
||||
|
||||
func stringToFloat32(stringVal string) float32 {
|
||||
value, _ := strconv.ParseFloat(stringVal, 32)
|
||||
return float32(value)
|
||||
}
|
||||
|
||||
func stringToFloat64(stringVal string) (val float64) {
|
||||
val, _ = strconv.ParseFloat(stringVal, 64)
|
||||
return
|
||||
}
|
||||
|
||||
func stringToObject(stringVal string) nwjson.Object {
|
||||
return nwjson.ObjectFromString(stringVal)
|
||||
}
|
||||
|
||||
func stringToArray(stringVal string) nwjson.Array {
|
||||
return nwjson.ArrayFromString(stringVal)
|
||||
}
|
||||
|
||||
func anyToString(value any) string {
|
||||
switch value.(type) {
|
||||
case nwjson.Object:
|
||||
return value.(nwjson.Object).ToString()
|
||||
case nwjson.Array:
|
||||
return value.(nwjson.Array).ToString()
|
||||
default:
|
||||
return fmt.Sprintf("%v", value)
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.nwestland.com/tools/nwjson"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
req, err := http.NewRequest(http.MethodGet, "https://www.postman-echo.com/get", nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
data, _ := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
|
||||
fmt.Println(len(data))
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
req := NewRequest(POST, "https://www.postman-echo.com/post")
|
||||
req.QueryParameters.Set("query", "test")
|
||||
req.Body.MarshalJson(nwjson.Object{"Username": "johndoe"})
|
||||
|
||||
resp := DefaultClient.Do(req)
|
||||
fmt.Println(resp.Body.Object().ToPrettyString())
|
||||
}
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
server := NewServer("localhost", 8080)
|
||||
server.RegisterController(TestController{})
|
||||
server.Start()
|
||||
}
|
||||
|
||||
type TestController struct{}
|
||||
|
||||
func (e TestController) GetRoutes() []Route {
|
||||
return []Route{
|
||||
{
|
||||
Pattern: "/",
|
||||
Handler: e.Test,
|
||||
Method: GET,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (e TestController) Test(response *Response, request *Request) {
|
||||
response.Body.WriteString("Hi there")
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type queryParameters struct {
|
||||
convertable
|
||||
httpRequest *http.Request
|
||||
}
|
||||
|
||||
func newQueryParameters(httpRequest *http.Request) queryParameters {
|
||||
q := queryParameters{httpRequest: httpRequest}
|
||||
q.stringVal = func(key string) string {
|
||||
return q.httpRequest.URL.Query().Get(key)
|
||||
}
|
||||
|
||||
return q
|
||||
}
|
||||
|
||||
func (q queryParameters) Set(key string, value any) {
|
||||
if len(q.httpRequest.URL.RawQuery) > 0 {
|
||||
q.httpRequest.URL.RawQuery += fmt.Sprintf("&%s=%s", key, url.QueryEscape(fmt.Sprintf("%v", value)))
|
||||
} else {
|
||||
q.httpRequest.URL.RawQuery = fmt.Sprintf("%s=%s", key, url.QueryEscape(fmt.Sprintf("%v", value)))
|
||||
}
|
||||
}
|
||||
|
||||
func (q queryParameters) ReplaceWith(query url.Values) {
|
||||
q.httpRequest.URL.RawQuery = query.Encode()
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
httpRequest *http.Request
|
||||
Body body
|
||||
Headers headers
|
||||
QueryParameters queryParameters
|
||||
Form form
|
||||
}
|
||||
|
||||
func NewRequest(method, urlFmt string, args ...any) *Request {
|
||||
var httpRequest *http.Request
|
||||
if len(args) > 0 {
|
||||
httpRequest, _ = http.NewRequest(method, fmt.Sprintf(urlFmt, args...), nil)
|
||||
} else {
|
||||
httpRequest, _ = http.NewRequest(method, urlFmt, nil)
|
||||
}
|
||||
|
||||
r := &Request{
|
||||
httpRequest: httpRequest,
|
||||
Headers: newHeaders(httpRequest),
|
||||
QueryParameters: newQueryParameters(httpRequest),
|
||||
Form: newForm(httpRequest),
|
||||
}
|
||||
|
||||
r.Body = newBody(r, new(bytes.Buffer))
|
||||
return r
|
||||
}
|
||||
|
||||
func newRequestServer(httpRequest *http.Request) *Request {
|
||||
r := &Request{
|
||||
httpRequest: httpRequest,
|
||||
Headers: newHeaders(httpRequest),
|
||||
QueryParameters: newQueryParameters(httpRequest),
|
||||
Form: newForm(httpRequest),
|
||||
}
|
||||
|
||||
r.Body = newBody(r, httpRequest.Body)
|
||||
return r
|
||||
}
|
||||
|
||||
func (r Request) Method() string {
|
||||
return r.httpRequest.Method
|
||||
}
|
||||
|
||||
func (r Request) Cookie(key string) *http.Cookie {
|
||||
cookie, _ := r.httpRequest.Cookie(key)
|
||||
return cookie
|
||||
}
|
||||
|
||||
func (r Request) IP() net.IP {
|
||||
if ipString, _, err := net.SplitHostPort(r.httpRequest.RemoteAddr); err == nil {
|
||||
return net.ParseIP(ipString)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r Request) SetCookie(cookie *http.Cookie) {
|
||||
r.httpRequest.AddCookie(cookie)
|
||||
}
|
||||
|
||||
func (r *Request) finalize() {
|
||||
r.httpRequest.ContentLength = int64(r.Body.Len())
|
||||
r.httpRequest.Body = r.Body
|
||||
r.httpRequest.GetBody = func() (io.ReadCloser, error) {
|
||||
return r.Body, nil
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package nwweb
|
||||
|
||||
import "net/http"
|
||||
|
||||
type Response struct {
|
||||
httpObj any
|
||||
Body body
|
||||
Headers headers
|
||||
}
|
||||
|
||||
func newResponseClient(httpResponse *http.Response) *Response {
|
||||
r := &Response{
|
||||
httpObj: httpResponse,
|
||||
Headers: newHeaders(httpResponse),
|
||||
}
|
||||
|
||||
r.Body = newBody(r, httpResponse.Body)
|
||||
return r
|
||||
}
|
||||
|
||||
func newResponseServer(httpResponseWriter http.ResponseWriter) *Response {
|
||||
r := &Response{
|
||||
httpObj: httpResponseWriter,
|
||||
Headers: newHeaders(httpResponseWriter),
|
||||
}
|
||||
|
||||
r.Body = newBody(r, httpResponseWriter)
|
||||
return r
|
||||
}
|
||||
|
||||
func (r Response) StatusCode() int {
|
||||
if response, ok := r.httpObj.(*http.Response); ok {
|
||||
return response.StatusCode
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (r Response) Cookie(name string) *http.Cookie {
|
||||
if response, ok := r.httpObj.(*http.Response); ok {
|
||||
for _, cookie := range response.Cookies() {
|
||||
if cookie.Name == name {
|
||||
return cookie
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r Response) SetStatusCode(statusCode int) {
|
||||
if responseWriter, ok := r.httpObj.(http.ResponseWriter); ok {
|
||||
responseWriter.WriteHeader(statusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func (r Response) SetCookie(cookie *http.Cookie) {
|
||||
if responseWriter, ok := r.httpObj.(http.ResponseWriter); ok {
|
||||
http.SetCookie(responseWriter, cookie)
|
||||
}
|
||||
}
|
||||
|
||||
func (r Response) Redirect(request *Request, toUrl string, statusCode int) {
|
||||
if responseWriter, ok := r.httpObj.(http.ResponseWriter); ok {
|
||||
http.Redirect(responseWriter, request.httpRequest, toUrl, statusCode)
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package nwweb
|
||||
|
||||
type Route struct {
|
||||
Pattern string
|
||||
Handler func(response *Response, request *Request)
|
||||
Method string
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package nwweb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
httpServeMux *http.ServeMux
|
||||
httpServer *http.Server
|
||||
}
|
||||
|
||||
func NewServer(hostname string, port int) *Server {
|
||||
mux := http.NewServeMux()
|
||||
return &Server{
|
||||
httpServeMux: mux,
|
||||
httpServer: &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", hostname, port),
|
||||
Handler: mux,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) RegisterFunc(pattern, method string, handler func(response *Response, request *Request)) {
|
||||
s.httpServeMux.HandleFunc(pattern, func(httpResponseWriter http.ResponseWriter, httpRequest *http.Request) {
|
||||
if len(method) == 0 || method == "*" || method == httpRequest.Method {
|
||||
handler(newResponseServer(httpResponseWriter), newRequestServer(httpRequest))
|
||||
return
|
||||
}
|
||||
|
||||
httpResponseWriter.WriteHeader(http.StatusMethodNotAllowed)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) RegisterController(controller IController) {
|
||||
for _, route := range controller.GetRoutes() {
|
||||
s.RegisterFunc(route.Pattern, route.Method, route.Handler)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
return s.httpServer.ListenAndServe()
|
||||
}
|
Loading…
Reference in new issue