Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c458cb6

Browse files
Merge pull request #1614 from kraxel/http
add ip4config2 + http protocols support
2 parents 16f248f + e782459 commit c458cb6

File tree

8 files changed

+672
-0
lines changed

8 files changed

+672
-0
lines changed

‎uefi-test-runner/https/README.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
https ca cert database in efi signature list format
2+
3+
Copied over from centos stream 9 where this is available as
4+
/etc/pki/ca-trust/extracted/edk2/cacerts.bin
5+
6+
It's the Mozilla Foundation CA certificate list, shipped in
7+
ca-certificates.rpm, licensed as "MIT AND GPL-2.0-or-later".

‎uefi-test-runner/https/cacerts.bin‎

160 KB
Binary file not shown.
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
use alloc::vec::Vec;
4+
5+
use uefi::proto::device_path::text::{AllowShortcuts, DisplayOnly};
6+
use uefi::proto::device_path::DevicePath;
7+
use uefi::proto::network::http::{HttpBinding, HttpHelper};
8+
use uefi::proto::network::ip4config2::Ip4Config2;
9+
use uefi::{boot, Handle};
10+
11+
use uefi_raw::protocol::network::http::HttpStatusCode;
12+
13+
pub fn print_handle_devpath(prefix: &str, handle: &Handle) {
14+
let Ok(dp) = boot::open_protocol_exclusive::<DevicePath>(*handle) else {
15+
info!("{}no device path for handle", prefix);
16+
return;
17+
};
18+
if let Ok(string) = dp.to_string(DisplayOnly(true), AllowShortcuts(true)) {
19+
info!("{}{}", prefix, string);
20+
}
21+
}
22+
23+
fn fetch_http(handle: Handle, url: &str) -> Option<Vec<u8>> {
24+
info!("http: fetching {} ...", url);
25+
26+
let http_res = HttpHelper::new(handle);
27+
if let Err(e) = http_res {
28+
error!("http new: {}", e);
29+
return None;
30+
}
31+
let mut http = http_res.unwrap();
32+
33+
let res = http.configure();
34+
if let Err(e) = res {
35+
error!("http configure: {}", e);
36+
return None;
37+
}
38+
39+
let res = http.request_get(url);
40+
if let Err(e) = res {
41+
error!("http request: {}", e);
42+
return None;
43+
}
44+
45+
let res = http.response_first(true);
46+
if let Err(e) = res {
47+
error!("http response: {}", e);
48+
return None;
49+
}
50+
51+
let rsp = res.unwrap();
52+
if rsp.status != HttpStatusCode::STATUS_200_OK {
53+
error!("http server error: {:?}", rsp.status);
54+
return None;
55+
}
56+
let Some(cl_hdr) = rsp.headers.iter().find(|h| h.0 == "content-length") else {
57+
// The only way to figure when your transfer is complete is to
58+
// get the content length header and count the bytes you got.
59+
// So missing header -> fatal error.
60+
error!("no content length");
61+
return None;
62+
};
63+
let Ok(cl) = cl_hdr.1.parse::<usize>() else {
64+
error!("parse content length ({})", cl_hdr.1);
65+
return None;
66+
};
67+
info!("http: size is {} bytes", cl);
68+
69+
let mut data = rsp.body;
70+
loop {
71+
if data.len() >= cl {
72+
break;
73+
}
74+
75+
let res = http.response_more();
76+
if let Err(e) = res {
77+
error!("read response: {}", e);
78+
return None;
79+
}
80+
81+
let mut buf = res.unwrap();
82+
data.append(&mut buf);
83+
}
84+
85+
Some(data)
86+
}
87+
88+
pub fn test() {
89+
info!("Testing ip4 config2 + http protocols");
90+
91+
let handles = boot::locate_handle_buffer(boot::SearchType::from_proto::<HttpBinding>())
92+
.expect("get nic handles");
93+
94+
for h in handles.as_ref() {
95+
print_handle_devpath("nic: ", h);
96+
97+
info!("Bring up interface (ip4 config2 protocol)");
98+
let mut ip4 = Ip4Config2::new(*h).expect("open ip4 config2 protocol");
99+
ip4.ifup(true).expect("acquire ipv4 address");
100+
101+
// hard to find web sites which still allow plain http these days ...
102+
info!("Testing HTTP");
103+
fetch_http(*h, "http://example.com/").expect("http request failed");
104+
105+
// FYI: not all firmware builds support modern tls versions.
106+
// request() -> ABORTED typically is a tls handshake error.
107+
// check the firmware log for details.
108+
info!("Testing HTTPS");
109+
fetch_http(
110+
*h,
111+
"https://raw.githubusercontent.com/rust-osdev/uefi-rs/refs/heads/main/Cargo.toml",
112+
)
113+
.expect("https request failed");
114+
115+
info!("PASSED");
116+
}
117+
}

‎uefi-test-runner/src/proto/network/mod.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
pub fn test() {
44
info!("Testing Network protocols");
55

6+
http::test();
67
pxe::test();
78
snp::test();
89
}
910

11+
mod http;
1012
mod pxe;
1113
mod snp;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /