Skip to content

Commit

Permalink
Merge pull request #95 from steveeJ-forks/qe/migrate-to-reqwest
Browse files Browse the repository at this point in the history
*: substitute hyper for reqwest
  • Loading branch information
Luca Bruno committed Feb 8, 2019
2 parents 1227fba + 087a956 commit a10c1ab
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 84 deletions.
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ exclude = [
base64 = "0.10"
error-chain = { version = "0.12", default-features = false }
futures = "0.1"
hyper = "0.12"
hyper-rustls = "0.15"
http = "0.1"
libflate = "0.1"
log = "0.4"
Expand Down
7 changes: 3 additions & 4 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use base64;
use http;
use hyper;
use regex;
use reqwest;
use serde_json;
Expand All @@ -11,9 +10,9 @@ use std::{io, string};
error_chain! {
foreign_links {
Base64Decode(base64::DecodeError);
HeaderInvalid(hyper::header::InvalidHeaderValue);
HeaderParse(hyper::header::ToStrError);
Hyper(hyper::Error);
HeaderInvalid(http::header::InvalidHeaderValue);
HeaderParse(http::header::ToStrError);
Hyper(http::Error);
Io(io::Error);
Json(serde_json::Error);
Regex(regex::Error);
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@
extern crate base64;
extern crate futures;
extern crate http;
extern crate hyper;
extern crate hyper_rustls;
extern crate mime;
extern crate serde;
extern crate serde_json;
Expand Down
41 changes: 19 additions & 22 deletions src/v2/auth.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use base64;
use futures::{future, prelude::*};
use hyper::header;
use reqwest::{StatusCode, Url};
use v2::*;

/// Convenience alias for future `TokenAuth` result.
Expand Down Expand Up @@ -85,7 +84,7 @@ impl Client {
///
/// On success, the returned token will be valid for all requested scopes.
pub fn login(&self, scopes: &[&str]) -> FutureTokenAuth {
let subclient = self.hclient.clone();
let subclient = self.clone();
let creds = self.credentials.clone();
let scope = scopes
.iter()
Expand All @@ -95,32 +94,30 @@ impl Client {
.and_then(move |token_ep| {
let auth_ep = token_ep + scope.as_str();
trace!("Token endpoint: {}", auth_ep);
hyper::Uri::from_str(auth_ep.as_str()).map_err(|e| e.into())

reqwest::Url::parse(&auth_ep).map_err(|e| {
Error::from(format!(
"failed to parse url from string '{}': {}",
auth_ep, e
))
})
})
.and_then(move |u| {
let mut auth_req = hyper::Request::default();
*auth_req.method_mut() = hyper::Method::GET;
*auth_req.uri_mut() = u;
if let Some(c) = creds {
let plain = format!("{}:{}", c.0, c.1);
let basic = format!("Basic {}", base64::encode(&plain));
if let Ok(basic_header) = header::HeaderValue::from_str(&basic) {
auth_req
.headers_mut()
.append(header::AUTHORIZATION, basic_header);
let auth_req = {
let auth_req = subclient.build_reqwest(reqwest::async::Client::new().get(u));
if let Some(creds) = creds {
auth_req.basic_auth(creds.0, Some(creds.1))
} else {
let msg = format!("could not parse HeaderValue from '{}'", basic);
error!("{}", msg);
// TODO: return an error. seems difficult to match the error type for the whole closure
};
auth_req
}
};
subclient.request(auth_req).map_err(|e| e.into())
auth_req.send().map_err(|e| e.into())
})
.and_then(|r| {
let status = r.status();
trace!("Got status {}", status);
match status {
hyper::StatusCode::OK => Ok(r),
StatusCode::OK => Ok(r),
_ => Err(format!("login: wrong HTTP status '{}'", status).into()),
}
})
Expand All @@ -130,7 +127,7 @@ impl Client {
.map_err(|e| format!("login: failed to fetch the whole body: {}", e).into())
})
.and_then(|body| {
let s = String::from_utf8(body.into_bytes().to_vec())?;
let s = String::from_utf8(body.to_vec())?;
serde_json::from_slice(s.as_bytes()).map_err(|e| e.into())
})
.inspect(|_| {
Expand All @@ -143,7 +140,7 @@ impl Client {
pub fn is_auth(&self, token: Option<&str>) -> FutureBool {
let url = {
let ep = format!("{}/v2/", self.base_url.clone(),);
match reqwest::Url::parse(&ep) {
match Url::parse(&ep) {
Ok(url) => url,
Err(e) => {
return Box::new(future::err::<_, _>(Error::from(format!(
Expand Down
33 changes: 14 additions & 19 deletions src/v2/catalog.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use errors::{Error, Result};
use futures::{self, Future, Stream};
use hyper;
use futures::{self, stream, Future, Stream};
use reqwest::StatusCode;
use serde_json;
use std::str::FromStr;
use v2;
Expand All @@ -21,33 +21,28 @@ impl v2::Client {
} else {
"".to_string()
};
let ep = format!("{}/v2/_catalog{}", self.base_url, suffix);
match hyper::Uri::from_str(ep.as_str()) {
let ep = format!("{}/v2/_catalog{}", self.base_url.clone(), suffix);
match reqwest::Url::parse(&ep) {
Ok(url) => url,
Err(e) => {
let msg = format!("new_request failed: {}", e);
error!("{}", msg);
return Box::new(futures::stream::once::<_, Error>(Err(Error::from(msg))));
return Box::new(stream::once::<_, _>(Err(Error::from(format!(
"failed to parse url from string '{}': {}",
ep, e
)))));
}
}
};

let req = match self.new_request(hyper::Method::GET, url) {
Ok(r) => r,
Err(e) => {
let msg = format!("new_request failed: {}", e);
error!("{}", msg);
return Box::new(futures::stream::once::<_, Error>(Err(Error::from(msg))));
}
};
let freq = self.hclient.request(req);
let fres = freq
let req = self.build_reqwest(reqwest::async::Client::new().get(url));

let fres = req
.send()
.from_err()
.and_then(|r| {
let status = r.status();
trace!("Got status: {:?}", status);
match status {
hyper::StatusCode::OK => Ok(r),
StatusCode::OK => Ok(r),
_ => Err(format!("get_catalog: wrong HTTP status '{}'", status).into()),
}
})
Expand All @@ -57,7 +52,7 @@ impl v2::Client {
})
})
.and_then(|body| -> Result<Catalog> {
serde_json::from_slice(&body.into_bytes()).map_err(|e| e.into())
serde_json::from_slice(&body).map_err(|e| e.into())
})
.map(|cat| futures::stream::iter_ok(cat.repositories.into_iter()))
.flatten_stream();
Expand Down
6 changes: 0 additions & 6 deletions src/v2/config.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use hyper::client;
use v2::*;

/// Configuration for a `Client`.
#[derive(Debug)]
pub struct Config {
config: client::Client<hyper_rustls::HttpsConnector<client::HttpConnector>, hyper::Body>,
index: String,
insecure_registry: bool,
user_agent: Option<String>,
Expand All @@ -15,10 +13,7 @@ pub struct Config {
impl Config {
/// Initialize `Config` with default values.
pub fn default() -> Self {
let dns_threads = 4;
Self {
config: hyper::client::Client::builder()
.build(hyper_rustls::HttpsConnector::new(dns_threads)),
index: "registry-1.docker.io".into(),
insecure_registry: false,
user_agent: Some(::USER_AGENT.to_owned()),
Expand Down Expand Up @@ -89,7 +84,6 @@ impl Config {
let c = Client {
base_url: base,
credentials: creds,
hclient: self.config,
index: self.index,
user_agent: self.user_agent,
token: None,
Expand Down
32 changes: 3 additions & 29 deletions src/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@

use super::errors::*;
use futures::prelude::*;
use hyper::{self, client, header};
use hyper_rustls;
use reqwest::StatusCode;
use serde_json;

use std::str::FromStr;
Expand All @@ -59,7 +58,6 @@ pub use self::blobs::FutureBlob;
pub struct Client {
base_url: String,
credentials: Option<(String, String)>,
hclient: client::Client<hyper_rustls::HttpsConnector<client::HttpConnector>>,
index: String,
user_agent: Option<String>,
token: Option<String>,
Expand All @@ -79,30 +77,6 @@ impl Client {
Config::default()
}

fn new_request(
&self,
method: hyper::Method,
url: hyper::Uri,
) -> Result<hyper::Request<hyper::Body>> {
let mut req = hyper::Request::default();
*req.method_mut() = method;
*req.uri_mut() = url;
req.headers_mut()
.append(header::HOST, header::HeaderValue::from_str(&self.index)?);
if let Some(ref t) = self.token {
let bearer = format!("Bearer {}", t);
req.headers_mut().append(
header::AUTHORIZATION,
header::HeaderValue::from_str(&bearer)?,
);
};
if let Some(ref ua) = self.user_agent {
req.headers_mut()
.append(header::USER_AGENT, header::HeaderValue::from_str(ua)?);
};
Ok(req)
}

/// Ensure remote registry supports v2 API.
pub fn ensure_v2_registry(self) -> impl Future<Item = Self, Error = Error> {
self.is_v2_supported()
Expand Down Expand Up @@ -136,8 +110,8 @@ impl Client {
// https://docs.docker.com/registry/spec/api/#api-version-check
get_v2
.and_then(move |r| match (r.status(), r.headers().get(api_header)) {
(hyper::StatusCode::OK, Some(x)) => Ok(x == api_version),
(hyper::StatusCode::UNAUTHORIZED, Some(x)) => Ok(x == api_version),
(StatusCode::OK, Some(x)) => Ok(x == api_version),
(StatusCode::UNAUTHORIZED, Some(x)) => Ok(x == api_version),
(s, v) => {
trace!("Got unexpected status {}, header version {:?}", s, v);
Ok(false)
Expand Down

0 comments on commit a10c1ab

Please sign in to comment.