Implement BACKLOG.md items: config-only, request limits, URL validation
- Remove CLI options except --config and --test-processing-delay - Enforce 1026 byte request limit per Gemini spec (1024 + 2 for CRLF) - Add comprehensive URL parsing with host and port validation - Reject malformed URIs and wrong ports with 59 Bad Request - Update tests for new URL parsing signature - Fix clippy warning in port parsing
This commit is contained in:
parent
6a61b562f5
commit
f05b9373f1
3 changed files with 38 additions and 37 deletions
|
|
@ -6,14 +6,34 @@ pub enum PathResolutionError {
|
|||
NotFound,
|
||||
}
|
||||
|
||||
pub fn parse_gemini_url(request: &str, expected_host: &str) -> Result<String, ()> {
|
||||
pub fn parse_gemini_url(request: &str, expected_host: &str, expected_port: u16) -> Result<String, ()> {
|
||||
if let Some(url) = request.strip_prefix("gemini://") {
|
||||
let host_end = url.find('/').unwrap_or(url.len());
|
||||
let host = &url[..host_end];
|
||||
let host_port_end = url.find('/').unwrap_or(url.len());
|
||||
let host_port = &url[..host_port_end];
|
||||
|
||||
// Parse host and port
|
||||
let (host, port_str) = if let Some(colon_pos) = host_port.find(':') {
|
||||
let host = &host_port[..colon_pos];
|
||||
let port_str = &host_port[colon_pos + 1..];
|
||||
(host, Some(port_str))
|
||||
} else {
|
||||
(host_port, None)
|
||||
};
|
||||
|
||||
// Validate host
|
||||
if host != expected_host {
|
||||
return Err(()); // Hostname mismatch
|
||||
}
|
||||
let path = if host_end < url.len() { &url[host_end..] } else { "/" };
|
||||
|
||||
// Validate port
|
||||
let port = port_str
|
||||
.and_then(|p| p.parse::<u16>().ok())
|
||||
.unwrap_or(1965);
|
||||
if port != expected_port {
|
||||
return Err(()); // Port mismatch
|
||||
}
|
||||
|
||||
let path = if host_port_end < url.len() { &url[host_port_end..] } else { "/" };
|
||||
Ok(path.trim().to_string())
|
||||
} else {
|
||||
Err(())
|
||||
|
|
@ -69,18 +89,18 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_parse_gemini_url_valid() {
|
||||
assert_eq!(parse_gemini_url("gemini://gemini.jeena.net/", "gemini.jeena.net"), Ok("/".to_string()));
|
||||
assert_eq!(parse_gemini_url("gemini://gemini.jeena.net/posts/test", "gemini.jeena.net"), Ok("/posts/test".to_string()));
|
||||
assert_eq!(parse_gemini_url("gemini://gemini.jeena.net/", "gemini.jeena.net", 1965), Ok("/".to_string()));
|
||||
assert_eq!(parse_gemini_url("gemini://gemini.jeena.net/posts/test", "gemini.jeena.net", 1965), Ok("/posts/test".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_gemini_url_invalid_host() {
|
||||
assert!(parse_gemini_url("gemini://foo.com/", "gemini.jeena.net").is_err());
|
||||
assert!(parse_gemini_url("gemini://foo.com/", "gemini.jeena.net", 1965).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_gemini_url_no_prefix() {
|
||||
assert!(parse_gemini_url("http://gemini.jeena.net/", "gemini.jeena.net").is_err());
|
||||
assert!(parse_gemini_url("http://gemini.jeena.net/", "gemini.jeena.net", 1965).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue