milstian_http/lib.rs
1//! # Milstian HTTP
2//!
3//! 
4//!
5//! In progress, primarily used for learning Rust programming.
6//!
7//! This project is used by the milstian-internet-framework to parse and build HTTP requests and responses.
8//!
9//! ## Major goal
10//! * Easy and fast way to decode and encode HTTP requests and responses
11//!
12//! ## Usage
13//! ### Include in project
14//! This crate is on [crates.io](https://crates.io/crates/milstian-http) and can be used by adding time to the dependencies in your project's `Cargo.toml`.
15//!
16//! ```toml
17//! [dependencies]
18//! milstian_http = "0.1.*"
19//! ```
20//! And this in your crate root:
21//! ```rust,dont_run
22//! extern crate milstian_http;
23//! ```
24//!
25//! ### Decoding a TCP stream into a HTTP request
26//! ```rust
27//! use milstian_http::request::{Message, Method, Protocol};
28//!
29//! let request =
30//! Message::from_tcp_stream(b"POST / HTTP/1.0\r\nAgent: Random browser\r\n\r\ntest=abc");
31//! assert!(request.is_some());
32//!
33//! let request_unwrapped = request.expect("POST HTTP1");
34//! assert_eq!(request_unwrapped.request_line.method, Method::Post);
35//! assert_eq!(request_unwrapped.request_line.protocol, Protocol::V1_0);
36//! ```
37//!
38//! ### Encoding protocol, status, headers and body into a HTTP response
39//! ```rust
40//! use milstian_http::response::Message;
41//! use std::collections::HashMap;
42//!
43//! assert_eq!(
44//! Message::new(
45//! "HTTP/1.0".to_string(),
46//! "200 OK".to_string(),
47//! HashMap::new(),
48//! b"<html><body>Nothing here</body></html>".to_vec()
49//! ).to_bytes(),
50//! b"HTTP/1.0 200 OK\r\n\r\n<html><body>Nothing here</body></html>".to_vec()
51//! );
52//! ```
53
54pub mod request;
55pub mod response;
56
57/// # Capitalize key, used for http header keys
58/// ## Usage
59/// ```rust
60///assert_eq!("Content-Type".to_string(), milstian_http::capitalize_key("content-type"));
61/// ```
62pub fn capitalize_key(word: &str) -> String {
63 let parts: Vec<&str> = word.split("-").collect();
64 let mut converted = String::new();
65 let mut first_part = true;
66 let mut first_char: bool;
67 for part in parts {
68 if first_part {
69 first_part = false;
70 } else {
71 converted.push('-');
72 }
73 first_char = true;
74 for character in part.chars() {
75 if first_char {
76 first_char = false;
77 for char in character.to_uppercase() {
78 converted.push(char);
79 }
80 } else {
81 for char in character.to_lowercase() {
82 converted.push(char);
83 }
84 }
85 }
86 }
87 converted
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_capitalize_key() {
96 assert_eq!("Content-Type".to_string(), capitalize_key("content-type"));
97 assert_eq!("Content-Type".to_string(), capitalize_key("CONTENT-TYPE"));
98 assert_eq!("Accept".to_string(), capitalize_key("acCept"));
99 }
100}