This commit is contained in:
retoor 2025-11-24 10:26:12 +01:00
parent fc05199a76
commit ded2448ebd
3 changed files with 195 additions and 6 deletions

View File

@ -155,13 +155,25 @@ int main() {
### HTTP Server Examples
**Simple HTTP Server** (`examples/http_simple.rc`)
Single-connection HTTP server that accepts one request and exits.
Single-connection HTTP server that accepts one request and exits with a fixed response.
**Persistent HTTP Server** (`examples/http_persistent.rc`)
HTTP server with request counter that continuously accepts connections.
HTTP server with request counter that continuously accepts connections with fixed responses.
**Multi-Connection HTTP Server** (`examples/http_multi.rc`)
HTTP server that handles up to 100 consecutive connections.
**HTTP File Server** (`examples/http_fileserver.rc`)
HTTP server that serves files from the filesystem. Handles up to 100 connections and streams file content using proper HTTP responses. Demonstrates socket programming, file I/O, and HTTP protocol implementation within RC's type system constraints.
Run examples:
```bash
make run-http-simple # Simple single-connection server
make run-http-persistent # Persistent multi-connection server
./bin/rc examples/http_fileserver.rc # File serving server
```
Test with curl or browser:
```bash
curl http://localhost:8080/
```
## Project Structure
@ -250,6 +262,7 @@ For technical details, see:
- Pointer arithmetic works on virtual memory addresses
- Maximum 100 concurrent async operations
- Async execution is serialized (not parallel)
- **Type system constraints**: String functions (substr, strpos, strcmp) work with string pointers (`char*`) but not with char arrays used as buffers for socket operations
## Testing

View File

@ -868,6 +868,182 @@ close(sockfd);
- `AF_INET()` - IPv4 address family
- `SOCK_STREAM()` - TCP socket type
### Building an HTTP File Server
This section demonstrates how to build a complete HTTP file server in RC. The example shows proper socket handling, file I/O, and HTTP response generation.
#### Complete HTTP File Server Example
```c
int main() {
int server_fd;
int client_fd;
char buffer[4096];
int bytes_received;
int file;
char *line;
int line_len;
char *response_header;
int header_len;
int total_sent;
int count;
char *filename;
server_fd = socket(AF_INET(), SOCK_STREAM(), 0);
if (server_fd < 0) {
printf("Failed to create socket\n");
return 1;
}
if (bind(server_fd, 8080) < 0) {
printf("Failed to bind to port 8080\n");
close(server_fd);
return 1;
}
if (listen(server_fd, 10) < 0) {
printf("Failed to listen\n");
close(server_fd);
return 1;
}
printf("HTTP File Server listening on port 8080\n");
printf("Serving README.md for all requests\n");
printf("Example: http://localhost:8080/\n\n");
filename = "README.md";
count = 0;
while (count < 100) {
printf("Waiting for connection %d\n", count + 1);
client_fd = accept(server_fd);
if (client_fd < 0) {
printf("Failed to accept connection\n");
count = count + 1;
continue;
}
printf("Client connected\n");
bytes_received = recv(client_fd, buffer, 1024, 0);
if (bytes_received <= 0) {
printf("Failed to receive request\n");
close(client_fd);
count = count + 1;
continue;
}
printf("Received %d bytes\n", bytes_received);
file = fopen(filename, "r");
if (file == 0) {
printf("File not found: %s\n", filename);
response_header = "HTTP/1.1 404 Not Found\nContent-Type: text/html\n\n<html><body><h1>404 Not Found</h1><p>The requested file was not found.</p></body></html>";
header_len = strlen(response_header);
send(client_fd, response_header, header_len, 0);
close(client_fd);
count = count + 1;
continue;
}
printf("File opened successfully\n");
response_header = "HTTP/1.1 200 OK\nContent-Type: text/plain\n\n";
header_len = strlen(response_header);
send(client_fd, response_header, header_len, 0);
total_sent = 0;
while (feof(file) == 0) {
line = fgets(file, 8192);
line_len = strlen(line);
if (line_len > 0) {
send(client_fd, line, line_len, 0);
total_sent = total_sent + line_len;
}
}
printf("Sent %d bytes\n", total_sent);
fclose(file);
close(client_fd);
printf("Connection closed\n\n");
count = count + 1;
}
close(server_fd);
printf("Server shutdown after %d requests\n", count);
return 0;
}
```
#### Key Concepts
**Socket Creation and Binding:**
The server creates a TCP socket, binds it to port 8080, and listens for incoming connections.
**Request Loop:**
The server runs a loop accepting up to 100 connections. For each connection:
1. Accept the client connection
2. Receive the HTTP request
3. Open the requested file
4. Send HTTP response headers
5. Send file content line by line
6. Close the connection
**Error Handling:**
The server checks for errors at each step and provides appropriate HTTP error responses (404 for file not found).
**Buffer Usage:**
The `char buffer[4096]` declaration creates a receive buffer. In RC, char arrays are used for socket recv() operations but cannot be directly manipulated as strings.
**File Streaming:**
Instead of loading the entire file into memory, the server reads and sends it line by line using `fgets()` and `send()`, which is more memory-efficient.
#### Important Limitations
**String Manipulation:**
RC's type system has limitations when working with char arrays. Functions like `substr()`, `strpos()`, and `strcmp()` work with string pointers (`char*`) but not with char arrays used as buffers.
**Simplified HTTP Parsing:**
The example serves a fixed file rather than parsing the HTTP request path. Full HTTP request parsing requires string manipulation that is challenging with RC's buffer semantics.
**Working with Buffers:**
- Use `char buffer[size]` for recv() operations
- Buffers receive data but cannot be easily parsed as strings
- Use `char *str = "..."` for string literals and manipulation
- Keep HTTP logic simple to avoid buffer parsing issues
#### Testing the Server
Run the server:
```bash
./bin/rc examples/http_fileserver.rc
```
Test with curl:
```bash
curl http://localhost:8080/
```
Test with a browser:
```
http://localhost:8080/
```
#### Production Considerations
For production HTTP servers:
1. Add request timeout handling
2. Implement proper HTTP request parsing (in a more suitable language)
3. Add support for multiple file types and MIME types
4. Implement connection pooling for better performance
5. Add logging for debugging and monitoring
6. Consider using async I/O for handling multiple concurrent connections
This example demonstrates RC's capabilities for network programming while working within its type system constraints.
## Comments
RC supports single-line comments using `//`.

View File

@ -36,8 +36,8 @@ int main() {
printf("Example: http://localhost:8080/\n\n");
filename = "README.md";
count = 0;
while (count < 100) {
count = 1;
while (count > 0) {
printf("Waiting for connection %d\n", count + 1);
client_fd = accept(server_fd);