Skip to content

Commit

Permalink
Merge pull request #24 from vvatanabe/issue-23/change-way-to-path-mat…
Browse files Browse the repository at this point in the history
…ching

#23 change the path matching to string comparison from regular expres…
  • Loading branch information
vvatanabe authored Nov 22, 2017
2 parents 331747a + f085dae commit 5acdf14
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 41 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ func main() {
// You can add some custom route.
ght.Router.Add(githttptransfer.NewRoute(
http.MethodGet,
regexp.MustCompile("(.*?)/hello$"),
func (path string) (match string) {
suffix := "/hello"
if strings.HasSuffix(path, suffix) {
match = suffix
}
return
},
func(ctx githttptransfer.Context) {
resp, req := ctx.Response(), ctx.Request()
rp, fp := ctx.RepoPath(), ctx.FilePath()
Expand Down
10 changes: 8 additions & 2 deletions addon/archivehandler/archivehandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ import (
)

var (
Pattern = regexp.MustCompile("(.*?)/archive/.*?\\.(zip|tar)$")
Method = http.MethodGet
r = regexp.MustCompile(".*?(/archive/.*?\\.(zip|tar))$")
Pattern = func(path string) (match string) {
if m := r.FindStringSubmatch(path); m != nil {
match = m[1]
}
return
}
Method = http.MethodGet
)

func New(ght *githttptransfer.GitHTTPTransfer) *ArchiveHandler {
Expand Down
10 changes: 8 additions & 2 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import (
"fmt"
"log"
"net/http"
"regexp"
"time"

"flag"

"github.com/vvatanabe/go-git-http-transfer/addon/archivehandler"
"github.com/vvatanabe/go-git-http-transfer/githttptransfer"
"strings"
)

func main() {
Expand Down Expand Up @@ -40,7 +40,13 @@ func main() {
// You can add some custom route.
ght.Router.Add(githttptransfer.NewRoute(
http.MethodGet,
regexp.MustCompile("(.*?)/hello$"),
func(path string) (match string) {
suffix := "/hello"
if strings.HasSuffix(path, suffix) {
match = suffix
}
return
},
func(ctx githttptransfer.Context) {
resp, req := ctx.Response(), ctx.Request()
rp, fp := ctx.RepoPath(), ctx.FilePath()
Expand Down
1 change: 0 additions & 1 deletion githttptransfer/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@ type MethodNotAllowedError struct {
func (e *MethodNotAllowedError) Error() string {
return fmt.Sprintf("Method Not Allowed: Method %s, Path %s", e.Method, e.Path)
}

71 changes: 59 additions & 12 deletions githttptransfer/githttptransfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,64 @@ import (
)

var (
serviceRPCUpload = regexp.MustCompile("(.*?)/git-upload-pack$")
serviceRPCReceive = regexp.MustCompile("(.*?)/git-receive-pack$")
getInfoRefs = regexp.MustCompile("(.*?)/info/refs$")
getHead = regexp.MustCompile("(.*?)/HEAD$")
getAlternates = regexp.MustCompile("(.*?)/objects/info/alternates$")
getHTTPAlternates = regexp.MustCompile("(.*?)/objects/info/http-alternates$")
getInfoPacks = regexp.MustCompile("(.*?)/objects/info/packs$")
getInfoFile = regexp.MustCompile("(.*?)/objects/info/[^/]*$")
getLooseObject = regexp.MustCompile("(.*?)/objects/[0-9a-f]{2}/[0-9a-f]{38}$")
getPackFile = regexp.MustCompile("(.*?)/objects/pack/pack-[0-9a-f]{40}\\.pack$")
getIdxFile = regexp.MustCompile("(.*?)/objects/pack/pack-[0-9a-f]{40}\\.idx$")
serviceRPCUpload = func(path string) (match string) {
return hasSuffix(path, "/git-upload-pack")
}
serviceRPCReceive = func(path string) (match string) {
return hasSuffix(path, "/git-receive-pack")
}

getInfoRefs = func(path string) (match string) {
return hasSuffix(path, "/info/refs")
}

getHead = func(path string) (match string) {
return hasSuffix(path, "/HEAD")
}

getAlternates = func(path string) (match string) {
return hasSuffix(path, "/objects/info/alternates")
}

getHTTPAlternates = func(path string) (match string) {
return hasSuffix(path, "/objects/info/http-alternates")
}

getInfoPacks = func(path string) (match string) {
return hasSuffix(path, "/objects/info/packs")
}

getInfoFile = func(path string) (match string) {
return findStringSubmatch(path, regexp.MustCompile(".*?(/objects/info/[^/]*)$"))
}

getLooseObject = func(path string) (match string) {
return findStringSubmatch(path, regexp.MustCompile(".*?(/objects/[0-9a-f]{2}/[0-9a-f]{38})$"))
}

getPackFile = func(path string) (match string) {
return findStringSubmatch(path, regexp.MustCompile(".*?(/objects/pack/pack-[0-9a-f]{40}\\.pack)$"))
}

getIdxFile = func(path string) (match string) {
return findStringSubmatch(path, regexp.MustCompile(".*?(/objects/pack/pack-[0-9a-f]{40}\\.idx)$"))
}
)

func hasSuffix(path, suffix string) (match string) {
if strings.HasSuffix(path, suffix) {
match = suffix
}
return
}

func findStringSubmatch(path string, prefix *regexp.Regexp) (match string) {
if m := prefix.FindStringSubmatch(path); m != nil {
match = m[1]
}
return
}

type options struct {
uploadPack bool
receivePack bool
Expand Down Expand Up @@ -72,7 +117,9 @@ func New(gitRootPath, gitBinPath string, opts ...Option) (*GitHTTPTransfer, erro
event := newEvent()

ght := &GitHTTPTransfer{git, router, event}

ght.Router.Add(NewRoute(http.MethodPost, serviceRPCUpload, ght.serviceRPCUpload))

ght.Router.Add(NewRoute(http.MethodPost, serviceRPCReceive, ght.serviceRPCReceive))
ght.Router.Add(NewRoute(http.MethodGet, getInfoRefs, ght.getInfoRefs))

Expand Down Expand Up @@ -122,7 +169,7 @@ func (ght *GitHTTPTransfer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
func (ght *GitHTTPTransfer) matchRouting(method, path string) (repoPath string, filePath string, handler HandlerFunc, err error) {
match, route, err := ght.Router.Match(method, path)
if err == nil {
repoPath = match[1]
repoPath = strings.Replace(path, match, "", 1)
filePath = strings.Replace(path, repoPath+"/", "", 1)
handler = route.Handler
}
Expand Down
15 changes: 7 additions & 8 deletions githttptransfer/router.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package githttptransfer

import (
"regexp"
)

type router struct {
routes []*Route
}
Expand All @@ -15,9 +11,9 @@ func (r *router) Add(route *Route) {
r.routes = append(r.routes, route)
}

func (r *router) Match(method string, path string) (match []string, route *Route, err error) {
func (r *router) Match(method string, path string) (match string, route *Route, err error) {
for _, v := range r.routes {
if m := v.Pattern.FindStringSubmatch(path); m != nil {
if m := v.Pattern(path); m != "" {
if v.Method != method {
err = &MethodNotAllowedError{
Method: method,
Expand All @@ -30,6 +26,7 @@ func (r *router) Match(method string, path string) (match []string, route *Route
return
}
}

err = &URLNotFoundError{
Method: method,
Path: path,
Expand All @@ -41,12 +38,14 @@ func newRouter() *router {
return &router{routes: []*Route{}}
}

type Pattern = func(path string) (match string)

type Route struct {
Method string
Pattern *regexp.Regexp
Pattern Pattern
Handler HandlerFunc
}

func NewRoute(method string, pattern *regexp.Regexp, handler HandlerFunc) *Route {
func NewRoute(method string, pattern Pattern, handler HandlerFunc) *Route {
return &Route{method, pattern, handler}
}
36 changes: 21 additions & 15 deletions githttptransfer/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ package githttptransfer

import (
"net/http"
"regexp"
"testing"
)

func Test_Router_Append_should_append_route(t *testing.T) {
router := &router{}
router.Add(&Route{
http.MethodPost,
regexp.MustCompile("(.*?)/foo"),
func(path string) (match string) {
return hasSuffix(path, "/foo")
},
func(ctx Context) {},
})
router.Add(&Route{
http.MethodPost,
regexp.MustCompile("(.*?)/bar"),
func(path string) (match string) {
return hasSuffix(path, "/bar")
},
func(ctx Context) {},
})
length := len(router.routes)
Expand All @@ -29,7 +32,9 @@ func Test_Router_Match_should_match_route(t *testing.T) {
router := &router{}
router.Add(&Route{
http.MethodPost,
regexp.MustCompile("(.*?)/foo"),
func(path string) (match string) {
return hasSuffix(path, "/foo")
},
func(ctx Context) {},
})
match, route, err := router.Match(http.MethodPost, "/base/foo")
Expand All @@ -39,27 +44,26 @@ func Test_Router_Match_should_match_route(t *testing.T) {
if http.MethodPost != route.Method {
t.Errorf("http method is not %s . result: %s", http.MethodPost, route.Method)
}
if "/base/foo" != match[0] {
t.Errorf("match index 0 is not %s . result: %s", "/base/foo", match[0])
}
if "/base" != match[1] {
t.Errorf("match index 1 is not %s . result: %s", "/base", match[1])
if "/foo" != match {
t.Errorf("match is not %s . result: %s", "/foo", match)
}
}

func Test_Router_Match_should_return_UrlNotFound_error(t *testing.T) {
router := &router{}
router.Add(&Route{
http.MethodPost,
regexp.MustCompile("(.*?)/foo"),
func(path string) (match string) {
return hasSuffix(path, "/foo")
},
func(ctx Context) {},
})
match, route, err := router.Match(http.MethodPost, "/base/hoge")
if err == nil {
t.Error("error is nil.")
}
if match != nil {
t.Error("match is not nil.")
if match != "" {
t.Error("match is not empty.")
}
if route != nil {
t.Error("route is not nil.")
Expand All @@ -75,15 +79,17 @@ func Test_Router_Match_should_return_MethodNotAllowed_error(t *testing.T) {
router := &router{}
router.Add(&Route{
http.MethodPost,
regexp.MustCompile("(.*?)/foo"),
func(path string) (match string) {
return hasSuffix(path, "/foo")
},
func(ctx Context) {},
})
match, route, err := router.Match(http.MethodGet, "/base/foo")
if err == nil {
t.Error("error is nil.")
}
if match != nil {
t.Error("match is not nil.")
if match != "" {
t.Error("match is not empty.")
}
if route != nil {
t.Error("route is not nil.")
Expand Down

0 comments on commit 5acdf14

Please sign in to comment.