-
Notifications
You must be signed in to change notification settings - Fork 26
Add cache-busting and server headers with a wrapper. #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add cache-busting and server headers with a wrapper. #5
Conversation
In order to support custom headers for various response types, this commit adds a wrapper type, ResponseWrapper, which can service all types of response in `bin`. For paste objects, the preferred `Last-Modified` is used, so that caches can compare their exact timings with the HEAD response when revalidating. For static objects, an `ETag` is used instead, based on the Cargo version and git hash of the codebase at compilation time; a `build.rs` is used for this.
| static BINARY_ETAG: Lazy<String> = | ||
| Lazy::new(|| sha256::digest(BINARY_VERSION)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went on searching for a library which provides a constant function to generate sha256 digests.
The closest I got was https://github.com/saleemrashid/sha2-const, but it brings in more weight than we would have after replacing it with both once-cell and sha256.
| impl<'r, 'o: 'r, R: Responder<'r, 'o>> Responder<'r, 'o> | ||
| for ResponseWrapper<R> | ||
| { | ||
| fn respond_to(self, request: &'r Request<'_>) -> Result<'o> { | ||
| use ResponseWrapper::*; | ||
|
|
||
| // Add global headers. | ||
| let mut response = Response::build(); | ||
| response.raw_header("Server", crate::SERVER_VERSION); | ||
|
|
||
| // Handle individual request types. | ||
| match self { | ||
| MetaInterfaceResponse(sup) => response | ||
| .join(sup.respond_to(request)?) | ||
| .raw_header("ETag", &*crate::BINARY_ETAG) | ||
| .ok(), | ||
| PasteContentResponse(sup, modified) => response | ||
| .join(sup.respond_to(request)?) | ||
| .raw_header("Last-Modified", http_strftime(modified)) | ||
| .ok(), | ||
| Redirect(sup) => response.join(sup.respond_to(request)?).ok(), | ||
| NotFound(s) => { | ||
| let body = format!("Unable to find entity '{}'", s); | ||
|
|
||
| response | ||
| .sized_body(body.len(), Cursor::new(body)) | ||
| .status(Status::NotFound) | ||
| .ok() | ||
| } | ||
|
|
||
| ServerError(s) => { | ||
| let body = format!("Server error: '{}'", s); | ||
| response | ||
| .sized_body(body.len(), Cursor::new(body)) | ||
| .status(Status::InternalServerError) | ||
| .ok() | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is neat. It would prove useful in being versatile to future changes.
|
Thanks for the PR ! |
In order to support custom headers for various response types, this commit adds a wrapper type, ResponseWrapper, which can service all types of response in
bin.For paste objects, the preferred
Last-Modifiedis used, so that caches can compare their exact timings with the HEAD response when revalidating.For static objects, an
ETagis used instead, based on the Cargo version and git hash of the codebase at compilation time; abuild.rsis used for this.Cargo Format
cargo fmton the project.Clippy lints
cargo clippy -- -Dwarningson the project to check for suggestionscargo clippy --fixto let clippy apply the suggestions itself, if any.