How do you handle HTTP redirects in Go?
Example
package main
import (
"fmt"
"net/http"
)
func main() {
client := http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
fmt.Println("Redirected to:", req.URL)
return nil
},
}
resp, err := client.Get("https://example.com")
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
fmt.Println("Status code:", resp.StatusCode)
}
In this example, we create an instance of http.Client with a CheckRedirect function that will be called whenever a redirect is encountered. The CheckRedirect function takes two arguments: the current request (req) and a slice of previous requests (via). It returns an error, which should be nil to allow the redirect to happen.
The Get method of the http.Client sends an HTTP GET request to the specified URL, and the defer resp.Body.Close() statement ensures that the response body is closed after the request has been completed.
If a redirect occurs, the CheckRedirect function will be called with the new request URL, which we print to the console in this example. Finally, we print the status code of the final response.
Note that the CheckRedirect function is optional. If you don't provide a CheckRedirect function, the http.Client will automatically follow redirects for you.
Example
package main
import (
"fmt"
"net/http"
)
func main() {
// create a new HTTP client
client := &http.Client{}
// create a new GET request
req, err := http.NewRequest("GET", "http://example.com", nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
// send the request and get the response
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
// check if the response was a redirect
if resp.StatusCode >= 300 && resp.StatusCode <= 399 {
redirectUrl, err := resp.Location()
if err != nil {
fmt.Println("Error getting redirect location:", err)
return
}
// create a new GET request to follow the redirect
req.URL = redirectUrl
resp, err = client.Do(req)
if err != nil {
fmt.Println("Error sending redirect request:", err)
return
}
defer resp.Body.Close()
}
// process the response
fmt.Println("Status code:", resp.StatusCode)
// ...
}