Rename test function as_write_vec -> into_written_bytes
Tests use `Response::as_write_vec` to inspect the outgoing HTTP/1.1 request line and headers. The current version has two problems: 1. Called `as_write_vec` when it actually returns a `&[u8]`. 2. Inspects/uses the `Response::stream` without consuming `Response`. The first problem is trivial, but the second is subtle. Currently all calls on `Response` that works with the internal `Response::stream` consumes `self` (`into_string`, `into_reader`). `Response` is by itself `Send + Sync`, and must be so because the nested Stream is `Read + Write + Send + Sync`. However for implementors of `TLSStream`, it would be nice to relax the `Sync` requirement. Assumption: If all fields in Response are `Sync` except `Response::stream`, but any access to `stream` consumes `Response`, we can consider the entire `Response` `Sync`. This assumption can help us relax the `TlsStream` `Sync` requirement in a later PR.
This commit is contained in:
@@ -520,8 +520,9 @@ impl Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn as_write_vec(&self) -> &[u8] {
|
pub fn into_written_bytes(self) -> Vec<u8> {
|
||||||
self.stream.as_write_vec()
|
// Deliberately consume `self` so that any access to `self.stream` must be non-shared.
|
||||||
|
self.stream.written_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -37,8 +37,10 @@ pub(crate) struct Stream {
|
|||||||
trait Inner: Read + Write {
|
trait Inner: Read + Write {
|
||||||
fn is_poolable(&self) -> bool;
|
fn is_poolable(&self) -> bool;
|
||||||
fn socket(&self) -> Option<&TcpStream>;
|
fn socket(&self) -> Option<&TcpStream>;
|
||||||
fn as_write_vec(&self) -> &[u8] {
|
|
||||||
panic!("as_write_vec on non Test stream");
|
/// The bytes written to the stream as a Vec<u8>. This is used for tests only.
|
||||||
|
fn written_bytes(&self) -> Vec<u8> {
|
||||||
|
panic!("written_bytes on non Test stream");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,8 +78,10 @@ impl Inner for TestStream {
|
|||||||
fn socket(&self) -> Option<&TcpStream> {
|
fn socket(&self) -> Option<&TcpStream> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn as_write_vec(&self) -> &[u8] {
|
|
||||||
&self.1
|
/// For tests only
|
||||||
|
fn written_bytes(&self) -> Vec<u8> {
|
||||||
|
self.1.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,8 +278,8 @@ impl Stream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn as_write_vec(&self) -> &[u8] {
|
pub fn written_bytes(&self) -> Vec<u8> {
|
||||||
self.inner.get_ref().as_write_vec()
|
self.inner.get_ref().written_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ fn content_length_on_str() {
|
|||||||
let resp = post("test://host/content_length_on_str")
|
let resp = post("test://host/content_length_on_str")
|
||||||
.send_string("Hello World!!!")
|
.send_string("Hello World!!!")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("\r\nContent-Length: 14\r\n"));
|
assert!(s.contains("\r\nContent-Length: 14\r\n"));
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ fn user_set_content_length_on_str() {
|
|||||||
.set("Content-Length", "12345")
|
.set("Content-Length", "12345")
|
||||||
.send_string("Hello World!!!")
|
.send_string("Hello World!!!")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("\r\nContent-Length: 12345\r\n"));
|
assert!(s.contains("\r\nContent-Length: 12345\r\n"));
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ fn content_length_on_json() {
|
|||||||
let resp = post("test://host/content_length_on_json")
|
let resp = post("test://host/content_length_on_json")
|
||||||
.send_json(serde_json::Value::Object(json))
|
.send_json(serde_json::Value::Object(json))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("\r\nContent-Length: 20\r\n"));
|
assert!(s.contains("\r\nContent-Length: 20\r\n"));
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ fn content_length_and_chunked() {
|
|||||||
.set("Transfer-Encoding", "chunked")
|
.set("Transfer-Encoding", "chunked")
|
||||||
.send_string("Hello World!!!")
|
.send_string("Hello World!!!")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("Transfer-Encoding: chunked\r\n"));
|
assert!(s.contains("Transfer-Encoding: chunked\r\n"));
|
||||||
assert!(!s.contains("\r\nContent-Length:\r\n"));
|
assert!(!s.contains("\r\nContent-Length:\r\n"));
|
||||||
@@ -73,7 +73,7 @@ fn str_with_encoding() {
|
|||||||
.set("Content-Type", "text/plain; charset=iso-8859-1")
|
.set("Content-Type", "text/plain; charset=iso-8859-1")
|
||||||
.send_string("Hällo Wörld!!!")
|
.send_string("Hällo Wörld!!!")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&vec[vec.len() - 14..],
|
&vec[vec.len() - 14..],
|
||||||
//H ä l l o _ W ö r l d ! ! !
|
//H ä l l o _ W ö r l d ! ! !
|
||||||
@@ -95,7 +95,7 @@ fn content_type_on_json() {
|
|||||||
let resp = post("test://host/content_type_on_json")
|
let resp = post("test://host/content_type_on_json")
|
||||||
.send_json(serde_json::Value::Object(json))
|
.send_json(serde_json::Value::Object(json))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("\r\nContent-Type: application/json\r\n"));
|
assert!(s.contains("\r\nContent-Type: application/json\r\n"));
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ fn content_type_not_overriden_on_json() {
|
|||||||
.set("content-type", "text/plain")
|
.set("content-type", "text/plain")
|
||||||
.send_json(serde_json::Value::Object(json))
|
.send_json(serde_json::Value::Object(json))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("\r\ncontent-type: text/plain\r\n"));
|
assert!(s.contains("\r\ncontent-type: text/plain\r\n"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ fn no_query_string() {
|
|||||||
test::make_response(200, "OK", vec![], vec![])
|
test::make_response(200, "OK", vec![], vec![])
|
||||||
});
|
});
|
||||||
let resp = get("test://host/no_query_string").call().unwrap();
|
let resp = get("test://host/no_query_string").call().unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("GET /no_query_string HTTP/1.1"))
|
assert!(s.contains("GET /no_query_string HTTP/1.1"))
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ fn escaped_query_string() {
|
|||||||
.query("baz", "yo lo")
|
.query("baz", "yo lo")
|
||||||
.call()
|
.call()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(
|
assert!(
|
||||||
s.contains("GET /escaped_query_string?foo=bar&baz=yo+lo HTTP/1.1"),
|
s.contains("GET /escaped_query_string?foo=bar&baz=yo+lo HTTP/1.1"),
|
||||||
@@ -38,7 +38,7 @@ fn query_in_path() {
|
|||||||
test::make_response(200, "OK", vec![], vec![])
|
test::make_response(200, "OK", vec![], vec![])
|
||||||
});
|
});
|
||||||
let resp = get("test://host/query_in_path?foo=bar").call().unwrap();
|
let resp = get("test://host/query_in_path?foo=bar").call().unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("GET /query_in_path?foo=bar HTTP/1.1"))
|
assert!(s.contains("GET /query_in_path?foo=bar HTTP/1.1"))
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ fn query_in_path_and_req() {
|
|||||||
.query("baz", "1 2 3")
|
.query("baz", "1 2 3")
|
||||||
.call()
|
.call()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("GET /query_in_path_and_req?foo=bar&baz=1+2+3 HTTP/1.1"))
|
assert!(s.contains("GET /query_in_path_and_req?foo=bar&baz=1+2+3 HTTP/1.1"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ fn escape_path() {
|
|||||||
test::make_response(200, "OK", vec![], vec![])
|
test::make_response(200, "OK", vec![], vec![])
|
||||||
});
|
});
|
||||||
let resp = get("test://host/escape_path here").call().unwrap();
|
let resp = get("test://host/escape_path here").call().unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("GET /escape_path%20here HTTP/1.1"))
|
assert!(s.contains("GET /escape_path%20here HTTP/1.1"))
|
||||||
}
|
}
|
||||||
@@ -198,7 +198,7 @@ pub fn host_no_port() {
|
|||||||
test::make_response(200, "OK", vec![], vec![])
|
test::make_response(200, "OK", vec![], vec![])
|
||||||
});
|
});
|
||||||
let resp = get("test://myhost/host_no_port").call().unwrap();
|
let resp = get("test://myhost/host_no_port").call().unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("\r\nHost: myhost\r\n"));
|
assert!(s.contains("\r\nHost: myhost\r\n"));
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ pub fn host_with_port() {
|
|||||||
test::make_response(200, "OK", vec![], vec![])
|
test::make_response(200, "OK", vec![], vec![])
|
||||||
});
|
});
|
||||||
let resp = get("test://myhost:234/host_with_port").call().unwrap();
|
let resp = get("test://myhost:234/host_with_port").call().unwrap();
|
||||||
let vec = resp.as_write_vec();
|
let vec = resp.into_written_bytes();
|
||||||
let s = String::from_utf8_lossy(&vec);
|
let s = String::from_utf8_lossy(&vec);
|
||||||
assert!(s.contains("\r\nHost: myhost:234\r\n"));
|
assert!(s.contains("\r\nHost: myhost:234\r\n"));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user