Skip to content

Commit

Permalink
refactor(headers): Use url::percent_encoding functions
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedilger committed Nov 14, 2015
1 parent b5c117c commit a7be5fd
Showing 1 changed file with 6 additions and 75 deletions.
81 changes: 6 additions & 75 deletions src/header/common/content_disposition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use language_tags::LanguageTag;
use std::fmt;
use std::str::FromStr;
use unicase::UniCase;
use url::percent_encoding;

use header::{Header, HeaderFormat, parsing};
use header::shared::Charset;
Expand Down Expand Up @@ -182,7 +183,9 @@ impl fmt::Display for ContentDisposition {
try!(write!(f, "{}", lang));
};
try!(write!(f, "'"));
try!(f.write_str(&*try!(bytes_to_value_chars(bytes))))
try!(f.write_str(
&*percent_encoding::percent_encode(
bytes, percent_encoding::HTTP_VALUE_ENCODE_SET)))
}
},
&DispositionParam::Ext(ref k, ref v) => try!(write!(f, "; {}=\"{}\"", k, v)),
Expand Down Expand Up @@ -248,81 +251,15 @@ fn parse_ext_value(val: &str) -> ::Result<(Charset, Option<LanguageTag>, Vec<u8>
// Interpret the third piece as a sequence of value characters
let value: Vec<u8> = match parts.next() {
None => return Err(::Error::Header),
Some(v) => try!(value_chars_to_bytes(v)),
Some(v) => percent_encoding::percent_decode(v.as_bytes()),
};

Ok( (charset, lang, value) )
}

/// Parsing of `value-chars`
fn value_chars_to_bytes(value_chars: &str) -> ::Result<Vec<u8>> {
let mut output: Vec<u8> = Vec::new();

let mut iter = value_chars.chars();
loop {
match iter.next() {
None => return Ok(output),
Some('%') => {
let mut byte: u8 = 0;
match iter.next() {
None => return Err(::Error::Header), // hex char expected,
Some(c) => byte += 16 * try!(c.to_digit(16).ok_or(::Error::Header)) as u8,
}
match iter.next() {
None => return Err(::Error::Header), // hex char expected,
Some(c) => byte += try!(c.to_digit(16).ok_or(::Error::Header)) as u8,
}
output.push(byte);
},
Some(other) => match other {
'a'...'z' | 'A'...'Z' | '0'...'9' | '!' | '#' | '$' | '&' |
'+' | '-' | '.' | '^' | '_' | '`' | '|' | '~' => output.push(other as u8),
_ => return Err(::Error::Header) // invalid value character
}
}
}
}

/// Generation of `value-chars`
fn bytes_to_value_chars(bytes: &Vec<u8>) -> Result<String,fmt::Error> {
let mut output: String = String::new();
for byte in bytes.iter() {
match *byte as char {
'a'...'z' | 'A'...'Z' | '0'...'9' | '!' | '#' | '$' | '&' |
'+' | '-' | '.' | '^' | '_' | '`' | '|' | '~' => output.push(*byte as char),
_ => for ch in percent_encode(*byte).iter() {
output.push(*ch)
},
}
}
Ok(output)
}

/// Percent encoding of a byte
fn percent_encode(byte: u8) -> Vec<char>
{
let mut output: Vec<char> = Vec::new();
output.push('%');

let high: u8 = (byte & 0xF0) >> 4;
match high {
0...9 => output.push((b'0' + high) as char),
10...15 => output.push((b'a' + high - 10) as char),
_ => panic!("Not reachable in percent_encode()"),
}
let low: u8 = byte & 0x0F;
match low {
0...9 => output.push((b'0' + low) as char),
10...15 => output.push((b'a' + low - 10) as char),
_ => panic!("Not reachable in percent_encode()"),
}
output
}

#[cfg(test)]
mod tests {
use super::{ContentDisposition,DispositionType,DispositionParam};
use super::bytes_to_value_chars;
use ::header::Header;
use ::header::shared::Charset;

Expand Down Expand Up @@ -370,15 +307,9 @@ mod tests {
assert_eq!(a, b);
}

#[test]
fn test_bytes_to_value_chars() {
let bytes: Vec<u8> = vec![ 0xc2, 0xa3, 0x20, 0x61, 0x41 ];
assert_eq!(bytes_to_value_chars(&bytes).unwrap(), "%c2%a3%20aA".to_owned());
}

#[test]
fn test_display() {
let a = [b"attachment; filename*=UTF-8'en'%c2%a3%20and%20%e2%82%ac%20rates".to_vec()];
let a = [b"attachment; filename*=UTF-8'en'%C2%A3%20and%20%E2%82%AC%20rates".to_vec()];
let as_string = ::std::str::from_utf8(&(a[0])).unwrap();
let a: ContentDisposition = ContentDisposition::parse_header(a.as_ref()).unwrap();
let display_rendered = format!("{}",a);
Expand Down

0 comments on commit a7be5fd

Please sign in to comment.