Skip to content

Instantly share code, notes, and snippets.

@tuklusan
Last active October 30, 2021 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuklusan/4af8be0b3b6f13f5893bb03687e129e4 to your computer and use it in GitHub Desktop.
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
/*
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