Skip to content

Commit

Permalink
issue #26 separate global and custom handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
wmentor committed Jan 9, 2021
1 parent cbf0b8a commit f05251d
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 93 deletions.
16 changes: 16 additions & 0 deletions global.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,19 @@ func Static(prefix string, dir string) {
func File(path string, filename string) {
server.File(path, filename)
}

func Register(method string, path string, fn Handler) {
server.Register(method, path, fn)
}

func RegisterAuth(method string, path string, fn Handler) {
server.RegisterAuth(method, path, fn)
}

func RegMethod(method string, fn interface{}) {
server.RegMethod(method, fn)
}

func RegisterJsonRPC(url string) {
server.RegisterJsonRPC(url)
}
90 changes: 0 additions & 90 deletions router.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package serv

import (
"bytes"
"errors"
"fmt"
"net/http"
"strings"
"time"

"github.com/wmentor/jrpc"
"github.com/wmentor/latency"
"github.com/wmentor/tt"
"github.com/wmentor/uniq"
Expand Down Expand Up @@ -58,94 +56,6 @@ func (sr *router) optionsOrNotFound(c *Context) {
}
}

func Register(method string, path string, fn Handler) {

root, has := rt.methods[method]
if !has {
root = &node{childs: make(map[string]*node)}
rt.methods[method] = root
}

list := path2list(path)
if len(list) == 0 {
return
}

for _, item := range list {

if item[0] == ':' {
n, h := root.childs[""]
if !h {
name := item
if len(name) > 1 {
name = item[1:]
} else {
name = ""
}
n = &node{name: name, wildCard: false, childs: make(map[string]*node)}
}
root.childs[""] = n
root = n
} else if item == "*" {
_, h := root.childs[""]
if !h {
root.childs[""] = &node{name: "*", fn: fn, wildCard: true}
}
return
} else {

n, h := root.childs[item]
if !h {
n = &node{name: "", wildCard: false, childs: make(map[string]*node)}
}
root.childs[item] = n
root = n
}
}

root.fn = fn
}

func RegisterAuth(method string, path string, fn Handler) {

Register(method, path, func(c *Context) {

if user, login, has := c.BasicAuth(); has {
if rt.authCheck(user, login) {
fn(c)
return
}
}

c.SetHeader("WWW-Authenticate", `Basic realm="Enter your login and password"`)
c.WriteHeader(http.StatusUnauthorized)
c.WriteString("Unauthorized.")
})

}

func RegMethod(method string, fn interface{}) {
jrpc.RegMethod(method, fn)
}

func RegisterJsonRPC(url string) {

Register("POST", url, func(c *Context) {

out := bytes.NewBuffer(nil)

if err := jrpc.Process(c.Body(), out); err == nil {
c.SetContentType("application/json; charset=utf-8")
c.WriteHeader(200)
c.Write(out.Bytes())
} else {
c.StandardError(400)
}

})

}

func (r *router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

if handler, has := r.fileHandlers[req.URL.Path]; has {
Expand Down
4 changes: 2 additions & 2 deletions router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestServ(t *testing.T) {
rw := httptest.NewRecorder()
req := httptest.NewRequest("GET", url, nil)

rt.ServeHTTP(rw, req)
server.router.ServeHTTP(rw, req)

res := rw.Result()

Expand Down Expand Up @@ -82,7 +82,7 @@ func TestServ(t *testing.T) {
rw := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/rpc", bytes.NewReader(data))

rt.ServeHTTP(rw, req)
server.router.ServeHTTP(rw, req)

res := rw.Result()

Expand Down
95 changes: 94 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package serv

import (
"bytes"
"context"
"net/http"
"strings"
"time"

"github.com/wmentor/jrpc"
)

type Server struct {
router *router
server *http.Server
jrpc jrpc.JRPC
}

func New() *Server {
Expand All @@ -27,6 +31,8 @@ func New() *Server {
authCheck: func(login string, passwd string) bool { return false },
}

s.jrpc = jrpc.New()

return s
}

Expand All @@ -47,7 +53,7 @@ func (s *Server) Shutdown() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
if err := s.server.Shutdown(ctx); err != nil {
if rt != nil && s.router.errorHandler != nil {
if s.router != nil && s.router.errorHandler != nil {
s.router.errorHandler(err)
}
}
Expand Down Expand Up @@ -90,3 +96,90 @@ func (s *Server) Static(prefix string, dir string) {
func (s *Server) File(path string, filename string) {
s.router.fileHandlers[path] = &fileHandler{Filename: filename}
}

func (s *Server) Register(method string, path string, fn Handler) {

root, has := s.router.methods[method]
if !has {
root = &node{childs: make(map[string]*node)}
s.router.methods[method] = root
}

list := path2list(path)
if len(list) == 0 {
return
}

for _, item := range list {

if item[0] == ':' {
n, h := root.childs[""]
if !h {
name := item
if len(name) > 1 {
name = item[1:]
} else {
name = ""
}
n = &node{name: name, wildCard: false, childs: make(map[string]*node)}
}
root.childs[""] = n
root = n
} else if item == "*" {
_, h := root.childs[""]
if !h {
root.childs[""] = &node{name: "*", fn: fn, wildCard: true}
}
return
} else {

n, h := root.childs[item]
if !h {
n = &node{name: "", wildCard: false, childs: make(map[string]*node)}
}
root.childs[item] = n
root = n
}
}

root.fn = fn
}

func (s *Server) RegisterAuth(method string, path string, fn Handler) {

s.Register(method, path, func(c *Context) {

if user, login, has := c.BasicAuth(); has {
if s.router.authCheck(user, login) {
fn(c)
return
}
}

c.SetHeader("WWW-Authenticate", `Basic realm="Enter your login and password"`)
c.WriteHeader(http.StatusUnauthorized)
c.WriteString("Unauthorized.")
})
}

func (s *Server) RegMethod(method string, fn interface{}) {
s.jrpc.RegMethod(method, fn)
}

func (s *Server) RegisterJsonRPC(url string) {

s.Register("POST", url, func(c *Context) {

out := bytes.NewBuffer(nil)

if err := s.jrpc.Process(c.Body(), out); err == nil {
c.SetContentType("application/json; charset=utf-8")
c.WriteHeader(200)
c.Write(out.Bytes())
} else {
c.StandardError(400)
}

})

}

0 comments on commit f05251d

Please sign in to comment.