util

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Apr 10, 2024 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Possible GoToSocial mimetypes.
	AppJSON = `application/json`
	AppXML  = `application/xml`

	AppXMLXRD       = `application/xrd+xml`
	AppRSSXML       = `application/rss+xml`
	AppActivityJSON = `application/activity+json`

	AppActivityLDJSON = appActivityLDJSON + `; profile="https://www.w3.org/ns/activitystreams"`
	AppJRDJSON        = `application/jrd+json` // https://www.rfc-editor.org/rfc/rfc7033#section-10.2
	AppForm           = `application/x-www-form-urlencoded`
	MultipartForm     = `multipart/form-data`
	TextXML           = `text/xml`
	TextHTML          = `text/html`
	TextCSS           = `text/css`
)
View Source
const (
	APIVersionKey = "api_version"
	APIv1         = "v1"
	APIv2         = "v2"

	IDKey      = "id"
	LimitKey   = "limit"
	LocalKey   = "local"
	MaxIDKey   = "max_id"
	SinceIDKey = "since_id"
	MinIDKey   = "min_id"

	OnlyOtherAccountsKey = "only_other_accounts"

	SearchExcludeUnreviewedKey = "exclude_unreviewed"
	SearchFollowingKey         = "following"
	SearchLookupKey            = "acct"
	SearchOffsetKey            = "offset"
	SearchQueryKey             = "q"
	SearchResolveKey           = "resolve"
	SearchTypeKey              = "type"

	TagNameKey = "tag_name"

	WebUsernameKey = "username"
	WebStatusIDKey = "status"

	DomainPermissionExportKey = "export"
	DomainPermissionImportKey = "import"
)

Variables

View Source
var (
	// Pre-preared response body data.
	StatusOKJSON = mustJSON(map[string]string{
		"status": http.StatusText(http.StatusOK),
	})
	StatusAcceptedJSON = mustJSON(map[string]string{
		"status": http.StatusText(http.StatusAccepted),
	})
	StatusForbiddenJSON = mustJSON(map[string]string{
		"status": http.StatusText(http.StatusForbidden),
	})
	StatusInternalServerErrorJSON = mustJSON(map[string]string{
		"status": http.StatusText(http.StatusInternalServerError),
	})
	ErrorCapacityExceeded = mustJSON(map[string]string{
		"error": "server capacity exceeded",
	})
	ErrorRateLimited = mustJSON(map[string]string{
		"error": "rate limit reached",
	})
	EmptyJSONObject = json.RawMessage(`{}`)
	EmptyJSONArray  = json.RawMessage(`[]`)
)
View Source
var ActivityPubHeaders = []string{
	AppActivityLDJSON,
	AppActivityJSON,
}

ActivityPubHeaders matches only activitypub Accept headers. This is useful for URLs should only serve ActivityPub.

https://www.w3.org/TR/activitypub/#retrieving-objects

View Source
var ActivityPubOrHTMLHeaders = []string{
	AppActivityLDJSON,
	AppActivityJSON,
	TextHTML,
}

ActivityPubOrHTMLHeaders matches activitypub types first, then text/html. This is useful for URLs that should serve ActivityPub by default, but which a user might also go to in their browser sometimes.

https://www.w3.org/TR/activitypub/#retrieving-objects

View Source
var HTMLAcceptHeaders = []string{
	TextHTML,
}

HTMLAcceptHeaders is a slice of offers that just contains text/html types.

View Source
var HTMLOrActivityPubHeaders = []string{
	TextHTML,
	AppActivityLDJSON,
	AppActivityJSON,
}

HTMLOrActivityPubHeaders matches text/html first, then activitypub types. This is useful for user URLs that a user might go to in their browser, but which should also be able to serve ActivityPub as a fallback.

https://www.w3.org/TR/activitypub/#retrieving-objects

View Source
var HostMetaHeaders = []string{
	AppXMLXRD,
	AppXML,
}
View Source
var JSONAcceptHeaders = []string{
	AppJSON,
}

JSONAcceptHeaders is a slice of offers that just contains application/json types.

View Source
var JSONOrHTMLAcceptHeaders = []string{
	AppJSON,
	TextHTML,
}

