Browse Source

Infer gemini:// scheme in the URL

Signed-off-by: Alexey Yerin <yerinalexey98fd@gmail.com>
master
Alexey Yerin 4 years ago committed by Garrit Franke
parent
commit
025dda6847
  1. 50
      src/gemini.rs
  2. 5
      src/main.rs

50
src/gemini.rs

@ -27,6 +27,27 @@ impl FromStr for GeminiRequest {
type Err = TaurusError;
fn from_str(s: &str) -> TaurusResult<Self> {
let mut s = s.to_string();
// Add gemini: scheme if not explicitly set
if s.starts_with("//") {
s = format!("gemini:{}", s);
}
// Check protocol
if let Some(proto_end) = s.find("://") {
// If set, check if it's allowed
let protocol = &s[..proto_end];
if protocol != "gemini" {
// TODO: return 53 error instead of dropping
return Err(TaurusError::InvalidRequest("invalid protocol".into()));
}
} else {
// If no protocol is found, gemini: is implied
s = format!("gemini://{}", s);
}
// Extract and parse the url from the request.
let raw = s
.trim_end_matches(0x0 as char)
@ -88,32 +109,35 @@ impl GeminiResponse {
mod tests {
use super::*;
#[test]
fn parse_request() {
let raw = "gemini://example.space\r\n";
fn check_request(raw: &str, expected_url: &str) {
let req = GeminiRequest::parse(raw).unwrap();
assert_eq!(
req,
GeminiRequest {
url: Url::parse("gemini://example.space").unwrap()
url: Url::parse(expected_url).unwrap()
}
);
}
#[test]
fn parse_malformed_request() {
let raw = "gemini://example.space";
fn parse_request() {
check_request("gemini://example.space\r\n", "gemini://example.space");
}
match GeminiRequest::parse(raw) {
Err(TaurusError::InvalidRequest(_)) => {}
x => panic!("expected TaurusError::InvalidRequest, got: {:?}", x),
}
#[test]
fn parse_without_scheme() {
check_request("example.space\r\n", "gemini://example.space");
}
#[test]
fn parse_without_scheme_double_slash() {
check_request("//example.space\r\n", "gemini://example.space");
}
#[test]
fn parse_invalid_request_url() {
let raw = "foobar@example.com\r\n";
fn parse_malformed_request() {
let raw = "gemini://example.space";
match GeminiRequest::parse(raw) {
Err(TaurusError::InvalidRequest(_)) => {}

5
src/main.rs

@ -134,10 +134,7 @@ fn handle_client(mut stream: TlsStream<TcpStream>, static_root: &str) -> TaurusR
.read(&mut buffer)
.map_err(TaurusError::StreamReadFailed)?;
let mut raw_request = String::from_utf8_lossy(&buffer[..]).into_owned();
if !raw_request.starts_with("gemini://") {
raw_request = format!("gemini://{}", raw_request);
}
let raw_request = String::from_utf8_lossy(&buffer[..]).into_owned();
let request = GeminiRequest::parse(&raw_request)?;
let url_path = request.file_path();

Loading…
Cancel
Save