Skip to content
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

Version | 0.0.10 #2

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,15 @@
# Changes

## v0.0.10

### Added

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

## v0.0.9

### Added

* [CLI](https://github.com/EstebanBorai/http-server/commit/f7ea5b278e8b46c322d82c324c7f263ecae3914b)
* [Config Shape](https://github.com/EstebanBorai/http-server/commit/49e4cd73ddc4401bf684ad70875b075bb35caf5a)
* [HTTP server with File Explorer](https://github.com/EstebanBorai/http-server/commit/7aa59495dab51c52a0a79b75c185b3b74dda5be1)
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "http-server"
version = "0.0.9"
version = "0.0.10"
authors = ["Esteban Borai <estebanborai@gmail.com>"]
edition = "2018"
license = "MIT"
Expand Down
1 change: 0 additions & 1 deletion README.md
Expand Up @@ -9,7 +9,6 @@
<div align="center">

[![Crates.io](https://img.shields.io/crates/v/http-server.svg)](https://crates.io/crates/http-server)
[![Documentation](https://docs.rs/http-server/badge.svg)](https://docs.rs/http-server)
![Build](https://github.com/EstebanBorai/http-server/workflows/build/badge.svg)
![Lint](https://github.com/EstebanBorai/http-server/workflows/clippy/fmt/badge.svg)
![Tests](https://github.com/EstebanBorai/http-server/workflows/tests/badge.svg)
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
14 changes: 14 additions & 0 deletions src/error.rs
@@ -0,0 +1,14 @@
#[derive(Debug)]
pub struct HttpError {
pub status_code: u16,
pub message: String,
}

impl HttpError {
pub fn new(status_code: u16, message: &str) -> Self {
Self {
status_code,
message: message.to_string(),
}
}
}
69 changes: 69 additions & 0 deletions src/handler/file_explorer/handler.rs
@@ -0,0 +1,69 @@
use crate::file_explorer::FileExplorer;
use crate::handler::build_html;
use crate::server::{ETag, HttpHeader};
use ascii::AsciiString;
use std::fs::{read_dir, File};
use tiny_http::{Header, Request, Response, ResponseBox};

/// Creates a path by merging the URL params and the `root_dir`.
/// Then reads the file system entries in the resulting path.
///
/// If the resulting path is a directory, enumerates every file system entry
/// and responds with an HTML with the entry listing.
///
/// Otherwise retrieves the provided file.
pub fn file_explorer(request: Request, file_explorer: &FileExplorer) -> (Request, ResponseBox) {
match file_explorer.read(request.url().as_ref()) {
Ok(entry) => {
if entry.is_file {
let mime_type = mime_guess::from_path(&entry.path)
.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 = ETag::from_metadata(&file.metadata().unwrap()).unwrap();
let entity_tag: HttpHeader = entity_tag.into();
let entity_tag: Header = entity_tag.into();

(
request,
Response::from_file(file)
.with_header(tiny_http::Header {
field: "Content-Type".parse().unwrap(),
value: mime_type,
})
.with_header(entity_tag)
.boxed(),
)
} else {
let dirpath = entry.path.clone();
let dirpath = dirpath.to_str().unwrap();
let dirname = &dirpath[file_explorer.root_dir_string.len()..];

let entries = read_dir(entry.path).unwrap();

let html = build_html(
dirname,
&file_explorer.root_dir_string,
&file_explorer,
entries,
);
let mime_type_value: AsciiString = AsciiString::from_ascii("text/html").unwrap();
let response = Response::from_string(html)
.with_status_code(200)
.with_header(tiny_http::Header {
field: "Content-Type".parse().unwrap(),
value: mime_type_value,
});

(request, response.boxed())
}
}
Err(_) => (
request,
Response::from_string("Not Found")
.with_status_code(404)
.boxed(),
),
}
}
File renamed without changes.
17 changes: 17 additions & 0 deletions src/handler/main_handler.rs
@@ -0,0 +1,17 @@
use crate::file_explorer::FileExplorer;
use crate::handler::file_explorer;
use tiny_http::{Request, Response, ResponseBox};

/// The main handler acts like a router for every supported method.
/// If a method is not supported then responds with `Method Not Allowed 405`
pub fn main_handler(req: Request, fexplorer: &FileExplorer) -> (Request, ResponseBox) {
match req.method().to_string().to_lowercase().as_str() {
"get" => file_explorer(req, fexplorer),
_ => (
req,
Response::from_string("Method Not Allowed")
.with_status_code(405)
.boxed(),
),
}
}
6 changes: 4 additions & 2 deletions src/handler/mod.rs
@@ -1,3 +1,5 @@
mod static_fs;
mod file_explorer;
mod main_handler;

pub use static_fs::*;
pub use file_explorer::*;
pub use main_handler::*;
60 changes: 0 additions & 60 deletions src/handler/static_fs/handler.rs

This file was deleted.

88 changes: 1 addition & 87 deletions src/main.rs
@@ -1,92 +1,6 @@
//! <div>
//! <div align="center" style="display: block; text-align: center;">
//! <img src="https://raw.githubusercontent.com/EstebanBorai/http-server/main/docs/http-logo.png" height="120" width="200" />
//! </div>
//! <h1 align="center">http-server</h1>
//! <h4 align="center">Command-line HTTP Server</h4>
//! </div>
//!
//! <div align="center">
//!
//! [![Crates.io](https://img.shields.io/crates/v/http-server.svg)](https://crates.io/crates/http-server)
//! [![Documentation](https://docs.rs/http-server/badge.svg)](https://docs.rs/http-server)
//! ![Build](https://github.com/EstebanBorai/http-server/workflows/build/badge.svg)
//! ![Lint](https://github.com/EstebanBorai/http-server/workflows/clippy/fmt/badge.svg)
//! ![Tests](https://github.com/EstebanBorai/http-server/workflows/tests/badge.svg)
//!
//! </div>
//!
//! ## Index
//!
//! - [Installation](#installation)
//! - [Usage](#usage)
//! - [Flags](#flags)
//! - [Options](#options)
//! - [Contributing](#contributing)
//! - [License](#license)
//! - [Contribution](#contribution)
//!
//! ## Installation
//!
//! ```bash
//! cargo install http-server
//! ```
//!
//! Check for the installation to be successful.
//!
//! ```bash
//! http-server --help
//! ```
//!
//! ## Usage
//!
//! ```
//! http-server [FLAGS] [OPTIONS] [root_dir]
//! ```
//!
//! ### Flags
//!
//! Flags are provided without any values. For example:
//!
//! ```
//! http-server --help
//! ```
//!
//! Name | Short | Long | Description
//! --- | --- | --- | ---
//! Help | `h` | `help` | Prints help information
//! Version | `V` | `version` | Prints version information
//!
//! ### Options
//!
//! Options are provided with a value and also have default values. For example:
//!
//! ```
//! http-server --address 127.0.0.1
//! ```
//!
//! Name | Short | Long | Description | Default Value
//! --- | --- | --- | --- | ---
//! Address | `a` | `address` | Address to bind the server | `0.0.0.0`
//! Port | `p` | `port` | Port to bind the server | `7878`
//!
//! ## Contributing
//!
//! Every contribution to this project is welcome. Feel free to open a pull request,
//! an issue or just by starting this project.
//!
//! ## License
//!
//! Licensed under the MIT License
//!
//! ### Contribution
//!
//! Unless you explicitly state otherwise, any contribution intentionally submitted for
//! inclusion in http-server by you, shall be dual licensed as above, without any additional
//! terms or conditions.
//!
mod cli;
mod config;
mod error;
mod file_explorer;
mod handler;
mod server;
Expand Down