Account Settings

Dark ModeSwitch Canvas UI theme
Grade Change NotificationsEmail when grades post
Course AnnouncementsEmail digest
CS 350 Assignments Assignment 3
CS 350: Operating Systems & Systems Programming

Assignment 3: Multi-Threaded HTTP Web Server

Due
Oct 18 by 11:59pm Individual
Points
100
Submitting
a file upload or a text entry box Allowed file types: c, cpp, h
Available
Oct 4 at 12:00am – Oct 25 at 11:59pm until Oct 25 at 11:59pm

In this assignment you will build a multi-threaded HTTP/1.0 web server in C that can serve static files to multiple clients concurrently. This assignment builds directly on the socket-programming concepts from Lecture 12 and the POSIX threading material from Lecture 14.

Learning Objectives

  • Use the Berkeley sockets API (socket, bind, listen, accept) to build a TCP server.
  • Spawn a worker thread per connection using pthread_create, and manage thread lifecycle with pthread_join / pthread_detach.
  • Protect shared state (connection counters, logging buffer) with pthread_mutex_t to avoid race conditions.
  • Parse a minimal HTTP/1.0 request line and respond with correct status codes (200, 404, 400).

Requirements

  1. Your server must accept a port number as a command-line argument: ./httpserver <port>.
  2. Each incoming connection must be handled on its own thread — no forking, no single-threaded blocking loops.
  3. A global request counter must be incremented on every request, guarded by a mutex. We will stress-test this with ab (Apache Bench) at 200 concurrent connections; any lost updates will fail the correctness tests.
  4. Implement a bounded thread pool (max 16 concurrent workers) using a condition variable to block additional connections until a worker frees up — do not spawn unbounded threads.
  5. Serve files relative to a ./www directory. Requests outside that directory (path traversal via ../) must return 400 Bad Request.
  6. Gracefully handle SIGINT by joining all outstanding threads before exit — no dangling connections in valgrind's output.
Race condition warning: the #1 point deduction last semester was an unguarded increment on the shared request-count variable. Run your submission under helgrind or ThreadSanitizer (-fsanitize=thread) before submitting — a clean run is required for full credit on Requirement 3.

Starter Code

Starter code is provided in hw3_starter.tar.gz on the course Modules page. The socket setup boilerplate is provided; you are responsible for the threading and request-handling logic:

// server.c — provided scaffold, fill in handle_connection() int main(int argc, char *argv[]) { int server_fd = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(atoi(argv[1])), .sin_addr.s_addr = INADDR_ANY }; bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)); listen(server_fd, SOMAXCONN); while (1) { int *client_fd = malloc(sizeof(int)); *client_fd = accept(server_fd, NULL, NULL); pthread_t tid; pthread_create(&tid, NULL, handle_connection, client_fd); pthread_detach(tid); // TODO: replace with bounded pool } }

Submission Guidelines

  • Submit a single .tar.gz containing server.c, any additional .c/.h files, and your Makefile.
  • Alternatively, upload individual .c / .h files directly using the file upload box below.
  • Include a short README (as text entry or plain file) describing your thread-pool design and any known limitations.
  • Late submissions: −10% per day, up to 3 days, per the syllabus late policy.
Submit Assignment
Drag a file here, or browse your computer
Accepted file types: c, cpp, h