@ -2,9 +2,9 @@ package caddyhugo
import (
import (
"encoding/base64"
"encoding/base64"
"errors"
"fmt"
"fmt"
"io"
"io"
"net"
"net/http"
"net/http"
"os"
"os"
"path"
"path"
@ -12,26 +12,25 @@ import (
"strings"
"strings"
"git.stephensearles.com/stephen/caddy-hugo2/assets"
"git.stephensearles.com/stephen/caddy-hugo2/assets"
"github.com/caddyserver/caddy"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/caddyserver/caddy/caddyhttp/httpserver"
"github.com/spf13/afero"
"github.com/spf13/afero"
)
)
func ( ch * CaddyHugo ) ServeHTTPWithNext ( next httpserver . Handler , w http . ResponseWriter , r * http . Request ) ( int , error ) {
func ( ch * CaddyHugo ) ServeHTTP ( w http . ResponseWriter , r * http . Request , next caddyhttp . Handler ) error {
if ! ch . Match ( r ) {
if ! ch . Match ( r ) {
p := path . Join ( ch . Dir , "public" , r . URL . Path )
p := path . Join ( ch . Dir , "public" , r . URL . Path )
http . ServeFile ( w , r , p )
http . ServeFile ( w , r , p )
return 200 , nil
return nil
}
}
if ch . Comments != nil && strings . HasSuffix ( r . URL . Path , "/comments" ) {
if ch . Comments != nil && strings . HasSuffix ( r . URL . Path , "/comments" ) {
docName := docNameFromCommentRequest ( r )
docName := docNameFromCommentRequest ( r )
err := ch . Comments . ServeComments ( docName , w , r )
err := ch . Comments . ServeComments ( docName , w , r )
if err != nil {
if err != nil {
return 500 , fmt . Errorf ( "couldn't load comments:" , err )
return fmt . Errorf ( "couldn't load comments:" , err )
}
}
return 200 , nil
return nil
}
}
if r . URL . Path == "/login" {
if r . URL . Path == "/login" {
@ -41,32 +40,31 @@ func (ch *CaddyHugo) ServeHTTPWithNext(next httpserver.Handler, w http.ResponseW
if strings . HasPrefix ( r . URL . Path , "/hugo/publish" ) {
if strings . HasPrefix ( r . URL . Path , "/hugo/publish" ) {
err := ch . Publish ( )
err := ch . Publish ( )
if err != nil {
if err != nil {
http . Error ( w , err . Error ( ) , http . StatusInternalServerError )
return err
return http . StatusInternalServerError , nil
}
}
http . Redirect ( w , r , "/" , http . StatusFound )
http . Redirect ( w , r , "/" , http . StatusFound )
return http . StatusFound , nil
return nil
}
}
if strings . HasPrefix ( r . URL . Path , "/hugo/simplemde.css" ) {
if strings . HasPrefix ( r . URL . Path , "/hugo/simplemde.css" ) {
w . Write ( assets . MustAsset ( "simplemde/dist/simplemde.min.css" ) )
w . Write ( assets . MustAsset ( "simplemde/dist/simplemde.min.css" ) )
return http . StatusOK , nil
return nil
}
}
if strings . HasPrefix ( r . URL . Path , "/hugo/simplemde.js" ) {
if strings . HasPrefix ( r . URL . Path , "/hugo/simplemde.js" ) {
w . Write ( assets . MustAsset ( "simplemde/debug/simplemde.js" ) )
w . Write ( assets . MustAsset ( "simplemde/debug/simplemde.js" ) )
return http . StatusOK , nil
return nil
}
}
if strings . HasPrefix ( r . URL . Path , "/hugo/vue.js" ) {
if strings . HasPrefix ( r . URL . Path , "/hugo/vue.js" ) {
w . Write ( assets . MustAsset ( "js/vue.js" ) )
w . Write ( assets . MustAsset ( "js/vue.js" ) )
return http . StatusOK , nil
return nil
}
}
if strings . HasPrefix ( r . URL . Path , "/hugo/moment.js" ) {
if strings . HasPrefix ( r . URL . Path , "/hugo/moment.js" ) {
w . Write ( assets . MustAsset ( "js/moment.js" ) )
w . Write ( assets . MustAsset ( "js/moment.js" ) )
return http . StatusOK , nil
return nil
}
}
if strings . HasPrefix ( r . URL . Path , "/hugo/font-awesome.css" ) {
if strings . HasPrefix ( r . URL . Path , "/hugo/font-awesome.css" ) {
w . Write ( assets . MustAsset ( "css/font-awesome.min.css" ) )
w . Write ( assets . MustAsset ( "css/font-awesome.min.css" ) )
return http . StatusOK , nil
return nil
}
}
if strings . HasPrefix ( r . URL . Path , "/hugo/admin" ) {
if strings . HasPrefix ( r . URL . Path , "/hugo/admin" ) {
return ch . Admin ( ) . ServeHTTP ( w , r )
return ch . Admin ( ) . ServeHTTP ( w , r )
@ -91,38 +89,25 @@ func (ch *CaddyHugo) ServeHTTPWithNext(next httpserver.Handler, w http.ResponseW
}
}
if strings . HasPrefix ( r . URL . Path , "/hugo/fs/" ) {
if strings . HasPrefix ( r . URL . Path , "/hugo/fs/" ) {
printTree ( afero . NewOsFs ( ) , w , ch . Dir )
printTree ( afero . NewOsFs ( ) , w , ch . Dir )
return 200 , nil
return nil
}
}
return next . ServeHTTP ( w , r )
return next . ServeHTTP ( w , r )
}
}
func ( ch * CaddyHugo ) ServeNewContent ( w http . ResponseWriter , r * http . Request ) ( int , error ) {
func ( ch * CaddyHugo ) ServeNewContent ( w http . ResponseWriter , r * http . Request ) error {
name := r . FormValue ( "name" )
name := r . FormValue ( "name" )
ctype := r . FormValue ( "type" )
ctype := r . FormValue ( "type" )
filename , err := ch . NewContent ( name , ctype )
filename , err := ch . NewContent ( name , ctype )
if err != nil {
if err != nil {
fmt . Println ( "error creating new content:" , err )
fmt . Println ( "error creating new content:" , err )
return http . StatusInternalServerError , err
return err
}
}
// serve redirect
// serve redirect
http . Redirect ( w , r , filepath . Join ( "/hugo/edit/" , "content" , filename ) , http . StatusFound )
http . Redirect ( w , r , filepath . Join ( "/hugo/edit/" , "content" , filename ) , http . StatusFound )
return http . StatusFound , nil
return nil
}
func ( ch * CaddyHugo ) Middleware ( c * caddy . Controller ) httpserver . Middleware {
return func ( next httpserver . Handler ) httpserver . Handler {
host := ch . Site . Addr . Host
hostport := net . JoinHostPort ( ch . Site . Addr . Host , ch . Site . Addr . Port )
return httpserver . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) ( int , error ) {
if r . Host != host && r . Host != hostport {
return next . ServeHTTP ( w , r )
}
return ch . ServeHTTPWithNext ( next , w , r )
} )
}
}
}
func ( ch * CaddyHugo ) Auth ( r * http . Request ) bool {
func ( ch * CaddyHugo ) Auth ( r * http . Request ) bool {
@ -131,11 +116,6 @@ func (ch *CaddyHugo) Auth(r *http.Request) bool {
}
}
func ( ch * CaddyHugo ) Match ( r * http . Request ) bool {
func ( ch * CaddyHugo ) Match ( r * http . Request ) bool {
host := ch . Site . Addr . Host
hostport := net . JoinHostPort ( ch . Site . Addr . Host , ch . Site . Addr . Port )
if r . Host != host && r . Host != hostport {
return false
}
if strings . HasPrefix ( r . URL . Path , "/media/" ) {
if strings . HasPrefix ( r . URL . Path , "/media/" ) {
return true
return true
}
}
@ -155,34 +135,34 @@ func (ch *CaddyHugo) Match(r *http.Request) bool {
return strings . HasPrefix ( r . URL . Path , "/hugo/" )
return strings . HasPrefix ( r . URL . Path , "/hugo/" )
}
}
func ( ch * CaddyHugo ) Admin ( ) httpserver . Handler {
func ( ch * CaddyHugo ) Admin ( ) caddy http. Handler {
return httpserver . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) ( int , error ) {
return caddy http. HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) error {
err := ch . adminTmpl . Execute ( w , ch . TmplData ( r , nil ) )
err := ch . adminTmpl . Execute ( w , ch . TmplData ( r , nil ) )
if err != nil {
if err != nil {
fmt . Println ( err )
fmt . Println ( err )
return http . StatusInternalServerError , err
return err
}
}
return http . StatusOK , nil
return nil
} )
} )
}
}
func ( ch * CaddyHugo ) AuthorHome ( ) httpserver . Handler {
func ( ch * CaddyHugo ) AuthorHome ( ) caddy http. Handler {
return httpserver . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) ( int , error ) {
return caddy http. HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) error {
td := ch . TmplData ( r , nil )
td := ch . TmplData ( r , nil )
err := ch . authorTmpl . Execute ( w , td )
err := ch . authorTmpl . Execute ( w , td )
if err != nil {
if err != nil {
fmt . Println ( err )
fmt . Println ( err )
return http . StatusInternalServerError , err
return err
}
}
return http . StatusOK , nil
return nil
} )
} )
}
}
func ( ch * CaddyHugo ) Edit ( ) httpserver . Handler {
func ( ch * CaddyHugo ) Edit ( ) caddy http. Handler {
return httpserver . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) ( int , error ) {
return caddy http. HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) error {
if r . URL . Path == "/hugo/edit/new" {
if r . URL . Path == "/hugo/edit/new" {
return ch . ServeNewContent ( w , r )
return ch . ServeNewContent ( w , r )
}
}
@ -194,32 +174,31 @@ func (ch *CaddyHugo) Edit() httpserver.Handler {
doc , err := ch . editSession ( docNameFromEditRequest ( r ) )
doc , err := ch . editSession ( docNameFromEditRequest ( r ) )
if err != nil {
if err != nil {
fmt . Println ( err )
fmt . Println ( err )
return http . StatusNotFound , err
http . Error ( w , err . Error ( ) , http . StatusNotFound )
return err
}
}
err = ch . editTmpl . Execute ( w , ch . TmplData ( r , doc ) )
err = ch . editTmpl . Execute ( w , ch . TmplData ( r , doc ) )
if err != nil {
if err != nil {
fmt . Println ( err )
fmt . Println ( err )
return http . StatusInternalServerError , err
return err
}
}
return http . StatusOK , nil
return nil
} )
} )
}
}
func ( ch * CaddyHugo ) serveDraft ( w http . ResponseWriter , r * http . Request ) ( int , error ) {
func ( ch * CaddyHugo ) serveDraft ( w http . ResponseWriter , r * http . Request ) error {
pathSegments := strings . SplitN ( r . URL . Path , "/" , 5 )
pathSegments := strings . SplitN ( r . URL . Path , "/" , 5 )
if len ( pathSegments ) < 4 {
if len ( pathSegments ) < 4 {
return errors . New ( "not found" )
return http . StatusNotFound , nil
}
}
encoded := pathSegments [ 3 ]
encoded := pathSegments [ 3 ]
nameBytes , err := base64 . RawURLEncoding . DecodeString ( encoded )
nameBytes , err := base64 . RawURLEncoding . DecodeString ( encoded )
if err != nil {
if err != nil {
return http . StatusNotFound , err
return errors . New ( "not found" )
}
}
name := string ( nameBytes )
name := string ( nameBytes )
@ -229,7 +208,7 @@ func (ch *CaddyHugo) serveDraft(w http.ResponseWriter, r *http.Request) (int, er
docref , ok := ch . docs [ ch . docFilename ( name ) ]
docref , ok := ch . docs [ ch . docFilename ( name ) ]
if ! ok {
if ! ok {
return http . StatusNotFound , fmt . Errorf ( "draft not found" )
return fmt . Errorf ( "draft not found" )
}
}
r . URL . Path = strings . ToLower ( r . URL . Path )
r . URL . Path = strings . ToLower ( r . URL . Path )
@ -240,13 +219,13 @@ func (ch *CaddyHugo) serveDraft(w http.ResponseWriter, r *http.Request) (int, er
page := ch . HugoSites . GetContentPage ( ch . docFilename ( name ) )
page := ch . HugoSites . GetContentPage ( ch . docFilename ( name ) )
if page == nil {
if page == nil {
fmt . Fprintf ( w , "can't find %q to display a draft" , name )
fmt . Fprintf ( w , "can't find %q to display a draft" , name )
return 404 , nil
return fmt . Errorf ( "draft not found" )
}
}
r . URL . Path = page . RelPermalink ( )
r . URL . Path = page . RelPermalink ( )
http . FileServer ( aferoHTTP { afero . NewBasePathFs ( docref . tmpfs , path . Join ( ch . Dir , "public" ) ) } ) . ServeHTTP ( w , r )
http . FileServer ( aferoHTTP { afero . NewBasePathFs ( docref . tmpfs , path . Join ( ch . Dir , "public" ) ) } ) . ServeHTTP ( w , r )
return 200 , nil
return nil
}
}
func printTree ( fs afero . Fs , w io . Writer , dir string ) {
func printTree ( fs afero . Fs , w io . Writer , dir string ) {
@ -328,9 +307,9 @@ func (a aferoHTTP) Open(name string) (http.File, error) {
return af , err
return af , err
}
}
func ( ch * CaddyHugo ) commentsLogin ( r * http . Request , w http . ResponseWriter ) ( int , error ) {
func ( ch * CaddyHugo ) commentsLogin ( r * http . Request , w http . ResponseWriter ) error {
if ch . Comments == nil {
if ch . Comments == nil {
return 200 , nil
return nil
}
}
_ , ok := ch . Comments . User ( r )
_ , ok := ch . Comments . User ( r )
@ -338,10 +317,10 @@ func (ch *CaddyHugo) commentsLogin(r *http.Request, w http.ResponseWriter) (int,
w . Header ( ) . Set ( "WWW-Authenticate" , ` Basic realm="Log in with your name and the password. Ask Dan or Stephen for the password." ` )
w . Header ( ) . Set ( "WWW-Authenticate" , ` Basic realm="Log in with your name and the password. Ask Dan or Stephen for the password." ` )
w . WriteHeader ( 401 )
w . WriteHeader ( 401 )
fmt . Fprintf ( w , "<html><body>Log in with your name and the password. Ask Dan or Stephen for the password. <a href=%q>go back</a></body></html>" , r . Referer ( ) )
fmt . Fprintf ( w , "<html><body>Log in with your name and the password. Ask Dan or Stephen for the password. <a href=%q>go back</a></body></html>" , r . Referer ( ) )
return 200 , nil
return nil
}
}
http . Redirect ( w , r , r . Referer ( ) , http . StatusFound )
http . Redirect ( w , r , r . Referer ( ) , http . StatusFound )
return 200 , nil
return nil
}
}