Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Łukasz Nowak
caddy
Commits
47717fee
Commit
47717fee
authored
May 05, 2015
by
Matthew Holt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Expanded index file support to other middlewares (fixes #27)
parent
a9064a78
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
117 additions
and
52 deletions
+117
-52
config/setup/fastcgi.go
config/setup/fastcgi.go
+9
-5
config/setup/markdown.go
config/setup/markdown.go
+6
-2
config/setup/templates.go
config/setup/templates.go
+10
-3
middleware/fastcgi/fastcgi.go
middleware/fastcgi/fastcgi.go
+33
-31
middleware/markdown/markdown.go
middleware/markdown/markdown.go
+18
-4
middleware/middleware.go
middleware/middleware.go
+25
-1
middleware/templates/templates.go
middleware/templates/templates.go
+16
-6
No files found.
config/setup/fastcgi.go
View file @
47717fee
...
@@ -2,6 +2,7 @@ package setup
...
@@ -2,6 +2,7 @@ package setup
import
(
import
(
"errors"
"errors"
"net/http"
"path/filepath"
"path/filepath"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware"
...
@@ -10,7 +11,7 @@ import (
...
@@ -10,7 +11,7 @@ import (
// FastCGI configures a new FastCGI middleware instance.
// FastCGI configures a new FastCGI middleware instance.
func
FastCGI
(
c
*
Controller
)
(
middleware
.
Middleware
,
error
)
{
func
FastCGI
(
c
*
Controller
)
(
middleware
.
Middleware
,
error
)
{
r
oot
,
err
:=
filepath
.
Abs
(
c
.
Root
)
absR
oot
,
err
:=
filepath
.
Abs
(
c
.
Root
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -24,7 +25,9 @@ func FastCGI(c *Controller) (middleware.Middleware, error) {
...
@@ -24,7 +25,9 @@ func FastCGI(c *Controller) (middleware.Middleware, error) {
return
fastcgi
.
Handler
{
return
fastcgi
.
Handler
{
Next
:
next
,
Next
:
next
,
Rules
:
rules
,
Rules
:
rules
,
Root
:
root
,
Root
:
c
.
Root
,
AbsRoot
:
absRoot
,
FileSys
:
http
.
Dir
(
c
.
Root
),
SoftwareName
:
c
.
AppName
,
SoftwareName
:
c
.
AppName
,
SoftwareVersion
:
c
.
AppVersion
,
SoftwareVersion
:
c
.
AppVersion
,
ServerName
:
c
.
Host
,
ServerName
:
c
.
Host
,
...
@@ -72,10 +75,11 @@ func fastcgiParse(c *Controller) ([]fastcgi.Rule, error) {
...
@@ -72,10 +75,11 @@ func fastcgiParse(c *Controller) ([]fastcgi.Rule, error) {
}
}
rule
.
SplitPath
=
c
.
Val
()
rule
.
SplitPath
=
c
.
Val
()
case
"index"
:
case
"index"
:
if
!
c
.
NextArg
()
{
args
:=
c
.
RemainingArgs
()
if
len
(
args
)
==
0
{
return
rules
,
c
.
ArgErr
()
return
rules
,
c
.
ArgErr
()
}
}
rule
.
IndexFile
=
c
.
Val
()
rule
.
IndexFile
s
=
args
case
"env"
:
case
"env"
:
envArgs
:=
c
.
RemainingArgs
()
envArgs
:=
c
.
RemainingArgs
()
if
len
(
envArgs
)
<
2
{
if
len
(
envArgs
)
<
2
{
...
@@ -98,7 +102,7 @@ func fastcgiPreset(name string, rule *fastcgi.Rule) error {
...
@@ -98,7 +102,7 @@ func fastcgiPreset(name string, rule *fastcgi.Rule) error {
case
"php"
:
case
"php"
:
rule
.
Ext
=
".php"
rule
.
Ext
=
".php"
rule
.
SplitPath
=
".php"
rule
.
SplitPath
=
".php"
rule
.
IndexFile
=
"index.php"
rule
.
IndexFile
s
=
[]
string
{
"index.php"
}
default
:
default
:
return
errors
.
New
(
name
+
" is not a valid preset name"
)
return
errors
.
New
(
name
+
" is not a valid preset name"
)
}
}
...
...
config/setup/markdown.go
View file @
47717fee
package
setup
package
setup
import
(
import
(
"net/http"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware/markdown"
"github.com/mholt/caddy/middleware/markdown"
"github.com/russross/blackfriday"
"github.com/russross/blackfriday"
...
@@ -15,7 +17,9 @@ func Markdown(c *Controller) (middleware.Middleware, error) {
...
@@ -15,7 +17,9 @@ func Markdown(c *Controller) (middleware.Middleware, error) {
md
:=
markdown
.
Markdown
{
md
:=
markdown
.
Markdown
{
Root
:
c
.
Root
,
Root
:
c
.
Root
,
FileSys
:
http
.
Dir
(
c
.
Root
),
Configs
:
mdconfigs
,
Configs
:
mdconfigs
,
IndexFiles
:
[]
string
{
"index.md"
},
}
}
return
func
(
next
middleware
.
Handler
)
middleware
.
Handler
{
return
func
(
next
middleware
.
Handler
)
middleware
.
Handler
{
...
...
config/setup/templates.go
View file @
47717fee
package
setup
package
setup
import
(
import
(
"net/http"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware/templates"
"github.com/mholt/caddy/middleware/templates"
)
)
...
@@ -13,8 +15,9 @@ func Templates(c *Controller) (middleware.Middleware, error) {
...
@@ -13,8 +15,9 @@ func Templates(c *Controller) (middleware.Middleware, error) {
}
}
tmpls
:=
templates
.
Templates
{
tmpls
:=
templates
.
Templates
{
Root
:
c
.
Root
,
Rules
:
rules
,
Rules
:
rules
,
Root
:
c
.
Root
,
FileSys
:
http
.
Dir
(
c
.
Root
),
}
}
return
func
(
next
middleware
.
Handler
)
middleware
.
Handler
{
return
func
(
next
middleware
.
Handler
)
middleware
.
Handler
{
...
@@ -43,6 +46,10 @@ func templatesParse(c *Controller) ([]templates.Rule, error) {
...
@@ -43,6 +46,10 @@ func templatesParse(c *Controller) ([]templates.Rule, error) {
rule
.
Extensions
=
defaultExtensions
rule
.
Extensions
=
defaultExtensions
}
}
for
_
,
ext
:=
range
rule
.
Extensions
{
rule
.
IndexFiles
=
append
(
rule
.
IndexFiles
,
"index"
+
ext
)
}
rules
=
append
(
rules
,
rule
)
rules
=
append
(
rules
,
rule
)
}
}
...
@@ -51,4 +58,4 @@ func templatesParse(c *Controller) ([]templates.Rule, error) {
...
@@ -51,4 +58,4 @@ func templatesParse(c *Controller) ([]templates.Rule, error) {
const
defaultPath
=
"/"
const
defaultPath
=
"/"
var
defaultExtensions
=
[]
string
{
".html"
,
".htm"
,
".txt"
}
var
defaultExtensions
=
[]
string
{
".html"
,
".htm"
,
".t
mpl"
,
".tpl"
,
".t
xt"
}
middleware/fastcgi/fastcgi.go
View file @
47717fee
...
@@ -17,8 +17,10 @@ import (
...
@@ -17,8 +17,10 @@ import (
// Handler is a middleware type that can handle requests as a FastCGI client.
// Handler is a middleware type that can handle requests as a FastCGI client.
type
Handler
struct
{
type
Handler
struct
{
Next
middleware
.
Handler
Next
middleware
.
Handler
Root
string
// must be absolute path to site root
Rules
[]
Rule
Rules
[]
Rule
Root
string
AbsRoot
string
// same as root, but absolute path
FileSys
http
.
FileSystem
// These are sent to CGI scripts in env variables
// These are sent to CGI scripts in env variables
SoftwareName
string
SoftwareName
string
...
@@ -30,26 +32,27 @@ type Handler struct {
...
@@ -30,26 +32,27 @@ type Handler struct {
// ServeHTTP satisfies the middleware.Handler interface.
// ServeHTTP satisfies the middleware.Handler interface.
func
(
h
Handler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
func
(
h
Handler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
for
_
,
rule
:=
range
h
.
Rules
{
for
_
,
rule
:=
range
h
.
Rules
{
// First requirement: Base path must match
if
!
middleware
.
Path
(
r
.
URL
.
Path
)
.
Matches
(
rule
.
Path
)
{
continue
}
// In addition to matching the path, a request must meet some
// In addition to matching the path, a request must meet some
// other criteria before being proxied as FastCGI. For example,
// other criteria before being proxied as FastCGI. For example,
// we probably want to exclude static assets (CSS, JS, images...)
// we probably want to exclude static assets (CSS, JS, images...)
// but we also want to be flexible for the script we proxy to.
// but we also want to be flexible for the script we proxy to.
path
:=
r
.
URL
.
Path
fpath
:=
r
.
URL
.
Path
if
idx
,
ok
:=
middleware
.
IndexFile
(
h
.
FileSys
,
fpath
,
rule
.
IndexFiles
);
ok
{
fpath
=
idx
}
// These criteria work well in this order for PHP sites
// These criteria work well in this order for PHP sites
if
middleware
.
Path
(
path
)
.
Matches
(
rule
.
Path
)
&&
if
fpath
[
len
(
fpath
)
-
1
]
==
'/'
||
strings
.
HasSuffix
(
fpath
,
rule
.
Ext
)
||
!
h
.
exists
(
fpath
)
{
(
path
[
len
(
path
)
-
1
]
==
'/'
||
strings
.
HasSuffix
(
path
,
rule
.
Ext
)
||
!
h
.
exists
(
path
))
{
if
path
[
len
(
path
)
-
1
]
==
'/'
&&
h
.
exists
(
path
+
rule
.
IndexFile
)
{
// If index file in specified folder exists, send request to it
path
+=
rule
.
IndexFile
}
// Create environment for CGI script
// Create environment for CGI script
env
,
err
:=
h
.
buildEnv
(
r
,
rule
,
path
)
env
,
err
:=
h
.
buildEnv
(
r
,
rule
,
f
path
)
if
err
!=
nil
{
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
return
http
.
StatusInternalServerError
,
err
}
}
...
@@ -115,14 +118,12 @@ func (h Handler) exists(path string) bool {
...
@@ -115,14 +118,12 @@ func (h Handler) exists(path string) bool {
return
false
return
false
}
}
func
(
h
Handler
)
buildEnv
(
r
*
http
.
Request
,
rule
Rule
,
path
string
)
(
map
[
string
]
string
,
error
)
{
// buildEnv returns a set of CGI environment variables for the request.
func
(
h
Handler
)
buildEnv
(
r
*
http
.
Request
,
rule
Rule
,
fpath
string
)
(
map
[
string
]
string
,
error
)
{
var
env
map
[
string
]
string
var
env
map
[
string
]
string
// Get absolute path of requested resource
// Get absolute path of requested resource
absPath
,
err
:=
filepath
.
Abs
(
h
.
Root
+
path
)
absPath
:=
filepath
.
Join
(
h
.
AbsRoot
,
fpath
)
if
err
!=
nil
{
return
env
,
err
}
// Separate remote IP and port; more lenient than net.SplitHostPort
// Separate remote IP and port; more lenient than net.SplitHostPort
var
ip
,
port
string
var
ip
,
port
string
...
@@ -134,19 +135,19 @@ func (h Handler) buildEnv(r *http.Request, rule Rule, path string) (map[string]s
...
@@ -134,19 +135,19 @@ func (h Handler) buildEnv(r *http.Request, rule Rule, path string) (map[string]s
}
}
// Split path in preparation for env variables
// Split path in preparation for env variables
splitPos
:=
strings
.
Index
(
path
,
rule
.
SplitPath
)
splitPos
:=
strings
.
Index
(
f
path
,
rule
.
SplitPath
)
var
docURI
,
scriptName
,
scriptFilename
,
pathInfo
string
var
docURI
,
scriptName
,
scriptFilename
,
pathInfo
string
if
splitPos
==
-
1
{
if
splitPos
==
-
1
{
// Request doesn't have the extension, so assume index file in root
// Request doesn't have the extension, so assume index file in root
docURI
=
"/"
+
rule
.
IndexFile
docURI
=
"/"
+
rule
.
IndexFile
s
[
0
]
scriptName
=
"/"
+
rule
.
IndexFile
scriptName
=
"/"
+
rule
.
IndexFile
s
[
0
]
scriptFilename
=
h
.
Root
+
"/"
+
rule
.
IndexFile
scriptFilename
=
filepath
.
Join
(
h
.
AbsRoot
,
rule
.
IndexFiles
[
0
])
pathInfo
=
path
pathInfo
=
f
path
}
else
{
}
else
{
// Request has the extension; path was split successfully
// Request has the extension; path was split successfully
docURI
=
path
[
:
splitPos
+
len
(
rule
.
SplitPath
)]
docURI
=
f
path
[
:
splitPos
+
len
(
rule
.
SplitPath
)]
pathInfo
=
path
[
splitPos
+
len
(
rule
.
SplitPath
)
:
]
pathInfo
=
f
path
[
splitPos
+
len
(
rule
.
SplitPath
)
:
]
scriptName
=
path
scriptName
=
f
path
scriptFilename
=
absPath
scriptFilename
=
absPath
}
}
...
@@ -160,7 +161,7 @@ func (h Handler) buildEnv(r *http.Request, rule Rule, path string) (map[string]s
...
@@ -160,7 +161,7 @@ func (h Handler) buildEnv(r *http.Request, rule Rule, path string) (map[string]s
"CONTENT_TYPE"
:
r
.
Header
.
Get
(
"Content-Type"
),
"CONTENT_TYPE"
:
r
.
Header
.
Get
(
"Content-Type"
),
"GATEWAY_INTERFACE"
:
"CGI/1.1"
,
"GATEWAY_INTERFACE"
:
"CGI/1.1"
,
"PATH_INFO"
:
pathInfo
,
"PATH_INFO"
:
pathInfo
,
"PATH_TRANSLATED"
:
h
.
Root
+
"/"
+
pathInfo
,
// Source for path_translated
: http://www.oreilly.com/openbook/cgi/ch02_04.html
"PATH_TRANSLATED"
:
filepath
.
Join
(
h
.
AbsRoot
,
pathInfo
),
// Info
: http://www.oreilly.com/openbook/cgi/ch02_04.html
"QUERY_STRING"
:
r
.
URL
.
RawQuery
,
"QUERY_STRING"
:
r
.
URL
.
RawQuery
,
"REMOTE_ADDR"
:
ip
,
"REMOTE_ADDR"
:
ip
,
"REMOTE_HOST"
:
ip
,
// For speed, remote host lookups disabled
"REMOTE_HOST"
:
ip
,
// For speed, remote host lookups disabled
...
@@ -174,7 +175,7 @@ func (h Handler) buildEnv(r *http.Request, rule Rule, path string) (map[string]s
...
@@ -174,7 +175,7 @@ func (h Handler) buildEnv(r *http.Request, rule Rule, path string) (map[string]s
"SERVER_SOFTWARE"
:
h
.
SoftwareName
+
"/"
+
h
.
SoftwareVersion
,
"SERVER_SOFTWARE"
:
h
.
SoftwareName
+
"/"
+
h
.
SoftwareVersion
,
// Other variables
// Other variables
"DOCUMENT_ROOT"
:
h
.
Root
,
"DOCUMENT_ROOT"
:
h
.
Abs
Root
,
"DOCUMENT_URI"
:
docURI
,
"DOCUMENT_URI"
:
docURI
,
"HTTP_HOST"
:
r
.
Host
,
// added here, since not always part of headers
"HTTP_HOST"
:
r
.
Host
,
// added here, since not always part of headers
"REQUEST_URI"
:
r
.
URL
.
RequestURI
(),
"REQUEST_URI"
:
r
.
URL
.
RequestURI
(),
...
@@ -214,8 +215,9 @@ type Rule struct {
...
@@ -214,8 +215,9 @@ type Rule struct {
// PATH_INFO for the CGI script to use.
// PATH_INFO for the CGI script to use.
SplitPath
string
SplitPath
string
// If the URL does not indicate a file, an index file with this name will be assumed.
// If the URL ends with '/' (which indicates a directory), these index
IndexFile
string
// files will be tried instead.
IndexFiles
[]
string
// Environment Variables
// Environment Variables
EnvVars
[][
2
]
string
EnvVars
[][
2
]
string
...
...
middleware/markdown/markdown.go
View file @
47717fee
...
@@ -20,11 +20,17 @@ type Markdown struct {
...
@@ -20,11 +20,17 @@ type Markdown struct {
// Server root
// Server root
Root
string
Root
string
// Jail the requests to site root with a mock file system
FileSys
http
.
FileSystem
// Next HTTP handler in the chain
// Next HTTP handler in the chain
Next
middleware
.
Handler
Next
middleware
.
Handler
// The list of markdown configurations
// The list of markdown configurations
Configs
[]
Config
Configs
[]
Config
// The list of index files to try
IndexFiles
[]
string
}
}
// Config stores markdown middleware configurations.
// Config stores markdown middleware configurations.
...
@@ -52,11 +58,14 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
...
@@ -52,11 +58,14 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
continue
continue
}
}
for
_
,
ext
:=
range
m
.
Extensions
{
fpath
:=
r
.
URL
.
Path
if
strings
.
HasSuffix
(
r
.
URL
.
Path
,
ext
)
{
if
idx
,
ok
:=
middleware
.
IndexFile
(
md
.
FileSys
,
fpath
,
md
.
IndexFiles
);
ok
{
fpath
:=
md
.
Root
+
r
.
URL
.
Path
fpath
=
idx
}
body
,
err
:=
ioutil
.
ReadFile
(
fpath
)
for
_
,
ext
:=
range
m
.
Extensions
{
if
strings
.
HasSuffix
(
fpath
,
ext
)
{
f
,
err
:=
md
.
FileSys
.
Open
(
fpath
)
if
err
!=
nil
{
if
err
!=
nil
{
if
os
.
IsPermission
(
err
)
{
if
os
.
IsPermission
(
err
)
{
return
http
.
StatusForbidden
,
err
return
http
.
StatusForbidden
,
err
...
@@ -64,6 +73,11 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
...
@@ -64,6 +73,11 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
return
http
.
StatusNotFound
,
nil
return
http
.
StatusNotFound
,
nil
}
}
body
,
err
:=
ioutil
.
ReadAll
(
f
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
content
:=
blackfriday
.
Markdown
(
body
,
m
.
Renderer
,
0
)
content
:=
blackfriday
.
Markdown
(
body
,
m
.
Renderer
,
0
)
var
scripts
,
styles
string
var
scripts
,
styles
string
...
...
middleware/middleware.go
View file @
47717fee
// Package middleware provides some types and functions common among middleware.
// Package middleware provides some types and functions common among middleware.
package
middleware
package
middleware
import
"net/http"
import
(
"net/http"
"path/filepath"
)
type
(
type
(
// Middleware is the middle layer which represents the traditional
// Middleware is the middle layer which represents the traditional
...
@@ -47,3 +50,24 @@ type (
...
@@ -47,3 +50,24 @@ type (
func
(
f
HandlerFunc
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
func
(
f
HandlerFunc
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
return
f
(
w
,
r
)
return
f
(
w
,
r
)
}
}
// IndexFile looks for a file in /root/fpath/indexFile for each string
// in indexFiles. If an index file is found, it returns the root-relative
// path to the file and true. If no index file is found, empty string
// and false is returned. fpath must end in a forward slash '/'
// otherwise no index files will be tried (directory paths must end
// in a forward slash according to HTTP).
func
IndexFile
(
root
http
.
FileSystem
,
fpath
string
,
indexFiles
[]
string
)
(
string
,
bool
)
{
if
fpath
[
len
(
fpath
)
-
1
]
!=
'/'
||
root
==
nil
{
return
""
,
false
}
for
_
,
indexFile
:=
range
indexFiles
{
fp
:=
filepath
.
Join
(
fpath
,
indexFile
)
f
,
err
:=
root
.
Open
(
fp
)
if
err
==
nil
{
f
.
Close
()
return
fp
,
true
}
}
return
""
,
false
}
middleware/templates/templates.go
View file @
47717fee
...
@@ -5,6 +5,7 @@ import (
...
@@ -5,6 +5,7 @@ import (
"bytes"
"bytes"
"net/http"
"net/http"
"path"
"path"
"path/filepath"
"text/template"
"text/template"
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware"
...
@@ -17,15 +18,22 @@ func (t Templates) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
...
@@ -17,15 +18,22 @@ func (t Templates) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
continue
continue
}
}
reqExt
:=
path
.
Ext
(
r
.
URL
.
Path
)
// Check for index files
fpath
:=
r
.
URL
.
Path
if
idx
,
ok
:=
middleware
.
IndexFile
(
t
.
FileSys
,
fpath
,
rule
.
IndexFiles
);
ok
{
fpath
=
idx
}
// Check the extension
reqExt
:=
path
.
Ext
(
fpath
)
for
_
,
ext
:=
range
rule
.
Extensions
{
for
_
,
ext
:=
range
rule
.
Extensions
{
if
reqExt
==
ext
{
if
reqExt
==
ext
{
// Create execution context
// Create execution context
ctx
:=
context
{
root
:
http
.
Dir
(
t
.
Root
)
,
req
:
r
,
URL
:
r
.
URL
}
ctx
:=
context
{
root
:
t
.
FileSys
,
req
:
r
,
URL
:
r
.
URL
}
// Build the template
// Build the template
tpl
,
err
:=
template
.
ParseFiles
(
t
.
Root
+
r
.
URL
.
Path
)
tpl
,
err
:=
template
.
ParseFiles
(
filepath
.
Join
(
t
.
Root
,
fpath
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
return
http
.
StatusInternalServerError
,
err
}
}
...
@@ -49,8 +57,9 @@ func (t Templates) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
...
@@ -49,8 +57,9 @@ func (t Templates) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
// Templates is middleware to render templated files as the HTTP response.
// Templates is middleware to render templated files as the HTTP response.
type
Templates
struct
{
type
Templates
struct
{
Next
middleware
.
Handler
Next
middleware
.
Handler
Root
string
Rules
[]
Rule
Rules
[]
Rule
Root
string
FileSys
http
.
FileSystem
}
}
// Rule represents a template rule. A template will only execute
// Rule represents a template rule. A template will only execute
...
@@ -59,4 +68,5 @@ type Templates struct {
...
@@ -59,4 +68,5 @@ type Templates struct {
type
Rule
struct
{
type
Rule
struct
{
Path
string
Path
string
Extensions
[]
string
Extensions
[]
string
IndexFiles
[]
string
}
}
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