JSONOrHTMLAcceptHeaders is a slice of offers that prefers AppJSON and will fall back to HTML if necessary. This is useful for error handling, since it can be used to serve a nice HTML page if the caller accepts that, or just JSON if not.

View Source
var WebfingerJSONAcceptHeaders = []string{
	AppJRDJSON,
	AppJSON,
}

WebfingerJSONAcceptHeaders is a slice of offers that prefers the jrd+json content type, but will be chill and fall back to app/json. This is to be used specifically for webfinger responses. See https://www.rfc-editor.org/rfc/rfc7033#section-10.2

Functions

func ASContentType added in v0.13.3

func ASContentType(ct string) bool

ASContentType returns whether is valid ActivityStreams content-types: - application/activity+json - application/ld+json;profile=https://w3.org/ns/activitystreams

func AccountTitle added in v0.14.0

func AccountTitle(account *apimodel.Account, accountDomain string) string

AccountTitle parses a page title from account and accountDomain

func Data added in v0.13.0

func Data(c *gin.Context, code int, contentType string, data []byte)

Data calls WriteResponseBytes() using gin.Context{}, with given content-type.

func EncodeJSONResponse added in v0.13.0

func EncodeJSONResponse(
	rw http.ResponseWriter,
	r *http.Request,
	statusCode int,
	contentType string,
	data any,
)

EncodeJSONResponse encodes 'data' as JSON HTTP response to ResponseWriter with given status code, content-type.

func EncodeXMLResponse added in v0.13.0

func EncodeXMLResponse(
	rw http.ResponseWriter,
	r *http.Request,
	statusCode int,
	contentType string,
	data any,
)

EncodeJSONResponse encodes 'data' as XML HTTP response to ResponseWriter with given status code, content-type.

func ErrorHandler

func ErrorHandler(
	c *gin.Context,
	errWithCode gtserror.WithCode,
	instanceGet func(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode),
	offers ...string,
)

ErrorHandler takes the provided gin context and errWithCode and tries to serve a helpful error to the caller.

It will do content negotiation to figure out if the caller prefers to see an html page with the error rendered there. If not, or if something goes wrong during the function, it will recover and just try to serve an appropriate application/json content-type error. To override the default response type, specify `offers`.

If the requester already hung up on the request, or the server timed out a very slow request, ErrorHandler will overwrite the given errWithCode with a 408 or 499 error to indicate that the failure wasn't due to something we did, and will avoid trying to write extensive bytes to the caller by just aborting.

For 499, see https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#nginx.

func ForbiddenAfterMove added in v0.15.0

func ForbiddenAfterMove(c *gin.Context)

ForbiddenAfterMove returns code 403 to the caller and writes a helpful error message. Specifically used for accounts trying to take actions on endpoints they cannot do while moving.

func JSON added in v0.13.0

func JSON(c *gin.Context, code int, data any)

JSON calls EncodeJSONResponse() using gin.Context{}, with content-type = AppJSON, This function handles the case of JSON unmarshal errors and pools read buffers.

func JSONContentType added in v0.13.3

func JSONContentType(ct string) bool

JSONContentType returns whether is application/json(;charset=utf-8)? content-type.

func JSONJRDContentType added in v0.13.3

func JSONJRDContentType(ct string) bool

JSONJRDContentType returns whether is application/(jrd+)?json(;charset=utf-8)? content-type.

func JSONType added in v0.13.0

func JSONType(c *gin.Context, code int, contentType string, data any)

JSON calls EncodeJSONResponse() using gin.Context{}, with given content-type. This function handles the case of JSON unmarshal errors and pools read buffers.

func NegotiateAccept

func NegotiateAccept(c *gin.Context, offers ...string) (string, error)

NegotiateAccept takes the *gin.Context from an incoming request, and a slice of Offers, and performs content negotiation for the given request with the given content-type offers. It will return a string representation of the first suitable content-type, or an error if something goes wrong or a suitable content-type cannot be matched.

For example, if the request in the *gin.Context has Accept headers of value [application/json, text/html], and the provided offers are of value [application/json, application/xml], then the returned string will be 'application/json', which indicates the content-type that should be returned.

