From 711394f472879a50a8401a84bcae0a8f303475c4 Mon Sep 17 00:00:00 2001 From: Adrian Stanciu Date: Wed, 31 Oct 2018 22:22:36 +0200 Subject: [PATCH 1/2] Fix HTTP headers verification --- tests/reqwest.rs | 93 ++++++++++++++++++++++++++------------------- tests/server/mod.rs | 56 +++++++++++++++------------ 2 files changed, 85 insertions(+), 64 deletions(-) diff --git a/tests/reqwest.rs b/tests/reqwest.rs index bfde10c..42dddbc 100644 --- a/tests/reqwest.rs +++ b/tests/reqwest.rs @@ -10,30 +10,34 @@ mod server; fn server() -> Server { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -User-Agent: reqwest/0.8.0\r\n\ -Accept: text/event-stream\r\n\ -Accept-Encoding: gzip\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + User-Agent: reqwest/0.8.8\r\n\ + Accept: text/event-stream\r\n\ + Accept-Encoding: gzip\r\n\ + \r\n", + ); return s; } #[test] fn simple_events() { let s = server(); - s.send("HTTP/1.1 200 OK\r\n\ -Content-Type: text/event-stream\r\n\ -\r\n\ -id: 42\r\n\ -event: foo\r\n\ -data: bar\r\n\ -\r\n\ -event: bar\n\ -: comment\n\ -data: baz\n\ -\n"); + s.send( + "HTTP/1.1 200 OK\r\n\ + Content-Type: text/event-stream\r\n\ + \r\n\ + id: 42\r\n\ + event: foo\r\n\ + data: bar\r\n\ + \r\n\ + event: bar\n\ + : comment\n\ + data: baz\n\ + \n", + ); println!("url: {}", s.url("/")); let mut client = Client::new(Url::parse(&s.url("/")).unwrap()); @@ -52,12 +56,14 @@ data: baz\n\ #[test] fn retry() { let s = server(); - s.send("HTTP/1.1 200 OK\r\n\ -Content-Type: text/event-stream\r\n\ -\r\n\ -retry: 42\r\n\ -data: bar\r\n\ -\r\n"); + s.send( + "HTTP/1.1 200 OK\r\n\ + Content-Type: text/event-stream\r\n\ + \r\n\ + retry: 42\r\n\ + data: bar\r\n\ + \r\n", + ); println!("url: {}", s.url("/")); let mut client = Client::new(Url::parse(&s.url("/")).unwrap()); @@ -69,10 +75,12 @@ data: bar\r\n\ #[test] fn missing_content_type() { let s = server(); - s.send("HTTP/1.1 200 OK\r\n\ -\r\n\ -data: bar\r\n\ -\r\n"); + s.send( + "HTTP/1.1 200 OK\r\n\ + \r\n\ + data: bar\r\n\ + \r\n", + ); let mut client = Client::new(Url::parse(&s.url("/")).unwrap()); match client.next().unwrap() { @@ -84,11 +92,13 @@ data: bar\r\n\ #[test] fn invalid_content_type() { let s = server(); - s.send("HTTP/1.1 200 OK\r\n\ -Content-Type: text/plain\r\n\ -\r\n\ -data: bar\r\n\ -\r\n"); + s.send( + "HTTP/1.1 200 OK\r\n\ + Content-Type: text/plain\r\n\ + \r\n\ + data: bar\r\n\ + \r\n", + ); let mut client = Client::new(Url::parse(&s.url("/")).unwrap()); match client.next().unwrap() { @@ -100,13 +110,18 @@ data: bar\r\n\ #[test] fn content_type_with_mime_parameter() { let s = server(); - s.send("HTTP/1.1 200 OK\r\n\ -Content-Type: text/event-stream;charset=utf8\r\n\ -\r\n\ -data: bar\r\n\ -\r\n"); + s.send( + "HTTP/1.1 200 OK\r\n\ + Content-Type: text/event-stream;charset=utf8\r\n\ + \r\n\ + data: bar\r\n\ + \r\n", + ); let mut client = Client::new(Url::parse(&s.url("/")).unwrap()); - let event = client.next().unwrap().expect("MIME parameter should be ignored"); + let event = client + .next() + .unwrap() + .expect("MIME parameter should be ignored"); assert_eq!(event.data, "bar\n"); } diff --git a/tests/server/mod.rs b/tests/server/mod.rs index 4d38de3..53fa14f 100644 --- a/tests/server/mod.rs +++ b/tests/server/mod.rs @@ -1,17 +1,19 @@ #![allow(dead_code)] use std::collections::HashSet; -use std::net::{TcpListener, SocketAddr, TcpStream}; use std::io::prelude::*; -use std::thread; -use std::sync::mpsc::{Sender, Receiver, channel}; use std::io::BufReader; +use std::net::{SocketAddr, TcpListener, TcpStream}; +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::thread; macro_rules! t { - ($e:expr) => (match $e { - Ok(e) => e, - Err(e) => panic!("{} failed with {:?}", stringify!($e), e), - }) + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {:?}", stringify!($e), e), + } + }; } pub struct Server { @@ -35,9 +37,9 @@ fn run(listener: &TcpListener, rx: &Receiver) { while let Some(i) = expected.find("\n") { let line = &expected[..i + 1]; expected = &expected[i + 1..]; - expected_headers.insert(line); + expected_headers.insert(line.to_ascii_lowercase()); if line == "\r\n" { - break + break; } } @@ -45,31 +47,34 @@ fn run(listener: &TcpListener, rx: &Receiver) { while expected_headers.len() > 0 { let mut actual = String::new(); t!(socket.read_line(&mut actual)); + actual = actual.to_ascii_lowercase(); if actual.starts_with("Content-Length") { let len = actual.split(": ").skip(1).next().unwrap(); expected_len = len.trim().parse().ok(); } // various versions of libcurl do different things here if actual == "Proxy-Connection: Keep-Alive\r\n" { - continue + continue; } if expected_headers.remove(&actual[..]) { - continue + continue; } let mut found = None; for header in expected_headers.iter() { if lines_match(header, &actual) { found = Some(header.clone()); - break + break; } } if let Some(found) = found { expected_headers.remove(&found); - continue + continue; } - panic!("unexpected header: {:?} (remaining headers {:?})", - actual, expected_headers); + panic!( + "unexpected header: {:?} (remaining headers {:?})", + actual, expected_headers + ); } for header in expected_headers { panic!("expected header but not found: {:?}", header); @@ -84,7 +89,7 @@ fn run(listener: &TcpListener, rx: &Receiver) { line.truncate(0); t!(socket.read_line(&mut line)); if line.len() == 0 { - break + break; } if expected.len() == 0 { panic!("unexpected line: {:?}", line); @@ -93,11 +98,14 @@ fn run(listener: &TcpListener, rx: &Receiver) { let expected_line = &expected[..i + 1]; expected = &expected[i + 1..]; if lines_match(expected_line, &line) { - continue + continue; } - panic!("lines didn't match:\n\ - expected: {:?}\n\ - actual: {:?}\n", expected_line, line) + panic!( + "lines didn't match:\n\ + expected: {:?}\n\ + actual: {:?}\n", + expected_line, line + ) } if expected.len() != 0 { println!("didn't get expected data: {:?}", expected); @@ -105,7 +113,7 @@ fn run(listener: &TcpListener, rx: &Receiver) { } Message::Write(ref to_write) => { t!(socket.get_mut().write_all(to_write.as_bytes())); - return + return; } } } @@ -120,13 +128,11 @@ fn lines_match(expected: &str, mut actual: &str) -> bool { match actual.find(part) { Some(j) => { if i == 0 && j != 0 { - return false + return false; } actual = &actual[j + part.len()..]; } - None => { - return false - } + None => return false, } } actual.is_empty() || expected.ends_with("[..]") From 206e0b0c75c3c4ae1bef64e05f3cd641fa3cc331 Mon Sep 17 00:00:00 2001 From: Adrian Stanciu Date: Sat, 10 Nov 2018 13:36:10 +0200 Subject: [PATCH 2/2] fix case when comparing with lowercase header --- tests/server/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/server/mod.rs b/tests/server/mod.rs index 53fa14f..24d7c69 100644 --- a/tests/server/mod.rs +++ b/tests/server/mod.rs @@ -48,12 +48,12 @@ fn run(listener: &TcpListener, rx: &Receiver) { let mut actual = String::new(); t!(socket.read_line(&mut actual)); actual = actual.to_ascii_lowercase(); - if actual.starts_with("Content-Length") { + if actual.starts_with("content-length") { let len = actual.split(": ").skip(1).next().unwrap(); expected_len = len.trim().parse().ok(); } // various versions of libcurl do different things here - if actual == "Proxy-Connection: Keep-Alive\r\n" { + if actual == "proxy-connection: keep-alive\r\n" { continue; } if expected_headers.remove(&actual[..]) {