CodeRigor

LESSON

Construct requests without string-splicing URLs

Encode path segments and ordered query pairs, preserve repeated parameters and keep header values out of URLs.

This course turns the earlier HTTP policy lab into a working local integration. You will fetch order pages from a bundled HTTP server and export a deterministic report. The public runner continues to use supplied transports and exchanges; it receives no new outbound network access.

A request starts as data: method, URL and headers. Construct those components deliberately instead of splicing untrusted strings into a URL. Our helper builds GET requests; later lessons control the transport and response contract.

Request components have different jobs
start / 3
An origin, encoded path segments and ordered query pairs form the URL. Validated headers remain a separate request field.
Request components have different jobs
An origin, encoded path segments and ordered query pairs form the URL. Validated headers remain a separate request field.

A slash between segments is structure; a slash inside a segment is data. quote(segment, safe="") encodes the latter before joining segments. Query encoding has different conventions: urlencode converts spaces to plus and a literal plus to %2B.

Keep ordered pairs when repeated parameters are meaningful. dict(query) loses earlier values for duplicate keys.

Python
from urllib.parse import quote, urlencode
segments = ["team/a", "orders"]
path = "/" + "/".join(quote(s,safe="") for s in segments)
query = urlencode([("tag","C++ & Python"),("tag","x/y")])
print(path)
print(query)

The supplied validation accepts a bounded absolute HTTP(S) origin and rejects embedded credentials, extra path/query/fragment and control characters. Header construction sets Accept and User-Agent and can add a validated synthetic bearer token. The lab does not need a real account or credential.

Never put bearer tokens in a query or print them in request logs. This builder keeps them in a separate header field. It does not itself authorize destinations or prevent every server-side routing interpretation. The downloadable transport has a narrower policy: literal 127.0.0.1 HTTP to the bundled API, no proxy lookup and no redirect following.

The optional Corey Schafer video uses Requests to explain HTTP. Our artifact uses the standard library and an injected adapter, so you can finish it without installing Requests. Broader external HTTPS communication is a later continuation.

Opaque cursor remains data
start / 3
A cursor supplied by an API is encoded as one query value. The client never interprets it as a path or a new destination.
Opaque cursor remains data
A cursor supplied by an API is encoded as one query value. The client never interprets it as a path or a new destination.
Python
from urllib.parse import urlencode
pairs = [("tag","first"),("tag","second")]
print("preserved:", urlencode(pairs))
print("collapsed:", urlencode(dict(pairs)))

Complete the final assembly block and test an embedded slash, repeated keys, Unicode text and an empty query. Keep inputs unchanged and use synthetic authorization values only in exercises.

Next the transport will open a response with a timeout, read at most the configured body limit plus one detection byte, and close it on every exit.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Optional HTTP background using Requests. Our original lab uses the standard library and an injected transport; no Requests dependency is required.