Handle redirects using regular expressions, not just literal paths.

This commit is contained in:
Solderpunk 2020-07-01 11:13:38 +02:00
parent b30fc0923b
commit cc5410494e
2 changed files with 24 additions and 18 deletions

View File

@ -206,12 +206,16 @@ directory listing:
### Redirects
* `TempRedirects`: In this section of the config file, keys and values
are both path strings. If the path component of a received request
matches one of the keys, Molly Brown will serve a redirect to the
corresponding value, using status code 30. Note that currently
redirects cannot be specified using regular exressions, only literal
path strings.
* `TempRedirects`: In this section of the config file, keys are
regular expressions which the server will attempt to match against
the path component if incoming request URLs. If a match is found,
Molly Brown will serve a redirect to a new URL derived by replacing
the path component with the value corresponding to the matched key.
Within the replacement values, $1, $2, etc. will be replaced by the
first, second, etc. submatch in the regular expression. Named
captures can also be used for more sophisticated redirect logic -
see the documentation for the Go standard library's `regexp` package
for full details.
* `PermRedirects`: As per `TempRedirects` above, but Molly Brown will
use the 31 status code instead of 30.

View File

@ -248,19 +248,21 @@ func parseMollyFiles(path string, config *Config, errorLogEntries chan string) {
}
func handleRedirects(URL *url.URL, config Config, conn net.Conn, log *LogEntry) {
for src, dst := range config.TempRedirects {
if URL.Path == src {
URL.Path = dst
conn.Write([]byte("30 " + URL.String() + "\r\n"))
log.Status = 30
return
handleRedirectsInner(URL, config.TempRedirects, 30, conn, log)
handleRedirectsInner(URL, config.PermRedirects, 31, conn, log)
}
func handleRedirectsInner(URL *url.URL, redirects map[string]string, status int, conn net.Conn, log *LogEntry) {
strStatus := strconv.Itoa(status)
for src, dst := range redirects {
compiled, err := regexp.Compile(src)
if err != nil {
continue
}
}
for src, dst := range config.PermRedirects {
if URL.Path == src {
URL.Path = dst
conn.Write([]byte("31 " + URL.String() + "\r\n"))
log.Status = 31
if compiled.MatchString(URL.Path) {
URL.Path = compiled.ReplaceAllString(URL.Path, dst)
conn.Write([]byte(strStatus + " " + URL.String() + "\r\n"))
log.Status = status
return
}
}