1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
//! # Milstian HTTP
//!
//! ![Milstian Logo](https://raw.githubusercontent.com/cjohansson/milstian-rust-internet-framework/master/html/img/logo1-modified.jpg)
//!
//! In progress, primarily used for learning Rust programming.
//!
//! This project is used by the milstian-internet-framework to parse and build HTTP requests and responses.
//!
//! ## Major goal
//! * Easy and fast way to decode and encode HTTP requests and responses
//!
//! ## Usage
//! ### Include in project
//! 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`.
//!
//! ```toml
//! [dependencies]
//! milstian_http = "0.1.*"
//! ```
//! And this in your crate root:
//! ```rust,dont_run
//! extern crate milstian_http;
//! ```
//!
//! ### Decoding a TCP stream into a HTTP request
//! ```rust
//! use milstian_http::request::{Message, Method, Protocol};
//!
//! let request =
//!     Message::from_tcp_stream(b"POST / HTTP/1.0\r\nAgent: Random browser\r\n\r\ntest=abc");
//! assert!(request.is_some());
//!
//! let request_unwrapped = request.expect("POST HTTP1");
//! assert_eq!(request_unwrapped.request_line.method, Method::Post);
//! assert_eq!(request_unwrapped.request_line.protocol, Protocol::V1_0);
//! ```
//!
//! ### Encoding protocol, status, headers and body into a HTTP response
//! ```rust
//! use milstian_http::response::Message;
//! use std::collections::HashMap;
//!
//! assert_eq!(
//!     Message::new(
//!         "HTTP/1.0".to_string(),
//!         "200 OK".to_string(),
//!         HashMap::new(),
//!         b"<html><body>Nothing here</body></html>".to_vec()
//!     ).to_bytes(),
//!     b"HTTP/1.0 200 OK\r\n\r\n<html><body>Nothing here</body></html>".to_vec()
//! );
//! ```

pub mod request;
pub mod response;

/// # Capitalize key, used for http header keys
/// ## Usage
/// ```rust
///assert_eq!("Content-Type".to_string(), milstian_http::capitalize_key("content-type"));
/// ```
pub fn capitalize_key(word: &str) -> String {
    let parts: Vec<&str> = word.split("-").collect();
    let mut converted = String::new();
    let mut first_part = true;
    let mut first_char: bool;
    for part in parts {
        if first_part {
            first_part = false;
        } else {
            converted.push('-');
        }
        first_char = true;
        for character in part.chars() {
            if first_char {
                first_char = false;
                for char in character.to_uppercase() {
                    converted.push(char);
                }
            } else {
                for char in character.to_lowercase() {
                    converted.push(char);
                }
            }
        }
    }
    converted
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_capitalize_key() {
        assert_eq!("Content-Type".to_string(), capitalize_key("content-type"));
        assert_eq!("Content-Type".to_string(), capitalize_key("CONTENT-TYPE"));
        assert_eq!("Accept".to_string(), capitalize_key("acCept"));
    }
}