chore: resolve TODOs in the pingora client example

Signed-off-by: Shane Utt <shaneutt@linux.com>
This commit is contained in:
Shane Utt 2024-02-28 10:39:59 -05:00
parent 45791f6345
commit 5833556e5f
No known key found for this signature in database
GPG key ID: 2A0C1E3016ECC921
2 changed files with 50 additions and 17 deletions

View file

@ -40,6 +40,7 @@ log = { workspace = true }
prometheus = "0.13"
once_cell = { workspace = true }
bytes = { workspace = true }
regex = "1"
[features]
default = ["openssl"]

View file

@ -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 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?;
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();
// 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(())
}