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 ### Redirects
* `TempRedirects`: In this section of the config file, keys and values * `TempRedirects`: In this section of the config file, keys are
are both path strings. If the path component of a received request regular expressions which the server will attempt to match against
matches one of the keys, Molly Brown will serve a redirect to the the path component if incoming request URLs. If a match is found,
corresponding value, using status code 30. Note that currently Molly Brown will serve a redirect to a new URL derived by replacing
redirects cannot be specified using regular exressions, only literal the path component with the value corresponding to the matched key.
path strings. 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 * `PermRedirects`: As per `TempRedirects` above, but Molly Brown will
use the 31 status code instead of 30. 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) { func handleRedirects(URL *url.URL, config Config, conn net.Conn, log *LogEntry) {
for src, dst := range config.TempRedirects { handleRedirectsInner(URL, config.TempRedirects, 30, conn, log)
if URL.Path == src { handleRedirectsInner(URL, config.PermRedirects, 31, conn, log)
URL.Path = dst }
conn.Write([]byte("30 " + URL.String() + "\r\n"))
log.Status = 30 func handleRedirectsInner(URL *url.URL, redirects map[string]string, status int, conn net.Conn, log *LogEntry) {
return strStatus := strconv.Itoa(status)
for src, dst := range redirects {
compiled, err := regexp.Compile(src)
if err != nil {
continue
} }
} if compiled.MatchString(URL.Path) {
for src, dst := range config.PermRedirects { URL.Path = compiled.ReplaceAllString(URL.Path, dst)
if URL.Path == src { conn.Write([]byte(strStatus + " " + URL.String() + "\r\n"))
URL.Path = dst log.Status = status
conn.Write([]byte("31 " + URL.String() + "\r\n"))
log.Status = 31
return return
} }
} }