diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d8b0c8..067fecb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,7 +11,9 @@
* `CheckError` now has an `HttpForbidden` variant. [PR#138]
* The `check_http` field of `CheckContext` is now an enum instead of a boolean [PR#138]
+* ureq has been upgraded to 2.0. This affects the public `CheckError` API, but should otherwise have no user-facing impact. [PR#134]
+[PR#134]: https://github.com/deadlinks/cargo-deadlinks/pull/134
[PR#138]: https://github.com/deadlinks/cargo-deadlinks/pull/138
diff --git a/Cargo.lock b/Cargo.lock
index ecd69cd..565949f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -680,15 +680,6 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1383dff4092fe903ac180e391a8d4121cc48f08ccf850614b0290c6673b69d"
-[[package]]
-name = "qstring"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e"
-dependencies = [
- "percent-encoding",
-]
-
[[package]]
name = "quote"
version = "1.0.7"
@@ -1194,15 +1185,14 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "ureq"
-version = "1.5.4"
+version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "294b85ef5dbc3670a72e82a89971608a1fcc4ed5c7c5a2895230d31a95f0569b"
+checksum = "96014ded8c85822677daee4f909d18acccca744810fd4f8ffc492c284f2324bc"
dependencies = [
"base64",
"chunked_transfer",
"log",
"once_cell",
- "qstring",
"rustls",
"url",
"webpki",
diff --git a/Cargo.toml b/Cargo.toml
index 92e259f..1ea9608 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,7 +33,7 @@ num_cpus = "1.8"
once_cell = "1.5.1"
rayon = "1.0"
regex = { version = "1", default-features = false, features = ["std", "perf"] }
-ureq = { version = "1.5.4", features = ["tls"], default-features = false }
+ureq = { version = "2.0.1", features = ["tls"], default-features = false }
serde = "1.0"
serde_derive = "1.0"
url = "2"
diff --git a/src/check.rs b/src/check.rs
index fe9c024..b37869f 100644
--- a/src/check.rs
+++ b/src/check.rs
@@ -23,21 +23,21 @@ const PREFIX_BLACKLIST: [&str; 1] = ["https://doc.rust-lang.org"];
#[derive(Debug)]
pub enum IoError {
- HttpUnexpectedStatus(Url, ureq::Response),
- HttpFetch(Url, ureq::Error),
+ HttpUnexpectedStatus(ureq::Response),
+ HttpFetch(ureq::Transport),
FileIo(String, std::io::Error),
}
impl fmt::Display for IoError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- IoError::HttpUnexpectedStatus(url, resp) => write!(
+ IoError::HttpUnexpectedStatus(resp) => write!(
f,
"Unexpected HTTP status fetching {}: {}",
- url,
+ resp.get_url(),
resp.status_text()
),
- IoError::HttpFetch(url, e) => write!(f, "Error fetching {}: {}", url, e),
+ IoError::HttpFetch(e) => write!(f, "Error fetching {}", e),
IoError::FileIo(url, e) => write!(f, "Error fetching {}: {}", url, e),
}
}
@@ -89,6 +89,16 @@ pub enum CheckError {
Io(Box),
}
+impl From for CheckError {
+ fn from(err: ureq::Error) -> Self {
+ let io_err = match err {
+ ureq::Error::Status(_, response) => IoError::HttpUnexpectedStatus(response),
+ ureq::Error::Transport(err) => IoError::HttpFetch(err),
+ };
+ CheckError::Io(Box::new(io_err))
+ }
+}
+
impl fmt::Display for CheckError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
@@ -277,23 +287,7 @@ fn check_file_fragment(
is_fragment_available(&Link::File(path.to_path_buf()), fragment, fetch_html)
}
-fn handle_response(url: &Url, resp: ureq::Response) -> Result {
- if resp.synthetic() {
- Err(CheckError::Io(Box::new(IoError::HttpFetch(
- url.clone(),
- resp.into_synthetic_error().unwrap(),
- ))))
- } else if resp.ok() {
- Ok(resp)
- } else {
- Err(CheckError::Io(Box::new(IoError::HttpUnexpectedStatus(
- url.clone(),
- resp,
- ))))
- }
-}
-
-/// Check a URL with "http" or "https" scheme for availability. Returns `false` if it is unavailable.
+/// Check a URL with "http" or "https" scheme for availability. Returns `Err` if it is unavailable.
fn check_http_url(url: &Url, ctx: &CheckContext) -> Result<(), CheckError> {
if ctx.check_http == HttpCheck::Ignored {
warn!(
@@ -320,13 +314,15 @@ fn check_http_url(url: &Url, ctx: &CheckContext) -> Result<(), CheckError> {
// The URL might contain a fragment. In that case we need a full GET
// request to check if the fragment exists.
if url.fragment().is_none() || !ctx.check_fragments {
- let mut resp = ureq::head(url.as_str()).call();
- // If HEAD isn't allowed, try sending a GET instead
- if resp.status() == 405 {
- resp = ureq::get(url.as_str()).call();
+ match ureq::head(url.as_str()).call() {
+ Err(ureq::Error::Status(405, _)) => {
+ // If HEAD isn't allowed, try sending a GET instead
+ ureq::get(url.as_str()).call()?;
+ Ok(())
+ }
+ Err(other) => Err(other.into()),
+ Ok(_) => Ok(()),
}
-
- handle_response(url, resp).map(|_: ureq::Response| ())
} else {
// the URL might contain a fragment, in that case we need to check if
// the fragment exists, this issues a GET request
@@ -338,8 +334,8 @@ fn check_http_fragment(url: &Url, fragment: &str) -> Result<(), CheckError> {
debug!("Checking fragment {} of URL {}.", fragment, url.as_str());
fn get_html(url: &Url) -> Result {
- let resp = ureq::get(url.as_str()).call();
- handle_response(&url, resp).map(|resp| resp.into_string().unwrap())
+ let resp = ureq::get(url.as_str()).call()?;
+ Ok(resp.into_string().unwrap())
}
let fetch_html = || {
@@ -359,7 +355,8 @@ fn check_http_fragment(url: &Url, fragment: &str) -> Result<(), CheckError> {
}
};
- is_fragment_available(&Link::Http(url.clone()), fragment, fetch_html)
+ is_fragment_available(&Link::Http(url.clone()), fragment, fetch_html)?;
+ Ok(())
}
#[cfg(test)]
diff --git a/tests/non_existent_http_link.rs b/tests/non_existent_http_link.rs
index 4d39a18..ba13a36 100644
--- a/tests/non_existent_http_link.rs
+++ b/tests/non_existent_http_link.rs
@@ -1,6 +1,7 @@
extern crate assert_cmd;
use assert_cmd::prelude::*;
+use predicates::str::contains;
use std::process::Command;
mod non_existent_http_link {
@@ -40,6 +41,9 @@ mod non_existent_http_link {
.args(&["deadlinks", "--check-http"])
.current_dir("./tests/non_existent_http_link")
.assert()
- .failure();
+ .failure()
+ .stdout(contains(
+ "Unexpected HTTP status fetching http://example.com/this/does/not/exist: Not Found",
+ ));
}
}