12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- package feed
- import (
- "fmt"
- "html"
- "html/template"
- "io"
- "log/slog"
- "net/http"
- "net/url"
- )
- type ExtensionType int
- const (
- ExtensionContentHTML ExtensionType = iota
- ExtensionContentUnknown = iota
- )
- var ExtensionStringToType = map[string]ExtensionType{
- "html": ExtensionContentHTML,
- }
- const (
- ExtensionHeaderTitle = "Widget-Title"
- ExtensionHeaderContentType = "Widget-Content-Type"
- )
- type ExtensionRequestOptions struct {
- URL string `yaml:"url"`
- Parameters map[string]string `yaml:"parameters"`
- AllowHtml bool `yaml:"allow-potentially-dangerous-html"`
- }
- type Extension struct {
- Title string
- Content template.HTML
- }
- func convertExtensionContent(options ExtensionRequestOptions, content []byte, contentType ExtensionType) template.HTML {
- switch contentType {
- case ExtensionContentHTML:
- if options.AllowHtml {
- return template.HTML(content)
- }
- fallthrough
- default:
- return template.HTML(html.EscapeString(string(content)))
- }
- }
- func FetchExtension(options ExtensionRequestOptions) (Extension, error) {
- request, _ := http.NewRequest("GET", options.URL, nil)
- query := url.Values{}
- for key, value := range options.Parameters {
- query.Set(key, value)
- }
- request.URL.RawQuery = query.Encode()
- response, err := http.DefaultClient.Do(request)
- if err != nil {
- slog.Error("failed fetching extension", "error", err, "url", options.URL)
- return Extension{}, fmt.Errorf("%w: request failed: %w", ErrNoContent, err)
- }
- defer response.Body.Close()
- body, err := io.ReadAll(response.Body)
- if err != nil {
- slog.Error("failed reading response body of extension", "error", err, "url", options.URL)
- return Extension{}, fmt.Errorf("%w: could not read body: %w", ErrNoContent, err)
- }
- extension := Extension{}
- if response.Header.Get(ExtensionHeaderTitle) == "" {
- extension.Title = "Extension"
- } else {
- extension.Title = response.Header.Get(ExtensionHeaderTitle)
- }
- contentType, ok := ExtensionStringToType[response.Header.Get(ExtensionHeaderContentType)]
- if !ok {
- contentType = ExtensionContentUnknown
- }
- extension.Content = convertExtensionContent(options, body, contentType)
- return extension, nil
- }
|