Skip to content

Commit

Permalink
Add always-forward config to proxy server
Browse files Browse the repository at this point in the history
  • Loading branch information
benbjohnson committed Oct 19, 2023
1 parent c477633 commit 5b6e45b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
1 change: 1 addition & 0 deletions cmd/litefs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ type ProxyConfig struct {
MaxLag time.Duration `yaml:"max-lag"`
Debug bool `yaml:"debug"`
Passthrough []string `yaml:"passthrough"`
AlwaysForward []string `yaml:"always-forward"`
PrimaryRedirectTimeout time.Duration `yaml:"primary-redirect-timeout"`
}

Expand Down
11 changes: 11 additions & 0 deletions cmd/litefs/mount_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,13 +522,24 @@ func (c *MountCommand) runProxyServer(ctx context.Context) error {
passthroughs = append(passthroughs, re)
}

// Parse always-forward expressions.
var alwaysForward []*regexp.Regexp
for _, s := range c.Config.Proxy.AlwaysForward {
re, err := http.CompileMatch(s)
if err != nil {
return fmt.Errorf("cannot parse proxy always-forward expression: %q", s)
}
alwaysForward = append(alwaysForward, re)
}

server := http.NewProxyServer(c.Store)
server.Target = c.Config.Proxy.Target
server.DBName = c.Config.Proxy.DB
server.Addr = c.Config.Proxy.Addr
server.MaxLag = c.Config.Proxy.MaxLag
server.Debug = c.Config.Proxy.Debug
server.Passthroughs = passthroughs
server.AlwaysForward = alwaysForward
server.PrimaryRedirectTimeout = c.Config.Proxy.PrimaryRedirectTimeout
if err := server.Listen(); err != nil {
return err
Expand Down
29 changes: 23 additions & 6 deletions http/proxy_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ type ProxyServer struct {
// List of path expressions that will be passed through if matched.
Passthroughs []*regexp.Regexp

// List of path expressions that will always be redirected to the primary.
AlwaysForward []*regexp.Regexp

// If true, add verbose debug logging.
Debug bool

Expand Down Expand Up @@ -184,14 +187,18 @@ func (s *ProxyServer) serveHTTP(w http.ResponseWriter, r *http.Request) {
return
}

switch r.Method {
case http.MethodGet:
s.serveRead(w, r)
case http.MethodHead:
isReadOnly := r.Method == http.MethodGet || r.Method == http.MethodHead

// Override if path is configured to always forward.
if isReadOnly && s.isAlwaysForwarded(r) {
isReadOnly = false
}

if isReadOnly {
s.serveRead(w, r)
default:
s.serveNonRead(w, r)
return
}
s.serveNonRead(w, r)
}

func (s *ProxyServer) serveGetHealth(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -337,6 +344,16 @@ func (s *ProxyServer) isPassthrough(r *http.Request) bool {
return false
}

// isAlwaysForwarded returns true if request matches any of the redirection expressions.
func (s *ProxyServer) isAlwaysForwarded(r *http.Request) bool {
for _, re := range s.AlwaysForward {
if re.MatchString(r.URL.Path) {
return true
}
}
return false
}

// logf logs if debug logging is enabled.
func (s *ProxyServer) logf(format string, v ...any) {
if s.Debug {
Expand Down

0 comments on commit 5b6e45b

Please sign in to comment.