For our Intermediate Computer Systems (CIS 3990) class, we built Bingus Search, a multi-threaded HTTP web server and search engine in C++. The goal was to create a system that could efficiently index files, handle multiple simultaneous users, and provide both web-based and command-line interfaces for interacting with files on the server.
Special thanks to my teammate Praise for their collaboration on this project.
Project Overview
Bingus Search is a C++ HTTP server that allows users to:
Index a directory of text files and recursively track word occurrences.
Search for terms through a web interface with results ranked by frequency.
Manage files via a custom command-line shell (upload, delete, download, and update files).
To handle multiple clients simultaneously, we implemented a thread pool using std::jthread. Incoming HTTP requests are dispatched to worker threads, allowing the server to efficiently handle concurrent connections without data races or slowdowns.
File Crawling and Search
The server recursively indexes a given directory, extracting words while ignoring case and punctuation. Users can submit queries containing one or more words, and the server returns all documents containing every word in the query. Results are ranked by total occurrences of the query words, making the most relevant files appear first.
HTTP Server
The server supports persistent HTTP connections and correctly parses headers and bodies for requests such as GET, POST, PUT, and DELETE. For security, we used canonical path resolution to prevent clients from accessing files outside the designated directory.
Command-Line Shell
Our custom shell allows for fine grained file operations beyond what the web interface provides. Commands include:
get <server_path> — fetch a file’s contents.
get <server_path> <local_path> — download a file locally.
delete <server_path> — remove a file from the server.
post <server_path> <local_path> — upload a new file.
put <server_path> <local_path> — overwrite an existing file.
help — display available commands.
Thread Pool and Multi-Threading
We designed a ThreadPool class that maintains a pool of worker threads ready to process incoming requests. This architecture ensures that the server remains responsive even under heavy load, efficiently distributing tasks without blocking.
Graceful Shutdown
Bingus Search handles SIGINT (Ctrl+C) signals to cleanly terminate the server, close all active connections, and free memory, ensuring no leaks or dangling threads.
Testing
We wrote unit tests to ensure the correctness and reliability of our code. These tests covered key components like the indexer, thread pool, and HTTP request handling, helping us catch bugs and verify expected behavior throughout development.
Demo