Documentation
¶
Overview ¶
Package metadata fetches a web page once and extracts an oEmbed-adjacent Preview from every source the page carries: ActivityStreams, Open Graph, Twitter Cards, oEmbed, and HTML natives.
Fetching ¶
One request negotiates ActivityStreams and HTML together. The response is byte-capped (truncated, not rejected, so the head of a huge page survives), charset-decoded to UTF-8, and parsed exactly once. Every in-page extractor reads that single tree.
Precedence ¶
Each source returns a sparse partial, and those partials merge in a fixed order: ActivityStreams, Open Graph, Twitter Cards, oEmbed, HTML natives. Call order IS the precedence: merge never overwrites a field that an earlier source already supplied. One field breaks that order on purpose — the canonical URL prefers rel=canonical over og:url, and requires the same origin.
Correlated fields — thumbnail, embed, provider, authors — fill as whole groups from one source, past a validity floor. One source's image URL is never paired with another source's dimensions.
The oEmbed endpoint is the only extra network hop, and it is gated: called only when an embed is plausible and not already found, or when a field oEmbed can carry is still empty.
Boundaries ¶
This package is sherlock's extraction engine and deliberately knows nothing about ActivityStreams result types. A Preview is never AS2; the Preview-to-ActivityStreams projection lives in the parent package, which imports this one and never the reverse. Callers who need AS2 use sherlock.Client.Load instead.
Index ¶
Examples ¶
Constants ¶
const DefaultMaxBodySize = 1 << 20
DefaultMaxBodySize is the default cap (1MB) on response bodies read by the metadata engine. Bodies larger than this are truncated, not rejected.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Author ¶
Author is one creator of the resource. Name and URL travel together as a group so one source's name is never paired with another source's URL.
type Embed ¶
type Embed struct {
Mode EmbedMode // how this embed renders
IframeURL string // twitter:player, VideoObject.embedUrl
StreamURL string // twitter:player:stream, og:video with a file MIME type
HTML string // provider markup; only meaningful when Mode == EmbedProviderHTML
Width, Height int // player dimensions; zero means unknown
}
Embed is a playable/interactive representation of the resource. Its dimensions are the PLAYER's, never the thumbnail's.
type EmbedMode ¶
type EmbedMode uint8
EmbedMode identifies how an Embed can be rendered.
const ( EmbedIframe EmbedMode = iota + 1 // we construct the iframe from IframeURL EmbedStream // StreamURL is a direct media file EmbedProviderHTML // HTML is sanitized provider markup — last resort )
EmbedMode values, ordered by preference: build our own iframe wherever possible, trust provider markup last.
type GetOption ¶
type GetOption func(*config)
GetOption configures one Get call.
func WithAllowPrivateIPs ¶
WithAllowPrivateIPs controls whether fetches may reach non-public IP addresses (loopback, private ranges); the default FALSE is an SSRF guard.
func WithAllowSandboxEmbeds ¶
WithAllowSandboxEmbeds controls whether oEmbed provider HTML that cannot be reduced to a single clean iframe may render inside a sandboxed srcdoc iframe.
func WithMaxBodySize ¶
WithMaxBodySize caps how many bytes are read from any response body; values of zero or less restore DefaultMaxBodySize.
func WithRemoteOptions ¶
WithRemoteOptions adds remote.Options that are passed to the remote library when making requests (signatures, caching, instrumentation).
func WithUserAgent ¶
WithUserAgent sets the User-Agent string sent with every request.
type Preview ¶
type Preview struct {
RequestURL string // the URL the caller asked for
URL string // canonical URL: AS id, rel=canonical, or og:url — same-origin verified
Kind Kind // what the resource is (not how it renders)
Title string // scalars: filled individually, first source wins
Description string // oEmbed's missing field
Language string // BCP-47, normalized at extraction
Thumbnail *Thumbnail // groups: nil, or filled whole from ONE source
Embed *Embed
Provider *Provider
Authors []Author
PublishedAt *time.Time
ModifiedAt *time.Time
CreatorHandle string // FEP-2345 fediverse:creator, e.g. "@user@example.social"
FetchedAt time.Time // bookkeeping — cache TTL only, never rendered
}
Preview is everything the engine could learn about a web page, in an oEmbed-adjacent shape: a rebuildable cache entry, never persisted or federated.
func Get ¶
Get fetches a URL once and returns everything the engine could learn about it, as an oEmbed-adjacent Preview.
Example ¶
ExampleGet fetches a page and prints the extracted preview. The page is served locally so the example is hermetic; real callers pass a public URL and omit WithAllowPrivateIPs.
package main
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"github.com/benpate/sherlock/metadata"
)
func main() {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_, _ = fmt.Fprint(w, `<html><head>
<title>Silver Blaze | The Strand</title>
<meta property="og:type" content="article">
<meta property="og:title" content="The Adventure of Silver Blaze">
<meta property="og:site_name" content="The Strand">
</head><body></body></html>`)
}))
defer server.Close()
preview, err := metadata.Get(context.Background(), server.URL,
metadata.WithUserAgent("example/1.0"),
metadata.WithAllowPrivateIPs(true), // httptest is loopback
)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(preview.Title)
fmt.Println(preview.Kind == metadata.KindArticle)
fmt.Println(preview.Provider.Name)
}
Output: The Adventure of Silver Blaze true The Strand
type Provider ¶
type Provider struct {
Name string // display name, e.g. "YouTube"
URL string // site root
IconURL string // favicon or touch icon
}
Provider identifies the site or service hosting the resource.
type Thumbnail ¶
type Thumbnail struct {
URL string // image location
Width, Height int // declared dimensions; zero means unknown
Alt string // alt text, where a source carries it
}
Thumbnail is a preview image for the resource, mirroring oEmbed's thumbnail_* fields. It never shares a dimension with Embed.