Skip to content

Commit

Permalink
add: entity tag support
Browse files Browse the repository at this point in the history
Implements an Entity Tag hash by obtaining the date created, the
date of the last modification and the size of the file.
  • Loading branch information
EstebanBorai committed Oct 15, 2020
1 parent 72de4e2 commit 54be7c0
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
# Changes

## v0.0.10

### Added

* [Etag Support](https://github.com/EstebanBorai/http-server/commit/32dc9a2e6b32bb18906ef06d45c155731d91519e)

## v0.0.9

### Added
Expand Down
2 changes: 0 additions & 2 deletions src/config.rs
Expand Up @@ -28,8 +28,6 @@ impl From<App<'static, 'static>> for Config {
};

let silent = matches.is_present(SILENT.1);

// at this point the values provided to the config are validated by the CLI
Self {
address,
port,
Expand Down
11 changes: 9 additions & 2 deletions src/handler/file_explorer/handler.rs
@@ -1,5 +1,6 @@
use crate::file_explorer::FileExplorer;
use crate::handler::build_html;
use crate::server::make_entity_tag;
use ascii::AsciiString;
use std::fs::{read_dir, File};
use tiny_http::{Request, Response, ResponseBox};
Expand All @@ -16,10 +17,12 @@ pub fn file_explorer(request: Request, file_explorer: &FileExplorer) -> (Request
Ok(entry) => {
if entry.is_file {
let mime_type = mime_guess::from_path(&entry.path)
.first_or_octet_stream()
.to_string();
.first_or_octet_stream()
.to_string();
let mime_type = AsciiString::from_ascii(mime_type.as_bytes()).unwrap();
let file = File::open(entry.path).unwrap();
let entity_tag = make_entity_tag(&file.metadata().unwrap());
let entity_tag = AsciiString::from_ascii(entity_tag).unwrap();

(
request,
Expand All @@ -28,6 +31,10 @@ pub fn file_explorer(request: Request, file_explorer: &FileExplorer) -> (Request
field: "Content-Type".parse().unwrap(),
value: mime_type,
})
.with_header(tiny_http::Header {
field: "Etag".parse().unwrap(),
value: entity_tag
})
.boxed(),
)
} else {
Expand Down
17 changes: 17 additions & 0 deletions src/server/etag.rs
@@ -0,0 +1,17 @@
use std::fs::Metadata;
use std::time::SystemTime;
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;

/// Creates an Entity Tag from a `File` `Metadata`
pub fn make_entity_tag(meta: &Metadata) -> String {
let mut created_hasher = DefaultHasher::new();
let mut modified_hasher = DefaultHasher::new();
let mut size_hasher = DefaultHasher::new();

meta.len().hash(&mut size_hasher);
meta.created().unwrap_or(SystemTime::now()).hash(&mut created_hasher);
meta.modified().unwrap_or(SystemTime::now()).hash(&mut modified_hasher);

format!("{0:x}{1:x}{2:x}", created_hasher.finish(), modified_hasher.finish(), size_hasher.finish())
}
2 changes: 2 additions & 0 deletions src/server/mod.rs
@@ -1,3 +1,5 @@
mod etag;
mod http;

pub use etag::*;
pub use http::*;

0 comments on commit 54be7c0

Please sign in to comment.