<commit_before>use time::now_utc;
use time::Tm;
use std::ascii::AsciiExt;
use openssl::crypto::hash::hash;
use openssl::crypto::hmac::hmac;
use openssl::crypto::hash::Type::SHA256;
use serialize::hex::ToHex;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry;
use url::percent_encoding::{percent_encode_to, FORM_URLENCODED_ENCODE_SET};

use credentials::Credentials;

#[derive(Clone)]
pub struct SigV4 {
    credentials: Option<Credentials>,
    date: Tm,
    headers: BTreeMap<String, Vec<String>>,
    method: Option<String>,
    path: Option<String>,
    payload: Option<String>,
    query: Option<String>,
    region: Option<String>,
    service: Option<String>,
}

impl<'a> SigV4 {
    pub fn new() -> SigV4{
        let dt = now_utc();
        SigV4 {
            credentials: None,
            date: dt,
            headers: BTreeMap::new(),
            method: None,
            path: None,
            payload: None,
            query: None,
            region: None,
            service: None,
        }
    }

    pub fn header(mut self, header: (&str, &str)) -> SigV4 {
        append_header(&mut self.headers, header.0, header.1);
        self
    }

    pub fn credentials(mut self, credentials: Credentials) -> SigV4 {
        self.credentials = Some(credentials);
        self
    }

    pub fn path(mut self, path: String) -> SigV4 {
        self.path = Some(path);
        self
    }

    pub fn method(mut self, method: String) -> SigV4 {
        self.method = Some(method);
        self
    }

    pub fn query(mut self, query: String) -> SigV4 {
        self.query = Some(query);
        self
    }

    pub fn payload(mut self, payload: String) -> SigV4 {
        self.payload = Some(payload);
        self
    }

    fn date(mut self) -> SigV4 {
        append_header(&mut self.headers, "x-amz-date",
                      self.date.strftime("%Y%m%dT%H%M%SZ").unwrap().to_string().as_ref());
        self
    }

    fn authorization(mut self) -> SigV4 {
        let cs = self.credential_scope();
        let h = self.signed_headers();
        let s = self.clone().signature();

        let auth = format!("AWS4-HMAC-SHA256 Credential={}/{}, SignedHeaders={}, Signature={}",
               self.clone().credentials.unwrap().key.unwrap(),
               cs, h, s);

        append_header(&mut self.headers, "authorization", &auth);
        self
    }

    pub fn as_headers(self) -> Vec<(String, String)> {
        let fin = self.date().authorization();

        fin.headers.iter().
            map( |h| (h.0.clone(), canonical_value(h.1)) ).
            collect::<Vec<_>>()
    }

    fn signature(self) -> String {
        hmac(SHA256, &self.derived_signing_key(),
             self.signing_string().as_bytes()).to_hex().to_string()
    }

    #[allow(non_snake_case)]
    fn derived_signing_key(&self) -> Vec<u8> {
        let kSecret = self.clone().credentials.unwrap().secret.unwrap();
        let kDate = hmac(SHA256, format!("AWS4{}", kSecret).as_bytes(),
                self.date.strftime("%Y%m%d").unwrap().to_string().as_bytes());
        let kRegion = hmac(SHA256, &kDate, expand_string(&self.region).as_bytes());
        let kService = hmac(SHA256, &kRegion, expand_string(&self.service).as_bytes());
        hmac(SHA256, &kService, "aws4_request".as_bytes())
    }

    fn signing_string(&self) -> String {
        format!("AWS4-HMAC-SHA256\n{}\n{}\n{}",
                self.date.strftime("%Y%m%dT%H%M%SZ").unwrap(),
                self.credential_scope(),
                self.hashed_canonical_request())
    }

    fn credential_scope(&self) -> String {
        format!("{}/{}/{}/aws4_request",
                self.date.strftime("%Y%m%d").unwrap(),
                expand_string(&self.region),
                expand_string(&self.service))
    }

    fn hashed_canonical_request(&self) -> String {
        to_hexdigest(self.canonical_request())
    }

    fn hashed_payload(&self) -> String {
        let val = match self.payload {
            Some(ref x) => x.to_string(),
            None => "".to_string(),
        };
        to_hexdigest(val)
    }

    fn signed_headers(&self) -> String {
        let mut h = String::new();

        for (key,_) in self.headers.iter() {
            if h.len() > 0 {
                h.push(';')
            }
            if key.as_slice() == "authorization" {
                continue;
            }
            h.push_str(&key);
        }
        h
    }

    fn canonical_headers(&self) -> String {
        let mut h = String::new();

        for (key,value) in self.headers.iter() {
            if key.as_slice() == "authorization" {
                continue;
            }
            h.push_str(format!("{}:{}\n", key, canonical_value(value)).as_ref());<commit_msg>compare strings<commit_after>use time::now_utc;
use time::Tm;
use std::ascii::AsciiExt;
use openssl::crypto::hash::hash;
use openssl::crypto::hmac::hmac;
use openssl::crypto::hash::Type::SHA256;
use serialize::hex::ToHex;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry;
use url::percent_encoding::{percent_encode_to, FORM_URLENCODED_ENCODE_SET};

use credentials::Credentials;

#[derive(Clone)]
pub struct SigV4 {
    credentials: Option<Credentials>,
    date: Tm,
    headers: BTreeMap<String, Vec<String>>,
    method: Option<String>,
    path: Option<String>,
    payload: Option<String>,
    query: Option<String>,
    region: Option<String>,
    service: Option<String>,
}

impl<'a> SigV4 {
    pub fn new() -> SigV4{
        let dt = now_utc();
        SigV4 {
            credentials: None,
            date: dt,
            headers: BTreeMap::new(),
            method: None,
            path: None,
            payload: None,
            query: None,
            region: None,
            service: None,
        }
    }

    pub fn header(mut self, header: (&str, &str)) -> SigV4 {
        append_header(&mut self.headers, header.0, header.1);
        self
    }

    pub fn credentials(mut self, credentials: Credentials) -> SigV4 {
        self.credentials = Some(credentials);
        self
    }

    pub fn path(mut self, path: String) -> SigV4 {
        self.path = Some(path);
        self
    }

    pub fn method(mut self, method: String) -> SigV4 {
        self.method = Some(method);
        self
    }

    pub fn query(mut self, query: String) -> SigV4 {
        self.query = Some(query);
        self
    }

    pub fn payload(mut self, payload: String) -> SigV4 {
        self.payload = Some(payload);
        self
    }

    fn date(mut self) -> SigV4 {
        append_header(&mut self.headers, "x-amz-date",
                      self.date.strftime("%Y%m%dT%H%M%SZ").unwrap().to_string().as_ref());
        self
    }

    fn authorization(mut self) -> SigV4 {
        let cs = self.credential_scope();
        let h = self.signed_headers();
        let s = self.clone().signature();

        let auth = format!("AWS4-HMAC-SHA256 Credential={}/{}, SignedHeaders={}, Signature={}",
               self.clone().credentials.unwrap().key.unwrap(),
               cs, h, s);

        append_header(&mut self.headers, "authorization", &auth);
        self
    }

    pub fn as_headers(self) -> Vec<(String, String)> {
        let fin = self.date().authorization();

        fin.headers.iter().
            map( |h| (h.0.clone(), canonical_value(h.1)) ).
            collect::<Vec<_>>()
    }

    fn signature(self) -> String {
        hmac(SHA256, &self.derived_signing_key(),
             self.signing_string().as_bytes()).to_hex().to_string()
    }

    #[allow(non_snake_case)]
    fn derived_signing_key(&self) -> Vec<u8> {
        let kSecret = self.clone().credentials.unwrap().secret.unwrap();
        let kDate = hmac(SHA256, format!("AWS4{}", kSecret).as_bytes(),
                self.date.strftime("%Y%m%d").unwrap().to_string().as_bytes());
        let kRegion = hmac(SHA256, &kDate, expand_string(&self.region).as_bytes());
        let kService = hmac(SHA256, &kRegion, expand_string(&self.service).as_bytes());
        hmac(SHA256, &kService, "aws4_request".as_bytes())
    }

    fn signing_string(&self) -> String {
        format!("AWS4-HMAC-SHA256\n{}\n{}\n{}",
                self.date.strftime("%Y%m%dT%H%M%SZ").unwrap(),
                self.credential_scope(),
                self.hashed_canonical_request())
    }

    fn credential_scope(&self) -> String {
        format!("{}/{}/{}/aws4_request",
                self.date.strftime("%Y%m%d").unwrap(),
                expand_string(&self.region),
                expand_string(&self.service))
    }

    fn hashed_canonical_request(&self) -> String {
        to_hexdigest(self.canonical_request())
    }

    fn hashed_payload(&self) -> String {
        let val = match self.payload {
            Some(ref x) => x.to_string(),
            None => "".to_string(),
        };
        to_hexdigest(val)
    }

    fn signed_headers(&self) -> String {
        let mut h = String::new();

        for (key,_) in self.headers.iter() {
            if h.len() > 0 {
                h.push(';')
            }
            if key.as_ref() == String::from_str("authorization") {
                continue;
            }
            h.push_str(&key);
        }
        h
    }

    fn canonical_headers(&self) -> String {
        let mut h = String::new();

        for (key,value) in self.headers.iter() {
            if key.as_ref() == String::from_str("authorization") {
                continue;
            }
            h.push_str(format!("{}:{}\n", key, canonical_value(value)).as_ref());
{'fraction_non_alphanumeric': 0.15778474399164055, 'fraction_numerical': 0.009822361546499478, 'mean_word_length': 2.150427913100724, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5070550', 'n_tokens_mistral': 3118, 'n_tokens_neox': 3023, 'n_words': 580}