Skip to content

Commit 530b36b

Browse files
Iulian Barbuacatangiu
authored andcommitted
micro_http: add support for accept headers
Signed-off-by: Iulian Barbu <[email protected]> Signed-off-by: YUAN LYU <[email protected]>
1 parent 4a25226 commit 530b36b

File tree

1 file changed

+65
-8
lines changed

1 file changed

+65
-8
lines changed

src/common/headers.rs

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub enum Header {
1818
TransferEncoding,
1919
/// Header `Server`.
2020
Server,
21+
/// Header `Accept`
22+
Accept,
2123
}
2224

2325
impl Header {
@@ -29,6 +31,7 @@ impl Header {
2931
Self::Expect => b"Expect",
3032
Self::TransferEncoding => b"Transfer-Encoding",
3133
Self::Server => b"Server",
34+
Self::Accept => b"Accept",
3235
}
3336
}
3437

@@ -47,6 +50,7 @@ impl Header {
4750
"expect" => Ok(Self::Expect),
4851
"transfer-encoding" => Ok(Self::TransferEncoding),
4952
"server" => Ok(Self::Server),
53+
"accept" => Ok(Self::Accept),
5054
_ => Err(RequestError::InvalidHeader),
5155
}
5256
} else {
@@ -80,6 +84,9 @@ pub struct Headers {
8084
/// server must support it. It is useful only when receiving the body of the request and should
8185
/// be known immediately after parsing the headers.
8286
chunked: bool,
87+
/// `Accept` header might be used by HTTP clients to enforce server responses with content
88+
/// formatted in a specific way.
89+
accept: MediaType,
8390
}
8491

8592
impl Default for Headers {
@@ -89,6 +96,9 @@ impl Default for Headers {
8996
content_length: Default::default(),
9097
expect: Default::default(),
9198
chunked: Default::default(),
99+
// The default `Accept` media type is plain text. This is inclusive enough
100+
// for structured and unstructured text.
101+
accept: MediaType::PlainText,
92102
}
93103
}
94104
}
@@ -137,6 +147,13 @@ impl Headers {
137147
Err(_) => Err(RequestError::UnsupportedHeader),
138148
}
139149
}
150+
Header::Accept => match MediaType::try_from(entry[1].trim().as_bytes()) {
151+
Ok(accept_type) => {
152+
self.accept = accept_type;
153+
Ok(())
154+
}
155+
Err(_) => Err(RequestError::UnsupportedHeader),
156+
},
140157
Header::TransferEncoding => match entry[1].trim() {
141158
"chunked" => {
142159
self.chunked = true;
@@ -179,6 +196,11 @@ impl Headers {
179196
self.expect
180197
}
181198

199+
/// Returns the `Accept` header `MediaType`.
200+
pub fn accept(&self) -> MediaType {
201+
self.accept
202+
}
203+
182204
/// Parses a byte slice into a Headers structure for a HTTP request.
183205
///
184206
/// The byte slice is expected to have the following format: </br>
@@ -219,6 +241,11 @@ impl Headers {
219241
}
220242
Err(RequestError::InvalidRequest)
221243
}
244+
245+
/// Accept header setter.
246+
pub fn set_accept(&mut self, media_type: MediaType) {
247+
self.accept = media_type;
248+
}
222249
}
223250

224251
/// Wrapper over supported Media Types.
@@ -296,6 +323,7 @@ mod tests {
296323
content_length,
297324
expect,
298325
chunked,
326+
accept: MediaType::PlainText,
299327
}
300328
}
301329
}
@@ -343,14 +371,27 @@ mod tests {
343371
#[test]
344372
fn test_try_from_headers() {
345373
// Valid headers.
346-
assert_eq!(
347-
Headers::try_from(
348-
b"Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r\nContent-Length: 55\r\n\r\n"
349-
)
350-
.unwrap()
351-
.content_length,
352-
55
353-
);
374+
let headers = Headers::try_from(
375+
b"Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r\nAccept: application/json\r\nContent-Length: 55\r\n\r\n"
376+
)
377+
.unwrap();
378+
assert_eq!(headers.content_length, 55);
379+
assert_eq!(headers.accept, MediaType::ApplicationJson);
380+
381+
// Valid headers.
382+
let headers = Headers::try_from(
383+
b"Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r\nAccept: text/plain\r\nContent-Length: 49\r\n\r\n"
384+
)
385+
.unwrap();
386+
assert_eq!(headers.content_length, 49);
387+
assert_eq!(headers.accept, MediaType::PlainText);
388+
389+
// Valid headers.
390+
let headers = Headers::try_from(
391+
b"Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r\nContent-Length: 29\r\n\r\n",
392+
)
393+
.unwrap();
394+
assert_eq!(headers.content_length, 29);
354395

355396
// Valid headers.
356397
assert_eq!(
@@ -425,6 +466,19 @@ mod tests {
425466
assert!(header
426467
.parse_header_line(b"Content-Type: application/json")
427468
.is_ok());
469+
470+
// Test valid accept media type.
471+
assert!(header
472+
.parse_header_line(b"Accept: application/json")
473+
.is_ok());
474+
assert!(header.accept == MediaType::ApplicationJson);
475+
assert!(header.parse_header_line(b"Accept: text/plain").is_ok());
476+
assert!(header.accept == MediaType::PlainText);
477+
478+
// Test invalid accept media type.
479+
assert!(header
480+
.parse_header_line(b"Accept: application/json-patch")
481+
.is_err());
428482
}
429483

430484
#[test]
@@ -451,5 +505,8 @@ mod tests {
451505

452506
let header = Header::try_from(b"content-length").unwrap();
453507
assert_eq!(header.raw(), b"Content-Length");
508+
509+
let header = Header::try_from(b"Accept").unwrap();
510+
assert_eq!(header.raw(), b"Accept");
454511
}
455512
}

0 commit comments

Comments
 (0)