Last active
October 30, 2021 16:22
-
-
Save tuklusan/4af8be0b3b6f13f5893bb03687e129e4 to your computer and use it in GitHub Desktop.
shs.c - absolutely minimal web server in C (tested on 4.3 BSD for VAX with gcc 2.7.2.2) | See https://supratim-sanyal.blogspot.com/2019/04/deploying-single-greatest-piece-of.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
shs.c - simple http server for 4.3 BSD on VAX | |
Compiles with gcc version 2.7.2.2 vax-dec-bsd | |
Tweaked from David Egan's HTTP Server in C (https://dev-notes.eu/2018/06/http-server-in-c/) | |
For each connection accepted on the designated port, this | |
minimal server returns a single file (index.html). | |
# gcc -v | |
Reading specs from /usr/local/lib/gcc-lib/vax-dec-bsd/2.7.2.2/specs | |
gcc version 2.7.2.2 | |
# gcc -o shs shs.c | |
# ./shs | |
report() | |
waiting on accept | |
waiting on accept | |
... | |
The binary can be downloaded from http://bit.ly/43bsdvax-httpd-wget | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <unistd.h> | |
#include <netdb.h> // for getnameinfo() | |
// Usual socket headers | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#define SERVER_PORT 80 | |
#define SIZE 1024 | |
#define BACKLOG 10 // Passed to listen() | |
#define INET6_ADDRSTRLEN 46 | |
#define NI_MAXSERV 32 | |
void report(struct sockaddr_in *serverAddress); | |
void setHttpHeader(char httpHeader[]) | |
{ | |
// File object to return | |
char line[100]; | |
char responseData[8000]; | |
FILE *htmlData = fopen("/var/www/index.html", "r"); | |
if(NULL==htmlData){printf("Cannot open index.html to send\n"); exit(1); } | |
while (fgets(line, 100, htmlData) != 0) { | |
strcat(responseData, line); | |
} | |
strcat(httpHeader, responseData); | |
} | |
int main(void) | |
{ | |
char httpHeader[8000] = "HTTP/1.1 200 OK\r\n\n"; | |
int listening=0; | |
int clientSocket=0; | |
// Socket setup: creates an endpoint for communication, returns a descriptor | |
// ----------------------------------------------------------------------------------------------------------------- | |
int serverSocket = socket( | |
AF_INET, // Domain: specifies protocol family | |
SOCK_STREAM, // Type: specifies communication semantics | |
0 // Protocol: 0 because there is a single protocol for the specified family | |
); | |
// Construct local address structure | |
// ----------------------------------------------------------------------------------------------------------------- | |
struct sockaddr_in serverAddress; | |
serverAddress.sin_family = AF_INET; | |
serverAddress.sin_port = htons(SERVER_PORT); | |
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);//inet_addr("127.0.0.1"); | |
// Bind socket to local address | |
// ----------------------------------------------------------------------------------------------------------------- | |
// bind() assigns the address specified by serverAddress to the socket | |
// referred to by the file descriptor serverSocket. | |
bind( | |
serverSocket, // file descriptor referring to a socket | |
(struct sockaddr *) &serverAddress, // Address to be assigned to the socket | |
sizeof(serverAddress) // Size (bytes) of the address structure | |
); | |
// Mark socket to listen for incoming connections | |
// ----------------------------------------------------------------------------------------------------------------- | |
listening = listen(serverSocket, BACKLOG); | |
if (listening < 0) { | |
printf("Error: The server is not listening.\n"); | |
return 1; | |
} | |
report(&serverAddress); // Custom report function | |
setHttpHeader(httpHeader); // Custom function to set header | |
// Wait for a connection, create a connected socket if a connection is pending | |
// ----------------------------------------------------------------------------------------------------------------- | |
while(1) { | |
printf("waiting on accept\n"); | |
clientSocket = accept(serverSocket, NULL, NULL); | |
send(clientSocket, httpHeader, sizeof(httpHeader), 0); | |
close(clientSocket); | |
} | |
return 0; | |
} | |
void report(struct sockaddr_in *serverAddress) | |
{ | |
printf("report()\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment