// 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" _ "os" "io" "errors" "crypto/sha256" ) type HTTP struct { Endpoint string `yaml:"endpoint" json:"endpoint"` } func NewHTTP() *HTTP { return &HTTP{} } func init() { SourceTypes.Register([]string{"http","https"}, func(u *url.URL) DocSource { t := NewHTTP() t.Endpoint = u.String() return t }) } func (d *HTTP) Type() string { return "http" } func (h *HTTP) ExtractResources(filter ResourceSelector) ([]*resource.Document, error) { documents := make([]*resource.Document, 0, 100) documents = append(documents, resource.NewDocument()) resp, err := http.Get(h.Endpoint) if err != nil { return documents, err } defer resp.Body.Close() signature := resp.Header.Get("Signature") hash := sha256.New() sumReadData := iofilter.New(resp.Body, func(p []byte, readn int, readerr error) (n int, err error) { hash.Write(p) return }) decoder := resource.NewYAMLDecoder(sumReadData) index := 0 for { doc := documents[index] e := decoder.Decode(doc) if errors.Is(e, io.EOF) { if len(documents) > 1 { documents[index] = nil } break } if e != nil { return documents, e } if validationErr := doc.Validate(); validationErr != nil { return documents, validationErr } /* if applyErr := doc.Apply(); applyErr != nil { return documents, applyErr } */ documents = append(documents, resource.NewDocument()) index++ } if signature != "" { sig := signature.&Ident{} sig.VerifySum(hash.Sum(nil), signature) } return documents, nil }