Skip to content

Commit 0a58eb1

Browse files
georgepisaltudianpopa
authored andcommitted
added support for Deprecation header
This commit adds support for the `Deprecation` HTTP header based on https://tools.ietf.org/id/draft-dalal-deprecation-header-03.html . Users can set this header in a `Response` to send a "Deprecation: true" header field back to the requester, signaling that the resource accessed has been deprecated. Signed-off-by: George Pisaltu <[email protected]>
1 parent 36e59a0 commit 0a58eb1

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

coverage_config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"coverage_score": 92.9, "exclude_path": "", "crate_features": ""}
1+
{"coverage_score": 93.1, "exclude_path": "", "crate_features": ""}

src/response.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ impl StatusLine {
8888
pub struct ResponseHeaders {
8989
content_length: i32,
9090
content_type: MediaType,
91+
deprecation: bool,
9192
server: String,
9293
allow: Vec<Method>,
9394
accept_encoding: bool,
@@ -98,6 +99,7 @@ impl Default for ResponseHeaders {
9899
Self {
99100
content_length: Default::default(),
100101
content_type: Default::default(),
102+
deprecation: false,
101103
server: String::from("Firecracker API"),
102104
allow: Vec::new(),
103105
accept_encoding: false,
@@ -126,6 +128,16 @@ impl ResponseHeaders {
126128
buf.write_all(&[CR, LF])
127129
}
128130

131+
// The logic pertaining to `Deprecation` header writing.
132+
fn write_deprecation_header<T: Write>(&self, buf: &mut T) -> Result<(), WriteError> {
133+
if !self.deprecation {
134+
return Ok(());
135+
}
136+
137+
buf.write_all(b"Deprecation: true")?;
138+
buf.write_all(&[CR, LF])
139+
}
140+
129141
/// Writes the headers to `buf` using the HTTP specification.
130142
pub fn write_all<T: Write>(&self, buf: &mut T) -> Result<(), WriteError> {
131143
buf.write_all(Header::Server.raw())?;
@@ -137,6 +149,7 @@ impl ResponseHeaders {
137149
buf.write_all(&[CR, LF])?;
138150

139151
self.write_allow_header(buf)?;
152+
self.write_deprecation_header(buf)?;
140153

141154
if self.content_length != 0 {
142155
buf.write_all(Header::ContentType.raw())?;
@@ -175,6 +188,13 @@ impl ResponseHeaders {
175188
self.content_type = content_type;
176189
}
177190

191+
/// Sets the `Deprecation` header to be written in the HTTP response.
192+
/// https://tools.ietf.org/id/draft-dalal-deprecation-header-03.html
193+
#[allow(unused)]
194+
pub fn set_deprecation(&mut self) {
195+
self.deprecation = true;
196+
}
197+
178198
/// Sets the encoding type to be written in the HTTP response.
179199
#[allow(unused)]
180200
pub fn set_encoding(&mut self) {
@@ -219,6 +239,11 @@ impl Response {
219239
self.headers.set_content_type(content_type);
220240
}
221241

242+
/// Marks the `Response` as deprecated.
243+
pub fn set_deprecation(&mut self) {
244+
self.headers.set_deprecation();
245+
}
246+
222247
/// Updates the encoding type of `Response`.
223248
pub fn set_encoding(&mut self) {
224249
self.headers.set_encoding();
@@ -279,6 +304,11 @@ impl Response {
279304
self.headers.content_type
280305
}
281306

307+
/// Returns the deprecation status of the response.
308+
pub fn deprecation(&self) -> bool {
309+
self.headers.deprecation
310+
}
311+
282312
/// Returns the HTTP Version of the response.
283313
pub fn http_version(&self) -> Version {
284314
self.status_line.http_version
@@ -392,6 +422,54 @@ mod tests {
392422
assert_eq!(response.allow(), vec![Method::Get, Method::Put]);
393423
}
394424

425+
#[test]
426+
fn test_deprecation() {
427+
// Test a deprecated response with body.
428+
let mut response = Response::new(Version::Http10, StatusCode::OK);
429+
let body = "This is a test";
430+
response.set_body(Body::new(body));
431+
response.set_content_type(MediaType::PlainText);
432+
response.set_encoding();
433+
response.set_deprecation();
434+
435+
assert_eq!(response.status(), StatusCode::OK);
436+
assert_eq!(response.body().unwrap(), Body::new(body));
437+
assert_eq!(response.http_version(), Version::Http10);
438+
assert_eq!(response.content_length(), 14);
439+
assert_eq!(response.content_type(), MediaType::PlainText);
440+
assert!(response.deprecation());
441+
442+
let expected_response: &'static [u8] = b"HTTP/1.0 200 \r\n\
443+
Server: Firecracker API\r\n\
444+
Connection: keep-alive\r\n\
445+
Deprecation: true\r\n\
446+
Content-Type: text/plain\r\n\
447+
Content-Length: 14\r\n\
448+
Accept-Encoding: identity\r\n\r\n\
449+
This is a test";
450+
451+
let mut response_buf: [u8; 172] = [0; 172];
452+
assert!(response.write_all(&mut response_buf.as_mut()).is_ok());
453+
assert_eq!(response_buf.as_ref(), expected_response);
454+
455+
// Test a deprecated response without a body.
456+
let mut response = Response::new(Version::Http10, StatusCode::NoContent);
457+
response.set_deprecation();
458+
459+
assert_eq!(response.status(), StatusCode::NoContent);
460+
assert_eq!(response.http_version(), Version::Http10);
461+
assert!(response.deprecation());
462+
463+
let expected_response: &'static [u8] = b"HTTP/1.0 204 \r\n\
464+
Server: Firecracker API\r\n\
465+
Connection: keep-alive\r\n\
466+
Deprecation: true\r\n\r\n";
467+
468+
let mut response_buf: [u8; 85] = [0; 85];
469+
assert!(response.write_all(&mut response_buf.as_mut()).is_ok());
470+
assert_eq!(response_buf.as_ref(), expected_response);
471+
}
472+
395473
#[test]
396474
fn test_equal() {
397475
let response = Response::new(Version::Http10, StatusCode::MethodNotAllowed);

0 commit comments

Comments
 (0)