about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFranck Cuny <franck@lumberjaph.net>2013-04-17 21:48:28 -0700
committerFranck Cuny <franck@lumberjaph.net>2013-04-17 21:48:28 -0700
commitcf92b3634954474ee753c74d0ea4f22d60a6a953 (patch)
tree2b2d584262876c7cae6a3bb1827e03a41decca4d
parentWelcome to mooh. (diff)
downloadpath-router-cf92b3634954474ee753c74d0ea4f22d60a6a953.tar.gz
Very simple implementation for the framework.
For now the framework provide a "dispatcher" and a mechanism to add
routes.  The type "route" provide a constructor so some logic can be
applied before creating the type.

The way the dispatcher works for now is very stupid: it looks for all
the registered routes, and check if it's the right HTTP method and if
the patch matches.

The next step is to deal with place holder in the path.
-rw-r--r--dispatcher.go53
-rw-r--r--mooh.go28
-rw-r--r--request.go9
-rw-r--r--response.go7
-rw-r--r--route.go61
5 files changed, 158 insertions, 0 deletions
diff --git a/dispatcher.go b/dispatcher.go
new file mode 100644
index 0000000..b40b556
--- /dev/null
+++ b/dispatcher.go
@@ -0,0 +1,53 @@
+package mooh
+
+type Dispatcher struct {
+	Routes      []Route
+	RouteAccess map[string]*Route
+}
+
+func BuildDispatcher() Dispatcher {
+	router := Dispatcher{}
+	router.RouteAccess = map[string]*Route{}
+	return router
+}
+
+func (self *Dispatcher) GetRoute(path string) *Route {
+	r := self.RouteAccess[path]
+
+	if r != nil {
+		return r
+	}
+
+	return nil
+}
+
+func (self *Dispatcher) AddRoute(path string, method string, code func(*Request) (Response, error)) {
+	r := self.GetRoute(path)
+
+	if r == nil {
+		route := MakeRoute(path, method, code)
+		self.Routes = append(self.Routes, route)
+		self.RouteAccess[path] = &route
+	} else {
+		r.Executors[method] = code
+	}
+}
+
+func (self *Dispatcher) Match(request Request) *Route {
+	for _, r := range self.Routes {
+		match, route := r.Match(request)
+		if match == true {
+			return route
+		}
+	}
+	return nil
+}
+
+// func (*dispatcher) ListRoutes() {
+// }
+
+// func (*dispatcher) AddRoutes() {
+// }
+
+// func (self *dispatcher) UriFor() {
+// }
diff --git a/mooh.go b/mooh.go
new file mode 100644
index 0000000..6e0670f
--- /dev/null
+++ b/mooh.go
@@ -0,0 +1,28 @@
+package mooh
+
+import (
+	"fmt"
+	"net/http"
+)
+
+func (self *Dispatcher) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
+
+	request := Request{
+		req,
+	}
+
+	route := self.Match(request)
+
+	if route == nil {
+		fmt.Fprint(resp, "Not Found")
+		return
+	}
+
+	nresp, error := route.Execute(&request)
+
+	if error == nil {
+		fmt.Fprint(resp, nresp.Content)
+	} else {
+		fmt.Println(error)
+	}
+}
diff --git a/request.go b/request.go
new file mode 100644
index 0000000..eee6c80
--- /dev/null
+++ b/request.go
@@ -0,0 +1,9 @@
+package mooh
+
+import (
+	"net/http"
+)
+
+type Request struct {
+	*http.Request
+}
diff --git a/response.go b/response.go
new file mode 100644
index 0000000..d7069d7
--- /dev/null
+++ b/response.go
@@ -0,0 +1,7 @@
+package mooh
+
+type Response struct {
+	Location string
+	Content  string
+	Status   int
+}
diff --git a/route.go b/route.go
new file mode 100644
index 0000000..0c397f3
--- /dev/null
+++ b/route.go
@@ -0,0 +1,61 @@
+package mooh
+
+import (
+	"strings"
+)
+
+type Route struct {
+	Path       string
+	Executors  map[string]func(*Request) (Response, error)
+	Components []string
+	Length     int
+	//TODO validator
+}
+
+func (self *Route) Match(request Request) (bool, *Route) {
+
+	methodMatch := false
+	for m, _ := range self.Executors {
+		if m == request.Method {
+			methodMatch = true
+		}
+	}
+	if methodMatch == false {
+		return false, nil
+	}
+
+	components := strings.Split(request.Request.URL.Path, "/")
+
+	if len(components) > self.Length {
+		return false, nil
+	}
+
+	for i, c := range self.Components {
+		p := components[i]
+		if p != c {
+			return false, nil
+		}
+	}
+	return true, self
+}
+
+func (self *Route) Execute(request *Request) (Response, error) {
+	code := self.Executors[request.Method]
+	return code(request)
+}
+
+func MakeRoute(path string, method string, code func(*Request) (Response, error)) Route {
+
+	components := strings.Split(path, "/")
+
+	exec := map[string]func(*Request) (Response, error){method: code}
+
+	route := Route{
+		Path:       path,
+		Executors:  exec,
+		Components: components,
+		Length:     len(components),
+	}
+
+	return route
+}