p1: /v2/scrape, /v1/fetch, auth, CLI, contract tests

Single Fetcher.Fetch on the Guard that holds DenyPrefixes. skipTlsVerification
is ignored. No 502. keys add writes the secret only to --out. Release binary
has no -test-allow-prefix.
This commit is contained in:
2026-09-22 21:54:01 -07:00
parent 6cb206fb27
commit 9444a35322
311 changed files with 238557 additions and 92 deletions
+124
View File
@@ -0,0 +1,124 @@
package unstable
import (
"errors"
"fmt"
)
// Iterator over a sequence of nodes.
//
// Starts uninitialized, you need to call Next() first.
//
// For example:
//
// it := n.Children()
// for it.Next() {
// n := it.Node()
// // do something with n
// }
type Iterator struct {
started bool
node *Node
}
// Next moves the iterator forward and returns true if points to a node, false
// otherwise.
func (c *Iterator) Next() bool {
if !c.started {
c.started = true
} else if c.node.Valid() {
c.node = c.node.Next()
}
return c.node.Valid()
}
// IsLast returns true if the current node of the iterator is the last
// one. Subsequent calls to Next() will return false.
func (c *Iterator) IsLast() bool {
return c.node.next == 0
}
// Node returns a pointer to the node pointed at by the iterator.
func (c *Iterator) Node() *Node {
return c.node
}
// Node in a TOML expression AST.
//
// Depending on Kind, its sequence of children should be interpreted
// differently.
//
// - Array have one child per element in the array.
// - InlineTable have one child per key-value in the table (each of kind
// InlineTable).
// - KeyValue have at least two children. The first one is the value. The
// rest make a potentially dotted key.
// - Table and ArrayTable's children represent a dotted key (same as
// KeyValue, but without the first node being the value).
//
// When relevant, Raw describes the range of bytes this node is referring to in
// the input document. Use Parser.Raw() to retrieve the actual bytes.
type Node struct {
Kind Kind
Raw Range // Raw bytes from the input.
Data []byte // Node value (either allocated or referencing the input).
// References to other nodes, as 1-based indexes into the parser's arena.
// 0 means no node.
parser *Parser
next int32
child int32
}
// Next returns a pointer to the next node, or nil if there is no next node.
func (n *Node) Next() *Node {
if n.next == 0 {
return nil
}
return &n.parser.nodes[n.next-1]
}
// Child returns a pointer to the first child node of this node. Other children
// can be accessed calling Next on the first child. Returns nil if there is no
// child node.
func (n *Node) Child() *Node {
if n.child == 0 {
return nil
}
return &n.parser.nodes[n.child-1]
}
// Valid returns true if the node's kind is set (not to Invalid).
func (n *Node) Valid() bool {
return n != nil && n.Kind != Invalid
}
// Key returns the children nodes making the Key on a supported node. Panics
// otherwise. They are guaranteed to be all be of the Kind Key. A simple key
// would return just one element.
func (n *Node) Key() Iterator {
switch n.Kind {
case KeyValue:
value := n.Child()
if !value.Valid() {
panic(errors.New("KeyValue should have at least two children"))
}
return Iterator{node: value.Next()}
case Table, ArrayTable:
return Iterator{node: n.Child()}
default:
panic(fmt.Errorf("Key() is not supported on a %s", n.Kind))
}
}
// Value returns a pointer to the value node of a KeyValue.
// Guaranteed to be non-nil. Panics if not called on a KeyValue node,
// or if the Children are malformed.
func (n *Node) Value() *Node {
return n.Child()
}
// Children returns an iterator over a node's children.
func (n *Node) Children() Iterator {
return Iterator{node: n.Child()}
}
+21
View File
@@ -0,0 +1,21 @@
package unstable
import "github.com/pelletier/go-toml/v2/internal/parserbridge"
// Expose the non-AST scanners to the root toml package without committing to
// them in the public API. See internal/parserbridge for the rationale.
//
//nolint:gochecknoinits // load-time wiring of an internal bridge (see internal/parserbridge)
func init() {
parserbridge.ScanScalar = func(p any, b []byte) (kind int, raw, value, rest []byte, err error) {
k, raw, value, rest, err := p.(*Parser).scanScalar(b)
return int(k), raw, value, rest, err
}
parserbridge.ScanKey = func(p any, b []byte, dst [][]byte) (parts [][]byte, raw, rest []byte, err error) {
return p.(*Parser).scanKey(b, dst)
}
parserbridge.ScanComment = scanComment
parserbridge.ParseValue = func(p any, b []byte) (node any, rest []byte, err error) {
return p.(*Parser).parseValue(b)
}
}
+3
View File
@@ -0,0 +1,3 @@
// Package unstable provides APIs that do not meet the backward compatibility
// guarantees yet.
package unstable
+83
View File
@@ -0,0 +1,83 @@
package unstable
import "fmt"
// Kind represents the type of TOML structure contained in a given Node.
type Kind int
const (
// Invalid represents an invalid meta node.
Invalid Kind = iota
// Comment represents a comment meta node.
Comment
// Key represents a key meta node.
Key
// Table represents a top-level table.
Table
// ArrayTable represents a top-level array table.
ArrayTable
// KeyValue represents a top-level key value.
KeyValue
// Array represents an array container value.
Array
// InlineTable represents an inline table container value.
InlineTable
// String represents a string value.
String
// Bool represents a boolean value.
Bool
// Float represents a floating point value.
Float
// Integer represents an integer value.
Integer
// LocalDate represents a local date value.
LocalDate
// LocalTime represents a local time value.
LocalTime
// LocalDateTime represents a local date/time value.
LocalDateTime
// DateTime represents a data/time value.
DateTime
)
// String implementation of fmt.Stringer.
func (k Kind) String() string {
switch k {
case Invalid:
return "Invalid"
case Comment:
return "Comment"
case Key:
return "Key"
case Table:
return "Table"
case ArrayTable:
return "ArrayTable"
case KeyValue:
return "KeyValue"
case Array:
return "Array"
case InlineTable:
return "InlineTable"
case String:
return "String"
case Bool:
return "Bool"
case Float:
return "Float"
case Integer:
return "Integer"
case LocalDate:
return "LocalDate"
case LocalTime:
return "LocalTime"
case LocalDateTime:
return "LocalDateTime"
case DateTime:
return "DateTime"
}
panic(fmt.Errorf("Kind.String() not implemented for kind %d", int(k)))
}
+29
View File
@@ -0,0 +1,29 @@
package unstable
// Marshaler is implemented by types that can marshal themselves into a raw
// TOML description. The returned bytes are spliced verbatim into the encoded
// document, so they must be valid TOML for the position they end up in:
//
// - A single value (string, integer, array, inline table, …) is emitted
// inline, as in `key = <raw>`.
// - One or more key-value lines (optionally with relative sub-table headers)
// is emitted as the body of a `[key]` table.
// - At the document root, the bytes are emitted as the whole document.
//
// The encoder decides between those forms by parsing the returned bytes, and
// reports an error when they are not valid TOML for their position; see
// Encoder.EnableMarshalerInterface in the root toml package. MarshalTOML can
// be called more than once for the same value during a single encode, so it
// must be deterministic.
//
// Marshaler is the encoding counterpart of Unmarshaler.
type Marshaler interface {
MarshalTOML() ([]byte, error)
}
// MarshalTOML implements Marshaler. It returns the raw TOML bytes verbatim,
// mirroring json.RawMessage.MarshalJSON. The value receiver means both
// RawMessage and *RawMessage satisfy Marshaler.
func (m RawMessage) MarshalTOML() ([]byte, error) {
return []byte(m), nil
}
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
package unstable
// Unmarshaler is implemented by types that can unmarshal a TOML description
// of themselves. The input is a valid TOML document containing the relevant
// portion of the parsed document.
//
// For tables (including split tables defined in multiple places), the data
// contains the raw key-value bytes from the original document with adjusted
// table headers to be relative to the unmarshaling target.
//
// When the decoding target itself implements this interface, it receives the
// whole document — every top-level key-value as well as every table and array
// table — assembled into a single valid TOML document and delivered once.
type Unmarshaler interface {
UnmarshalTOML(data []byte) error
}
// RawMessage is a raw encoded TOML value. It implements both Unmarshaler and
// Marshaler and can be used to delay TOML decoding or capture raw content,
// similar to json.RawMessage.
//
// Decoding (requires Decoder.EnableUnmarshalerInterface) captures the raw TOML
// bytes for the target without decoding them:
//
// type Config struct {
// Plugin RawMessage `toml:"plugin"`
// }
//
// var cfg Config
// toml.NewDecoder(r).EnableUnmarshalerInterface().Decode(&cfg)
// // cfg.Plugin now contains the raw TOML bytes for [plugin]
//
// Encoding (requires Encoder.EnableMarshalerInterface) splices the stored bytes
// back into the document verbatim:
//
// toml.NewEncoder(w).EnableMarshalerInterface().Encode(cfg)
type RawMessage []byte
// UnmarshalTOML implements Unmarshaler.
func (m *RawMessage) UnmarshalTOML(data []byte) error {
*m = append((*m)[:0], data...)
return nil
}