If the length of offers is 0, then an error will be returned, so this function should only be called in places where format negotiation is actually needed.

If there are no Accept headers in the request, then the first offer will be returned, under the assumption that it's better to serve *something* than error out completely.

Callers can use the offer slices exported in this package as shortcuts for often-used Accept types.

See https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation#server-driven_content_negotiation

func NegotiateFormat added in v0.9.0

func NegotiateFormat(c *gin.Context, offered ...string) string

This is the exact same thing as gin.Context.NegotiateFormat except it contains tsmethurst's fix to make it work properly with multiple accept headers.

https://github.com/gin-gonic/gin/pull/3156

func NodeInfo2ContentType added in v0.13.3

func NodeInfo2ContentType(ct string) bool

NodeInfo2ContentType returns whether is nodeinfo schema 2.0 content-type.

func NotFoundAfterMove added in v0.15.0

func NotFoundAfterMove(c *gin.Context)

NotFoundAfterMove returns code 404 to the caller and writes a helpful error message. Specifically used for accounts trying to access endpoints they cannot use while moving.

func NotFoundHandler

func NotFoundHandler(c *gin.Context, instanceGet func(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode), accept string, errWithCode gtserror.WithCode)

NotFoundHandler serves a 404 html page through the provided gin context, if accept is 'text/html', or just returns a json error if 'accept' is empty or application/json.

When serving html, NotFoundHandler calls the provided InstanceGet function to fetch the apimodel representation of the instance, for serving in the 404 header and footer.

If an error is returned by InstanceGet, the function will panic.

func OAuthErrorHandler

func OAuthErrorHandler(c *gin.Context, errWithCode gtserror.WithCode)

OAuthErrorHandler is a lot like ErrorHandler, but it specifically returns errors that are compatible with https://datatracker.ietf.org/doc/html/rfc6749#section-5.2, but serializing errWithCode.Error() in the 'error' field, and putting any help text from the error in the 'error_description' field. This means you should be careful not to pass any detailed errors (that might contain sensitive information) into the errWithCode.Error() field, since the client will see this. Use your noggin!

func ParseAPIVersion added in v0.11.0

func ParseAPIVersion(value string, availableVersion ...string) (string, gtserror.WithCode)

func ParseDescription added in v0.14.0

func ParseDescription(in string) string

ParseDescription returns a string description which is safe to use as a template.HTMLAttr inside templates.

func ParseDomainPermissionExport added in v0.12.0

func ParseDomainPermissionExport(value string, defaultValue bool) (bool, gtserror.WithCode)

func ParseDomainPermissionImport added in v0.12.0

func ParseDomainPermissionImport(value string, defaultValue bool) (bool, gtserror.WithCode)

func ParseID added in v0.10.0

func ParseID(value string) (string, gtserror.WithCode)

func ParseLimit added in v0.10.0

func ParseLimit(value string, defaultValue int, max, min int) (int, gtserror.WithCode)

func ParseLocal added in v0.10.0

func ParseLocal(value string, defaultValue bool) (bool, gtserror.WithCode)

func ParseMaxID added in v0.10.0

func ParseMaxID(value string, defaultValue string) string

func ParseOnlyOtherAccounts added in v0.13.0

func ParseOnlyOtherAccounts(value string, defaultValue bool) (bool, gtserror.WithCode)

func ParseSearchExcludeUnreviewed added in v0.10.0

func ParseSearchExcludeUnreviewed(value string, defaultValue bool) (bool, gtserror.WithCode)

func ParseSearchFollowing added in v0.10.0

func ParseSearchFollowing(value string, defaultValue bool) (bool, gtserror.WithCode)

func ParseSearchLookup added in v0.10.0

func ParseSearchLookup(value string) (string, gtserror.WithCode)

func ParseSearchOffset added in v0.10.0

func ParseSearchOffset(value string, defaultValue int, max, min int) (int, gtserror.WithCode)

func ParseSearchQuery added in v0.10.0

func ParseSearchQuery(value string) (string, gtserror.WithCode)

func ParseSearchResolve added in v0.10.0

func ParseSearchResolve(value string, defaultValue bool) (bool, gtserror.WithCode)

