Implementing ETag Handling in a Go HTTP Server
ETags (Entity Tags) are a mechanism for web servers and browsers to validate cached resources. This challenge asks you to build a simple Go HTTP server that generates and validates ETags for a given resource, allowing clients to efficiently revalidate the resource without re-downloading it if it hasn't changed. This is crucial for improving website performance and reducing bandwidth usage.
Problem Description
You need to create a Go program that implements a basic HTTP server. This server should serve a single resource (a simple text file) and generate an ETag for it based on its content's hash. The server should:
- Generate ETag: Calculate an ETag for the resource based on its content. A simple MD5 hash is sufficient for this exercise.
- Serve Resource with ETag: Include the generated ETag in the
ETagheader of the HTTP response. - Handle
If-None-MatchHeader: Accept theIf-None-Matchheader from the client. If the client'sIf-None-Matchvalue matches the server's ETag, respond with a304 Not Modifiedstatus code and an empty body. - Serve Resource if Not Matching: If the client's
If-None-Matchvalue does not match the server's ETag, serve the resource with the200 OKstatus code and the resource content in the response body.
Key Requirements:
- The server must handle both GET requests.
- The server must correctly generate and validate ETags.
- The server must return the appropriate HTTP status codes (200 OK, 304 Not Modified).
- The server should handle the case where the resource doesn't exist gracefully (return a 404 Not Found).
Expected Behavior:
- The first request for the resource should return the resource content and an ETag header.
- Subsequent requests with a matching
If-None-Matchheader should return a 304 Not Modified response. - Subsequent requests with a non-matching
If-None-Matchheader should return the resource content and the updated ETag. - If the resource is modified (simulated by changing the file content), subsequent requests with the old
If-None-Matchheader should return 200 OK with the new content and ETag. - If the resource is not found, return a 404 Not Found.
Edge Cases to Consider:
- Resource not found.
- Empty resource content.
- Client sends an
If-None-Matchheader with a value that is not a valid ETag (e.g., an empty string). Treat this as a non-match. - Resource modification (simulated by changing the file content).
Examples
Example 1:
Input: GET request for "/resource" (first request)
Output: HTTP 200 OK
ETag: "e5d8e5a2a799a9999999999999999999"
Body: "This is the resource content."
Explanation: The server generates an ETag for the resource content and returns it along with the content.
Example 2:
Input: GET request for "/resource" with If-None-Match: "e5d8e5a2a799a9999999999999999999"
Output: HTTP 304 Not Modified
ETag: "e5d8e5a2a799a9999999999999999999"
Explanation: The client's `If-None-Match` matches the server's ETag, so a 304 response is returned.
Example 3:
Input: GET request for "/resource" with If-None-Match: "wrong_etag"
Output: HTTP 200 OK
ETag: "f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6" (new ETag after modification)
Body: "This is the modified resource content."
Explanation: The client's `If-None-Match` does not match the server's ETag (because the resource was modified), so the resource and a new ETag are returned.
Constraints
- The resource file path is hardcoded to "resource.txt" for simplicity.
- The ETag generation should use MD5 hashing. You can use the
crypto/md5package. - The server should listen on port 8080.
- The resource file should be small (less than 1KB) to avoid performance issues.
- The server should be able to handle at least 10 concurrent requests without significant performance degradation.
Notes
- Consider using the
net/httppackage for building the HTTP server. - You'll need to read the resource file content and calculate its MD5 hash.
- Remember to handle errors appropriately, such as file not found errors.
- The
If-None-Matchheader value is a string. - Focus on the core ETag handling logic; error handling and advanced features (e.g., wildcard ETags) are not required for this challenge.
- Simulate resource modification by manually changing the content of "resource.txt" between requests.