aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorShane Utt <[email protected]>2024-02-28 15:39:59 +0000
committerEdward Wang <[email protected]>2024-03-15 14:37:56 -0700
commit8963575ed23533daaed67ccbe68bdd08051bef88 (patch)
tree7002333e36e0d98137294ddf25c7168b893753d5
parent20fd391f3e78c9349149f11fae94da9e4657478e (diff)
downloadpingora-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--.bleep2
-rw-r--r--pingora/Cargo.toml1
-rw-r--r--pingora/examples/client.rs68
3 files changed, 52 insertions, 19 deletions
diff --git a/.bleep b/.bleep
index 1ac1f3c..86a87b9 100644
--- a/.bleep
+++ b/.bleep
@@ -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(())
}