mirror of
https://github.com/caddyserver/caddy.git
synced 2025-06-06 21:04:41 +08:00
Use RequestURI when redirecting to canonical path. (#1331)
* Use RequestURI when redirecting to canonical path. Caddy may trim a request's URL path when it starts with the path that's associated with the virtual host. This change uses the path from the request's RequestURI when performing a redirect. Fix issue #1327. * Rename redirurl to redirURL. * Redirect to the full URL. The scheme and host from the virtual host's site configuration is used in order to redirect to the full URL. * Add comment and remove redundant check. * Store the original URL path in request context. By storing the original URL path as a value in the request context, middlewares can access both it and the sanitized path. The default default FileServer handler will use the original URL on redirects. * Replace contextKey type with CtxKey. In addition to moving the CtxKey definition to the caddy package, this change updates the CtxKey references in the httpserver, fastcgi, and basicauth packages. * httpserver: Fix reference to CtxKey
This commit is contained in:
@ -14,6 +14,7 @@ import (
|
||||
|
||||
"os"
|
||||
|
||||
"github.com/mholt/caddy"
|
||||
"github.com/russross/blackfriday"
|
||||
)
|
||||
|
||||
@ -325,10 +326,8 @@ func (c Context) Files(name string) ([]string, error) {
|
||||
// IsMITM returns true if it seems likely that the TLS connection
|
||||
// is being intercepted.
|
||||
func (c Context) IsMITM() bool {
|
||||
if val, ok := c.Req.Context().Value(CtxKey("mitm")).(bool); ok {
|
||||
if val, ok := c.Req.Context().Value(caddy.CtxKey("mitm")).(bool); ok {
|
||||
return val
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type CtxKey string
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mholt/caddy"
|
||||
)
|
||||
|
||||
// tlsHandler is a http.Handler that will inject a value
|
||||
@ -72,7 +74,7 @@ func (h *tlsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if checked {
|
||||
r = r.WithContext(context.WithValue(r.Context(), CtxKey("mitm"), mitm))
|
||||
r = r.WithContext(context.WithValue(r.Context(), caddy.CtxKey("mitm"), mitm))
|
||||
}
|
||||
|
||||
if mitm && h.closeOnMITM {
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/mholt/caddy"
|
||||
)
|
||||
|
||||
func TestParseClientHello(t *testing.T) {
|
||||
@ -285,7 +287,7 @@ func TestHeuristicFunctionsAndHandler(t *testing.T) {
|
||||
want := ch.interception
|
||||
handler := &tlsHandler{
|
||||
next: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
got, checked = r.Context().Value(CtxKey("mitm")).(bool)
|
||||
got, checked = r.Context().Value(caddy.CtxKey("mitm")).(bool)
|
||||
}),
|
||||
listener: newTLSListener(nil, nil),
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mholt/caddy"
|
||||
)
|
||||
|
||||
// requestReplacer is a strings.Replacer which is used to
|
||||
@ -299,7 +301,7 @@ func (r *replacer) getSubstitution(key string) string {
|
||||
}
|
||||
return requestReplacer.Replace(r.requestBody.String())
|
||||
case "{mitm}":
|
||||
if val, ok := r.request.Context().Value(CtxKey("mitm")).(bool); ok {
|
||||
if val, ok := r.request.Context().Value(caddy.CtxKey("mitm")).(bool); ok {
|
||||
if val {
|
||||
return "likely"
|
||||
} else {
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
@ -284,6 +285,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Server", "Caddy")
|
||||
c := context.WithValue(r.Context(), caddy.URLPathCtxKey, r.URL.Path)
|
||||
r = r.WithContext(c)
|
||||
|
||||
sanitizePath(r)
|
||||
|
||||
@ -340,6 +343,14 @@ func (s *Server) serveHTTP(w http.ResponseWriter, r *http.Request) (int, error)
|
||||
}
|
||||
}
|
||||
|
||||
// URL fields other than Path and RawQuery will be empty for most server
|
||||
// requests. Hence, the request URL is updated with the scheme and host
|
||||
// from the virtual host's site address.
|
||||
if vhostURL, err := url.Parse(vhost.Addr.String()); err == nil {
|
||||
r.URL.Scheme = vhostURL.Scheme
|
||||
r.URL.Host = vhostURL.Host
|
||||
}
|
||||
|
||||
// Apply the path-based request body size limit
|
||||
// The error returned by MaxBytesReader is meant to be handled
|
||||
// by whichever middleware/plugin that receives it when calling
|
||||
@ -398,10 +409,10 @@ func (s *Server) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// sanitizePath collapses any ./ ../ /// madness
|
||||
// which helps prevent path traversal attacks.
|
||||
// Note to middleware: use URL.RawPath If you need
|
||||
// the "original" URL.Path value.
|
||||
// sanitizePath collapses any ./ ../ /// madness which helps prevent
|
||||
// path traversal attacks. Note to middleware: use the value within the
|
||||
// request's context at key caddy.URLPathContextKey to access the
|
||||
// "original" URL.Path value.
|
||||
func sanitizePath(r *http.Request) {
|
||||
if r.URL.Path == "/" {
|
||||
return
|
||||
|
Reference in New Issue
Block a user