HTTP Requests
Fetch web resources.
HTTP Requests is a free Lua Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The socket.http Module
LuaSocket ships a high-level HTTP client in socket.http. It builds on raw TCP but handles request formatting, headers, and chunked decoding for you.
It speaks HTTP/1.1 over plain TCP. For HTTPS you need the companion ssl.https module from LuaSec.
local http = require("socket.http")
print(http.PORT)A Simple GET
The simplest form takes a URL and returns the body, status code, response headers, and status line.
A status code of 200 means success. Any nil body indicates a transport-level failure rather than an HTTP error.
local http = require("socket.http")
local body, code, headers = http.request("http://example.com/")
print(code, #body)Reading the Status
Always check the numeric code before trusting the body. A 404 still returns a body (the error page), so the call succeeded at the TCP level.
The fourth return value is the status line string, like "HTTP/1.1 200 OK", useful for logging.
local body, code, headers, status = http.request(url)
if code == 200 then
process(body)
else
print("unexpected:", status)
endInspecting Headers
The returned headers table has lowercased keys, so you read headers["content-type"] regardless of how the server cased it.
Common fields include content-length, content-type, and location for redirects.
local body, code, headers = http.request(url)
print(headers["content-type"])
print(headers["content-length"])The Generic Request Form
Passing a table to http.request unlocks full control: method, custom headers, request body source, and a sink for the response.
This form returns 1 (not the body) plus code, headers, and status. You collect the body yourself via the sink.
local http = require("socket.http")
local ltn12 = require("ltn12")
local chunks = {}
http.request{
url = "http://example.com/",
sink = ltn12.sink.table(chunks)
}Sending a POST
For POST, set method = "POST", supply a source with the body, and set content-length. The ltn12.source.string helper wraps a Lua string as a source.
Set content-type to match your payload, such as application/json.
local body = "{\"name\":\"Lua\"}"
http.request{
url = url,
method = "POST",
source = ltn12.source.string(body),
headers = {
["content-type"] = "application/json",
["content-length"] = tostring(#body)
}
}Collecting the Body with ltn12
LuaSocket streams data through ltn12 filters. A sink consumes chunks; ltn12.sink.table(t) appends them to a table you then table.concat.
This streaming model keeps memory low for large downloads instead of buffering everything at once.
local ltn12 = require("ltn12")
local t = {}
http.request{ url = url, sink = ltn12.sink.table(t) }
local full = table.concat(t)Custom Request Headers
Add authentication, user agents, or cookies through the headers table. Keys should be lowercase to match how LuaSocket expects them.
For example, send a bearer token or a custom user-agent so the server identifies your client correctly.
http.request{
url = url,
headers = {
["authorization"] = "Bearer " .. token,
["user-agent"] = "lua-client/1.0"
}
}Following Redirects
By default socket.http follows redirects automatically for GET. You can disable this with redirect = false in the request table to inspect the 3xx response yourself.
When following is off, read headers["location"] to find the next URL.
local body, code, headers = http.request{
url = url,
redirect = false
}
if code == 301 then print("moved to", headers["location"]) endTimeouts and HTTPS
Set a global timeout for HTTP calls with http.TIMEOUT = 10, since hung downloads otherwise block forever.
Because socket.http is plaintext only, use require("ssl.https") from LuaSec for https:// URLs; its API mirrors socket.http.
local http = require("socket.http")
http.TIMEOUT = 10
-- for TLS:
local https = require("ssl.https")
local body, code = https.request("https://example.com/")Error Handling
Distinguish two failure layers. A transport failure returns nil and an error string such as "connection refused" or "timeout".
An application failure returns a body with a 4xx or 5xx code. Robust code checks the nil case first, then branches on the status code.
local body, code = http.request(url)
if not body then
print("transport error:", code)
elseif code >= 400 then
print("http error:", code)
endQuick Check
Recall what the simple URL form of http.request returns.
Recap
You learned the socket.http module: simple GETs returning body/code/headers, the generic table form with ltn12 sinks and sources, POST bodies, custom headers, redirects, and timeouts.
You also separated transport errors (nil) from HTTP status errors, and saw that HTTPS needs LuaSec's ssl.https. That completes the networking journey from raw TCP to HTTP.
Frequently asked questions
Is the “HTTP Requests” lesson free?
Yes — the full text of “HTTP Requests” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.
What will I learn in “HTTP Requests”?
Fetch web resources. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Lua Academy?
No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “HTTP Requests” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Lua Academy lesson?
Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- TCP Basics
- Building a Client
- Building a Server
- HTTP Requests