docs: drop the predecessor comparisons from comments and tests
This commit is contained in:
parent
36faa4fb93
commit
19e7cfaca3
19 changed files with 65 additions and 73 deletions
|
|
@ -99,7 +99,6 @@ struct Request<'a> {
|
|||
/// 53 is "a resource at a domain not served by the server" and 59 is a request
|
||||
/// the server could not parse: a URL that parses but names another scheme or
|
||||
/// host is a proxy request, while one that does not parse is a bad request.
|
||||
/// smolweb answers 59 to both, including to an ordinary `https://` URL.
|
||||
fn parse(line: &str) -> Result<Request<'_>, Refusal> {
|
||||
let Some((scheme, rest)) = line.split_once("://") else {
|
||||
return Err(Refusal { status: 59, meta: "Bad request: an absolute URL is required" });
|
||||
|
|
@ -195,8 +194,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn another_scheme_is_a_proxy_request_not_a_parse_failure() {
|
||||
// smolweb answers 59 here, which tells a client its request was malformed
|
||||
// when it was merely for somewhere this server does not fetch from.
|
||||
// 59 would tell a client its request was malformed when it was merely for
|
||||
// somewhere this server does not fetch from.
|
||||
assert_eq!(refused("https://example.org/"), 53);
|
||||
assert_eq!(refused("gopher://example.org/"), 53);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use itsybitsy_core::site::{Resolution, Resource};
|
|||
use crate::proto::for_log;
|
||||
use crate::serve::Listener;
|
||||
|
||||
/// Gopher selectors are short; the cap is smolweb's.
|
||||
/// Gopher selectors are short, and nothing in the protocol needs a long one.
|
||||
const MAX_REQUEST: usize = 512;
|
||||
|
||||
pub fn serve(listener: &Listener, mut stream: TcpStream) -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ pub fn serve(listener: &Listener, mut stream: TcpStream) -> Result<()> {
|
|||
if !version.starts_with("HTTP/1.") {
|
||||
return bad_request(&mut stream);
|
||||
}
|
||||
// Origin-form only. smolweb's `urlsplit` would have mishandled the others.
|
||||
// Origin-form only; the other request-target forms are refused, not
|
||||
// half-supported.
|
||||
if !target.starts_with('/') {
|
||||
return bad_request(&mut stream);
|
||||
}
|
||||
|
|
@ -168,8 +169,8 @@ pub fn serve(listener: &Listener, mut stream: TcpStream) -> Result<()> {
|
|||
write_head(&mut stream, 200, "OK", media_type, meta.len(), &[])?;
|
||||
if !head_only {
|
||||
let mut file = std::fs::File::open(&path)?;
|
||||
// Streamed, not buffered: smolweb reads the whole file into
|
||||
// memory on every request.
|
||||
// Streamed, not buffered, so a large file costs the copy buffer
|
||||
// rather than its own size on every request.
|
||||
std::io::copy(&mut file, &mut stream)?;
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use itsybitsy_core::site::{Resolution, Resource};
|
|||
use crate::proto::{for_log, read_line_capped};
|
||||
use crate::serve::Listener;
|
||||
|
||||
/// Nex requests are a single path; the cap is smolweb's.
|
||||
/// Nex requests are a single path, so the cap only has to be generous for one.
|
||||
const MAX_REQUEST: usize = 2048;
|
||||
|
||||
pub fn serve(listener: &Listener, mut stream: TcpStream) -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Spartan: `HOST PATH LENGTH` in, a one-digit status and a body out.
|
||||
//!
|
||||
//! The host field is what smolweb discards; here it selects the virtual host,
|
||||
//! falling back to the listener's `default_site` when it names nothing known.
|
||||
//! The host field selects the virtual host, falling back to the listener's
|
||||
//! `default_site` when it names nothing known.
|
||||
|
||||
use std::io::{BufReader, Read, Write};
|
||||
use std::net::TcpStream;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ fn accept_loop(listener: Arc<Listener>, socket: TcpListener) {
|
|||
};
|
||||
|
||||
// At the cap, refuse immediately rather than queueing threads without
|
||||
// bound. smolweb has no cap at all.
|
||||
// bound.
|
||||
let open = listener.open.fetch_add(1, Ordering::SeqCst);
|
||||
if open >= listener.max_connections {
|
||||
listener.open.fetch_sub(1, Ordering::SeqCst);
|
||||
|
|
@ -194,8 +194,9 @@ fn handle(listener: &Listener, stream: TcpStream) {
|
|||
}
|
||||
|
||||
// One malformed document must not take the process down, so a panic in a
|
||||
// handler is caught and logged. This is the Rust equivalent of smolweb's
|
||||
// bare `except Exception`, except the cause is recorded rather than lost.
|
||||
// handler is caught and logged with its cause rather than lost. A stack
|
||||
// overflow is not a panic and aborts regardless, which is why the parser caps
|
||||
// how deeply a document may nest.
|
||||
let caught =
|
||||
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| match listener.protocol {
|
||||
Protocol::Http => proto::http::serve(listener, stream),
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ fn spartan_serves_gemtext() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn spartan_routes_by_the_host_field_smolweb_discards() {
|
||||
fn spartan_routes_by_the_host_field() {
|
||||
let server = Server::start();
|
||||
assert!(server.send("spartan", b"one.test / 0\r\n").contains("# One"));
|
||||
assert!(server.send("spartan", b"two.test / 0\r\n").contains("# Two"));
|
||||
|
|
@ -560,8 +560,8 @@ fn nothing_outside_the_root_is_reachable_over_any_protocol() {
|
|||
|
||||
// -- Gopher --------------------------------------------------------------
|
||||
//
|
||||
// Ported from smolweb's tests/test_gopher.py, where the exact wire bytes are the
|
||||
// assertion: Gopher has no status line, so framing is all a client has.
|
||||
// The exact wire bytes are the assertion here: Gopher has no status line, so
|
||||
// framing is all a client has.
|
||||
|
||||
#[test]
|
||||
fn an_empty_selector_gets_a_one_item_menu() {
|
||||
|
|
@ -591,9 +591,8 @@ fn a_text_item_ends_with_the_lone_dot_terminator() {
|
|||
|
||||
#[test]
|
||||
fn a_missing_selector_is_a_well_formed_text_item() {
|
||||
// No status to report with, so the error is the item's content. smolweb says
|
||||
// "Not found." here and "Not found" over HTTP and Nex; one wording is used
|
||||
// across every protocol instead.
|
||||
// No status to report with, so the error is the item's content. One wording
|
||||
// is used across every protocol, so this matches the HTTP and Nex bodies.
|
||||
let server = Server::start();
|
||||
assert_eq!(server.send("gopher", b"/nope\r\n"), "Not found\n.\r\n");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue