Common Pitfalls of HTTP Request Timeout
Timeout Settings in Golang
-
Connection Timeout (Dial Timeout): This sets the maximum time to establish a connection. If it exceeds this time without connecting, it will timeout. -
Read Timeout: This refers to the timeout for reading response data from the server. -
Write Timeout: This refers to the timeout for sending request data.
Example Code
package main
import ( "fmt"
"net"
"net/http"
"time")
func main() { // Set timeout configuration timeout := 5 * time.Second
// Custom Transport, configure connection and read/write timeouts transport := &http.Transport{ // Set connection timeout DialContext: (&net.Dialer{ Timeout: timeout, // Maximum connection time }).DialContext,
// TLS handshake timeout TLSHandshakeTimeout: timeout,
ResponseHeaderTimeout: timeout, // Timeout for waiting for response headers
ExpectContinueTimeout: timeout, // Timeout for 100-continue status code }
// Create an http.Client with the custom Transport client := &http.Client{ Timeout: timeout, // Request timeout including connection, read, and write Transport: transport, }
// Send GET request resp, err := client.Get("https://example.com") if err != nil { fmt.Println("Request failed:", err) return } defer resp.Body.Close()
fmt.Println("Request successful, status code:", resp.StatusCode)}
Code Explanation
-
http.Client Timeout: We set the total request timeout using client.Timeout. This time includes all time for connection, reading, and writing data. Therefore, if your request exceeds this time without a response, the program will return a timeout error. -
Transport Timeout: By customizing http.Transport, we can control more granular timeouts, such as connection timeout, read/write timeout, and TLS handshake timeout. Here, we used a custom Dialer, which is responsible for establishing the connection, and we set a timeout for it.
Why Do It This Way?
Handling Asynchronous Scenarios
package main
import ( "context"
"fmt"
"net/http"
"time")
func main() { // Set timeout timeout := 5 * time.Second ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", "https://example.com", nil) if err != nil { fmt.Println("Failed to create request:", err) return }
client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("Request failed:", err) return }
defer resp.Body.Close()
fmt.Println("Request successful, status code:", resp.StatusCode)}
Detailed Explanation of Asynchronous Timeouts
-
context.WithTimeout: Here we use context to control the request’s timeout. If it exceeds the specified time, this context will automatically cancel, and all requests using it will terminate. This is very useful for multiple concurrent requests. 🕒 -
Cancellation Operation: The defer cancel() means that when our request ends, cancel() will be called to release some resources in the context. This also ensures that there are no “resource leaks”.
Currently, for students interested in programming and the workplace, you can contact me on WeChat: golang404, and I will add you to the “Programmer Group Chat”.
🔥 Hu Ge’s Private Collection of Quality Recommendations 🔥
As an experienced programmer, Hu Ge has compiled the most comprehensive “GO Backend Development Resource Collection”.
The resources include “IDEA Video Tutorial”, “Most Comprehensive GO Interview Question Bank”, “Most Comprehensive Project Practice Source Code and Videos”, and “Graduation Project System Source Code”, totaling up to 650GB.All are available for free! Fully meet the learning needs of programmers at all stages!