rfc8288

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2022 License: MIT Imports: 11 Imported by: 1

README

Disclaimer

This repository is effectively a fork of https://github.com/tniswong/go.rfcx/tree/master/rfc8288 by tniswong. That respository hadn't been touched in many years. So I forked it so I could upgrade the code to leverage Go modules and in the process I've switched the testing framework involved to Testify. I have, of course, retained Tim's copyright in the LICENSE.md file to reflect that the majority of the work here was his.

Usage

To use the library, do:

go get github.com/mtiller/rfc8288
result, err := ParseLink(`<https://www.google.com>; rel="next"; hreflang="en"; title="title"; title*="title*"; type="type"; extension="value"`)

In this case, you'll get a Link structure back that will look like this:

Link{
    HREF:          url.URL{
        Scheme: "https",
        Host: "www.google.com",
    },
    Rel:           "next",
    HREFLang:      "en",
    Title:         "title",
    TitleStar:     "title*",
    Type:          "type",
    extensionKeys: []string{"extension"},
    extensions: map[string]interface{}{
        "extension": "value",
    },
},

According to RFC8288, certain keys are reserved. These are all part of the Link structure so you can create a link and directly set their values, e.g.:

Link{
    HREF:   url.URL{
        Scheme: "https",
        Host: "www.google.com",
    },
    Rel:       "rel",
    HREFLang:  "hreflang",
    Media:     "media",
    Title:     "title",
    TitleStar: "title*",
    Type:      "type",
}

If you want to add a non-standard key, you need to use the Extends method on Link, e.g.,:

l.Extend("extension", "value")

It is an error to use Extend to add a reserved key.

To serialize a Link instance into the value used by RFC8288 Link Headers, just use the String() method on the Link type, e.g.,

link := Link{
    HREF: parseURL("https://www.google.com", t),
    Type: "type",
}
fmt.Printfln(link.String())

This will output:

<https://www.google.com>; type="type"

Note, this it the link header value, not the link header itself.

Headers

If you want to parse (one or more) HTTP headers, you can do that as well using ParseLinkHeaders, e.g.,

links, err = ParseLinkHeaders("Context-Type: application/json\r\nLink: </foo>; rel=\"hello\"\r\nAccept: *\r\nLink: </bar1>; rel=\"item\", </bar2>; rel=\"collection\"")

This will parse the headers, ignore any non Link headers and collect all Link headers (whether they be individual headers with only a single URI or headers that concatenate multiple links together with ,) and return them.

JSON

The Link structure defines special MarshalJSON and Links can be marshaled into JSON andUnmarshalJSONJSON methods so you can use the standardjsonpackage to marshal and unmarshalLink` instances.

Documentation

Overview

Package rfc8288 contains an implementation of IETF's RFC 8288. See: https://tools.ietf.org/html/rfc8288

Index

Constants

View Source
const (
	INVALID token = iota

	// delimiters
	QUOTE
	SEMICOLON
	LT
	GT
	EQ

	// special
	EOF
	STAR

	// multi-character
	WORD
	WS

	// reserved attribute names
	REL
	REV
	ANCHOR
	HREFLANG
	MEDIA
	TITLE
	TYPE
)

token types

Variables

View Source
var (
	// ErrExtensionKeyIsReserved describes an attempt to call Link.Extend(k,v) with a reserved key name
	ErrExtensionKeyIsReserved = errors.New("rfc8288: the given extension key name is reserved please choose another name")

	// ReservedKeys holds the names of all the reserved key names that are not allowed to be used as extensions
	ReservedKeys = map[string]struct{}{
		"href":     {},
		"rel":      {},
		"rev":      {},
		"anchor":   {},
		"hreflang": {},
		"media":    {},
		"title":    {},
		"title*":   {},
		"type":     {},
	}
)
View Source
var (
	ErrInvalidLink         = errors.New("rfc8288: invalid link")
	ErrMissingSemicolon    = errors.New("rfc8288: invalid link, missing semicolon")
	ErrMissingClosingQuote = errors.New("rfc8288: invalid link, missing closing quote")
	ErrMissingAttrValue    = errors.New("rfc8288: invalid link, missing attribute value")
)

parse Error Types

Functions

func LinkHeader

func LinkHeader(links ...Link) string

func LinkHeaderValue

func LinkHeaderValue(links ...Link) string

Types

type Link struct {
	HREF      url.URL
	Rel       string
	Rev       string
	Anchor    string
	HREFLang  string
	Media     string
	Title     string
	TitleStar string
	Type      string
	// contains filtered or unexported fields
}

Link is an implementation of the structure defined by RFC8288 Web Linking

func NewLink(href string) (*Link, error)
func ParseLink(link string) (Link, error)

ParseLink attempts to parse a link string

func ParseLinkHeaders

func ParseLinkHeaders(v string) ([]Link, error)

func (*Link) Extend

func (l *Link) Extend(key string, value interface{}) error

Extend adds an extension to the Link. Only non-reserved extension keys are allowed. Setting the value to nil will remove the extension.

func (*Link) Extension

func (l *Link) Extension(key string) (interface{}, bool)

Extension retrieves the value for an extension if present. A bool is also returned to signify whether the value was present upon retrieval

func (Link) ExtensionKeys

func (l Link) ExtensionKeys() []string

ExtensionKeys returns a slice of strings representing the names of extension keys for this Link struct in the order they were added

func (Link) MarshalJSON

func (l Link) MarshalJSON() ([]byte, error)

MarshalJSON Marshals JSON

func (Link) String

func (l Link) String() string

String returns the Link in a format usable for HTTP Headers as defined by RFC8288

func (*Link) StringExtension

func (l *Link) StringExtension(key string) (string, bool)

func (*Link) UnmarshalJSON

func (l *Link) UnmarshalJSON(data []byte) error

UnmarshalJSON unmarshal JSON

Jump to

Keyboard shortcuts

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