Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesGo’s net/http package covers both sides of HTTP: client code creates requests and reads responses, while server code receives requests through an http.Handler and writes responses. Start with http.Get for a basic fetch; use http.NewRequestWithContext and a reusable http.Client when you need headers, methods, bodies, cancellation, redirects, or connection policy. On the server, register a handler on a mux and serve it with http.Server.
This guide follows the current standard-library documentation (accessed September 29, 2026). Check the package documentation for behavior specific to the Go version your project supports.
Make a simple HTTP request
For a one-off GET where the defaults are acceptable, the shortest form is:
resp, err := http.Get("https://example.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.StatusCode, len(body))
http.Get returns an error only when the request cannot be made or the response cannot be obtained. A server response such as 404 or 500 is still a successful transport operation, so inspect resp.StatusCode yourself. Always close resp.Body when finished; leaving it open can prevent persistent connections from being reused.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
Use a request, context, and reusable client
Construct a request when you need a method other than GET, custom headers, a body, cancellation, or a deadline. Reuse clients: http.Client and its transports are safe for concurrent use, and transports cache connections.
package main
import (
"context"
"fmt"
"io"
"net/http"
"time"
)
func main() {
client := &http.Client{
Timeout: 10 * time.Second,
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(
ctx,
http.MethodGet,
"https://api.example.com/items",
nil,
)
if err != nil {
panic(err)
}
req.Header.Set("Accept", "application/json")
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
data, _ := io.ReadAll(io.LimitReader(resp.Body, 4<<10))
panic(fmt.Sprintf("unexpected status %s: %s", resp.Status, data))
}
body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
if err != nil {
panic(err)
}
fmt.Println(string(body))
}
The context governs connection acquisition, request transmission, and reading response headers and the body. A client timeout provides an additional upper bound. Use an explicit response-size limit when consuming untrusted or unexpectedly large data, then decode the bytes as JSON or another format.
Send methods, bodies, and headers
payload := strings.NewReader(`{"name":"Ada"}`)
req, err := http.NewRequestWithContext(ctx, http.MethodPost,
"https://api.example.com/items", payload)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
resp, err := client.Do(req)
Use io.Reader for request bodies. Close the response body even when you intend to reject its status. If the request carries credentials, review redirect behavior: Go’s security guidance describes stripping sensitive headers on cross-domain redirects as defense in depth, but your application should still decide which destinations are trusted. See Go’s security decisions.
Understand Client, Transport, and connection reuse
Use the client for higher-level policy such as redirects, cookies, and an overall timeout. Use a transport for lower-level networking: proxies, TLS, compression, keep-alives, and connection limits.
Recommended Free Tools
transport := &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 20,
IdleConnTimeout: 90 * time.Second,
}
client := &http.Client{Transport: transport}
Choose limits for your workload rather than copying universal numbers. Call client.CloseIdleConnections() when a long-running process has a deliberate reason to release idle sockets. The default transport supports HTTP/2 in documented HTTPS cases. A custom transport does not automatically enable every default protocol behavior, so check the documentation for your target Go release before configuring HTTP/2 or newer protocol fields.
Write an HTTP server
An http.Handler receives an http.ResponseWriter and *http.Request. Register handlers with a mux, then serve the mux.
package main
import (
"fmt"
"html"
"log"
"net/http"
"time"
)
func home(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
fmt.Fprintf(w, "hello from %sn", html.EscapeString(r.URL.Path))
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", home)
server := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Printf("listening on %s", server.Addr)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}
Run it with go run ., then open http://localhost:8080/. The listening method normally returns only on an error, so handle that return value instead of discarding it. A minimal alternative is http.HandleFunc("/", home) followed by http.ListenAndServe(":8080", nil); an explicit server makes timeout and header controls visible.
Read requests and write responses safely
Treat paths, query parameters, headers, and bodies as untrusted. Validate methods and input sizes, and escape data before placing it in HTML. Check r.Host when the application should serve only particular hostnames; the request documentation warns that handlers must validate whether a Host value is authoritative. Host-specific mux patterns can help protect registered routes.
func create(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.Header().Set("Allow", http.MethodPost)
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
r.Body = http.MaxBytesReader(w, r.Body, 1<<20)
defer r.Body.Close()
// Decode and validate the bounded body here.
w.WriteHeader(http.StatusCreated)
}
Incoming request contexts are canceled when the client connection closes, when an HTTP/2 request is canceled, or when the handler returns. Pass r.Context() to database and outbound HTTP calls so work stops with the request.
Choose timeouts and cancellation deliberately
- Outgoing calls: use
context.WithTimeoutorWithDeadlinefor per-operation limits, plus a client policy appropriate to the service. - Incoming calls: configure
ReadTimeout,WriteTimeout, and header limits onhttp.Server. Values depend on payload size, latency, and streaming requirements. - Streaming: avoid a write timeout that is shorter than the intended stream, or design a separate server policy for streaming endpoints.
Testing handlers with net/http/httptest
The net/http/httptest package lets tests exercise handlers without a live external service. httptest.NewRequest creates a request intended for a server handler, while httptest.NewRecorder captures the response.
func TestHome(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "http://example.com/", nil)
rec := httptest.NewRecorder()
home(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, want %d", rec.Code, http.StatusOK)
}
if got := rec.Body.String(); got == "" {
t.Fatal("empty response")
}
}
For integration-style client tests, httptest.NewServer(handler) starts a local HTTP server; close it with defer server.Close(), then send your real client request to server.URL. Consult the current httptest documentation for available helpers.
Or skip the browser setup
If your Go service needs website images or PDFs rather than an API response, ScreenshotNeo provides a website screenshot API and MCP server. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing result. Its MCP tools—take_screenshot, get_page_info, and capture_pdf—work with Claude, Cursor, and other MCP clients.
One GET request returns PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for all options.
Rank #4
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Features include full-page and CSS-selector captures, lazy-image loading, dark mode, device presets, custom viewports and retina scale, PDF paper and page controls, HTML/CSS rendering, custom JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. Existing parameter names from other screenshot APIs also work. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000, and every feature is available on every plan. Sign up free.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshoot common failures
“It returned 404, but err is nil”
That is expected client behavior. Inspect resp.StatusCode and handle non-2xx responses as application errors.
Connections are not reused or file descriptors grow
Ensure every response body is closed, preferably immediately after checking the error. Reuse one client and transport instead of creating them per request.
Free tools Windows power users keep installed
One-click scans. No signup required.
Requests hang indefinitely
Add a request context deadline and a client timeout. On servers, set read and write limits appropriate to the endpoint and investigate slow upstream dependencies.
Best Value
Credentials appear at an unexpected redirect target
Review redirect policy and trusted domains. Do not rely solely on default header stripping; prevent redirects to destinations your application does not authorize.
Custom transport changed protocol behavior
Compare it with the default transport and check the Go version’s documentation for HTTP/2 and other protocol configuration. Reproduce the required settings explicitly.
HTML contains escaped or unsafe data
Escape output in HTML contexts and validate paths, hosts, methods, and body sizes before processing.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Frequently Asked Questions
Does net/http treat every non-2xx response as an error?
No. Client transport errors are returned through err; an HTTP status such as 404 or 500 is returned in resp and must be checked by your code.
Are http.Client and http.Transport safe to share?
Yes. They are designed for concurrent use. Reusing them also allows transports to reuse connections.
When should I use http.Get instead of NewRequestWithContext?
Use http.Get for a simple GET with default policy. Construct a request for custom methods, headers, bodies, cancellation, deadlines, or explicit client behavior.
What package should I use to test a handler?
Use net/http/httptest, commonly with NewRequest and NewRecorder for a direct handler test or NewServer for an end-to-end client test.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

