Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
golang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Jobs
Commits
Open sidebar
Bogdan Ungureanu
golang
Commits
fe0ade8e
Commit
fe0ade8e
authored
Jul 02, 2014
by
Bogdan Ungureanu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding pat library
parent
44519877
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
193 additions
and
4 deletions
+193
-4
README.md
README.md
+5
-4
mux.go
net/http/pat/mux.go
+188
-0
No files found.
README.md
View file @
fe0ade8e
...
@@ -4,8 +4,9 @@ GO libraries
...
@@ -4,8 +4,9 @@ GO libraries
Libraries
Libraries
---------
---------
fs/inotify - inotify library
fs/inotify - inotify library
net/cluster - simple network cluster
net/cluster - simple network cluster
os/daemon - daemonize library
net/http/pat - http pat router library
util/ini - ini file library
os/daemon - daemonize library
util/ini - ini file library
net/http/pat/mux.go
0 → 100644
View file @
fe0ade8e
// Package pat implements a simple URL pattern muxer
package
pat
import
(
"net/http"
"net/url"
"strings"
)
type
PatternServeMux
struct
{
handlers
map
[
string
][]
*
patHandler
}
// New returns a new PatternServeMux.
func
New
()
*
PatternServeMux
{
return
&
PatternServeMux
{
make
(
map
[
string
][]
*
patHandler
)}
}
// ServeHTTP matches r.URL.Path against its routing table using the rules
// described above.
func
(
p
*
PatternServeMux
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
for
_
,
ph
:=
range
p
.
handlers
[
r
.
Method
]
{
if
params
,
ok
:=
ph
.
try
(
r
.
URL
.
Path
);
ok
{
if
len
(
params
)
>
0
{
r
.
URL
.
RawQuery
=
url
.
Values
(
params
)
.
Encode
()
+
"&"
+
r
.
URL
.
RawQuery
}
ph
.
ServeHTTP
(
w
,
r
)
return
}
}
allowed
:=
make
([]
string
,
0
,
len
(
p
.
handlers
))
for
meth
,
handlers
:=
range
p
.
handlers
{
if
meth
==
r
.
Method
{
continue
}
for
_
,
ph
:=
range
handlers
{
if
_
,
ok
:=
ph
.
try
(
r
.
URL
.
Path
);
ok
{
allowed
=
append
(
allowed
,
meth
)
}
}
}
if
len
(
allowed
)
==
0
{
http
.
NotFound
(
w
,
r
)
return
}
w
.
Header
()
.
Add
(
"Allow"
,
strings
.
Join
(
allowed
,
", "
))
http
.
Error
(
w
,
"Method Not Allowed"
,
405
)
}
// Head will register a pattern with a handler for HEAD requests.
func
(
p
*
PatternServeMux
)
Head
(
pat
string
,
h
http
.
Handler
)
{
p
.
Add
(
"HEAD"
,
pat
,
h
)
}
// Get will register a pattern with a handler for GET requests.
// It also registers pat for HEAD requests. If this needs to be overridden, use
// Head before Get with pat.
func
(
p
*
PatternServeMux
)
Get
(
pat
string
,
h
http
.
Handler
)
{
p
.
Add
(
"HEAD"
,
pat
,
h
)
p
.
Add
(
"GET"
,
pat
,
h
)
}
// Post will register a pattern with a handler for POST requests.
func
(
p
*
PatternServeMux
)
Post
(
pat
string
,
h
http
.
Handler
)
{
p
.
Add
(
"POST"
,
pat
,
h
)
}
// Put will register a pattern with a handler for PUT requests.
func
(
p
*
PatternServeMux
)
Put
(
pat
string
,
h
http
.
Handler
)
{
p
.
Add
(
"PUT"
,
pat
,
h
)
}
// Del will register a pattern with a handler for DELETE requests.
func
(
p
*
PatternServeMux
)
Del
(
pat
string
,
h
http
.
Handler
)
{
p
.
Add
(
"DELETE"
,
pat
,
h
)
}
// Options will register a pattern with a handler for OPTIONS requests.
func
(
p
*
PatternServeMux
)
Options
(
pat
string
,
h
http
.
Handler
)
{
p
.
Add
(
"OPTIONS"
,
pat
,
h
)
}
// Add will register a pattern with a handler for meth requests.
func
(
p
*
PatternServeMux
)
Add
(
meth
,
pat
string
,
h
http
.
Handler
)
{
p
.
handlers
[
meth
]
=
append
(
p
.
handlers
[
meth
],
&
patHandler
{
pat
,
h
})
n
:=
len
(
pat
)
if
n
>
0
&&
pat
[
n
-
1
]
==
'/'
{
p
.
Add
(
meth
,
pat
[
:
n
-
1
],
http
.
RedirectHandler
(
pat
,
http
.
StatusMovedPermanently
))
}
}
// Tail returns the trailing string in path after the final slash for a pat ending with a slash.
//
// Examples:
//
// Tail("/hello/:title/", "/hello/mr/mizerany") == "mizerany"
// Tail("/:a/", "/x/y/z") == "y/z"
//
func
Tail
(
pat
,
path
string
)
string
{
var
i
,
j
int
for
i
<
len
(
path
)
{
switch
{
case
j
>=
len
(
pat
)
:
if
pat
[
len
(
pat
)
-
1
]
==
'/'
{
return
path
[
j
-
1
:
]
}
return
""
case
pat
[
j
]
==
':'
:
var
nextc
byte
_
,
nextc
,
j
=
match
(
pat
,
isAlnum
,
j
+
1
)
_
,
_
,
i
=
match
(
path
,
matchPart
(
nextc
),
i
)
case
path
[
i
]
==
pat
[
j
]
:
i
++
j
++
default
:
return
""
}
}
return
""
}
type
patHandler
struct
{
pat
string
http
.
Handler
}
func
(
ph
*
patHandler
)
try
(
path
string
)
(
url
.
Values
,
bool
)
{
p
:=
make
(
url
.
Values
)
var
i
,
j
int
for
i
<
len
(
path
)
{
switch
{
case
j
>=
len
(
ph
.
pat
)
:
if
ph
.
pat
!=
"/"
&&
len
(
ph
.
pat
)
>
0
&&
ph
.
pat
[
len
(
ph
.
pat
)
-
1
]
==
'/'
{
return
p
,
true
}
return
nil
,
false
case
ph
.
pat
[
j
]
==
':'
:
var
name
,
val
string
var
nextc
byte
name
,
nextc
,
j
=
match
(
ph
.
pat
,
isAlnum
,
j
+
1
)
val
,
_
,
i
=
match
(
path
,
matchPart
(
nextc
),
i
)
p
.
Add
(
":"
+
name
,
val
)
case
path
[
i
]
==
ph
.
pat
[
j
]
:
i
++
j
++
default
:
return
nil
,
false
}
}
if
j
!=
len
(
ph
.
pat
)
{
return
nil
,
false
}
return
p
,
true
}
func
matchPart
(
b
byte
)
func
(
byte
)
bool
{
return
func
(
c
byte
)
bool
{
return
c
!=
b
&&
c
!=
'/'
}
}
func
match
(
s
string
,
f
func
(
byte
)
bool
,
i
int
)
(
matched
string
,
next
byte
,
j
int
)
{
j
=
i
for
j
<
len
(
s
)
&&
f
(
s
[
j
])
{
j
++
}
if
j
<
len
(
s
)
{
next
=
s
[
j
]
}
return
s
[
i
:
j
],
next
,
j
}
func
isAlpha
(
ch
byte
)
bool
{
return
'a'
<=
ch
&&
ch
<=
'z'
||
'A'
<=
ch
&&
ch
<=
'Z'
||
ch
==
'_'
}
func
isDigit
(
ch
byte
)
bool
{
return
'0'
<=
ch
&&
ch
<=
'9'
}
func
isAlnum
(
ch
byte
)
bool
{
return
isAlpha
(
ch
)
||
isDigit
(
ch
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment