Help us shape the future of Go! Take the 2026 Go Developer Survey

webfeed

package
v0.2.50 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: MPL-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package webfeed is the contract behind txco://web/feed: the request a rule may make, the answer it gets back, and the reading of a feed document (RSS, Atom or JSON Feed) into that answer. It does no networking: the handler in chassis/server fetches through chassis/fetch and hands the body here.

A feed is what a site publishes about itself: its newest items, each a title, an address, a date and a few lines. Reading it answers "what has this site published" without fetching the site's pages, which many refuse to a program. Items are external text: the stack that reads them decides what they may do.

Index

Constants

View Source
const (
	MaxCount     = 50
	DefaultCount = 20
	// MaxScanItems is how many items are read from one document; any past
	// them are left unread and the answer says it was truncated. A feed
	// holds its newest few dozen.
	MaxScanItems = 500

	MaxTitleBytes   = 1 << 10
	MaxSummaryBytes = 4 << 10
	MaxURLBytes     = 2 << 10
	MaxIDBytes      = 1 << 10
	MaxAuthorBytes  = 256
	MaxAnswerBytes  = 256 << 10
)

The contract's bounds.

View Source
const (
	CodeInvalidRequest = "invalid_request"
	CodeDisabled       = "disabled"
	CodeRateLimited    = "rate_limited"
	CodeBusy           = "busy"
	CodeNotAFeed       = "not_a_feed"
	CodeInvalidFeed    = "invalid_feed"
	CodeNoTenant       = "no_tenant"
	CodeInternal       = "internal_error"
)

Error codes. The handler prefixes them txco_feed_; the fetcher's own codes (timeout, destination_denied, http_error, …) pass through under the same prefix.

View Source
const DefaultInto = "_feed"

DefaultInto is where the answer lands when a rule names no `into`.

Variables

This section is empty.

Functions

func Discover

func Discover(page []byte, base string) []string

Discover lists the feeds an HTML page advertises with <link rel="alternate" type="application/rss+xml" href="…"> and its kin, resolved against base, in page order, without repeats.

func Parse

func Parse(meta []byte) (Request, *Error)

Parse reads and checks the op's WITH object. The URL itself is checked by the handler with the fetcher's policy. An *Error names the first field at fault.

func Read

func Read(body []byte, contentType, base string) (*Document, *Error)

Read turns a fetched body into a Document. contentType is the response's header (for its charset); base is the address the body came from, which relative links resolve against. An HTML page is not a feed: the error carries the feeds the page advertises, if any.

Types

type Answer

type Answer struct {
	OK       bool   `json:"ok"`
	URL      string `json:"url"`
	FinalURL string `json:"final_url,omitempty"`
	Status   int    `json:"status,omitempty"`
	// Format is rss (RSS 2.0, 0.9x and RSS 1.0), atom or json.
	Format string `json:"format"`
	Feed   Info   `json:"feed"`
	Items  []Item `json:"items"`
	Count  int    `json:"count"`
	// Total is how many items the document holds (up to MaxScanItems),
	// before `since` and `count`.
	Total     int  `json:"total"`
	Truncated bool `json:"truncated"`
}

Answer is the op's result object on success.

type Document

type Document struct {
	Format string
	Feed   Info
	Items  []Item
	// Total is how many items the document holds, up to MaxScanItems.
	Total int
	// Truncated says the document was not read whole: more items than
	// MaxScanItems, more elements than the reader holds, or a syntax
	// error after some items were read.
	Truncated bool
}

Document is a feed as read: its format, what it says about itself, and its items in document order, each already plain text with its date in RFC 3339 and its URL resolved and checked. Nothing is cut yet: Select applies the request and the caps.

type Error

type Error struct {
	Code    string   `json:"code"`
	Message string   `json:"message"`
	Status  int      `json:"status,omitempty"`
	Feeds   []string `json:"feeds,omitempty"`
}

Error is the in-band failure. Feeds is set on not_a_feed when the address was an HTML page that advertises feeds: the addresses to try.

func Errorf

func Errorf(code, format string, args ...any) *Error

Errorf builds an *Error.

func (*Error) Error

func (e *Error) Error() string

type Failure

type Failure struct {
	OK          bool   `json:"ok"`
	URL         string `json:"url"`
	FinalURL    string `json:"final_url,omitempty"`
	ContentType string `json:"content_type,omitempty"`
	Error       *Error `json:"error"`
}

Failure is the op's result object when the feed was not read. The body is never in it.

type Info

type Info struct {
	Title       string  `json:"title"`
	Link        string  `json:"link,omitempty"`
	Description string  `json:"description,omitempty"`
	Updated     *string `json:"updated"`
}

Info is what the feed says about itself.

type Item

type Item struct {
	ID    string `json:"id"`
	Title string `json:"title"`
	URL   string `json:"url"`
	// Date is the item's own date (published, else updated), RFC 3339 in
	// UTC, or null.
	Date    *string `json:"date"`
	Summary string  `json:"summary"`
	Author  string  `json:"author,omitempty"`
	// Source is the item URL's host, lower case.
	Source string `json:"source,omitempty"`
}

Item is one entry of the feed.

func Select

func Select(items []Item, req Request) (out []Item, truncated bool)

Select applies the request to a document's items: those before `since` go; when every remaining item is dated they are put newest first, otherwise the document's order stands; the first `count` are kept; and each is cut to the contract's caps (a title, summary or author at its cap on a character boundary; an id or URL over its cap dropped from the item, since a cut one points somewhere else). The answer as a whole stays under MaxAnswerBytes by dropping items from the end. Truncated reports any cut or drop for size; `count` is a choice, not a cut.

type Request

type Request struct {
	URL   string
	Count int
	// Since keeps only items dated at or after it. An undated item is
	// kept: nothing says it is old.
	Since *time.Time
}

Request is one validated read.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL