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