uefi_raw/protocol/network/
http.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use crate::{
4    Boolean, Char8, Char16, Event, Guid, Ipv4Address, Ipv6Address, Status, guid, newtype_enum,
5};
6use core::ffi::c_void;
7use core::fmt::{self, Debug, Formatter};
8use core::ptr;
9
10#[derive(Debug, Default)]
11#[repr(C)]
12pub struct HttpConfigData {
13    pub http_version: HttpVersion,
14    pub time_out_millisec: u32,
15    pub local_addr_is_ipv6: Boolean,
16    pub access_point: HttpAccessPoint,
17}
18
19newtype_enum! {
20    #[derive(Default)]
21    pub enum HttpVersion: i32 => {
22        HTTP_VERSION_10 = 0,
23        HTTP_VERSION_11 = 1,
24        HTTP_VERSION_UNSUPPORTED = 2,
25    }
26}
27
28#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
29#[repr(C)]
30pub struct HttpV4AccessPoint {
31    pub use_default_addr: Boolean,
32    pub local_address: Ipv4Address,
33    pub local_subnet: Ipv4Address,
34    pub local_port: u16,
35}
36
37#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
38#[repr(C)]
39pub struct HttpV6AccessPoint {
40    pub local_address: Ipv6Address,
41    pub local_port: u16,
42}
43
44#[repr(C)]
45pub union HttpAccessPoint {
46    pub ipv4_node: *const HttpV4AccessPoint,
47    pub ipv6_node: *const HttpV6AccessPoint,
48}
49
50impl Debug for HttpAccessPoint {
51    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
52        // This is a union type, so we can't access the internal data.
53        f.debug_struct("HttpAccessPoint").finish()
54    }
55}
56
57impl Default for HttpAccessPoint {
58    fn default() -> Self {
59        Self {
60            ipv4_node: ptr::null(),
61        }
62    }
63}
64
65#[derive(Debug)]
66#[repr(C)]
67pub struct HttpToken {
68    pub event: Event,
69    pub status: Status,
70    pub message: *mut HttpMessage,
71}
72
73impl Default for HttpToken {
74    fn default() -> Self {
75        Self {
76            event: ptr::null_mut(),
77            status: Status::SUCCESS,
78            message: ptr::null_mut(),
79        }
80    }
81}
82
83#[derive(Debug)]
84#[repr(C)]
85pub struct HttpMessage {
86    pub data: HttpRequestOrResponse,
87    pub header_count: usize,
88    pub header: *mut HttpHeader,
89    pub body_length: usize,
90    pub body: *mut c_void,
91}
92
93impl Default for HttpMessage {
94    fn default() -> Self {
95        Self {
96            data: HttpRequestOrResponse::default(),
97            header_count: 0,
98            header: ptr::null_mut(),
99            body_length: 0,
100            body: ptr::null_mut(),
101        }
102    }
103}
104
105#[derive(Debug)]
106#[repr(C)]
107pub struct HttpRequestData {
108    pub method: HttpMethod,
109    pub url: *const Char16,
110}
111
112impl Default for HttpRequestData {
113    fn default() -> Self {
114        Self {
115            method: HttpMethod::default(),
116            url: ptr::null(),
117        }
118    }
119}
120
121newtype_enum! {
122    #[derive(Default)]
123    pub enum HttpMethod: i32 => {
124        GET     = 0,
125        POST    = 1,
126        PATCH   = 2,
127        OPTIONS = 3,
128        CONNECT = 4,
129        HEAD    = 5,
130        PUT     = 6,
131        DELETE  = 7,
132        TRACE   = 8,
133        MAX     = 9,
134    }
135}
136
137#[derive(Debug, Default)]
138#[repr(C)]
139pub struct HttpResponseData {
140    pub status_code: HttpStatusCode,
141}
142
143#[repr(C)]
144pub union HttpRequestOrResponse {
145    pub request: *const HttpRequestData,
146    pub response: *const HttpResponseData,
147}
148
149impl Debug for HttpRequestOrResponse {
150    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
151        // This is a union type, so we can't access the internal data.
152        f.debug_struct("RequestOrResponse").finish()
153    }
154}
155
156impl Default for HttpRequestOrResponse {
157    fn default() -> Self {
158        Self {
159            request: ptr::null(),
160        }
161    }
162}
163
164#[derive(Clone, Debug)]
165#[repr(C)]
166pub struct HttpHeader {
167    pub field_name: *const Char8,
168    pub field_value: *const Char8,
169}
170
171impl Default for HttpHeader {
172    fn default() -> Self {
173        Self {
174            field_name: ptr::null(),
175            field_value: ptr::null(),
176        }
177    }
178}
179
180newtype_enum! {
181    #[derive(Default)]
182    pub enum HttpStatusCode: i32 => {
183        STATUS_UNSUPPORTED = 0,
184        STATUS_100_CONTINUE = 1,
185        STATUS_101_SWITCHING_PROTOCOLS = 2,
186        STATUS_200_OK = 3,
187        STATUS_201_CREATED = 4,
188        STATUS_202_ACCEPTED = 5,
189        STATUS_203_NON_AUTHORITATIVE_INFORMATION = 6,
190        STATUS_204_NO_CONTENT = 7,
191        STATUS_205_RESET_CONTENT = 8,
192        STATUS_206_PARTIAL_CONTENT = 9,
193        STATUS_300_MULTIPLE_CHOICES = 10,
194        STATUS_301_MOVED_PERMANENTLY = 11,
195        STATUS_302_FOUND = 12,
196        STATUS_303_SEE_OTHER = 13,
197        STATUS_304_NOT_MODIFIED = 14,
198        STATUS_305_USE_PROXY = 15,
199        STATUS_307_TEMPORARY_REDIRECT = 16,
200        STATUS_400_BAD_REQUEST = 17,
201        STATUS_401_UNAUTHORIZED = 18,
202        STATUS_402_PAYMENT_REQUIRED = 19,
203        STATUS_403_FORBIDDEN = 20,
204        STATUS_404_NOT_FOUND = 21,
205        STATUS_405_METHOD_NOT_ALLOWED = 22,
206        STATUS_406_NOT_ACCEPTABLE = 23,
207        STATUS_407_PROXY_AUTHENTICATION_REQUIRED = 24,
208        STATUS_408_REQUEST_TIME_OUT = 25,
209        STATUS_409_CONFLICT = 26,
210        STATUS_410_GONE = 27,
211        STATUS_411_LENGTH_REQUIRED = 28,
212        STATUS_412_PRECONDITION_FAILED = 29,
213        STATUS_413_REQUEST_ENTITY_TOO_LARGE = 30,
214        STATUS_414_REQUEST_URI_TOO_LARGE = 31,
215        STATUS_415_UNSUPPORTED_MEDIA_TYPE = 32,
216        STATUS_416_REQUESTED_RANGE_NOT_SATISFIED = 33,
217        STATUS_417_EXPECTATION_FAILED = 34,
218        STATUS_500_INTERNAL_SERVER_ERROR = 35,
219        STATUS_501_NOT_IMPLEMENTED = 36,
220        STATUS_502_BAD_GATEWAY = 37,
221        STATUS_503_SERVICE_UNAVAILABLE = 38,
222        STATUS_504_GATEWAY_TIME_OUT = 39,
223        STATUS_505_VERSION_NOT_SUPPORTED = 40,
224        STATUS_308_PERMANENT_REDIRECT = 41,
225    }
226}
227
228#[derive(Debug)]
229#[repr(C)]
230pub struct HttpProtocol {
231    pub get_mode_data:
232        unsafe extern "efiapi" fn(this: *const Self, config_data: *mut HttpConfigData) -> Status,
233    pub configure:
234        unsafe extern "efiapi" fn(this: *mut Self, config_data: *const HttpConfigData) -> Status,
235    pub request: unsafe extern "efiapi" fn(this: *mut Self, token: *mut HttpToken) -> Status,
236    pub cancel: unsafe extern "efiapi" fn(this: *mut Self, token: *mut HttpToken) -> Status,
237    pub response: unsafe extern "efiapi" fn(this: *mut Self, token: *mut HttpToken) -> Status,
238    pub poll: unsafe extern "efiapi" fn(this: *mut Self) -> Status,
239}
240
241impl HttpProtocol {
242    pub const GUID: Guid = guid!("7a59b29b-910b-4171-8242-a85a0df25b5b");
243    pub const SERVICE_BINDING_GUID: Guid = guid!("bdc8e6af-d9bc-4379-a72a-e0c4e75dae1c");
244}