1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use poem::{error::StaticFileError, Body};
use crate::{
payload::{Binary, PlainText},
ApiResponse,
};
/// A static file response.
#[cfg_attr(docsrs, doc(cfg(feature = "static-files")))]
#[derive(ApiResponse)]
#[oai(internal)]
pub enum StaticFileResponse {
/// Ok
#[oai(status = 200)]
Ok(
Binary<Body>,
/// The ETag (or entity tag) HTTP response header is an identifier for a
/// specific version of a resource. It lets caches be more efficient and
/// save bandwidth, as a web server does not need to resend a full
/// response if the content was not changed. Additionally, etags help to
/// prevent simultaneous updates of a resource from overwriting each
/// other ("mid-air collisions").
///
/// Reference: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag>
#[oai(header = "etag")]
Option<String>,
/// The Last-Modified response HTTP header contains a date and time when
/// the origin server believes the resource was last modified. It is
/// used as a validator to determine if the resource is the same as the
/// previously stored one. Less accurate than an ETag header, it is a
/// fallback mechanism. Conditional requests containing
/// If-Modified-Since or If-Unmodified-Since headers make use of this
/// field.
///
/// Reference: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified>
#[oai(header = "last-modified")]
Option<String>,
/// The Content-Type representation header is used to indicate the
/// original media type of the resource (prior to any content encoding
/// applied for sending).
///
/// Reference: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type>
#[oai(header = "content-type")]
Option<String>,
),
/// Not modified
///
/// Reference: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304>
#[oai(status = 304)]
NotModified,
/// Bad request
///
/// Reference: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400>
#[oai(status = 400)]
BadRequest,
/// Resource was not found
#[oai(status = 404)]
NotFound,
/// Precondition failed
///
/// Reference: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412>
#[oai(status = 412)]
PreconditionFailed,
/// Range not satisfiable
///
/// Reference: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416>
#[oai(status = 416)]
RangeNotSatisfiable(
/// The Content-Range response HTTP header indicates where in a full
/// body message a partial message belongs.
///
/// Reference: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range>
#[oai(header = "content-range")]
String,
),
/// Internal server error
#[oai(status = 500)]
InternalServerError(PlainText<String>),
}
impl StaticFileResponse {
/// Create a static file response.
pub fn new(res: Result<poem::web::StaticFileResponse, StaticFileError>) -> Self {
res.into()
}
}
impl From<Result<poem::web::StaticFileResponse, StaticFileError>> for StaticFileResponse {
fn from(res: Result<poem::web::StaticFileResponse, StaticFileError>) -> Self {
match res {
Ok(poem::web::StaticFileResponse::Ok {
body,
etag,
last_modified,
content_type,
..
}) => StaticFileResponse::Ok(Binary(body), etag, last_modified, content_type),
Ok(poem::web::StaticFileResponse::NotModified) => StaticFileResponse::NotModified,
Err(
StaticFileError::MethodNotAllowed(_)
| StaticFileError::NotFound
| StaticFileError::InvalidPath
| StaticFileError::Forbidden(_),
) => StaticFileResponse::NotFound,
Err(StaticFileError::PreconditionFailed) => StaticFileResponse::PreconditionFailed,
Err(StaticFileError::RangeNotSatisfiable { size }) => {
StaticFileResponse::RangeNotSatisfiable(format!("*/{}", size))
}
Err(StaticFileError::Io(_)) => StaticFileResponse::BadRequest,
}
}
}