gopher-protocol 0.1.0

An implementation of the Gopher protocol (gopher://) and its Gopher+ successor: async client, RFC 1436 menu parser with RFC 4266 URLs, and Gopher+ attribute blocks, alternate views, and ASK forms. The parser half has no dependencies.
Documentation
  • Coverage
  • 79.12%
    72 out of 91 items documented5 out of 25 items with examples
  • Size
  • Source code size: 57.95 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.34 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 10s Average build duration of successful builds.
  • all releases: 10s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • merely-made/smolweb
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • mark-ik

gopher-protocol

An implementation of Gopher (gopher://, port 70) and its Gopher+ successor in Rust: an async client, an RFC 1436 menu parser with RFC 4266 URL synthesis, and the Gopher+ attribute, view, and form model.

This is not the reference implementation of Gopher, and it does not speak for the protocol's community.

Gopher+

Gopher+ (1993) is an upward-compatible superset, so it is not a separate protocol here: a plain RFC 1436 menu just has no Gopher+ markers on its items. What it adds is a response header carrying a real length, attribute blocks (+INFO, +ADMIN, +VIEWS) that describe an item without fetching it, alternate representations, and +ASK forms for interactive queries.

Gopher-II (the later draft) is not implemented.

Two halves, separately usable

The parsers have no dependencies and are always compiled, Gopher+ included. A consumer that only renders gophermaps takes the crate without the client and pulls no async runtime:

gopher-protocol = { version = "0.1", default-features = false }

The client rides the default client feature.

Example

# async fn run() -> Result<(), gopher_protocol::ClientError> {
let reply = gopher_protocol::fetch("gopher://gopher.floodgap.com/1/").await?;
for item in gopher_protocol::parse_menu(&String::from_utf8_lossy(&reply.body)) {
    println!("{:?} {}", item.kind, item.display);
}
# Ok(())
# }

Scope

A client and a parser. It does not serve gopher, and it holds no document or render model: how a Search or Image item should look is the consumer's decision.

Gopher carries no status line and no MIME type, so Response::mime is a best-effort inference from the item type, documented as a client convention rather than part of the RFC.

License

MIT.