Skip to content

Instantly share code, notes, and snippets.

@iKunalChhabra
Created May 1, 2025 18:32
Show Gist options
  • Save iKunalChhabra/a5850722610b355bbedb12800814f679 to your computer and use it in GitHub Desktop.
Save iKunalChhabra/a5850722610b355bbedb12800814f679 to your computer and use it in GitHub Desktop.
Raw HTTP Sever in c++
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <thread>
#include <vector>
#define PORT 8080
#define MAX_EVENTS 1024
const char RESPONSE[] =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: 13\r\n"
"Connection: close\r\n"
"\r\n"
"Hello, World!\r\n";
int set_nonblocking(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
void run_worker() {
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
perror("socket");
return;
}
set_nonblocking(server_fd);
int opt = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(PORT);
if (bind(server_fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
perror("bind");
return;
}
if (listen(server_fd, SOMAXCONN) < 0) {
perror("listen");
return;
}
int epfd = epoll_create1(0);
if (epfd < 0) {
perror("epoll_create1");
return;
}
epoll_event ev{}, events[MAX_EVENTS];
ev.events = EPOLLIN;
ev.data.fd = server_fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, server_fd, &ev);
while (true) {
int nfds = epoll_wait(epfd, events, MAX_EVENTS, -1);
for (int i = 0; i < nfds; ++i) {
if (events[i].data.fd == server_fd) {
while (true) {
sockaddr_in client_addr{};
socklen_t client_len = sizeof(client_addr);
int client_fd = accept(server_fd, (sockaddr*)&client_addr, &client_len);
if (client_fd < 0) break;
set_nonblocking(client_fd);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = client_fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, client_fd, &ev);
}
} else {
int client_fd = events[i].data.fd;
char buf[1024];
int n = read(client_fd, buf, sizeof(buf));
if (n <= 0) {
close(client_fd);
} else {
const char* res = RESPONSE;
size_t to_write = sizeof(RESPONSE) - 1;
while (to_write > 0) {
ssize_t sent = write(client_fd, res, to_write);
if (sent < 0) {
perror("write");
break;
}
res += sent;
to_write -= sent;
}
close(client_fd);
}
}
}
}
}
int main() {
int thread_count = std::thread::hardware_concurrency();
std::cout << "Starting " << thread_count << " threads...\n";
std::vector<std::thread> workers;
for (int i = 0; i < thread_count; ++i) {
workers.emplace_back(run_worker);
}
for (auto& t : workers) {
t.join();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment