From 506f1314289e408a72a3aed274719b0b1e308cbf Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Sun, 24 May 2015 20:58:17 -0400 Subject: [PATCH 1/4] Fix lint warnings for middleware/proxy --- middleware/proxy/policy.go | 14 +++++++++----- middleware/proxy/proxy.go | 16 ++++++++++------ middleware/proxy/upstream.go | 16 ++++++++-------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/middleware/proxy/policy.go b/middleware/proxy/policy.go index 806055e28..27e02a177 100644 --- a/middleware/proxy/policy.go +++ b/middleware/proxy/policy.go @@ -5,6 +5,7 @@ import ( "sync/atomic" ) +// HostPool is a collection of UpstreamHosts. type HostPool []*UpstreamHost // Policy decides how a host will be selected from a pool. @@ -12,9 +13,10 @@ type Policy interface { Select(pool HostPool) *UpstreamHost } -// The random policy randomly selected an up host from the pool. +// Random is a policy that selects up hosts from a pool at random. type Random struct{} +// Select selects an up host at random from the specified pool. func (r *Random) Select(pool HostPool) *UpstreamHost { // instead of just generating a random index // this is done to prevent selecting a down host @@ -37,11 +39,12 @@ func (r *Random) Select(pool HostPool) *UpstreamHost { return randHost } -// The least_conn policy selects a host with the least connections. -// If multiple hosts have the least amount of connections, one is randomly -// chosen. +// LeastConn is a policy that selects the host with the least connections. type LeastConn struct{} +// Select selects the up host with the least number of connections in the +// pool. If more than one host has the same least number of connections, +// one of the hosts is chosen at random. func (r *LeastConn) Select(pool HostPool) *UpstreamHost { var bestHost *UpstreamHost count := 0 @@ -71,11 +74,12 @@ func (r *LeastConn) Select(pool HostPool) *UpstreamHost { return bestHost } -// The round_robin policy selects a host based on round robin ordering. +// RoundRobin is a policy that selects hosts based on round robin ordering. type RoundRobin struct { Robin uint32 } +// Select selects an up host from the pool using a round robin ordering scheme. func (r *RoundRobin) Select(pool HostPool) *UpstreamHost { poolLen := uint32(len(pool)) selection := atomic.AddUint32(&r.Robin, 1) % poolLen diff --git a/middleware/proxy/proxy.go b/middleware/proxy/proxy.go index bf36b1d85..389faaf93 100644 --- a/middleware/proxy/proxy.go +++ b/middleware/proxy/proxy.go @@ -19,18 +19,19 @@ type Proxy struct { Upstreams []Upstream } -// An upstream manages a pool of proxy upstream hosts. Select should return a +// Upstream manages a pool of proxy upstream hosts. Select should return a // suitable upstream host, or nil if no such hosts are available. type Upstream interface { - //The path this upstream host should be routed on + // The path this upstream host should be routed on From() string // Selects an upstream host to be routed to. Select() *UpstreamHost } +// UpstreamHostDownFunc can be used to customize how Down behaves. type UpstreamHostDownFunc func(*UpstreamHost) bool -// An UpstreamHost represents a single proxy upstream +// UpstreamHost represents a single proxy upstream type UpstreamHost struct { // The hostname of this upstream host Name string @@ -43,6 +44,9 @@ type UpstreamHost struct { CheckDown UpstreamHostDownFunc } +// Down checks whether the upstream host is down or not. +// Down will try to use uh.CheckDown first, and will fall +// back to some default criteria if necessary. func (uh *UpstreamHost) Down() bool { if uh.CheckDown == nil { // Default settings @@ -70,10 +74,10 @@ func (p Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { proxy := host.ReverseProxy r.Host = host.Name - if baseUrl, err := url.Parse(host.Name); err == nil { - r.Host = baseUrl.Host + if baseURL, err := url.Parse(host.Name); err == nil { + r.Host = baseURL.Host if proxy == nil { - proxy = NewSingleHostReverseProxy(baseUrl) + proxy = NewSingleHostReverseProxy(baseURL) } } else if proxy == nil { return http.StatusInternalServerError, err diff --git a/middleware/proxy/upstream.go b/middleware/proxy/upstream.go index b49beaa0c..c724da78e 100644 --- a/middleware/proxy/upstream.go +++ b/middleware/proxy/upstream.go @@ -1,7 +1,6 @@ package proxy import ( - "github.com/mholt/caddy/config/parse" "io" "io/ioutil" "net/http" @@ -9,6 +8,8 @@ import ( "strconv" "strings" "time" + + "github.com/mholt/caddy/config/parse" ) type staticUpstream struct { @@ -24,7 +25,7 @@ type staticUpstream struct { } } -// newStaticUpstreams parses the configuration input and sets up +// NewStaticUpstreams parses the configuration input and sets up // static upstreams for the proxy middleware. func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) { var upstreams []Upstream @@ -130,8 +131,8 @@ func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) { } }(upstream), } - if baseUrl, err := url.Parse(uh.Name); err == nil { - uh.ReverseProxy = NewSingleHostReverseProxy(baseUrl) + if baseURL, err := url.Parse(uh.Name); err == nil { + uh.ReverseProxy = NewSingleHostReverseProxy(baseURL) } else { return upstreams, err } @@ -152,8 +153,8 @@ func (u *staticUpstream) From() string { func (u *staticUpstream) healthCheck() { for _, host := range u.Hosts { - hostUrl := host.Name + u.HealthCheck.Path - if r, err := http.Get(hostUrl); err == nil { + hostURL := host.Name + u.HealthCheck.Path + if r, err := http.Get(hostURL); err == nil { io.Copy(ioutil.Discard, r.Body) r.Body.Close() host.Unhealthy = r.StatusCode < 200 || r.StatusCode >= 400 @@ -199,7 +200,6 @@ func (u *staticUpstream) Select() *UpstreamHost { if u.Policy == nil { return (&Random{}).Select(pool) - } else { - return u.Policy.Select(pool) } + return u.Policy.Select(pool) } From d0a51048d74628cea355e158536972da1b36eb72 Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Sun, 24 May 2015 21:00:54 -0400 Subject: [PATCH 2/4] Fix lint warnings in middleware/rewrite --- middleware/rewrite/rewrite.go | 5 +++-- middleware/rewrite/rewrite_test.go | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/middleware/rewrite/rewrite.go b/middleware/rewrite/rewrite.go index aefb23295..9e8d62bb4 100644 --- a/middleware/rewrite/rewrite.go +++ b/middleware/rewrite/rewrite.go @@ -6,12 +6,13 @@ import ( "net/http" "fmt" - "github.com/mholt/caddy/middleware" "net/url" "path" "path/filepath" "regexp" "strings" + + "github.com/mholt/caddy/middleware" ) // Rewrite is middleware to rewrite request locations internally before being handled. @@ -96,7 +97,7 @@ func NewRegexpRule(base, pattern, to string, ext []string) (*RegexpRule, error) } // regexpVars are variables that can be used for To (rewrite destination path). -var regexpVars []string = []string{ +var regexpVars = []string{ "{path}", "{query}", "{file}", diff --git a/middleware/rewrite/rewrite_test.go b/middleware/rewrite/rewrite_test.go index dd9c77df1..d9056b431 100644 --- a/middleware/rewrite/rewrite_test.go +++ b/middleware/rewrite/rewrite_test.go @@ -6,8 +6,9 @@ import ( "net/http/httptest" "testing" - "github.com/mholt/caddy/middleware" "strings" + + "github.com/mholt/caddy/middleware" ) func TestRewrite(t *testing.T) { From fd8490c68931675126f1d202577a858c5a618255 Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Sun, 24 May 2015 21:04:03 -0400 Subject: [PATCH 3/4] Fix lint warnings for middleware/websockets --- middleware/websockets/websockets.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/middleware/websockets/websockets.go b/middleware/websockets/websockets.go index 35838aadb..81e40510b 100644 --- a/middleware/websockets/websockets.go +++ b/middleware/websockets/websockets.go @@ -22,7 +22,7 @@ type ( Sockets []Config } - // WSConfig holds the configuration for a single websocket + // Config holds the configuration for a single websocket // endpoint which may serve multiple websocket connections. Config struct { Path string @@ -50,9 +50,11 @@ func (ws WebSockets) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err } var ( - // See CGI spec, 4.1.4 + // GatewayInterface is the dialect of CGI being used by the server + // to communicate with the script. See CGI spec, 4.1.4 GatewayInterface string - // See CGI spec, 4.1.17 + // ServerSoftware is the name and version of the information server + // software making the CGI request. See CGI spec, 4.1.17 ServerSoftware string ) From e4b50aa814476c4a610ad32b9f580f3e39f3bfc6 Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Sun, 24 May 2015 22:52:34 -0400 Subject: [PATCH 4/4] Fix more lint warnings --- app/app.go | 10 +-- config/config.go | 3 +- config/parse/lexer.go | 3 +- config/setup/git.go | 54 +++++++-------- config/setup/git_test.go | 22 +++--- config/setup/log.go | 11 +-- middleware/basicauth/basicauth.go | 8 +-- middleware/basicauth/basicauth_test.go | 18 ++--- middleware/browse/browse.go | 2 + middleware/extensions/ext.go | 2 +- middleware/fastcgi/fcgiclient.go | 93 +++++++++++++------------- middleware/git/git.go | 36 +++++----- middleware/git/git_test.go | 20 +++--- middleware/gzip/gzip.go | 3 +- middleware/internal/internal.go | 5 +- middleware/log/log.go | 6 +- middleware/markdown/markdown.go | 15 ++--- middleware/markdown/metadata.go | 12 ++-- middleware/path.go | 2 + server/fileserver.go | 7 +- server/server.go | 3 +- 21 files changed, 164 insertions(+), 171 deletions(-) diff --git a/app/app.go b/app/app.go index 0463dcb80..ca515ea12 100644 --- a/app/app.go +++ b/app/app.go @@ -16,10 +16,10 @@ import ( ) const ( - // Program name + // Name is the program name Name = "Caddy" - // Program version + // Version is the program version Version = "0.6.0" ) @@ -27,13 +27,13 @@ var ( // Servers is a list of all the currently-listening servers Servers []*server.Server - // This mutex protects the Servers slice during changes + // ServersMutex protects the Servers slice during changes ServersMutex sync.Mutex - // Waiting on Wg will block until all listeners have shut down. + // Wg is used to wait for all servers to shut down Wg sync.WaitGroup - // Whether HTTP2 is enabled or not + // Http2 indicates whether HTTP2 is enabled or not Http2 bool // TODO: temporary flag until http2 is standard // Quiet mode hides non-error initialization output diff --git a/config/config.go b/config/config.go index a93e7a3ca..7256ab8a0 100644 --- a/config/config.go +++ b/config/config.go @@ -19,7 +19,8 @@ const ( DefaultPort = "2015" DefaultRoot = "." - // The default configuration file to load if none is specified + // DefaultConfigFile is the name of the configuration file that is loaded + // by default if no other file is specified. DefaultConfigFile = "Caddyfile" ) diff --git a/config/parse/lexer.go b/config/parse/lexer.go index 32efc9e20..2ba131989 100644 --- a/config/parse/lexer.go +++ b/config/parse/lexer.go @@ -58,9 +58,8 @@ func (l *lexer) next() bool { } if err == io.EOF { return false - } else { - panic(err) } + panic(err) } if quoted { diff --git a/config/setup/git.go b/config/setup/git.go index a9390e51f..f25fbc22e 100644 --- a/config/setup/git.go +++ b/config/setup/git.go @@ -57,7 +57,7 @@ func gitParse(c *Controller) (*git.Repo, error) { repo.Path = filepath.Clean(c.Root + string(filepath.Separator) + args[1]) fallthrough case 1: - repo.Url = args[0] + repo.URL = args[0] } for c.NextBlock() { @@ -66,7 +66,7 @@ func gitParse(c *Controller) (*git.Repo, error) { if !c.NextArg() { return nil, c.ArgErr() } - repo.Url = c.Val() + repo.URL = c.Val() case "path": if !c.NextArg() { return nil, c.ArgErr() @@ -103,19 +103,19 @@ func gitParse(c *Controller) (*git.Repo, error) { } // if repo is not specified, return error - if repo.Url == "" { + if repo.URL == "" { return nil, c.ArgErr() } - // if private key is not specified, convert repository url to https + // if private key is not specified, convert repository URL to https // to avoid ssh authentication - // else validate git url + // else validate git URL // Note: private key support not yet available on Windows var err error if repo.KeyPath == "" { - repo.Url, repo.Host, err = sanitizeHttp(repo.Url) + repo.URL, repo.Host, err = sanitizeHTTP(repo.URL) } else { - repo.Url, repo.Host, err = sanitizeGit(repo.Url) + repo.URL, repo.Host, err = sanitizeGit(repo.URL) // TODO add Windows support for private repos if runtime.GOOS == "windows" { return nil, fmt.Errorf("Private repository not yet supported on Windows") @@ -134,12 +134,12 @@ func gitParse(c *Controller) (*git.Repo, error) { return repo, repo.Prepare() } -// sanitizeHttp cleans up repository url and converts to https format +// sanitizeHTTP cleans up repository URL and converts to https format // if currently in ssh format. // Returns sanitized url, hostName (e.g. github.com, bitbucket.com) // and possible error -func sanitizeHttp(repoUrl string) (string, string, error) { - url, err := url.Parse(repoUrl) +func sanitizeHTTP(repoURL string) (string, string, error) { + url, err := url.Parse(repoURL) if err != nil { return "", "", err } @@ -148,46 +148,46 @@ func sanitizeHttp(repoUrl string) (string, string, error) { url.Path = url.Path[len("git@"):] i := strings.Index(url.Path, ":") if i < 0 { - return "", "", fmt.Errorf("Invalid git url %s", repoUrl) + return "", "", fmt.Errorf("Invalid git url %s", repoURL) } url.Host = url.Path[:i] url.Path = "/" + url.Path[i+1:] } - repoUrl = "https://" + url.Host + url.Path + repoURL = "https://" + url.Host + url.Path // add .git suffix if missing - if !strings.HasSuffix(repoUrl, ".git") { - repoUrl += ".git" + if !strings.HasSuffix(repoURL, ".git") { + repoURL += ".git" } - return repoUrl, url.Host, nil + return repoURL, url.Host, nil } // sanitizeGit cleans up repository url and converts to ssh format for private // repositories if required. // Returns sanitized url, hostName (e.g. github.com, bitbucket.com) // and possible error -func sanitizeGit(repoUrl string) (string, string, error) { - repoUrl = strings.TrimSpace(repoUrl) +func sanitizeGit(repoURL string) (string, string, error) { + repoURL = strings.TrimSpace(repoURL) // check if valid ssh format - if !strings.HasPrefix(repoUrl, "git@") || strings.Index(repoUrl, ":") < len("git@a:") { + if !strings.HasPrefix(repoURL, "git@") || strings.Index(repoURL, ":") < len("git@a:") { // check if valid http format and convert to ssh - if url, err := url.Parse(repoUrl); err == nil && strings.HasPrefix(url.Scheme, "http") { - repoUrl = fmt.Sprintf("git@%v:%v", url.Host, url.Path[1:]) + if url, err := url.Parse(repoURL); err == nil && strings.HasPrefix(url.Scheme, "http") { + repoURL = fmt.Sprintf("git@%v:%v", url.Host, url.Path[1:]) } else { - return "", "", fmt.Errorf("Invalid git url %s", repoUrl) + return "", "", fmt.Errorf("Invalid git url %s", repoURL) } } - hostUrl := repoUrl[len("git@"):] - i := strings.Index(hostUrl, ":") - host := hostUrl[:i] + hostURL := repoURL[len("git@"):] + i := strings.Index(hostURL, ":") + host := hostURL[:i] // add .git suffix if missing - if !strings.HasSuffix(repoUrl, ".git") { - repoUrl += ".git" + if !strings.HasSuffix(repoURL, ".git") { + repoURL += ".git" } - return repoUrl, host, nil + return repoURL, host, nil } diff --git a/config/setup/git_test.go b/config/setup/git_test.go index 2c1a494c1..3a441bbd4 100644 --- a/config/setup/git_test.go +++ b/config/setup/git_test.go @@ -32,29 +32,29 @@ func TestGitParse(t *testing.T) { expected *git.Repo }{ {`git git@github.com:user/repo`, false, &git.Repo{ - Url: "https://github.com/user/repo.git", + URL: "https://github.com/user/repo.git", }}, {`git github.com/user/repo`, false, &git.Repo{ - Url: "https://github.com/user/repo.git", + URL: "https://github.com/user/repo.git", }}, {`git git@github.com/user/repo`, true, nil}, {`git http://github.com/user/repo`, false, &git.Repo{ - Url: "https://github.com/user/repo.git", + URL: "https://github.com/user/repo.git", }}, {`git https://github.com/user/repo`, false, &git.Repo{ - Url: "https://github.com/user/repo.git", + URL: "https://github.com/user/repo.git", }}, {`git http://github.com/user/repo { key ~/.key }`, false, &git.Repo{ KeyPath: "~/.key", - Url: "git@github.com:user/repo.git", + URL: "git@github.com:user/repo.git", }}, {`git git@github.com:user/repo { key ~/.key }`, false, &git.Repo{ KeyPath: "~/.key", - Url: "git@github.com:user/repo.git", + URL: "git@github.com:user/repo.git", }}, {`git `, true, nil}, {`git { @@ -66,7 +66,7 @@ func TestGitParse(t *testing.T) { key ~/.key }`, false, &git.Repo{ KeyPath: "~/.key", - Url: "git@github.com:user/repo.git", + URL: "git@github.com:user/repo.git", }}, {`git { repo git@github.com:user/repo @@ -74,7 +74,7 @@ func TestGitParse(t *testing.T) { interval 600 }`, false, &git.Repo{ KeyPath: "~/.key", - Url: "git@github.com:user/repo.git", + URL: "git@github.com:user/repo.git", Interval: time.Second * 600, }}, {`git { @@ -82,7 +82,7 @@ func TestGitParse(t *testing.T) { branch dev }`, false, &git.Repo{ Branch: "dev", - Url: "https://github.com/user/repo.git", + URL: "https://github.com/user/repo.git", }}, {`git { key ~/.key @@ -93,7 +93,7 @@ func TestGitParse(t *testing.T) { then echo hello world }`, false, &git.Repo{ KeyPath: "~/.key", - Url: "git@github.com:user/repo.git", + URL: "git@github.com:user/repo.git", Then: "echo hello world", }}, } @@ -137,7 +137,7 @@ func reposEqual(expected, repo *git.Repo) bool { if expected.Then != "" && expected.Then != repo.Then { return false } - if expected.Url != "" && expected.Url != repo.Url { + if expected.URL != "" && expected.URL != repo.URL { return false } return true diff --git a/config/setup/log.go b/config/setup/log.go index 32b5edba0..4b5e11c68 100644 --- a/config/setup/log.go +++ b/config/setup/log.go @@ -8,6 +8,7 @@ import ( caddylog "github.com/mholt/caddy/middleware/log" ) +// Log sets up the logging middleware. func Log(c *Controller) (middleware.Middleware, error) { rules, err := logParse(c) if err != nil { @@ -42,22 +43,22 @@ func Log(c *Controller) (middleware.Middleware, error) { }, nil } -func logParse(c *Controller) ([]caddylog.LogRule, error) { - var rules []caddylog.LogRule +func logParse(c *Controller) ([]caddylog.Rule, error) { + var rules []caddylog.Rule for c.Next() { args := c.RemainingArgs() if len(args) == 0 { // Nothing specified; use defaults - rules = append(rules, caddylog.LogRule{ + rules = append(rules, caddylog.Rule{ PathScope: "/", OutputFile: caddylog.DefaultLogFilename, Format: caddylog.DefaultLogFormat, }) } else if len(args) == 1 { // Only an output file specified - rules = append(rules, caddylog.LogRule{ + rules = append(rules, caddylog.Rule{ PathScope: "/", OutputFile: args[0], Format: caddylog.DefaultLogFormat, @@ -78,7 +79,7 @@ func logParse(c *Controller) ([]caddylog.LogRule, error) { } } - rules = append(rules, caddylog.LogRule{ + rules = append(rules, caddylog.Rule{ PathScope: args[0], OutputFile: args[1], Format: format, diff --git a/middleware/basicauth/basicauth.go b/middleware/basicauth/basicauth.go index 25d1d5046..bb39876df 100644 --- a/middleware/basicauth/basicauth.go +++ b/middleware/basicauth/basicauth.go @@ -41,16 +41,14 @@ func (a BasicAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error isAuthenticated = true } } - + if hasAuth { if !isAuthenticated { w.Header().Set("WWW-Authenticate", "Basic") return http.StatusUnauthorized, nil - } else { - // "It's an older code, sir, but it checks out. I was about to clear them." - return a.Next.ServeHTTP(w, r) } - + // "It's an older code, sir, but it checks out. I was about to clear them." + return a.Next.ServeHTTP(w, r) } // Pass-thru when no paths match diff --git a/middleware/basicauth/basicauth_test.go b/middleware/basicauth/basicauth_test.go index b590bc35b..51f944bd6 100644 --- a/middleware/basicauth/basicauth_test.go +++ b/middleware/basicauth/basicauth_test.go @@ -27,13 +27,10 @@ func TestBasicAuth(t *testing.T) { {"/testing", http.StatusUnauthorized, "ttest:test"}, {"/testing", http.StatusOK, "test:ttest"}, {"/testing", http.StatusUnauthorized, ""}, - } - for i, test := range tests { - req, err := http.NewRequest("GET", test.from, nil) if err != nil { t.Fatalf("Test %d: Could not create HTTP request %v", i, err) @@ -54,19 +51,17 @@ func TestBasicAuth(t *testing.T) { headers := rec.Header() if val, ok := headers["Www-Authenticate"]; ok { if val[0] != "Basic" { - t.Errorf("Test %d, Www-Authenticate should be %s provided %s", i, "Basic", val[0]) + t.Errorf("Test %d, Www-Authenticate should be %s provided %s", i, "Basic", val[0]) } } else { t.Errorf("Test %d, should provide a header Www-Authenticate", i) } } - } } - func TestMultipleOverlappingRules(t *testing.T) { rw := BasicAuth{ Next: middleware.HandlerFunc(contentHandler), @@ -75,7 +70,7 @@ func TestMultipleOverlappingRules(t *testing.T) { {Username: "t1", Password: "p2", Resources: []string{"/t/t"}}, }, } - + tests := []struct { from string result int @@ -89,9 +84,8 @@ func TestMultipleOverlappingRules(t *testing.T) { {"/t", http.StatusUnauthorized, "t1:p2"}, } - for i, test := range tests { - + req, err := http.NewRequest("GET", test.from, nil) if err != nil { t.Fatalf("Test %d: Could not create HTTP request %v", i, err) @@ -108,14 +102,12 @@ func TestMultipleOverlappingRules(t *testing.T) { t.Errorf("Test %d: Expected Header '%d' but was '%d'", i, test.result, result) } - + } } - - func contentHandler(w http.ResponseWriter, r *http.Request) (int, error) { fmt.Fprintf(w, r.URL.String()) return http.StatusOK, nil -} \ No newline at end of file +} diff --git a/middleware/browse/browse.go b/middleware/browse/browse.go index 9826bf696..ea2ff52c8 100644 --- a/middleware/browse/browse.go +++ b/middleware/browse/browse.go @@ -55,10 +55,12 @@ type FileInfo struct { Mode os.FileMode } +// HumanSize returns the size of the file as a human-readable string. func (fi FileInfo) HumanSize() string { return humanize.Bytes(uint64(fi.Size)) } +// HumanModTime returns the modified time of the file as a human-readable string. func (fi FileInfo) HumanModTime(format string) string { return fi.ModTime.Format(format) } diff --git a/middleware/extensions/ext.go b/middleware/extensions/ext.go index 6b0293271..c2852cbbe 100644 --- a/middleware/extensions/ext.go +++ b/middleware/extensions/ext.go @@ -1,4 +1,4 @@ -// Package extension is middleware for clean URLs. +// Package extensions contains middleware for clean URLs. // // The root path of the site is passed in as well as possible extensions // to try internally for paths requested that don't match an existing diff --git a/middleware/fastcgi/fcgiclient.go b/middleware/fastcgi/fcgiclient.go index 3e223d876..44b649e63 100644 --- a/middleware/fastcgi/fcgiclient.go +++ b/middleware/fastcgi/fcgiclient.go @@ -89,10 +89,10 @@ type header struct { // not synchronized because we don't care what the contents are var pad [maxPad]byte -func (h *header) init(recType uint8, reqId uint16, contentLength int) { +func (h *header) init(recType uint8, reqID uint16, contentLength int) { h.Version = 1 h.Type = recType - h.Id = reqId + h.Id = reqID h.ContentLength = uint16(contentLength) h.PaddingLength = uint8(-contentLength & 7) } @@ -135,7 +135,7 @@ type FCGIClient struct { reqId uint16 } -// Connects to the fcgi responder at the specified network address. +// Dial connects to the fcgi responder at the specified network address. // See func net.Dial for a description of the network and address parameters. func Dial(network, address string) (fcgi *FCGIClient, err error) { var conn net.Conn @@ -154,43 +154,43 @@ func Dial(network, address string) (fcgi *FCGIClient, err error) { return } -// Close fcgi connnection -func (this *FCGIClient) Close() { - this.rwc.Close() +// Close closes fcgi connnection +func (c *FCGIClient) Close() { + c.rwc.Close() } -func (this *FCGIClient) writeRecord(recType uint8, content []byte) (err error) { - this.mutex.Lock() - defer this.mutex.Unlock() - this.buf.Reset() - this.h.init(recType, this.reqId, len(content)) - if err := binary.Write(&this.buf, binary.BigEndian, this.h); err != nil { +func (c *FCGIClient) writeRecord(recType uint8, content []byte) (err error) { + c.mutex.Lock() + defer c.mutex.Unlock() + c.buf.Reset() + c.h.init(recType, c.reqId, len(content)) + if err := binary.Write(&c.buf, binary.BigEndian, c.h); err != nil { return err } - if _, err := this.buf.Write(content); err != nil { + if _, err := c.buf.Write(content); err != nil { return err } - if _, err := this.buf.Write(pad[:this.h.PaddingLength]); err != nil { + if _, err := c.buf.Write(pad[:c.h.PaddingLength]); err != nil { return err } - _, err = this.rwc.Write(this.buf.Bytes()) + _, err = c.rwc.Write(c.buf.Bytes()) return err } -func (this *FCGIClient) writeBeginRequest(role uint16, flags uint8) error { +func (c *FCGIClient) writeBeginRequest(role uint16, flags uint8) error { b := [8]byte{byte(role >> 8), byte(role), flags} - return this.writeRecord(FCGI_BEGIN_REQUEST, b[:]) + return c.writeRecord(FCGI_BEGIN_REQUEST, b[:]) } -func (this *FCGIClient) writeEndRequest(appStatus int, protocolStatus uint8) error { +func (c *FCGIClient) writeEndRequest(appStatus int, protocolStatus uint8) error { b := make([]byte, 8) binary.BigEndian.PutUint32(b, uint32(appStatus)) b[4] = protocolStatus - return this.writeRecord(FCGI_END_REQUEST, b) + return c.writeRecord(FCGI_END_REQUEST, b) } -func (this *FCGIClient) writePairs(recType uint8, pairs map[string]string) error { - w := newWriter(this, recType) +func (c *FCGIClient) writePairs(recType uint8, pairs map[string]string) error { + w := newWriter(c, recType) b := make([]byte, 8) nn := 0 for k, v := range pairs { @@ -333,32 +333,32 @@ func (w *streamReader) Read(p []byte) (n int, err error) { // Do made the request and returns a io.Reader that translates the data read // from fcgi responder out of fcgi packet before returning it. -func (this *FCGIClient) Do(p map[string]string, req io.Reader) (r io.Reader, err error) { - err = this.writeBeginRequest(uint16(FCGI_RESPONDER), 0) +func (c *FCGIClient) Do(p map[string]string, req io.Reader) (r io.Reader, err error) { + err = c.writeBeginRequest(uint16(FCGI_RESPONDER), 0) if err != nil { return } - err = this.writePairs(FCGI_PARAMS, p) + err = c.writePairs(FCGI_PARAMS, p) if err != nil { return } - body := newWriter(this, FCGI_STDIN) + body := newWriter(c, FCGI_STDIN) if req != nil { io.Copy(body, req) } body.Close() - r = &streamReader{c: this} + r = &streamReader{c: c} return } // Request returns a HTTP Response with Header and Body // from fcgi responder -func (this *FCGIClient) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) { +func (c *FCGIClient) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) { - r, err := this.Do(p, req) + r, err := c.Do(p, req) if err != nil { return } @@ -394,40 +394,39 @@ func (this *FCGIClient) Request(p map[string]string, req io.Reader) (resp *http. } else { resp.Body = ioutil.NopCloser(rb) } - return } // Get issues a GET request to the fcgi responder. -func (this *FCGIClient) Get(p map[string]string) (resp *http.Response, err error) { +func (c *FCGIClient) Get(p map[string]string) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "GET" p["CONTENT_LENGTH"] = "0" - return this.Request(p, nil) + return c.Request(p, nil) } // Head issues a HEAD request to the fcgi responder. -func (this *FCGIClient) Head(p map[string]string) (resp *http.Response, err error) { +func (c *FCGIClient) Head(p map[string]string) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "HEAD" p["CONTENT_LENGTH"] = "0" - return this.Request(p, nil) + return c.Request(p, nil) } // Options issues an OPTIONS request to the fcgi responder. -func (this *FCGIClient) Options(p map[string]string) (resp *http.Response, err error) { +func (c *FCGIClient) Options(p map[string]string) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "OPTIONS" p["CONTENT_LENGTH"] = "0" - return this.Request(p, nil) + return c.Request(p, nil) } // Post issues a POST request to the fcgi responder. with request body // in the format that bodyType specified -func (this *FCGIClient) Post(p map[string]string, bodyType string, body io.Reader, l int) (resp *http.Response, err error) { +func (c *FCGIClient) Post(p map[string]string, bodyType string, body io.Reader, l int) (resp *http.Response, err error) { if len(p["REQUEST_METHOD"]) == 0 || p["REQUEST_METHOD"] == "GET" { p["REQUEST_METHOD"] = "POST" @@ -439,44 +438,44 @@ func (this *FCGIClient) Post(p map[string]string, bodyType string, body io.Reade p["CONTENT_TYPE"] = "application/x-www-form-urlencoded" } - return this.Request(p, body) + return c.Request(p, body) } // Put issues a PUT request to the fcgi responder. -func (this *FCGIClient) Put(p map[string]string, bodyType string, body io.Reader, l int) (resp *http.Response, err error) { +func (c *FCGIClient) Put(p map[string]string, bodyType string, body io.Reader, l int) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "PUT" - return this.Post(p, bodyType, body, l) + return c.Post(p, bodyType, body, l) } // Patch issues a PATCH request to the fcgi responder. -func (this *FCGIClient) Patch(p map[string]string, bodyType string, body io.Reader, l int) (resp *http.Response, err error) { +func (c *FCGIClient) Patch(p map[string]string, bodyType string, body io.Reader, l int) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "PATCH" - return this.Post(p, bodyType, body, l) + return c.Post(p, bodyType, body, l) } // Delete issues a DELETE request to the fcgi responder. -func (this *FCGIClient) Delete(p map[string]string, bodyType string, body io.Reader, l int) (resp *http.Response, err error) { +func (c *FCGIClient) Delete(p map[string]string, bodyType string, body io.Reader, l int) (resp *http.Response, err error) { p["REQUEST_METHOD"] = "DELETE" - return this.Post(p, bodyType, body, l) + return c.Post(p, bodyType, body, l) } // PostForm issues a POST to the fcgi responder, with form // as a string key to a list values (url.Values) -func (this *FCGIClient) PostForm(p map[string]string, data url.Values) (resp *http.Response, err error) { +func (c *FCGIClient) PostForm(p map[string]string, data url.Values) (resp *http.Response, err error) { body := bytes.NewReader([]byte(data.Encode())) - return this.Post(p, "application/x-www-form-urlencoded", body, body.Len()) + return c.Post(p, "application/x-www-form-urlencoded", body, body.Len()) } // PostFile issues a POST to the fcgi responder in multipart(RFC 2046) standard, // with form as a string key to a list values (url.Values), // and/or with file as a string key to a list file path. -func (this *FCGIClient) PostFile(p map[string]string, data url.Values, file map[string]string) (resp *http.Response, err error) { +func (c *FCGIClient) PostFile(p map[string]string, data url.Values, file map[string]string) (resp *http.Response, err error) { buf := &bytes.Buffer{} writer := multipart.NewWriter(buf) bodyType := writer.FormDataContentType() @@ -509,7 +508,7 @@ func (this *FCGIClient) PostFile(p map[string]string, data url.Values, file map[ return } - return this.Post(p, bodyType, buf, buf.Len()) + return c.Post(p, bodyType, buf, buf.Len()) } // Checks whether chunked is part of the encodings stack diff --git a/middleware/git/git.go b/middleware/git/git.go index 5ed87395d..0c87cdb8f 100644 --- a/middleware/git/git.go +++ b/middleware/git/git.go @@ -28,7 +28,7 @@ var shell string // initMutex prevents parallel attempt to validate // git requirements. -var initMutex sync.Mutex = sync.Mutex{} +var initMutex = sync.Mutex{} // Logger is used to log errors; if nil, the default log.Logger is used. var Logger *log.Logger @@ -44,7 +44,7 @@ func logger() *log.Logger { // Repo is the structure that holds required information // of a git repository. type Repo struct { - Url string // Repository URL + URL string // Repository URL Path string // Directory to pull to Host string // Git domain host e.g. github.com Branch string // Git branch @@ -94,7 +94,7 @@ func (r *Repo) Pull() error { // Pull performs git clone, or git pull if repository exists func (r *Repo) pull() error { - params := []string{"clone", "-b", r.Branch, r.Url, r.Path} + params := []string{"clone", "-b", r.Branch, r.URL, r.Path} if r.pulled { params = []string{"pull", "origin", r.Branch} } @@ -113,7 +113,7 @@ func (r *Repo) pull() error { if err = runCmd(gitBinary, params, dir); err == nil { r.pulled = true r.lastPull = time.Now() - logger().Printf("%v pulled.\n", r.Url) + logger().Printf("%v pulled.\n", r.URL) r.lastCommit, err = r.getMostRecentCommit() } return err @@ -122,11 +122,11 @@ func (r *Repo) pull() error { // pullWithKey is used for private repositories and requires an ssh key. // Note: currently only limited to Linux and OSX. func (r *Repo) pullWithKey(params []string) error { - var gitSsh, script gitos.File + var gitSSH, script gitos.File // ensure temporary files deleted after usage defer func() { - if gitSsh != nil { - gos.Remove(gitSsh.Name()) + if gitSSH != nil { + gos.Remove(gitSSH.Name()) } if script != nil { gos.Remove(script.Name()) @@ -135,13 +135,13 @@ func (r *Repo) pullWithKey(params []string) error { var err error // write git.sh script to temp file - gitSsh, err = writeScriptFile(gitWrapperScript()) + gitSSH, err = writeScriptFile(gitWrapperScript()) if err != nil { return err } // write git clone bash script to file - script, err = writeScriptFile(bashScript(gitSsh.Name(), r, params)) + script, err = writeScriptFile(bashScript(gitSSH.Name(), r, params)) if err != nil { return err } @@ -154,7 +154,7 @@ func (r *Repo) pullWithKey(params []string) error { if err = runCmd(script.Name(), nil, dir); err == nil { r.pulled = true r.lastPull = time.Now() - logger().Printf("%v pulled.\n", r.Url) + logger().Printf("%v pulled.\n", r.URL) r.lastCommit, err = r.getMostRecentCommit() } return err @@ -181,13 +181,13 @@ func (r *Repo) Prepare() error { if isGit { // check if same repository - var repoUrl string - if repoUrl, err = r.getRepoUrl(); err == nil { + var repoURL string + if repoURL, err = r.getRepoURL(); err == nil { // add .git suffix if missing for adequate comparison. - if !strings.HasSuffix(repoUrl, ".git") { - repoUrl += ".git" + if !strings.HasSuffix(repoURL, ".git") { + repoURL += ".git" } - if repoUrl == r.Url { + if repoURL == r.URL { r.pulled = true return nil } @@ -195,7 +195,7 @@ func (r *Repo) Prepare() error { if err != nil { return fmt.Errorf("Cannot retrieve repo url for %v Error: %v", r.Path, err) } - return fmt.Errorf("Another git repo '%v' exists at %v", repoUrl, r.Path) + return fmt.Errorf("Another git repo '%v' exists at %v", repoURL, r.Path) } return fmt.Errorf("Cannot git clone into %v, directory not empty.", r.Path) } @@ -211,8 +211,8 @@ func (r *Repo) getMostRecentCommit() (string, error) { return runCmdOutput(c, args, r.Path) } -// getRepoUrl retrieves remote origin url for the git repository at path -func (r *Repo) getRepoUrl() (string, error) { +// getRepoURL retrieves remote origin url for the git repository at path +func (r *Repo) getRepoURL() (string, error) { _, err := gos.Stat(r.Path) if err != nil { return "", err diff --git a/middleware/git/git_test.go b/middleware/git/git_test.go index a2e8f1e82..2d76e0bf4 100644 --- a/middleware/git/git_test.go +++ b/middleware/git/git_test.go @@ -63,7 +63,7 @@ func TestGit(t *testing.T) { // prepare repos := []*Repo{ nil, - &Repo{Path: "gitdir", Url: "success.git"}, + &Repo{Path: "gitdir", URL: "success.git"}, } for _, r := range repos { repo := createRepo(r) @@ -79,26 +79,26 @@ func TestGit(t *testing.T) { output string }{ { - &Repo{Path: "gitdir", Url: "git@github.com:user/repo.git", KeyPath: "~/.key", Then: "echo Hello"}, + &Repo{Path: "gitdir", URL: "git@github.com:user/repo.git", KeyPath: "~/.key", Then: "echo Hello"}, `git@github.com:user/repo.git pulled. Command echo Hello successful. `, }, { - &Repo{Path: "gitdir", Url: "https://github.com/user/repo.git", Then: "echo Hello"}, + &Repo{Path: "gitdir", URL: "https://github.com/user/repo.git", Then: "echo Hello"}, `https://github.com/user/repo.git pulled. Command echo Hello successful. `, }, { - &Repo{Url: "git@github.com:user/repo"}, + &Repo{URL: "git@github.com:user/repo"}, `git@github.com:user/repo pulled. `, }, } for i, test := range tests { - gittest.CmdOutput = test.repo.Url + gittest.CmdOutput = test.repo.URL test.repo = createRepo(test.repo) @@ -117,8 +117,8 @@ Command echo Hello successful. // pull with error repos = []*Repo{ - &Repo{Path: "gitdir", Url: "http://github.com:u/repo.git"}, - &Repo{Path: "gitdir", Url: "https://github.com/user/repo.git", Then: "echo Hello"}, + &Repo{Path: "gitdir", URL: "http://github.com:u/repo.git"}, + &Repo{Path: "gitdir", URL: "https://github.com/user/repo.git", Then: "echo Hello"}, &Repo{Path: "gitdir"}, &Repo{Path: "gitdir", KeyPath: ".key"}, } @@ -143,7 +143,7 @@ Command echo Hello successful. func createRepo(r *Repo) *Repo { repo := &Repo{ - Url: "git@github.com/user/test", + URL: "git@github.com/user/test", Path: ".", Host: "github.com", Branch: "master", @@ -170,8 +170,8 @@ func createRepo(r *Repo) *Repo { if r.Then != "" { repo.Then = r.Then } - if r.Url != "" { - repo.Url = r.Url + if r.URL != "" { + repo.URL = r.URL } return repo diff --git a/middleware/gzip/gzip.go b/middleware/gzip/gzip.go index 64c885e5d..803612ef5 100644 --- a/middleware/gzip/gzip.go +++ b/middleware/gzip/gzip.go @@ -45,9 +45,8 @@ func (g Gzip) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { gz.WriteHeader(status) fmt.Fprintf(gz, "%d %s", status, http.StatusText(status)) return 0, err - } else { - return status, err } + return status, err } // gzipResponeWriter wraps the underlying Write method diff --git a/middleware/internal/internal.go b/middleware/internal/internal.go index 90746b063..7cb2d7826 100644 --- a/middleware/internal/internal.go +++ b/middleware/internal/internal.go @@ -1,4 +1,4 @@ -// The package internal provides a simple middleware that (a) prevents access +// Package internal provides a simple middleware that (a) prevents access // to internal locations and (b) allows to return files from internal location // by setting a special header, e.g. in a proxy response. package internal @@ -85,7 +85,6 @@ func (w internalResponseWriter) WriteHeader(code int) { func (w internalResponseWriter) Write(b []byte) (int, error) { if isInternalRedirect(w) { return 0, nil - } else { - return w.ResponseWriter.Write(b) } + return w.ResponseWriter.Write(b) } diff --git a/middleware/log/log.go b/middleware/log/log.go index 39d8ae038..f4329d21f 100644 --- a/middleware/log/log.go +++ b/middleware/log/log.go @@ -8,9 +8,10 @@ import ( "github.com/mholt/caddy/middleware" ) +// Logger is a basic request logging middleware. type Logger struct { Next middleware.Handler - Rules []LogRule + Rules []Rule } func (l Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { @@ -26,7 +27,8 @@ func (l Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { return l.Next.ServeHTTP(w, r) } -type LogRule struct { +// Rule configures the logging middleware. +type Rule struct { PathScope string OutputFile string Format string diff --git a/middleware/markdown/markdown.go b/middleware/markdown/markdown.go index f3cf75f98..6b7f35563 100644 --- a/middleware/markdown/markdown.go +++ b/middleware/markdown/markdown.go @@ -31,9 +31,9 @@ type Markdown struct { IndexFiles []string } -// Helper function to check if a file is an index file -func (m Markdown) IsIndexFile(file string) bool { - for _, f := range m.IndexFiles { +// IsIndexFile checks to see if a file is an index file +func (md Markdown) IsIndexFile(file string) bool { + for _, f := range md.IndexFiles { if f == file { return true } @@ -105,12 +105,11 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error if html, err := ioutil.ReadFile(filepath); err == nil { w.Write(html) return http.StatusOK, nil - } else { - if os.IsPermission(err) { - return http.StatusForbidden, err - } - return http.StatusNotFound, nil } + if os.IsPermission(err) { + return http.StatusForbidden, err + } + return http.StatusNotFound, nil } } } diff --git a/middleware/markdown/metadata.go b/middleware/markdown/metadata.go index 0f6ef9e85..453eb2df5 100644 --- a/middleware/markdown/metadata.go +++ b/middleware/markdown/metadata.go @@ -88,8 +88,8 @@ func (j *JSONMetadataParser) Parse(b []byte) ([]byte, error) { return buf[:n], nil } -// Parsed metadata. -// Should be called after a call to Parse returns no error +// Metadata returns parsed metadata. It should be called +// only after a call to Parse returns without error. func (j *JSONMetadataParser) Metadata() Metadata { return j.metadata } @@ -123,8 +123,8 @@ func (t *TOMLMetadataParser) Parse(b []byte) ([]byte, error) { return markdown, nil } -// Parsed metadata. -// Should be called after a call to Parse returns no error +// Metadata returns parsed metadata. It should be called +// only after a call to Parse returns without error. func (t *TOMLMetadataParser) Metadata() Metadata { return t.metadata } @@ -171,8 +171,8 @@ func (y *YAMLMetadataParser) Parse(b []byte) ([]byte, error) { return markdown, nil } -// Parsed metadata. -// Should be called after a call to Parse returns no error +// Metadata returns parsed metadata. It should be called +// only after a call to Parse returns without error. func (y *YAMLMetadataParser) Metadata() Metadata { return y.metadata } diff --git a/middleware/path.go b/middleware/path.go index c165ce8e0..ecfac7478 100644 --- a/middleware/path.go +++ b/middleware/path.go @@ -5,6 +5,8 @@ import "strings" // Path represents a URI path, maybe with pattern characters. type Path string +// Matches checks to see if other matches p. +// // Path matching will probably not always be a direct // comparison; this method assures that paths can be // easily and consistently matched. diff --git a/server/fileserver.go b/server/fileserver.go index dc5af4b53..4d12905bb 100644 --- a/server/fileserver.go +++ b/server/fileserver.go @@ -10,7 +10,7 @@ import ( "github.com/mholt/caddy/middleware/browse" ) -// This FileServer is adapted from the one in net/http by +// FileServer is adapted from the one in net/http by // the Go authors. Significant modifications have been made. // // @@ -28,15 +28,16 @@ type fileHandler struct { hide []string // list of files to treat as "Not Found" } -func (f *fileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { +func (fh *fileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { upath := r.URL.Path if !strings.HasPrefix(upath, "/") { upath = "/" + upath r.URL.Path = upath } - return f.serveFile(w, r, path.Clean(upath)) + return fh.serveFile(w, r, path.Clean(upath)) } +// serveFile writes the specified file to the HTTP response. // name is '/'-separated, not filepath.Separator. func (fh *fileHandler) serveFile(w http.ResponseWriter, r *http.Request, name string) (int, error) { f, err := fh.root.Open(name) diff --git a/server/server.go b/server/server.go index ecc2bc6bf..313101cfe 100644 --- a/server/server.go +++ b/server/server.go @@ -97,9 +97,8 @@ func (s *Server) Serve() error { tlsConfigs = append(tlsConfigs, vh.config.TLS) } return ListenAndServeTLSWithSNI(server, tlsConfigs) - } else { - return server.ListenAndServe() } + return server.ListenAndServe() } // ListenAndServeTLSWithSNI serves TLS with Server Name Indication (SNI) support, which allows