Skip to content

Commit

Permalink
gateway: follow happyleft in handler_unixfs__redirects.go
Browse files Browse the repository at this point in the history
  • Loading branch information
Jorropo committed Mar 29, 2023
1 parent 1c17d52 commit 890701e
Showing 1 changed file with 65 additions and 58 deletions.
123 changes: 65 additions & 58 deletions gateway/handler_unixfs__redirects.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,78 +39,85 @@ import (
func (i *handler) serveRedirectsIfPresent(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, logger *zap.SugaredLogger) (newResolvedPath ipath.Resolved, newContentPath ipath.Path, continueProcessing bool, hadMatchingRule bool) {
redirectsFile := i.getRedirectsFile(r, contentPath, logger)
if redirectsFile != nil {
redirectRules, err := i.getRedirectRules(r, redirectsFile)
if err != nil {
webError(w, err, http.StatusInternalServerError)
return nil, nil, false, true
}
// No matching rule, paths remain the same, continue regular processing
return resolvedPath, contentPath, true, false
}

redirected, newPath, err := i.handleRedirectsFileRules(w, r, contentPath, redirectRules)
if err != nil {
err = fmt.Errorf("trouble processing _redirects file at %q: %w", redirectsFile.String(), err)
webError(w, err, http.StatusInternalServerError)
return nil, nil, false, true
}
redirectRules, err := i.getRedirectRules(r, redirectsFile)
if err != nil {
webError(w, err, http.StatusInternalServerError)
return nil, nil, false, true
}

if redirected {
return nil, nil, false, true
}
redirected, newPath, err := i.handleRedirectsFileRules(w, r, contentPath, redirectRules)
if err != nil {
err = fmt.Errorf("trouble processing _redirects file at %q: %w", redirectsFile.String(), err)
webError(w, err, http.StatusInternalServerError)
return nil, nil, false, true
}

// 200 is treated as a rewrite, so update the path and continue
if newPath != "" {
// Reassign contentPath and resolvedPath since the URL was rewritten
contentPath = ipath.New(newPath)
resolvedPath, err = i.api.ResolvePath(r.Context(), contentPath)
if err != nil {
webError(w, err, http.StatusInternalServerError)
return nil, nil, false, true
}
if redirected {
return nil, nil, false, true
}

return resolvedPath, contentPath, true, true
}
// 200 is treated as a rewrite, so update the path and continue
if newPath == "" {
// No matching rule, paths remain the same, continue regular processing
return resolvedPath, contentPath, true, false
}

// Reassign contentPath and resolvedPath since the URL was rewritten
contentPath = ipath.New(newPath)
resolvedPath, err = i.api.ResolvePath(r.Context(), contentPath)
if err != nil {
webError(w, err, http.StatusInternalServerError)
return nil, nil, false, true
}
// No matching rule, paths remain the same, continue regular processing
return resolvedPath, contentPath, true, false

return resolvedPath, contentPath, true, true
}

func (i *handler) handleRedirectsFileRules(w http.ResponseWriter, r *http.Request, contentPath ipath.Path, redirectRules []redirects.Rule) (redirected bool, newContentPath string, err error) {
// Attempt to match a rule to the URL path, and perform the corresponding redirect or rewrite
pathParts := strings.Split(contentPath.String(), "/")
if len(pathParts) > 3 {
// All paths should start with /ipfs/cid/, so get the path after that
urlPath := "/" + strings.Join(pathParts[3:], "/")
rootPath := strings.Join(pathParts[:3], "/")
// Trim off the trailing /
urlPath = strings.TrimSuffix(urlPath, "/")

for _, rule := range redirectRules {
// Error right away if the rule is invalid
if !rule.MatchAndExpandPlaceholders(urlPath) {
continue
}
if len(pathParts) <= 3 {
// Path isn't /ipfs/cid/ as expected
return false, "", nil
}

// We have a match!
// All paths should start with /ipfs/cid/, so get the path after that
urlPath := "/" + strings.Join(pathParts[3:], "/")
rootPath := strings.Join(pathParts[:3], "/")
// Trim off the trailing /
urlPath = strings.TrimSuffix(urlPath, "/")

// Rewrite
if rule.Status == 200 {
// Prepend the rootPath
toPath := rootPath + rule.To
return false, toPath, nil
}
for _, rule := range redirectRules {
// Error right away if the rule is invalid
if !rule.MatchAndExpandPlaceholders(urlPath) {
continue
}

// Or 4xx
if rule.Status == 404 || rule.Status == 410 || rule.Status == 451 {
toPath := rootPath + rule.To
content4xxPath := ipath.New(toPath)
err := i.serve4xx(w, r, content4xxPath, rule.Status)
return true, toPath, err
}
// We have a match!

// Or redirect
if rule.Status >= 301 && rule.Status <= 308 {
http.Redirect(w, r, rule.To, rule.Status)
return true, "", nil
}
// Rewrite
if rule.Status == 200 {
// Prepend the rootPath
toPath := rootPath + rule.To
return false, toPath, nil
}

// Or 4xx
if rule.Status == 404 || rule.Status == 410 || rule.Status == 451 {
toPath := rootPath + rule.To
content4xxPath := ipath.New(toPath)
err := i.serve4xx(w, r, content4xxPath, rule.Status)
return true, toPath, err
}

// Or redirect
if rule.Status >= 301 && rule.Status <= 308 {
http.Redirect(w, r, rule.To, rule.Status)
return true, "", nil
}
}

Expand Down

0 comments on commit 890701e

Please sign in to comment.