// Copyright 2024 Matthew Rich . All rights reserved. package source import ( _ "context" _ "encoding/json" _ "fmt" _ "gopkg.in/yaml.v3" "net/url" _ "net/http" _ "path/filepath" "decl/internal/resource" "decl/internal/iofilter" "decl/internal/signature" "decl/internal/transport" _ "os" "io" "errors" "crypto/sha256" ) type HTTP struct { Endpoint string `yaml:"endpoint" json:"endpoint"` transport *transport.Reader `yaml:"-" json:"-"` } func NewHTTP() *HTTP { return &HTTP{} } func init() { SourceTypes.Register([]string{"http","https"}, func(u *url.URL) DocSource { t := NewHTTP() t.Endpoint = u.String() t.transport,_ = transport.NewReader(u) return t }) } func (d *HTTP) Type() string { return "http" } func (h *HTTP) ExtractResources(filter ResourceSelector) ([]*resource.Document, error) { documents := make([]*resource.Document, 0, 100) defer h.transport.Close() documentSignature := h.transport.Signature() hash := sha256.New() sumReadData := iofilter.NewReader(h.transport, func(p []byte, readn int, readerr error) (n int, err error) { hash.Write(p) return }) decoder := resource.NewYAMLDecoder(sumReadData) index := 0 for { doc := resource.NewDocument() e := decoder.Decode(doc) if errors.Is(e, io.EOF) { break } if e != nil { return documents, e } if validationErr := doc.Validate(); validationErr != nil { return documents, validationErr } documents = append(documents, doc) index++ } if documentSignature != "" { sig := &signature.Ident{} sigErr := sig.VerifySum(hash.Sum(nil), []byte(documentSignature)) if sigErr != nil { return documents, sigErr } } return documents, nil }