Merge pull request #47 from Orange-OpenSource/feature/expect-header

Add request Expect Header explicitly
This commit is contained in:
Fabrice Reix 2020-10-21 10:28:38 +02:00 committed by GitHub
commit 7b08c7bcfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 247 additions and 133 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@ jsonpath "$.nullable" equals null
} }
GET http://localhost:8000/assert-json/index GET http://localhost:8000/assert-json/index
HTTP/* 200 HTTP/1.0 200
[Captures] [Captures]
index: body index: body

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,8 @@
POST http://localhost:8000/expect
Expect: 100-continue
```data```
HTTP/1.0 200

View File

View File

@ -0,0 +1,11 @@
from tests import app
from flask import request
@app.route("/expect", methods=['POST'])
def expect():
assert request.headers['Expect'] == '100-continue'
s = request.data.decode("utf-8")
assert s == '''data'''
return ''

View File

@ -6,7 +6,7 @@ upload1: file,hello.txt;
upload2: file,hello.html; upload2: file,hello.html;
upload3: file,hello.txt; text/html upload3: file,hello.txt; text/html
HTTP/* 200 HTTP/1.0 200

View File

@ -6,6 +6,7 @@ from flask import request
def multipart_form_data(): def multipart_form_data():
assert request.form['key1'] == 'value1' assert request.form['key1'] == 'value1'
assert 'Expect' not in request.headers
upload1 = request.files['upload1'] upload1 = request.files['upload1']
assert upload1.filename == 'hello.txt' assert upload1.filename == 'hello.txt'

View File

@ -38,6 +38,7 @@ pub enum HttpError {
SSLCertificate, SSLCertificate,
InvalidUrl, InvalidUrl,
Timeout, Timeout,
StatuslineIsMissing,
Other { description: String, code: u32 }, Other { description: String, code: u32 },
} }
@ -152,7 +153,8 @@ impl Client {
}) })
.unwrap(); .unwrap();
let mut lines = vec![]; let mut status_lines = vec![];
let mut headers = vec![];
let mut body = Vec::<u8>::new(); let mut body = Vec::<u8>::new();
{ {
let mut transfer = self.handle.transfer(); let mut transfer = self.handle.transfer();
@ -165,7 +167,11 @@ impl Client {
transfer transfer
.header_function(|h| { .header_function(|h| {
if let Some(s) = decode_header(h) { if let Some(s) = decode_header(h) {
lines.push(s) if s.starts_with("HTTP/") {
status_lines.push(s);
} else {
headers.push(s)
}
} }
true true
}) })
@ -195,9 +201,11 @@ impl Client {
} }
let status = self.handle.response_code().unwrap(); let status = self.handle.response_code().unwrap();
let first_line = lines.remove(0); // remove the status line let version = match status_lines.last() {
let version = self.parse_response_version(first_line)?; None => return Err(HttpError::StatuslineIsMissing {}),
let headers = self.parse_response_headers(&mut lines); Some(status_line) => self.parse_response_version(status_line.clone())?,
};
let headers = self.parse_response_headers(&headers);
if let Some(url) = self.get_follow_location(headers.clone()) { if let Some(url) = self.get_follow_location(headers.clone()) {
let request = Request { let request = Request {
@ -289,6 +297,10 @@ impl Client {
} }
} }
if get_header_values(request.headers.clone(), "Expect".to_string()).is_empty() {
list.append("Expect:").unwrap(); // remove header Expect
}
// if request.form.is_empty() && request.multipart.is_empty() && request.body.is_empty() { // if request.form.is_empty() && request.multipart.is_empty() && request.body.is_empty() {
// list.append("Content-Length:").unwrap(); // list.append("Content-Length:").unwrap();
// } // }
@ -391,9 +403,8 @@ impl Client {
/// ///
/// parse headers from libcurl responses /// parse headers from libcurl responses
/// ///
fn parse_response_headers(&mut self, lines: &mut Vec<String>) -> Vec<Header> { fn parse_response_headers(&mut self, lines: &[String]) -> Vec<Header> {
let mut headers: Vec<Header> = vec![]; let mut headers: Vec<Header> = vec![];
lines.pop(); // remove the blank line between headers and body
for line in lines { for line in lines {
if let Some(header) = Header::parse(line.to_string()) { if let Some(header) = Header::parse(line.to_string()) {
headers.push(header); headers.push(header);

View File

@ -110,6 +110,10 @@ pub fn run(
HttpError::CouldNotParseResponse => RunnerError::CouldNotParseResponse, HttpError::CouldNotParseResponse => RunnerError::CouldNotParseResponse,
HttpError::SSLCertificate => RunnerError::SSLCertificate, HttpError::SSLCertificate => RunnerError::SSLCertificate,
HttpError::InvalidUrl => RunnerError::InvalidURL(http_request.url.clone()), HttpError::InvalidUrl => RunnerError::InvalidURL(http_request.url.clone()),
HttpError::StatuslineIsMissing => RunnerError::HttpConnection {
message: "status line is missing".to_string(),
url: http_request.url.clone(),
},
HttpError::Other { description, .. } => RunnerError::HttpConnection { HttpError::Other { description, .. } => RunnerError::HttpConnection {
message: description, message: description,
url: http_request.url.clone(), url: http_request.url.clone(),

View File

@ -427,6 +427,29 @@ fn test_post_bytes() {
// endregion // endregion
#[test]
fn test_expect() {
let mut client = default_client();
let request = Request {
method: Method::Post,
url: "http://localhost:8000/expect".to_string(),
headers: vec![Header {
name: "Expect".to_string(),
value: "100-continue".to_string(),
}],
querystring: vec![],
form: vec![],
multipart: vec![],
cookies: vec![],
body: b"data".to_vec(),
content_type: None,
};
let response = client.execute(&request, 0).unwrap();
assert_eq!(response.status, 200);
assert_eq!(response.version, Version::Http10);
assert!(response.body.is_empty());
}
// region error // region error
#[test] #[test]