The BBSWeb Protocol (bbs://): A BBS-Oriented Extension of Gopher Abstract BBSWeb (bbs://) is a distributed hypermedia protocol that extends the Gopher protocol (RFC 1436) with the visual conventions of the Bulletin Board System (BBS) era: CP437 character art and ANSI (ECMA- 48) styling. It preserves Gopher's stateless request/response model and adds a small set of extended item types, a hybrid menu format that carries both presentation art and machine-actionable links, and defined rendering targets so that a single authored page can be presented as raw ANSI to a capable client or as plain ASCII to a legacy Gopher client. For interactive experiences that Gopher's stateless model cannot express -- logging into a BBS, playing a door game, live chat -- BBSWeb does not attempt to carry a session itself. Instead it links to stateful endpoints (Telnet, and optionally SSH, WebSocket, and others) and defines how a client hands off to them and returns. The guiding principle is: BBSWeb browses; it does not host sessions. Table of Contents 1. Introduction 1.1. Motivation 1.2. Relationship to Gopher 1.3. Design Principles 1.4. Requirements Language 2. URIs 2.1. URI Syntax 2.2. Default Port 3. Item Types 4. Stateless Requests and Responses 4.1. Requests 4.2. Search and Input Requests (Type 7) 4.3. Responses 4.4. Errors 4.5. Interoperation with Gopher Servers and Clients 5. Menus and the Hybrid Menu Format 5.1. The Hybrid Menu (Type b) 5.2. The Link Block 5.3. Wire Format Summary 5.4. Client Handling of Hybrid Menus 5.5. Behaviour of Non-BBSWeb Clients 6. Representations and Rendering 6.1. Operator-Provided Representations Take Precedence 6.2. Native CP437/ANSI (Types b, a) 6.3. Down-Rendering to ASCII (Types 1, 0) 6.4. Consumers of the ASCII Representations 6.5. Width Variants 7. Pagination 8. Stateful Session Excursions 8.1. The Excursion Model 8.2. Endpoint Addressing 8.3. WebSocket Endpoints 8.4. Direct Connection by Capable Clients 8.5. Transport Support Levels 8.6. Graceful Refusal 9. Security Considerations 9.1. Cleartext Transport 9.2. Proxied Credentials 9.3. ANSI Sanitisation 9.4. Excursion Targets and Relays 10. IANA Considerations 10.1. The 'bbs' URI Scheme (Provisional) 10.2. Port Number 11. Design Rationale and Relation to Prior Work Appendix A. Recommended CP437-to-ASCII Transliteration (Non-Normative) Appendix B. Authoring and Serving Type b Content (Non-Normative) Appendix C. HTML Representation (Non-Normative) Appendix D. Example Transactions (Non-Normative) Acknowledgements 1. Introduction 1.1. Motivation The Bulletin Board System (BBS) culture that preceded and overlapped the early Web developed a rich visual vocabulary -- CP437 box-drawing and block characters, ANSI colour and cursor art, hotkey-driven menus -- and a strong sense of place and community. That aesthetic never had a distributed, URI-addressable hypermedia protocol of its own. BBSes were, and remain, individually stateful destinations reached one at a time. BBSWeb asks what an interlinked "web" of BBS-style content would have looked like had it grown from the same soil as Gopher: stateless, simple to serve, addressable by URI, but carrying BBS presentation as a first-class citizen rather than stripping it away. 1.2. Relationship to Gopher BBSWeb adopts the request/response mechanics of Gopher [RFC1436] and the URI conventions established for Gopher in [RFC4266], and extends them. Compatibility is direct and in both directions: a BBSWeb server serves unmodified Gopher clients on the same port (Section 6.3), and a BBSWeb menu may link to ordinary Gopher servers, which a BBSWeb client fetches as it would any type 1 or type 0 item. BBSWeb deliberately differs from Gemini, another contemporary Gopher-descended protocol. Where Gemini minimises presentation by design, BBSWeb maximises a specific presentation tradition. The two share Gopher's simplicity but pursue opposite aesthetic goals. BBSWeb is not a session protocol and does not attempt to be. A nested, stateful "web of BBSes" reachable only by tunnelling one interactive session through another is explicitly a non-goal; Section 8 instead defines clean hand-off to and return from stateful endpoints. 1.3. Design Principles Two principles shape every choice in this document: BBSWeb browses; it does not host sessions. Everything a user reads or navigates is a stateless fetch. Everything a user *does* interactively (logs into, plays, converses with) is a hand-off to a stateful endpoint (Section 8), not a feature of BBSWeb itself. CP437/ANSI first, ASCII always. A sysop authors content as CP437/ANSI and may supply hand-made alternatives (in ASCII, or for narrower screens); where none exists, the server derives an ASCII form automatically, so no content is unreachable by a plain Gopher client. A BBSWeb client states in its request which representation it wants (Section 4.1); a request that states nothing, as every Gopher request does, receives plain ASCII (Section 6). The server honours the representation it is asked for; it does not sniff or guess client identity. 1.4. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 2. URIs 2.1. URI Syntax A BBSWeb URI has the form: bbs://[:]/ where is a single item-type character (Section 3) and is an opaque string interpreted by the origin server. This mirrors the Gopher URI form defined in [RFC4266], substituting the "bbs" scheme name, and uses the same percent-encoding rules. For a type 7 item, the query is appended to the selector as "%09" followed by the percent-encoded query, as in [RFC4266]. A bbs URI and a gopher URI naming the same host, port, and selector with type 1 or 0 identify the same resource in the same representation; for example, bbs://bbs.example/1/files and gopher://bbs.example:23999/1/files are equivalent. Types b and a have no gopher URI form. 2.2. Default Port BBSWeb servers listen on a TCP port chosen by the operator. The RECOMMENDED default port is 23999. A client that is given a host with no port SHOULD attempt 23999. Use of any other port is permitted and requires no registration; conformance to this specification does not depend on the assignment or use of any particular port number. 3. Item Types BBSWeb uses the following item-type characters. Types marked "(Gopher)" carry their meaning from [RFC1436] unchanged. b BBSWeb menu: CP437/ANSI presentation plus a hybrid link block (Section 5). a CP437/ANSI document (8-bit text with ECMA-48 styling). 0 ASCII document (7-bit). (Gopher) 1 Directory / menu, ASCII. (Gopher) 3 Error (Section 4.4). (Gopher) 7 Search or input item (Section 4.2). (Gopher) 9 Binary file. (Gopher) 8 Telnet [RFC854] endpoint (stateful; Section 8). (Gopher) i Informational text line (menus only; not a link). Not defined in [RFC1436] but in near-universal use. S Secure Shell (SSH) [RFC4251] endpoint (stateful; Section 8). Support is OPTIONAL; see Section 8.5. W WebSocket [RFC6455] endpoint, ws:// or wss:// (stateful; Section 8). Support is OPTIONAL; see Section 8.5. Item-type characters are case-sensitive. The types a, b, S, and W are chosen to avoid the non-standard type characters in common Gopher use. Additional stateful transport types MAY be defined by future documents. Clients MUST handle unknown types as described in Section 8.6. 4. Stateless Requests and Responses 4.1. Requests For all item types other than the stateful endpoints of Section 8, a client opens a TCP connection to the host and port and sends a single request line. The item type is not itself transmitted, so a request for a type b or type a item carries a representation field: request = selector [ HTAB query HTAB rep-field ] CRLF rep-field = rep [ "/" width ] rep = "b" / "a" / "1" / "0" width = 2*3DIGIT ; screen columns, e.g. "40" where query is empty except for type 7 items (Section 4.2). o For type 9 items, and for any item on a server not known to implement BBSWeb (Section 4.5), the client sends the selector alone (with a query for type 7), exactly as in [RFC1436]. o For type b, the client sends rep "b"; for type a, "a". For example, the type b item with selector "/files" is requested as "/files" TAB TAB "b" CR LF. o For types 1 and 0, the client MAY send the selector alone, or rep "1" or "0" when it also sends a width. The optional width asks for a variant suited to a screen of that many columns (Section 6.5). A server that receives no representation field MUST respond with the ASCII representation (type 1 or type 0) of the item (Section 6). A server MUST ignore a representation field whose value it does not recognise and respond as if none were present. A Gopher+ request [GopherPlus] marks itself with "+", "!", or "$" in the field following the selector, or, for a search item, the field following the query. A BBSWeb request never places those characters in those positions, so the two cannot be confused, and a server MAY implement both. Because a legacy client never sends the field, it always receives a representation it can use. 4.2. Search and Input Requests (Type 7) A type 7 item accepts a single line of user input. The client sends: TAB CR LF where TAB is 0x09. This is the only form of user input carried by BBSWeb's stateless model, and it is a single round trip: the server holds no state between a type 7 request and any later request. Type 7 is suitable for search, directory lookup, and simple one-shot input (for example, signing a guest log). Anything requiring a conversation or retained session state is a stateful excursion (Section 8), not a type 7 request. A BBSWeb client MAY append the representation field "b" or "1" (Section 4.1) to a type 7 request, in which case the server MAY respond with a type b menu. Otherwise the response MUST be a type 1 menu. Links in either form MAY lead to items of any type. 4.3. Responses The server transmits the payload for the requested item and then closes the connection. There is no response header, status line, or content-type; as in Gopher, the item type carried in the URI is the only indication of how the bytes are to be interpreted. A server that receives a request with representation "b" for an item that has only a type 1 form (for example, a directory it serves as an ordinary Gopher menu) MUST respond with the type 1 menu; likewise, it responds to "a" with type 0 content when no type a form exists. A type 1 menu never contains a US byte, so a client that requested type b and receives a response containing no US byte MUST process it as a type 1 menu. ASCII content is valid type a content, so no corresponding rule is needed for type a. Authors may therefore link with type b to any item on a BBSWeb server without knowing whether it has a hybrid form. Text payloads (types b, a, 1, and 0) use CR LF line endings. Menu payloads (type 1, and the link block of type b) end with a line consisting of a single period (".") followed by CR LF, as in [RFC1436]. Clients SHOULD tolerate bare LF line endings and a missing terminator, as legacy Gopher clients commonly do. 4.4. Errors A server that cannot satisfy a request (for example, an unknown selector) SHOULD respond with a type 1 menu containing at least one type 3 line whose display string describes the error, following common Gopher practice. This is the response regardless of the representation requested. A client that requested type b receives it as a type 1 menu (Section 4.3) and displays it accordingly. A client that requested type a and receives a response beginning with "3" SHOULD present it as an error. 4.5. Interoperation with Gopher Servers and Clients BBSWeb and Gopher interoperate in both directions without gateways. o A legacy Gopher client can browse a BBSWeb server directly, using a gopher URI with the server's port (Section 2.1). It receives ASCII menus and documents, and follows their links as it would any other. o A BBSWeb menu can link to an ordinary Gopher server using types 1, 0, 7, and 9. A BBSWeb client requests these exactly as a Gopher client does and sends no representation field. o An author SHOULD use types b and a only in links to BBSWeb servers. If such a link nonetheless names a plain Gopher server, the request carries a field that server does not expect. Most Gopher servers ignore data after the selector, or treat it as a search string, and return the ordinary item, which the client handles by the fallback rule of Section 4.3. A client that receives an empty response, or one consisting only of a type 3 line, to a request carrying a representation field SHOULD retry once with the selector alone. These rules concern only links written by BBSWeb authors. Gopher clients, Gopher servers, and Gopher content need no change to take part. 5. Menus and the Hybrid Menu Format 5.1. The Hybrid Menu (Type b) A type b response carries two parts separated by a single Unit Separator byte (US, 0x1F): 1. The presentation block: CP437 text with ECMA-48 (ANSI) styling, authored for a legacy terminal geometry (commonly 80x25). 2. The link block: an optional mode byte followed by one link line per selectable item and the menu terminator (Section 5.2). The presentation block MUST NOT contain a US byte. Art files commonly end with an SUB byte (0x1A) followed by a SAUCE metadata record [SAUCE]; a server MUST remove the SUB byte and everything after it before transmitting the presentation block. The presentation block is what the user sees. The link block tells the client what is actionable and where each action leads. 5.2. The Link Block The first byte of the link block MAY be a mode byte: V (0x56) Visible: the client displays the link block. H (0x48) Hidden: the client does not display the link block. A mode byte, if present, is immediately followed by CR LF. If no mode byte is present, the mode is V. Mode V lets an author rely on the link block alone to present the menu. Mode H lets an author present the choices in a custom layout within the presentation block. Each link line is a Gopher menu line [RFC1436] prefixed with an index: "[", a single index character, and "]" (for example "[1]"). The index binds the item to a client hotkey. Index characters are limited to the following set, chosen to be displayable and typable on both modern systems and common 8-bit home computers: 0-9 A-Z ! $ % & * + , - . / : ; < = > ? @ Other than the index prefix, a link line is exactly an [RFC1436] menu line: type character, display string, TAB, selector, TAB, host, TAB, port, CR LF. Lines of type i MAY appear in the link block and carry no index; in mode V they are displayed in order, allowing headings and spacing. Letters are case-insensitive: "a" and "A" denote the same index, and a client MUST accept either case from the user. Each index MUST be unique within a menu, so a menu offers at most 53 items; larger collections are split across linked menus. A client MUST ignore a link line whose index is not in this set. 5.3. Wire Format Summary In ABNF [RFC5234] (informative; the prose above governs): hybrid-menu = presentation US link-block presentation = *( %x00-1E / %x20-FF ) ; no US link-block = [ mode CRLF ] *( link-line / info-line ) "." CRLF mode = "V" / "H" link-line = "[" index "]" menu-line index = DIGIT / ALPHA / "!" / "$" / "%" / "&" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "<" / "=" / ">" / "?" / "@" info-line = "i" menu-fields menu-line = type menu-fields menu-fields = display HTAB selector HTAB host HTAB port CRLF US = %x1F where type, display, selector, host, and port are as in [RFC1436]. 5.4. Client Handling of Hybrid Menus A BBSWeb client renders the presentation block and binds each index to its link, so that pressing that key (or activating that control) navigates to the linked item. In mode V the client also displays the link block, showing each index with the item's display string. In mode H it does not; the author places matching index labels in the presentation block. A client with a pointing device (mouse or touch) SHOULD make each index label activatable. An index label is a "[" character, an index character, and a "]" character occupying three horizontally adjacent character cells of the rendered screen, where the index character matches an index present in the link block; colour and other attributes are disregarded. Activating a label has the same effect as pressing its hotkey. Because ECMA-48 cursor movement can place characters anywhere, labels are recognised in the screen as rendered, not in the byte stream. Labels whose index does not appear in the link block are not activatable. 5.5. Behaviour of Non-BBSWeb Clients A legacy Gopher client never receives a type b response, because it never sends a representation field (Section 4.1). For every selector it requests, it receives the type 1 or type 0 representation, provided by the operator or generated automatically (Sections 6.1 and 6.3), and the links in those representations are themselves of types it can follow (Section 6.3). 6. Representations and Rendering The item type in the URI determines the representation requested, and the representation field (Section 4.1) conveys it to the server. Every type b item is also available as type 1, and every type a item as type 0, at the same selector. This section defines each representation and the rule that governs them. 6.1. Operator-Provided Representations Take Precedence For any item that has more than one representation, the server MUST serve an operator-provided representation for the requested type if one exists; otherwise it MUST generate the type 1 or type 0 representation automatically (Section 6.3). A hand-authored ASCII version therefore always overrides automatic transformation. (This generalises the long-standing BBS practice of serving a hand-made ".ASC" fallback in preference to auto-stripping an ".ANS" file.) 6.2. Native CP437/ANSI (Types b, a) Types b and a carry CP437 bytes with ECMA-48 styling, transmitted as authored. A capable client renders them directly. CP437 assigns printable glyphs to several code points in the C0 range (0x00-0x1F) and to 0x7F; whether such a byte denotes a glyph or a control function is context-dependent [CP437]. In BBSWeb payloads these bytes are always control information, never glyphs: TAB (0x09), CR (0x0D), and LF (0x0A) retain their usual meaning; ESC (0x1B) introduces ECMA-48 sequences; US (0x1F) separates the two parts of a type b response (Section 5.1); and ETB (0x17) marks a pagination pause (Section 7). A client MUST treat 0x00-0x1F and 0x7F as control information and MUST NOT render them as CP437 graphic characters. A glyph historically drawn for one of these code points cannot be expressed in a BBSWeb payload. 6.3. Down-Rendering to ASCII (Types 1, 0) When a type 1 (menu) or type 0 (document) representation of a type b or type a item is requested and no operator-provided representation exists (Section 6.1), the server MUST generate one by: o stripping all ECMA-48 control sequences (colour, cursor positioning, and other SGR/cursor codes); and o transliterating CP437 graphic characters to 7-bit ASCII approximations (Appendix A is a RECOMMENDED mapping); and o removing pagination marks (Section 7) and any other bytes in the range 0x00-0x1F or 0x7F other than CR, LF, and, in documents, TAB. For a type 1 result, non-actionable text is emitted as Gopher informational ("i") lines and actionable links as Gopher menu lines. When the source is a type b menu, the mode byte is discarded and every link line is emitted, regardless of mode, with its bracketed index removed from the start of the line. Each link keeps its selector, host, and port. A link to a type b item is emitted with type 1, and a link to a type a item with type 0, so that it resolves to the down-rendered representation of the same item. Links to stateful endpoints (types 8, S, and W) are emitted unchanged; a legacy client that does not recognise a type ignores it. A server MAY retain the index as a prefix of the display string (for example "[1] Files") so that it matches labels in the art. Automatic down-rendering targets STATIC art. Content that depends on cursor motion or timed redraws to convey meaning (ANSI "animation") cannot be represented as static ASCII and MUST NOT be expected to survive automatic down-rendering; stripping its control sequences yields a predictable but visually meaningless flattening. Operators who require a meaningful ASCII form of such content provide one (Section 6.1). 6.4. Consumers of the ASCII Representations The type 1 and type 0 representations serve two audiences. The first is legacy Gopher clients. The second, equally important, is BBS users whose terminals lack CP437 or ECMA-48 support: 7-bit ASCII terminals, many 8-bit home computers whose native character sets are not CP437 (for example PETSCII or ATASCII systems using an ASCII translation mode), screen readers, and teletype-style clients. A BBSWeb client whose user's terminal is not known to support both CP437 and ECMA-48 SHOULD request type 1 and type 0 representations in place of types b and a; that is, it follows every type b and type a link by sending no representation field. Such a client SHOULD still offer hotkey selection, using the index prefix of the display string (Section 6.3) where present. A client MAY let the user choose between the two modes. Because the operator's hand-authored ASCII versions take precedence (Section 6.1), operators serving significant ASCII-only audiences are encouraged to provide them. 6.5. Width Variants Presentation art is commonly authored for 80 columns. Many clients have narrower screens, including 40-column home computers and handheld devices, for which a 40x25 layout suits the display better. An operator MAY provide variants of any representation (b, a, 1, or 0) for particular screen widths. When a request carries a width (Section 4.1), the server MUST serve the operator-provided variant of the requested representation with the greatest width not exceeding the requested width, if one exists. Otherwise it serves the item as if no width were given. Automatic transformation never alters the layout of type b or type a content. When generating a type 0 or type 1 representation for a request with a width and no suitable variant exists, a server MAY wrap lines of text to that width; it MUST NOT wrap menu lines other than type i lines. A client MUST be prepared to receive content wider than it requested and SHOULD then truncate or scroll it rather than wrap it. 7. Pagination A server MAY insert an End of Transmission Block byte (ETB, 0x17) anywhere within a type a payload or the presentation block of a type b payload. ETB never appears in type 0 or type 1 payloads (Section 6.3); a client displaying those SHOULD paginate by its own means, as Gopher clients do. A client that is rendering interactively MUST pause at an ETB and await user input before processing subsequent bytes, producing a "more" prompt in the manner of a classic BBS. A client rendering non-interactively (for example, writing to a file) MAY ignore ETB bytes. ETB bytes are control information and are not part of the displayed text. 8. Stateful Session Excursions 8.1. The Excursion Model Item types 8 (Telnet), S (SSH), and W (WebSocket) name stateful endpoints. Activating such an item is an excursion: the client sets aside its current browsing context, conducts an interactive session with the endpoint, and, when that session ends, returns to the context it set aside. On return, a client SHOULD redraw the previously displayed page from the state it already holds, rather than re-fetching it. This mirrors classic Gopher behaviour, in which the client never left the menu and simply reclaims the terminal when the interactive session exits, and it avoids a dependence on the origin server remaining reachable at the end of the excursion. A client SHOULD provide a means to refresh (re-fetch) the current page on user request. 8.2. Endpoint Addressing Stateful endpoints appear in menus as ordinary link lines, whose fields are interpreted as follows. o Type 8 (Telnet): as in [RFC1436]. The host and port fields name the endpoint. A non-empty selector is a suggested login name, which the client MAY display to the user. o Type S (SSH): the host and port fields name the endpoint. A non-empty selector is the user name the client SHOULD present when authenticating; if empty, the client asks the user or uses a local default. o Type W (WebSocket): the selector field MUST contain the complete ws or wss URI [RFC6455] of the endpoint, including any path and query, and the host and port fields MUST name the same host and port as that URI. The URI is authoritative; the host and port fields exist so that Gopher software can process the line without parsing the URI. Section 8.3 defines the session carried. No excursion link carries credentials. 8.3. WebSocket Endpoints BBSes offer WebSocket access chiefly for browser-based terminals. Two arrangements are common, and both are type W endpoints: o BBS software that accepts WebSocket connections itself and connects each one to its terminal service (for example, the WebSocket service Synchronet provides for the fTelnet client [Synchronet]); and o a WebSocket-to-TCP bridge, such as websockify [websockify], that the BBS operator runs in front of the BBS's Telnet port. In both, the WebSocket connection carries the same byte stream as a Telnet connection to the BBS, including Telnet option negotiation. Accordingly, a client connecting to a type W endpoint: o opens a WebSocket connection to the URI in the selector field, offering the subprotocol "binary"; o sends and receives the session as the payload of binary messages, treating message boundaries as insignificant; and o processes the resulting byte stream exactly as it would a type 8 session, including Telnet commands [RFC854]. Where a bridge serves several BBSes and selects the destination by a token or path (websockify's token-based target selection is one example), that token or path is part of the URI and is opaque to the client. An operator who cannot offer this arrangement SHOULD NOT publish a type W link, and SHOULD publish a type 8 link where possible. 8.4. Direct Connection by Capable Clients A capable client (a dedicated client, a BBSWeb client embedded in a BBS as a "door", or a web-based client) MUST establish the stateful session by connecting directly to the named endpoint. The BBSWeb origin server is not involved in the session and MUST NOT be required to proxy it. A web-based client cannot open arbitrary TCP connections. It reaches type W endpoints directly (Section 8.3). It reaches BBSWeb servers, Gopher servers, and type 8 endpoints through a relay of the same kind as the bridge of Section 8.3, but operated by the provider of the web-based client rather than by a BBS. Such a relay forwards bytes unchanged in both directions, so the requests and responses of Section 4 are carried without modification and neither origin servers nor endpoints can distinguish a relayed client from a direct one. The relay is operated together with the web-based client that uses it, so the means by which the client names the destination to the relay is a private matter between the two and is not specified here. Relay operators are subject to Section 9.4. Interactive BBS users are expected to reach BBSWeb chiefly through such a door, running on a BBS they are already connected to. Because the door is itself a capable client, no server-side terminal gateway is required. A client that provides its own terminal for an excursion SHOULD support CP437 and ECMA-48 as commonly used by BBS software (see, for example, [CTerm]), and SHOULD report its terminal type and window size where the transport allows (for Telnet, [RFC1091] and [RFC1073]). A client running as a door uses the user's existing terminal and is not subject to this recommendation. 8.5. Transport Support Levels A conforming client MUST support Telnet (type 8) excursions. A client MAY support SSH (type S), WebSocket (type W), and any other stateful transport. A web-based client SHOULD support type W (Section 8.3), since it is the transport natively available to it. These levels reflect prevalence among live BBSes: Telnet is near-universal. 8.6. Graceful Refusal If a client cannot honour an excursion -- because it does not support the transport, or because a proxy declines -- it MUST NOT drop or abandon the user's browsing context. It MUST report the condition (for example, an inline message) and redraw the current page so the user may choose another action. 9. Security Considerations 9.1. Cleartext Transport BBSWeb, like Gopher and Telnet, is a cleartext protocol and is subject to eavesdropping and modification in transit. This document does not define a TLS binding, because many of the systems BBSWeb serves cannot use one; a binding may be defined by a future document. Content carried by BBSWeb is intended to be public, and users SHOULD NOT be asked to send secrets in type 7 queries. Where a web-based client and its relay (Section 8.4) communicate across a network, that connection SHOULD use wss. An excursion to a type S or wss endpoint is protected by that endpoint's own transport. 9.2. Proxied Credentials Stateful excursions (Section 8) may carry user credentials -- for example, a BBS login typed during a Telnet session. Because a capable client connects directly to the endpoint (Section 8.4), the BBSWeb origin server does not see those credentials. Any intermediary that does relay a stateful session (such as the relay of Section 8.4) MUST NOT log or persist session payload, as it may carry passwords and other secrets. 9.3. ANSI Sanitisation ECMA-48 defines control functions beyond colour and cursor positioning, including some historically used to remap keyboard input ("ANSI bombing"). A client MUST sanitise BBSWeb payloads (types b and a) so that only display-affecting functions (SGR colour and cursor positioning) are honoured. During an excursion (Section 8), a client MAY honour the wider set of functions used by BBS software, but MUST NOT act on control functions that remap keys, invoke host commands, or otherwise affect anything beyond the display. 9.4. Excursion Targets and Relays A menu can direct a client to any stateful endpoint (Section 8), including one on a private or loopback address, and a menu line of any type can name any host and port. A relay (Section 8.4) that connects to endpoints named in menus can therefore be abused to reach networks that the relay can reach but the requesting user cannot (a "confused deputy"). An operator of such a relay SHOULD restrict the hosts and ports it will connect to and SHOULD NOT relay to private or loopback addresses unless explicitly configured to do so; the logging prohibition of Section 9.2 also applies. A client SHOULD make the target host of an excursion visible to the user before connecting. 10. IANA Considerations 10.1. The 'bbs' URI Scheme (Provisional) This document requests PROVISIONAL registration of the "bbs" URI scheme in the Uniform Resource Identifier (URI) Schemes registry, per the procedures of [RFC7595]. Scheme name: bbs Status: provisional Applications/protocols that use this scheme name: The BBSWeb protocol defined in this document. Syntax: See Section 2.1 of this document. The scheme follows the Gopher URI conventions of [RFC4266], with item-type characters extended as described in Section 3. Security considerations: See Section 9 of this document. Registration is requested as provisional; the author intends to request advancement should the protocol mature. 10.2. Port Number This document does not require an assigned port number (Section 2.2). The author would welcome, but does not depend upon, assignment of TCP port 23999 for BBSWeb as a convenience to the community. The value 23999 lies in the User Ports range and is chosen as a mnemonic (the Telnet port 23 followed by 999). If IANA does not assign this value, or assigns a different value, this specification is unaffected. 11. Design Rationale and Relation to Prior Work Extending Gopher compatibly is not novel: Gopher+ [GopherPlus] showed that RFC 1436 could be extended while remaining usable by unmodified clients, achieving this with optional extra fields on menu lines that an RFC 1436 client skips. BBSWeb shares that goal but reaches it differently, and does not use the Gopher+ mechanisms of alternate views and "+ASK" forms. Those mechanisms require an altered transaction model and additional per-item metadata, and saw little deployment. BBSWeb does not change the menu-line format of RFC 1436. It extends the request form only by a single optional field, in the position Gopher+ uses and with values that cannot be mistaken for Gopher+ ones (Section 4.1), and chooses between exactly two representations with it. Input is confined to the single-round-trip type 7, and a request without the field, which is every request a legacy client sends, receives a standard type 1 or type 0 response. A type b response is therefore never delivered to a legacy client (Section 5.5). A reader familiar with Gopher+ may regard BBSWeb's representation model as a deliberately simpler alternative to alternate views. The precedence of an operator-provided representation over automatic transformation (Section 6.1), the pause-on-marker pagination of Section 7, and the bracketed-index hotkey convention of Section 5 derive from established BBS practice rather than from Gopher. Appendix A. Recommended CP437-to-ASCII Transliteration (Non-Normative) When a server auto-generates an ASCII representation (Section 6.3), it first removes all ECMA-48 control sequences and then replaces each CP437 graphic byte in the range 0x80-0xFF with a 7-bit ASCII byte. The mapping below produces readable output while preserving column alignment: it is one-to-one, so a line of art keeps its width and box frames stay aligned. For that reason single-glyph targets are chosen even where a multi-character spelling would read better (for example the ae ligature maps to "a", not "ae"). This mapping is advisory. An implementation SHOULD produce output substantially like it but is not required to match it byte for byte, and a hand-authored representation always overrides it (Section 6.1). Source bytes are identified by their CP437 code points [CP437]. Bytes 0x00-0x7F are passed through unchanged, subject to the control- byte rule of Section 6.2. A.1. Accented and Extended Latin (0x80-0xA7) Diacritics are dropped in favour of the nearest plain Latin letter; currency and letter forms map to a visual cousin. The target byte for each source byte, in order: 0x80-0x8F C u e a a a a c e e e i i i A A 0x90-0x9F E a A o o o u u y O U c L Y P f 0xA0-0xA7 a i o u n N a o A.2. Punctuation and Fractions (0xA8-0xAF) 0xA8 ? 0xA9 - 0xAA - 0xAB / 0xAC / 0xAD ! 0xAE < 0xAF > A.3. Shades and Block Elements (0xB0-0xB2, 0xDB-0xDF, 0xFE) Shade blocks map to characters of increasing visual density; solid and partial blocks map to "#", with half-blocks hinting at their orientation. 0xB0 . 0xB1 : 0xB2 # (light, medium, dark shade) 0xDB # 0xDC _ 0xDD | 0xDE | 0xDF - 0xFE # A.4. Box Drawing (0xB3-0xDA) All single- and double-line box characters collapse to three ASCII drawing characters: vertical lines (e.g. 0xB3, 0xBA) -> | horizontal lines (e.g. 0xC4, 0xCD) -> - every corner, T-junction, and cross -> + A.5. Greek, Mathematical, and Miscellaneous (0xE0-0xFF) Visual shape is preferred over mathematical meaning, so that layout art built from these glyphs degrades predictably. 0xE0-0xE7 a B G p E s u t 0xE8-0xEF O 0 O d 8 o e n 0xF0-0xF7 = + > < ( ) / ~ 0xF8-0xFD o . . V n 2 0xFF (a space, 0x20) Any CP437 graphic byte for which an implementation has no reasonable approximation SHOULD map to "?". Operators to whom the ASCII appearance matters are reminded that a hand-authored representation overrides this mapping (Section 6.1). Appendix B. Authoring and Serving Type b Content (Non-Normative) This specification defines only what is sent on the wire; as with [RFC1436], how a server stores and assembles content is an implementation matter. Gopher servers conventionally generate menus from directory listings, optionally overridden by a hand-written menu file ("gophermap") in each directory. BBSWeb servers are expected to follow similar conventions. The following is a RECOMMENDED convention, intended to let content move between servers unchanged. A type b source file is a single file whose content is the wire format of Section 5.3: the art, a US byte, then the link block. A server can therefore serve it byte for byte, removing only a SAUCE record (Section 5.1). Because many art editors cannot insert a US byte or preserve text after SAUCE, a server MAY instead accept a pair of files sharing a base name: MAIN.ANS the presentation block, as saved by an art editor MAIN.LNK the link block, as plain text and assemble them on request. Where a selector names a directory, a server MAY generate the link block from the directory's contents in mode V, as Gopher servers generate type 1 menus. Hand-authored fallbacks (Section 6.1) are conventionally stored beside the source under the same base name: MAIN.ASC for the type 1 presentation text, whose link lines the server still derives from the link block, or a complete Gopher menu file where the operator wishes to control the type 1 output entirely. A type a document DOC.ANS likewise has its type 0 fallback at DOC.ASC. Width variants (Section 6.5) are likewise stored beside the source, with the width in the name in a form that fits 8.3 file-name limits (for example, MAIN40.ANS and MAIN40.ASC). Selectors are opaque (Section 2.1); nothing in the file names above is visible to, or relied on by, clients. Appendix C. HTML Representation (Non-Normative) A BBSWeb item may also be represented as an HTML document [HTML], for example by a gateway that lets an ordinary web browser view BBSWeb content. Unlike ASCII down-rendering, this representation preserves the characters themselves. A producer: o maps each CP437 byte to its Unicode equivalent per [CP437] (preserving box-drawing and block art), subject to the control- byte rule of Section 6.2; o translates ECMA-48 colour styling to CSS, or strips it, and applies the sanitisation rules of Section 9.3; o wraps the resulting text in a "pre" element styled with a monospace font; and o renders the link block (Section 5.2) as HTML "a" elements whose targets are gateway URLs for the linked items, from which the gateway can recover the host, port, type, and selector, and renders stateful endpoints (Section 8) as links to a web-based terminal or, for type W, to its URI, subject to Section 9.4. A gateway fetches content as a BBSWeb client does (Section 4.1), requesting type b and type a where the link type calls for them. Whether and how such a gateway is offered is a deployment choice. No item type is defined for the HTML representation, and a BBSWeb server is not required to produce it. A dedicated BBSWeb client running in a web browser does not rely on it: it speaks BBSWeb natively (Section 8.4) and performs its own rendering. Appendix D. Example Transactions (Non-Normative) In the examples, "C:" and "S:" mark client and server data, is 0x1F, is 0x1B, and each line ends in CR LF. A capable client fetches bbs://bbs.example/b/ : C: /b S: [1;36m Welcome to Example BBS[0m S: [F] Files [T] Telnet in S: H S: [F]1Files/filesbbs.example23999 S: [T]8Example BBSbbs.example23 S: . (server closes connection) A legacy Gopher client fetches the same selector (gopher://bbs.example:23999/1/). Its request carries no representation field, so the server down-renders the menu: C: / S: i Welcome to Example BBSfake(NULL)0 S: i [F] Files [T] Telnet infake(NULL)0 S: 1[F] Files/filesbbs.example23999 S: 8[T] Example BBSbbs.example23 S: . (server closes connection) In the first example the link to "/files" is written with type 1 because the author chose to link to a plain menu; a link to another hybrid menu would be written "[F]b...", and would be emitted as type 1 in the down-rendered form (Section 6.3). Acknowledgements This document was prepared by the author with the assistance of AI tools used as drafting aids. All design decisions and the final text are the author's, and the author is solely responsible for the document's contents. The author thanks the BBS community for review and feedback.