func ParseTagName added in v0.11.0

func ParseTagName(value string) (string, gtserror.WithCode)

func ParseWebStatusID added in v0.10.0

func ParseWebStatusID(value string) (string, gtserror.WithCode)

func ParseWebUsername added in v0.10.0

func ParseWebUsername(value string) (string, gtserror.WithCode)

func TemplateWebPage added in v0.14.0

func TemplateWebPage(
	c *gin.Context,
	page WebPage,
)

TemplateWebPage renders the given HTML template and page params within the standard GtS "page" template.

ogMeta, stylesheets, javascript, and any extra properties will be provided to the template if set, but can all be nil.

func WebErrorHandler added in v0.9.0

func WebErrorHandler(c *gin.Context, errWithCode gtserror.WithCode, instanceGet func(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode))

WebErrorHandler is like ErrorHandler, but will display HTML over JSON by default.

func WriteResponse added in v0.13.0

func WriteResponse(
	rw http.ResponseWriter,
	r *http.Request,
	statusCode int,
	contentType string,
	data io.Reader,
	length int64,
)

WriteResponse buffered streams 'data' as HTTP response to ResponseWriter with given status code content-type.

func WriteResponseBytes added in v0.13.0

func WriteResponseBytes(
	rw http.ResponseWriter,
	r *http.Request,
	statusCode int,
	contentType string,
	data []byte,
)

WriteResponseBytes is functionally similar to WriteResponse except that it takes prepared bytes.

func XMLContentType added in v0.13.3

func XMLContentType(ct string) bool

XMLContentType returns whether is application/xml(;charset=utf-8)? content-type.

func XMLXRDContentType added in v0.13.3

func XMLXRDContentType(ct string) bool

XMLXRDContentType returns whether is application/(xrd+)?xml(;charset=utf-8)? content-type.

Types

type OGMeta added in v0.14.0

type OGMeta struct {
	// vanilla og tags
	Title       string // og:title
	Type        string // og:type
	Locale      string // og:locale
	URL         string // og:url
	SiteName    string // og:site_name
	Description string // og:description

	// image tags
	Image       string // og:image
	ImageWidth  string // og:image:width
	ImageHeight string // og:image:height
	ImageAlt    string // og:image:alt

	// article tags
	ArticlePublisher     string // article:publisher
	ArticleAuthor        string // article:author
	ArticleModifiedTime  string // article:modified_time
	ArticlePublishedTime string // article:published_time

	// profile tags
	ProfileUsername string // profile:username
}

OGMeta represents supported OpenGraph Meta tags

see eg https://ogp.me/

func OGBase added in v0.14.0

func OGBase(instance *apimodel.InstanceV1) *OGMeta

OGBase returns an *ogMeta suitable for serving at the base root of an instance. It also serves as a foundation for building account / status ogMeta on top of.

func (*OGMeta) WithAccount added in v0.14.0

func (og *OGMeta) WithAccount(account *apimodel.Account) *OGMeta

WithAccount uses the given account to build an ogMeta struct specific to that account. It's suitable for serving at account profile pages.

func (*OGMeta) WithStatus added in v0.14.0

func (og *OGMeta) WithStatus(status *apimodel.Status) *OGMeta

WithStatus uses the given status to build an ogMeta struct specific to that status. It's suitable for serving at status pages.

type WebPage added in v0.14.0

type WebPage struct {
	// Name of the template for rendering
	// the page. Eg., "example.tmpl".
	Template string

	// Instance model for rendering header,
	// footer, and "about" information.
	Instance *apimodel.InstanceV1

	// OGMeta for rendering page
	// "meta:og*" tags. Can be nil.
	OGMeta *OGMeta

	// Paths to CSS files to add to
	// the page as "stylesheet" entries.
	// Can be nil.
	Stylesheets []string

	// Paths to JS files to add to
	// the page as "script" entries.
	// Can be nil.
	Javascript []string

	// Extra parameters to pass to
	// the template for rendering,
	// eg., "account": *Account etc.
	// Can be nil.
	Extra map[string]any
}

WebPage encapsulates variables for rendering an HTML template within a standard GtS "page" template.

Jump to

Keyboard shortcuts

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