HTTP Module Documentation¶
The http module provides HTTP client and server functionality for Neutron programs. It uses libcurl for real HTTP client operations and POSIX sockets for real HTTP server functionality. All network operations are fully implemented - no mock implementations.
Usage¶
use http;
// Make HTTP requests
var response = http.get("https://api.example.com/data");
say("Status: " + response["status"]);
say("Body: " + response["body"]);
Response Object Structure¶
All HTTP functions return a response object with the following structure:
{
"status": 200, // HTTP status code (number)
"body": "response text", // Response body (string)
"headers": { // Response headers (object)
"content-type": "application/json",
"content-length": "123"
}
}
HTTP Methods¶
http.get(url, [headers])¶
Performs an HTTP GET request to retrieve data from a server.
Parameters:
- url (string): The URL to send the GET request to
- headers (object, optional): Additional HTTP headers to send
Returns: Response object with status, body, and headers
Example:
use http;
// Simple GET request
var response = http.get("https://api.example.com/users");
say("Status: " + response["status"]); // Output: Status: 200
say("Users data: " + response["body"]);
// GET request with custom headers
var headers = {"Authorization": "Bearer token123"};
var authResponse = http.get("https://api.example.com/profile", headers);
if (authResponse["status"] == 200) {
say("Profile loaded successfully");
}
Common Use Cases: - Fetching data from APIs - Downloading web content - Checking server status - Retrieving configuration files
http.post(url, [data], [headers])¶
Performs an HTTP POST request to send data to a server.
Parameters:
- url (string): The URL to send the POST request to
- data (string, optional): The data to send in the request body
- headers (object, optional): Additional HTTP headers to send
Returns: Response object with status, body, and headers
Example:
use http;
use json;
// Simple POST request
var response = http.post("https://api.example.com/users");
say("Status: " + response["status"]);
// POST request with JSON data
var userData = {"name": "Alice", "email": "alice@example.com"};
var jsonData = json.stringify(userData);
var headers = {"Content-Type": "application/json"};
var createResponse = http.post("https://api.example.com/users", jsonData, headers);
if (createResponse["status"] == 201) {
say("User created successfully");
say("Response: " + createResponse["body"]);
}
// POST request with form data
var formData = "name=Bob&email=bob@example.com";
var formHeaders = {"Content-Type": "application/x-www-form-urlencoded"};
var formResponse = http.post("https://api.example.com/submit", formData, formHeaders);
Common Use Cases: - Creating new resources - Submitting forms - User authentication - File uploads
http.put(url, [data], [headers])¶
Performs an HTTP PUT request to update or create a resource.
Parameters:
- url (string): The URL to send the PUT request to
- data (string, optional): The data to send in the request body
- headers (object, optional): Additional HTTP headers to send
Returns: Response object with status, body, and headers
Example:
use http;
use json;
// Update user profile
var updatedProfile = {
"name": "Alice Smith",
"email": "alice.smith@example.com",
"active": true
};
var jsonData = json.stringify(updatedProfile);
var headers = {"Content-Type": "application/json"};
var response = http.put("https://api.example.com/users/123", jsonData, headers);
if (response["status"] == 200) {
say("Profile updated successfully");
} else if (response["status"] == 201) {
say("Profile created successfully");
}
Common Use Cases: - Updating existing resources - Creating resources with specific IDs - Replacing entire resource representations
http.delete(url, [headers])¶
Performs an HTTP DELETE request to remove a resource.
Parameters:
- url (string): The URL to send the DELETE request to
- headers (object, optional): Additional HTTP headers to send
Returns: Response object with status, body, and headers
Example:
use http;
// Delete a user
var response = http.delete("https://api.example.com/users/123");
if (response["status"] == 204) {
say("User deleted successfully");
} else if (response["status"] == 404) {
say("User not found");
}
// Delete with authentication
var headers = {"Authorization": "Bearer token123"};
var authResponse = http.delete("https://api.example.com/posts/456", headers);
say("Delete status: " + authResponse["status"]);
Common Use Cases: - Removing resources - Cleanup operations - User account deletion
http.head(url, [headers])¶
Performs an HTTP HEAD request to retrieve only the headers (no body).
Parameters:
- url (string): The URL to send the HEAD request to
- headers (object, optional): Additional HTTP headers to send
Returns: Response object with status, empty body, and headers
Example:
use http;
// Check if resource exists without downloading content
var response = http.head("https://api.example.com/large-file.zip");
if (response["status"] == 200) {
say("File exists");
var contentLength = response["headers"]["Content-Length"];
say("File size: " + contentLength + " bytes");
} else {
say("File not found");
}
// Check last modified date
var headers = {"If-Modified-Since": "Wed, 21 Oct 2015 07:28:00 GMT"};
var modResponse = http.head("https://api.example.com/data.json", headers);
if (modResponse["status"] == 304) {
say("Resource not modified");
}
Common Use Cases: - Checking resource existence - Getting file sizes - Checking last modified dates - Validating URLs
http.patch(url, [data], [headers])¶
Performs an HTTP PATCH request to partially update a resource.
Parameters:
- url (string): The URL to send the PATCH request to
- data (string, optional): The partial data to send in the request body
- headers (object, optional): Additional HTTP headers to send
Returns: Response object with status, body, and headers
Example:
use http;
use json;
// Partially update user profile
var partialUpdate = {
"email": "newemail@example.com",
"active": false
};
var jsonData = json.stringify(partialUpdate);
var headers = {"Content-Type": "application/json"};
var response = http.patch("https://api.example.com/users/123", jsonData, headers);
if (response["status"] == 200) {
say("Profile updated successfully");
say("Updated data: " + response["body"]);
}
// Update specific fields
var statusUpdate = {"status": "inactive"};
var statusJson = json.stringify(statusUpdate);
var patchResponse = http.patch("https://api.example.com/accounts/456", statusJson, headers);
Common Use Cases: - Partial resource updates - Status changes - Incremental modifications - Field-specific updates
Common Usage Patterns¶
API Client Class¶
use http;
use json;
class ApiClient {
var baseUrl;
var defaultHeaders;
fun initialize(url, token) {
this.baseUrl = url;
this.defaultHeaders = {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
};
}
fun get(endpoint) {
var fullUrl = this.baseUrl + endpoint;
return http.get(fullUrl, this.defaultHeaders);
}
fun post(endpoint, data) {
var fullUrl = this.baseUrl + endpoint;
var jsonData = json.stringify(data);
return http.post(fullUrl, jsonData, this.defaultHeaders);
}
fun put(endpoint, data) {
var fullUrl = this.baseUrl + endpoint;
var jsonData = json.stringify(data);
return http.put(fullUrl, jsonData, this.defaultHeaders);
}
fun delete(endpoint) {
var fullUrl = this.baseUrl + endpoint;
return http.delete(fullUrl, this.defaultHeaders);
}
}
var client = ApiClient();
client.initialize("https://api.example.com", "your-token-here");
var users = client.get("/users");
var newUser = client.post("/users", {"name": "Alice", "email": "alice@example.com"});
Error Handling and Retry Logic¶
use http;
fun makeRequestWithRetry(url, maxRetries) {
var attempts = 0;
while (attempts < maxRetries) {
var response = http.get(url);
if (response["status"] == 200) {
return response;
} else if (response["status"] >= 500) {
say("Server error, retrying... Attempt " + (attempts + 1));
attempts = attempts + 1;
} else {
say("Client error: " + response["status"]);
return response;
}
}
say("Max retries exceeded");
return nil;
}
var response = makeRequestWithRetry("https://api.example.com/data", 3);
if (response != nil) {
say("Success: " + response["body"]);
}
Response Processing¶
use http;
use json;
fun processApiResponse(response) {
if (response["status"] >= 200 and response["status"] < 300) {
say("Success! Status: " + response["status"]);
// Try to parse JSON response
var data = json.parse(response["body"]);
return data;
} else if (response["status"] == 404) {
say("Resource not found");
return nil;
} else if (response["status"] >= 400 and response["status"] < 500) {
say("Client error: " + response["status"]);
say("Error details: " + response["body"]);
return nil;
} else if (response["status"] >= 500) {
say("Server error: " + response["status"]);
return nil;
}
return nil;
}
var response = http.get("https://api.example.com/users/123");
var userData = processApiResponse(response);
if (userData != nil) {
var name = json.get(userData, "name");
say("User name: " + name);
}
File Download Simulation¶
use http;
use sys;
fun downloadFile(url, filename) {
say("Downloading " + url + "...");
// Check file size first
var headResponse = http.head(url);
if (headResponse["status"] != 200) {
say("File not accessible: " + headResponse["status"]);
return false;
}
// Download the file
var response = http.get(url);
if (response["status"] == 200) {
sys.write(filename, response["body"]);
say("Downloaded to " + filename);
return true;
}
say("Download failed: " + response["status"]);
return false;
}
var success = downloadFile("https://example.com/data.json", "local_data.json");
if (success) {
say("File downloaded successfully");
}
REST API CRUD Operations¶
use http;
use json;
class UserManager {
var apiUrl;
var headers;
fun initialize() {
this.apiUrl = "https://api.example.com/users";
this.headers = {"Content-Type": "application/json"};
}
fun createUser(userData) {
var jsonData = json.stringify(userData);
var response = http.post(this.apiUrl, jsonData, this.headers);
return response["status"] == 201;
}
fun getUser(userId) {
var url = this.apiUrl + "/" + userId;
var response = http.get(url);
if (response["status"] == 200) {
return json.parse(response["body"]);
}
return nil;
}
fun updateUser(userId, userData) {
var url = this.apiUrl + "/" + userId;
var jsonData = json.stringify(userData);
var response = http.put(url, jsonData, this.headers);
return response["status"] == 200;
}
fun deleteUser(userId) {
var url = this.apiUrl + "/" + userId;
var response = http.delete(url);
return response["status"] == 204;
}
}
var userMgr = UserManager();
userMgr.initialize();
// Create user
var created = userMgr.createUser({"name": "Alice", "email": "alice@example.com"});
if (created) {
say("User created successfully");
}
Status Code Handling¶
Common HTTP status codes and their meanings:
use http;
fun handleStatusCode(status) {
if (status == 200) {
return "OK - Request successful";
} else if (status == 201) {
return "Created - Resource created successfully";
} else if (status == 204) {
return "No Content - Request successful, no response body";
} else if (status == 400) {
return "Bad Request - Invalid request data";
} else if (status == 401) {
return "Unauthorized - Authentication required";
} else if (status == 403) {
return "Forbidden - Access denied";
} else if (status == 404) {
return "Not Found - Resource doesn't exist";
} else if (status == 500) {
return "Internal Server Error - Server error";
} else {
return "Status: " + status;
}
}
var response = http.get("https://api.example.com/test");
var statusMessage = handleStatusCode(response["status"]);
say(statusMessage);
Utility Functions¶
http.request(method, url, [data], [headers])¶
Makes a custom HTTP request with specified method.
Parameters:
- method (string): HTTP method (GET, POST, PUT, DELETE, etc.)
- url (string): Target URL
- data (string, optional): Request body
- headers (object, optional): Request headers
Returns: Response object
Example:
use http;
var response = http.request("OPTIONS", "https://api.example.com");
say("Status: " + response.status);
http.urlEncode(string)¶
Encodes a string for safe use in URLs (percent-encoding).
Parameters:
- string (string): String to encode
Returns: URL-encoded string
Example:
http.urlDecode(string)¶
Decodes a URL-encoded string.
Parameters:
- string (string): URL-encoded string
Returns: Decoded string
Example:
http.parseQuery(queryString)¶
Parses a URL query string into an object.
Parameters:
- queryString (string): Query string (e.g., "name=John&age=30")
Returns: Object with key-value pairs
Example:
use http;
var params = http.parseQuery("name=John&age=30&city=NYC");
say(params.name); // Output: John
say(params.age); // Output: 30
Server Functions¶
The HTTP server uses POSIX sockets for real TCP/IP networking.
http.createServer(handler)¶
Creates an HTTP server object with a custom request handler.
Parameters:
- handler (function): A function that takes a request object and returns a response.
Returns: Server object
Handler Function:
The handler function receives a request object with the following properties:
- method (string): The HTTP method (e.g., "GET", "POST").
- path (string): The request path (e.g., "/api/users").
- raw (string): The raw HTTP request string.
The handler must return either:
1. A string (which will be sent as the response body with status 200 OK).
2. An object with:
- status (number, optional): HTTP status code (default: 200).
- body (string): The response body.
Example:
use http;
fun handler(req) {
say("Received " + req.method + " request for " + req.path);
if (req.path == "/") {
return "Welcome to the home page!";
} else if (req.path == "/api") {
return {
"status": 200,
"body": "{\"message\": \"API is working\"}"
};
} else {
return {
"status": 404,
"body": "Not Found"
};
}
}
var server = http.createServer(handler);
http.listen(server, 8080);
http.listen(server, port)¶
Starts the HTTP server and listens for incoming connections. This function blocks the current thread.
Parameters:
- server (object): Server object returned from http.createServer.
- port (number): Port number to listen on (e.g., 8080).
Returns: Does not return (blocking loop).
http.startServer(port)¶
Starts a simple background HTTP server on the specified port. This is useful for simple static serving or testing, but createServer is recommended for custom logic.
Parameters:
- port (number): Port number to listen on.
Returns: true on success.
http.stopServer()¶
Stops the currently running background HTTP server (started with startServer).
Returns: true on success.
Implementation Details¶
HTTP Client (libcurl)¶
- Uses libcurl 8.17.0 for real HTTP/HTTPS requests
- Supports TLS/SSL encryption
- Handles redirects automatically
- 30-second default timeout
- Custom User-Agent: "Neutron/1.0"
HTTP Server (POSIX Sockets)¶
- Real TCP/IP socket binding with
socket(),bind(),listen() - Background thread using C++
std::thread - Accepts connections with
accept() - Reads HTTP requests from socket
- Returns basic "Neutron HTTP Server" responses
Security Considerations¶
When using HTTP functionality:
- Always validate URLs and input data
- Use HTTPS for sensitive data (client supports it)
- Server listens on all interfaces (0.0.0.0) - configure firewall appropriately
- Validate server certificates when making requests
- Implement proper authentication for your endpoints
Performance Tips¶
- Use HEAD requests to check resources without downloading content
- Server uses non-blocking I/O for better concurrency
- Client implements 30-second timeout to prevent hanging
- Close connections properly with
stopServer()
Compatibility¶
The HTTP module is available in both interpreter mode and compiled binaries. All functionality uses real network operations with no mock implementations.