mirror of
https://gitlab.melroy.org/melroy/fediresolve.git
synced 2025-06-07 20:08:57 +00:00
83 lines
2.6 KiB
Go
83 lines
2.6 KiB
Go
package resolver
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
// checkForRedirect checks if a URL redirects to another URL
|
|
// and returns the final redirect URL after following all redirects
|
|
func (r *Resolver) checkForRedirect(inputURL string) (string, error) {
|
|
// Create a custom client that doesn't follow redirects automatically
|
|
client := &http.Client{
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
return http.ErrUseLastResponse
|
|
},
|
|
}
|
|
|
|
// Follow up to 10 redirects (to prevent infinite loops)
|
|
currentURL := inputURL
|
|
for i := 0; i < 10; i++ {
|
|
// Create the request
|
|
req, err := http.NewRequest("GET", currentURL, nil)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error creating redirect check request: %v", err)
|
|
}
|
|
|
|
// Set standard browser-like headers
|
|
req.Header.Set("User-Agent", "FediResolve/1.0 (https://github.com/dennis/fediresolve)")
|
|
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml")
|
|
|
|
// Perform the request
|
|
fmt.Printf("Checking for redirects from: %s\n", currentURL)
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error checking for redirects: %v", err)
|
|
}
|
|
|
|
// Check if we got a redirect (302, 301, etc.)
|
|
if resp.StatusCode == http.StatusFound || resp.StatusCode == http.StatusMovedPermanently ||
|
|
resp.StatusCode == http.StatusTemporaryRedirect || resp.StatusCode == http.StatusPermanentRedirect {
|
|
// Get the redirect URL from the Location header
|
|
redirectURL := resp.Header.Get("Location")
|
|
resp.Body.Close() // Close the response body before continuing
|
|
|
|
if redirectURL != "" {
|
|
fmt.Printf("Found redirect to: %s\n", redirectURL)
|
|
|
|
// Handle relative URLs
|
|
if redirectURL[0] == '/' {
|
|
// This is a relative URL, so we need to resolve it against the current URL
|
|
baseURL, err := url.Parse(currentURL)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error parsing base URL: %v", err)
|
|
}
|
|
relativeURL, err := url.Parse(redirectURL)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error parsing relative URL: %v", err)
|
|
}
|
|
resolvedURL := baseURL.ResolveReference(relativeURL)
|
|
redirectURL = resolvedURL.String()
|
|
fmt.Printf("Resolved relative URL to: %s\n", redirectURL)
|
|
}
|
|
|
|
// Update the current URL and continue following redirects
|
|
currentURL = redirectURL
|
|
continue
|
|
}
|
|
}
|
|
|
|
// If we didn't get a redirect, we're done
|
|
resp.Body.Close()
|
|
break
|
|
}
|
|
|
|
// If we followed redirects and ended up at a different URL, return it
|
|
if currentURL != inputURL {
|
|
return currentURL, nil
|
|
}
|
|
|
|
// No redirect found or we ended up back at the original URL
|
|
return "", nil
|
|
}
|