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
nexedi
caddy
Commits
dd4de698
Commit
dd4de698
authored
Apr 17, 2016
by
Tobias Weingartner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better search for config.
Handle LastModifiedHeader better. Handle HEAD/GET.
parent
19a85d08
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
53 deletions
+90
-53
middleware/markdown/markdown.go
middleware/markdown/markdown.go
+90
-53
No files found.
middleware/markdown/markdown.go
View file @
dd4de698
...
...
@@ -8,6 +8,7 @@ import (
"os"
"path"
"text/template"
"time"
"github.com/mholt/caddy/middleware"
"github.com/russross/blackfriday"
...
...
@@ -65,75 +66,111 @@ type Config struct {
// ServeHTTP implements the http.Handler interface.
func
(
md
Markdown
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
(
int
,
error
)
{
for
_
,
cfg
:=
range
md
.
Configs
{
if
!
middleware
.
Path
(
r
.
URL
.
Path
)
.
Matches
(
cfg
.
PathScope
)
{
continue
var
cfg
*
Config
for
_
,
c
:=
range
md
.
Configs
{
if
middleware
.
Path
(
r
.
URL
.
Path
)
.
Matches
(
c
.
PathScope
)
{
// not negated
cfg
=
c
break
// or goto
}
}
if
cfg
==
nil
{
return
md
.
Next
.
ServeHTTP
(
w
,
r
)
// exit early
}
var
dirents
[]
os
.
FileInfo
fpath
:=
r
.
URL
.
Path
if
idx
,
ok
:=
middleware
.
IndexFile
(
md
.
FileSys
,
fpath
,
md
.
IndexFiles
);
ok
{
// We're serving a directory index file, which may be a markdown
// file with a template. Let's grab a list of files this directory
// URL points to, and pass that in to any possible template invocations,
// so that templates can customize the look and feel of a directory.
fdp
,
err
:=
md
.
FileSys
.
Open
(
fpath
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
dirents
,
err
=
fdp
.
Readdir
(
-
1
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
// We only deal with HEAD/GET
switch
r
.
Method
{
case
http
.
MethodGet
,
http
.
MethodHead
:
default
:
return
http
.
StatusMethodNotAllowed
,
nil
}
var
dirents
[]
os
.
FileInfo
var
lastModTime
time
.
Time
fpath
:=
r
.
URL
.
Path
if
idx
,
ok
:=
middleware
.
IndexFile
(
md
.
FileSys
,
fpath
,
md
.
IndexFiles
);
ok
{
// We're serving a directory index file, which may be a markdown
// file with a template. Let's grab a list of files this directory
// URL points to, and pass that in to any possible template invocations,
// so that templates can customize the look and feel of a directory.
fdp
,
err
:=
md
.
FileSys
.
Open
(
fpath
)
if
err
!=
nil
{
if
os
.
IsPermission
(
err
)
{
return
http
.
StatusForbidden
,
err
}
return
http
.
StatusInternalServerError
,
err
}
// Set path to found index file
fpath
=
idx
// Grab a possible set of directory entries. Note, we do not check
// for errors here (unreadable directory, for example). It may
// still be useful to have a directory template file, without the
// directory contents being present.
dirents
,
_
=
fdp
.
Readdir
(
-
1
)
for
_
,
d
:=
range
dirents
{
lastModTime
=
latest
(
lastModTime
,
d
.
ModTime
())
}
// If supported extension, process it
if
_
,
ok
:=
cfg
.
Extensions
[
path
.
Ext
(
fpath
)];
ok
{
f
,
err
:=
md
.
FileSys
.
Open
(
fpath
)
if
err
!=
nil
{
if
os
.
IsPermission
(
err
)
{
return
http
.
StatusForbidden
,
err
}
return
http
.
StatusNotFound
,
nil
}
// Set path to found index file
fpath
=
idx
}
fs
,
err
:=
f
.
Stat
()
if
err
!=
nil
{
return
http
.
StatusNotFound
,
nil
// If supported extension, process it
if
_
,
ok
:=
cfg
.
Extensions
[
path
.
Ext
(
fpath
)];
ok
{
f
,
err
:=
md
.
FileSys
.
Open
(
fpath
)
if
err
!=
nil
{
if
os
.
IsPermission
(
err
)
{
return
http
.
StatusForbidden
,
err
}
return
http
.
StatusNotFound
,
nil
}
body
,
err
:=
ioutil
.
ReadAll
(
f
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
fs
,
err
:=
f
.
Stat
()
if
err
!=
nil
{
return
http
.
StatusNotFound
,
nil
}
lastModTime
=
latest
(
lastModTime
,
fs
.
ModTime
())
ctx
:=
middleware
.
Context
{
Root
:
md
.
FileSys
,
Req
:
r
,
URL
:
r
.
URL
,
}
html
,
err
:=
cfg
.
Markdown
(
fpath
,
body
,
dirents
,
ctx
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
body
,
err
:=
ioutil
.
ReadAll
(
f
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
ctx
:=
middleware
.
Context
{
Root
:
md
.
FileSys
,
Req
:
r
,
URL
:
r
.
URL
,
}
html
,
err
:=
cfg
.
Markdown
(
fpath
,
body
,
dirents
,
ctx
)
if
err
!=
nil
{
return
http
.
StatusInternalServerError
,
err
}
// TODO(weingart): move template execution here, something like:
//
// html, err = md.execTemplate(cfg, html, ctx)
// if err != nil {
// return http.StatusInternalServerError, err
// }
// TODO(weingart): move template execution here, something like:
//
// html, err = md.execTemplate(cfg, html, ctx)
// if err != nil {
// return http.StatusInternalServerError, err
// }
middleware
.
SetLastModifiedHeader
(
w
,
fs
.
ModTime
())
middleware
.
SetLastModifiedHeader
(
w
,
lastModTime
)
if
r
.
Method
==
"GET"
{
w
.
Write
(
html
)
return
http
.
StatusOK
,
nil
}
return
http
.
StatusOK
,
nil
}
// Didn't qualify to serve as markdown; pass-thru
return
md
.
Next
.
ServeHTTP
(
w
,
r
)
}
// latest returns the latest time.Time
func
latest
(
t
...
time
.
Time
)
time
.
Time
{
var
last
time
.
Time
for
_
,
tt
:=
range
t
{
if
tt
.
After
(
last
)
{
last
=
tt
}
}
return
last
}
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