Replace bare status codes with consts (#163)

* Replace bare status codes with consts
* Put the new consts in their own mod
This commit is contained in:
Albert Larsan 2022-04-06 16:25:09 +02:00 committed by GitHub
parent 3522a6596b
commit 75424b57fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 22 deletions

View file

@ -1,7 +1,9 @@
#![forbid(unsafe_code)]
mod certificates;
mod codes;
mod metadata;
use codes::*;
use metadata::{FileOptions, PresetMeta};
use {
@ -416,17 +418,19 @@ impl RequestHandle {
let bytes_read = if let Ok(read) = self.stream.read(buf).await {
read
} else {
break Err((59, "Request ended unexpectedly"));
break Err((BAD_REQUEST, "Request ended unexpectedly"));
};
len += bytes_read;
if request[..len].ends_with(b"\r\n") {
break Ok(());
} else if bytes_read == 0 {
break Err((59, "Request ended unexpectedly"));
break Err((BAD_REQUEST, "Request ended unexpectedly"));
}
buf = &mut request[len..];
}
.and_then(|()| std::str::from_utf8(&request[..len - 2]).or(Err((59, "Non-UTF-8 request"))));
.and_then(|()| {
std::str::from_utf8(&request[..len - 2]).or(Err((BAD_REQUEST, "Non-UTF-8 request")))
});
let request = result.map_err(|e| {
// write empty request to log line for uniformity
@ -437,17 +441,17 @@ impl RequestHandle {
// log literal request (might be different from or not an actual URL)
write!(self.log_line, " \"{}\"", request).unwrap();
let mut url = Url::parse(request).or(Err((59, "Invalid URL")))?;
let mut url = Url::parse(request).or(Err((BAD_REQUEST, "Invalid URL")))?;
// Validate the URL:
// correct scheme
if url.scheme() != "gemini" {
return Err((53, "Unsupported URL scheme"));
return Err((PROXY_REQUEST_REFUSED, "Unsupported URL scheme"));
}
// no userinfo and no fragment
if url.password().is_some() || !url.username().is_empty() || url.fragment().is_some() {
return Err((59, "URL contains fragment or userinfo"));
return Err((BAD_REQUEST, "URL contains fragment or userinfo"));
}
// correct host
@ -457,19 +461,19 @@ impl RequestHandle {
let host = Host::parse(
&percent_decode_str(domain)
.decode_utf8()
.or(Err((59, "Invalid URL")))?,
.or(Err((BAD_REQUEST, "Invalid URL")))?,
)
.or(Err((59, "Invalid URL")))?;
.or(Err((BAD_REQUEST, "Invalid URL")))?;
// TODO: simplify when <https://github.com/servo/rust-url/issues/586> resolved
url.set_host(Some(&host.to_string()))
.expect("invalid domain?");
// do not use "contains" here since it requires the same type and does
// not allow to check for Host<&str> if the vec contains Hostname<String>
if !ARGS.hostnames.is_empty() && !ARGS.hostnames.iter().any(|h| h == &host) {
return Err((53, "Proxy request refused"));
return Err((PROXY_REQUEST_REFUSED, "Proxy request refused"));
}
} else {
return Err((59, "URL does not contain a domain"));
return Err((BAD_REQUEST, "URL does not contain a domain"));
}
// correct port
@ -478,7 +482,7 @@ impl RequestHandle {
// Validate that the port in the URL is the same as for the stream this request
// came in on.
if port != self.stream.get_ref().0.local_addr().unwrap().port() {
return Err((53, "Proxy request refused"));
return Err((PROXY_REQUEST_REFUSED, "Proxy request refused"));
}
}
}
@ -513,16 +517,16 @@ impl RequestHandle {
match components.next() {
None => (),
Some(Component::Normal(c)) => path.push(c),
Some(_) => return self.send_header(51, "Not found, sorry.").await,
Some(_) => return self.send_header(NOT_FOUND, "Not found, sorry.").await,
}
// there must not be more than one component
if components.next().is_some() {
return self.send_header(51, "Not found, sorry.").await;
return self.send_header(NOT_FOUND, "Not found, sorry.").await;
}
// even if it's one component, there may be trailing path
// separators at the end
if decoded.ends_with(path::is_separator) {
return self.send_header(51, "Not found, sorry.").await;
return self.send_header(NOT_FOUND, "Not found, sorry.").await;
}
}
// check if hiding files is disabled
@ -533,7 +537,7 @@ impl RequestHandle {
&& segments.any(|segment| segment.starts_with('.'))
{
return self
.send_header(52, "If I told you, it would not be a secret.")
.send_header(GONE, "If I told you, it would not be a secret.")
.await;
}
}
@ -554,7 +558,7 @@ impl RequestHandle {
// if client is not redirected, links may not work as expected without trailing slash
let mut url = url;
url.set_path(&format!("{}/", url.path()));
return self.send_header(31, url.as_str()).await;
return self.send_header(REDIRECT_PERMANENT, url.as_str()).await;
}
}
}
@ -571,7 +575,7 @@ impl RequestHandle {
let mut file = match tokio::fs::File::open(&path).await {
Ok(file) => file,
Err(e) => {
self.send_header(51, "Not found, sorry.").await?;
self.send_header(NOT_FOUND, "Not found, sorry.").await?;
return Err(e.into());
}
};
@ -592,7 +596,7 @@ impl RequestHandle {
}
}
};
self.send_header(20, &mime).await?;
self.send_header(SUCCESS, &mime).await?;
// Send body.
tokio::io::copy(&mut file, &mut self.stream).await?;
@ -617,13 +621,14 @@ impl RequestHandle {
{
txt
} else {
self.send_header(51, "Directory index disabled.").await?;
self.send_header(NOT_FOUND, "Directory index disabled.")
.await?;
return Ok(());
};
log::info!("Listing directory {:?}", path);
self.send_header(20, "text/gemini").await?;
self.send_header(SUCCESS, "text/gemini").await?;
self.stream.write_all(preamble.as_bytes()).await?;
let mut entries = tokio::fs::read_dir(path).await?;