diff options
author | Shane Utt <[email protected]> | 2024-02-28 15:39:59 +0000 |
---|---|---|
committer | Edward Wang <[email protected]> | 2024-03-15 14:37:56 -0700 |
commit | 8963575ed23533daaed67ccbe68bdd08051bef88 (patch) | |
tree | 7002333e36e0d98137294ddf25c7168b893753d5 | |
parent | 20fd391f3e78c9349149f11fae94da9e4657478e (diff) | |
download | pingora-8963575ed23533daaed67ccbe68bdd08051bef88.tar.gz pingora-8963575ed23533daaed67ccbe68bdd08051bef88.zip |
chore: resolve TODOs in the pingora client example
Signed-off-by: Shane Utt <[email protected]>
Replicated-from: https://github.com/cloudflare/pingora/pull/9
Includes-commit: 5833556e5f8d9ccb346ef586cb1b5f51add64357
-rw-r--r-- | .bleep | 2 | ||||
-rw-r--r-- | pingora/Cargo.toml | 1 | ||||
-rw-r--r-- | pingora/examples/client.rs | 68 |
3 files changed, 52 insertions, 19 deletions
@@ -1 +1 @@ -c16c9e8bfd9334b77a6a7c1123954f41037c06c3
\ No newline at end of file +c3ec53f03ed27ce7ce90ec76e9ae67bab2097fd3
\ No newline at end of file diff --git a/pingora/Cargo.toml b/pingora/Cargo.toml index c269199..9d6aea3 100644 --- a/pingora/Cargo.toml +++ b/pingora/Cargo.toml @@ -40,6 +40,7 @@ log = { workspace = true } prometheus = "0.13" once_cell = { workspace = true } bytes = { workspace = true } +regex = "1" [features] default = ["openssl"] diff --git a/pingora/examples/client.rs b/pingora/examples/client.rs index c235dd1..9462aa2 100644 --- a/pingora/examples/client.rs +++ b/pingora/examples/client.rs @@ -12,29 +12,61 @@ // See the License for the specific language governing permissions and // limitations under the License. -use pingora::connectors::http::Connector; -use pingora::upstreams::peer::HttpPeer; +use pingora::{connectors::http::Connector, prelude::*}; use pingora_http::RequestHeader; +use regex::Regex; #[tokio::main] -async fn main() { +async fn main() -> Result<()> { let connector = Connector::new(None); - let mut peer = HttpPeer::new("1.1.1.1:443", true, "one.one.one.one".into()); + // create the HTTP session + let peer_addr = "1.1.1.1:443"; + let mut peer = HttpPeer::new(peer_addr, true, "one.one.one.one".into()); peer.options.set_http_version(2, 1); - let (mut http, _reused) = connector.get_http_session(&peer).await.unwrap(); - - let mut new_request = RequestHeader::build("GET", b"/", None).unwrap(); - new_request - .insert_header("Host", "one.one.one.one") - .unwrap(); - http.write_request_header(Box::new(new_request)) - .await - .unwrap(); + let (mut http, _reused) = connector.get_http_session(&peer).await?; + + // perform a GET request + let mut new_request = RequestHeader::build("GET", b"/", None)?; + new_request.insert_header("Host", "one.one.one.one")?; + http.write_request_header(Box::new(new_request)).await?; + // Servers usually don't respond until the full request body is read. - http.finish_request_body().await.unwrap(); - http.read_response_header().await.unwrap(); - println!("{:#?}", http.response_header().unwrap()); - // TODO: continue reading the body - // TODO: return the connection back to the `connector` (or discard it) + http.finish_request_body().await?; + http.read_response_header().await?; + + // display the headers from the response + if let Some(header) = http.response_header() { + println!("{header:#?}"); + } else { + return Error::e_explain(ErrorType::InvalidHTTPHeader, "No response header"); + }; + + // collect the response body + let mut response_body = String::new(); + while let Some(chunk) = http.read_response_body().await? { + response_body.push_str(&String::from_utf8_lossy(&chunk)); + } + + // verify that the response body is valid HTML by displaying the page <title> + let re = Regex::new(r"<title>(.*?)</title>") + .or_err(ErrorType::InternalError, "Failed to compile regex")?; + if let Some(title) = re + .captures(&response_body) + .and_then(|caps| caps.get(1).map(|match_| match_.as_str())) + { + println!("Page Title: {title}"); + } else { + return Error::e_explain( + ErrorType::new("InvalidHTML"), + "No <title> found in response body", + ); + } + + // gracefully release the connection + connector + .release_http_session(http, &peer, Some(std::time::Duration::from_secs(5))) + .await; + + Ok(()) } |