CS376: Operating Systems - Web Client and Server (100 Points)
Assignment Goals
The goals of this assignment are:- Explain HTTP request and response structures, including methods, headers, and bodies, through the practical implementation of an HTTP client and server.
- Use sockets for creating and managing connections between a client and a server.
- Handle errors in network communication, including interpreting and responding with appropriate HTTP status codes, particularly in server-side operations.
- Utilize file input/output operations in a networked environment, such as reading and serving files from a server, reinforcing understanding of file handling in conjunction with network programming.
Background Reading and References
Please refer to the following readings and examples offering templates to help get you started:The Assignment
Assignment: Building an HTTP Client and Server
Overview
Core Concepts — why this matters. This assignment reinforces the essential OS topics of interprocess communication over sockets, the client-server model, and the system-call interface to the network stack (
socket,bind,listen,accept,connect,read/write). Sockets are file descriptors too, so the sameread/writeand file-descriptor concepts from the File I/O assignment and the Kernel Data Structures reference apply directly here — you are just reading and writing to a network endpoint instead of a disk file.
In this assignment, you will develop a basic HTTP client and a corresponding HTTP server. This exercise aims to deepen your understanding of HTTP protocols, network sockets, and the client-server model. By the end of this assignment, you will have a functional understanding of HTTP headers, bodies, and error codes, along with practical experience in handling network communications.
Part 1: HTTP Client
Objective
Your task is to create an HTTP client that sends a GET request to a specified web server and displays the server’s response.
Requirements
- Command-Line Arguments: Your program should accept command-line arguments for:
- The hostname of the web server.
- The page to request (e.g.,
/index.html). - The port number (default to 80, but allow custom ports).
-
Network Sockets: Utilize network sockets to establish a connection with the server. You can use the CSAPP
open_clientfd()function for this purpose. - HTTP Request Format: Construct and send an HTTP GET request in the following format:
GET /[page] HTTP/1.1\r\n
Host: [hostname]\r\n
\r\n
Ensure that the [page] and [hostname] placeholders are replaced with the appropriate command-line arguments.
-
Response Handling: Read and display the entire response from the server.
-
Reference: Use the CSAPP echo client as a guide for handling network communications.
Example Usage
$ ./httpClient www.example.com /index.html 80
Part 2: HTTP Server
Objective
Develop an HTTP server that listens for connections, processes GET requests, and serves the requested files.
Requirements
-
Command-Line Argument: The server should accept a port number as a command-line argument.
-
Socket Creation and Listening: Use
socket()or CSAPPopen_listenfd()to create a listening socket. The server should continuously listen for incoming connections usingaccept(). - Request Processing:
- The server should read HTTP requests of the form
GET /path HTTP/1.1\\r\\n\\r\\n. - Tokenize the request string to extract the HTTP method (verb) and the requested path.
- Validate the HTTP method and handle the request accordingly.
- The server should read HTTP requests of the form
- Response Handling:
- If the file exists, read the file and send its contents back to the client.
- If the file does not exist, send an appropriate HTTP error code, such as
404 Not Found.
-
File Operations: Refer to the CSAPP file read/write examples for handling file descriptors.
- Reference: Use the CSAPP echo server as a template for managing connections and requests.
Example Usage
$ ./httpServer 8080
Additional Guidelines
- Error Handling: Implement robust error handling for both client and server, including handling network errors and malformed requests.
- HTTP Headers and Bodies:
- Client: Ensure proper formatting of the HTTP request headers.
- Server: Include necessary headers in the response, such as Content-Type.
- HTTP Error Codes: The server should be able to handle common HTTP errors, such as 404 Not Found.
Part 3: Makefile
Provide a makefile (or two) to build and run your client and server.
Makefile Requirements
Your submission must include a Makefile supporting the following standard targets (you may split these across separate client/server makefiles, but every target below must exist):
| Target | What it must do |
|---|---|
make |
Compile the client and server with no errors. |
make run |
Build if needed and launch the server (and/or run the client against it). |
make test |
Build if needed and run your test cases (e.g., client requests against your server for several status codes), printing observable pass/fail output. |
make clean |
Remove all executables, object files, and core dumps so a fresh make starts clean. |
Submission
In your submission, please include answers to any questions asked on the assignment page, as well as the questions listed below, in your README file. If you wrote code as part of this assignment, please describe your design, approach, and implementation in a separate document prepared using a word processor or typesetting program such as LaTeX. This document should include specific instructions on how to build and run your code, and a description of each code module or function that you created suitable for re-use by a colleague. In your README, please include answers to the following questions:- Describe what you did, how you did it, what challenges you encountered, and how you solved them.
- Please answer any questions found throughout the narrative of this assignment.
- If collaboration with a buddy was permitted, did you work with a buddy on this assignment? If so, who? If not, do you certify that this submission represents your own original work?
- Please identify any and all portions of your submission that were not originally written by you (for example, code originally written by your buddy, or anything taken or adapted from a non-classroom resource). It is always OK to use your textbook and instructor notes; however, you are certifying that any portions not designated as coming from an outside person or source are your own original work.
- Approximately how many hours it took you to finish this assignment (I will not judge you for this at all...I am simply using it to gauge if the assignments are too easy or hard)?
- Your overall impression of the assignment. Did you love it, hate it, or were you neutral? One word answers are fine, but if you have any suggestions for the future let me know.
- Using the grading specifications on this page, discuss briefly the grade you would give yourself and why. Discuss each item in the grading specification.
- Any other concerns that you have. For instance, if you have a bug that you were unable to solve but you made progress, write that here. The more you articulate the problem the more partial credit you will receive (it is fine to leave this blank).
Assignment Rubric
| Description | Pre-Emerging (< 50%) | Beginning (50%) | Progressing (85%) | Proficient (100%) |
|---|---|---|---|---|
| Correct Use of Sockets (15%) | Unable to establish socket connections. | Establishes connections but with frequent errors or instability. | Establishes stable connections but lacks optimal usage or efficiency. | Demonstrates efficient and error-free socket management. |
| Implementing the Client (15%) | Fails to send HTTP requests. | Sends HTTP requests but with incorrect format or errors in handling responses. | Sends correctly formatted requests and mostly handles responses well. | Flawlessly sends requests and handles responses, adhering to HTTP standards. |
| Implementing the Server (20%) | Server does not process requests. | Server processes requests but struggles with correct file serving or stability. | Server handles requests and serves files with minor issues. | Server perfectly handles requests and file serving, ensuring stability and efficiency. |
| Providing a Makefile (10%) | No Makefile provided. | Provides a basic Makefile with limited functionality. | Makefile covers essential functions but lacks advanced features or optimization. | Comprehensive and optimized Makefile, facilitating seamless compilation and execution. |
| Writing a README (10%) | No README or extremely poor documentation. | Basic README provided but lacks clarity or completeness. | Good README with most necessary instructions and information. | Excellent, well-structured README offering clear, comprehensive instructions and insights. |
| Correctly Tokenizing the HTTP Request (10%) | Unable to tokenize or parse HTTP requests. | Basic tokenization with frequent errors or misinterpretations. | Correctly tokenizes most requests but with minor flaws. | Flawlessly tokenizes and parses HTTP requests, ensuring accurate processing. |
| Correctly Forming the HTTP Response (10%) | Fails to form correct HTTP responses. | Forms basic HTTP responses with errors or non-standard structures. | Forms mostly correct responses with minor discrepancies. | Excellently constructs and sends fully compliant HTTP responses. |
| Handling HTTP Errors (10%) | Does not handle or incorrectly handles HTTP errors. | Basic handling of some HTTP errors, but lacks comprehensiveness. | Good handling of most HTTP errors, with minor oversights. | Expertly identifies and handles a wide range of HTTP errors, providing appropriate responses. |
Please refer to the Style Guide for code quality examples and guidelines.