webserver

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: MIT Imports: 45 Imported by: 0

Documentation

Overview

Example (ResultTreePrefixRange)
prefix := resultTreePathKey([]string{"top", "narrow"}) + "/"
fmt.Println(prefix, strings.TrimSuffix(prefix, "/")+"0")
Output:
top/narrow/ top/narrow0

Index

Examples

Constants

View Source
const (
	RuntimeTransportHTTP1 = "http1"
	RuntimeTransportHTTP2 = "http2"
	RuntimeTransportHTTP3 = "http3"
)
View Source
const (
	PreflightNotRun   = "not_run"
	PreflightRunning  = "running"
	PreflightComplete = "complete"
	PreflightFailed   = "failed"
)

Variables

View Source
var ErrFilterConflict = errors.New("filter addition conflicts with the persisted scan")
View Source
var ErrMissingFuzzKeyword = errors.New("no active fuzz keyword configured")

ErrMissingFuzzKeyword is returned when none of the configured input-provider keywords occur in the effective request. ConfigFromOptions supports FUZZ in the URL, method, headers or body, raw request files, and named wordlist keywords, so this check does not narrow ffuf's supported request shapes.

View Source
var ErrNotFound = errors.New("not found")

Functions

func DefaultDatabasePath

func DefaultDatabasePath() (string, error)

func DefaultTLSCertificatePaths

func DefaultTLSCertificatePaths(databasePath string) (certificatePath, privateKeyPath string, err error)

DefaultTLSCertificatePaths locates the generated certificate beside the web database. This couples the persisted Basic Auth identity and TLS identity, and means selecting a different -web-db cannot unexpectedly reuse a key.

func RandomPassword

func RandomPassword() (string, error)

RandomPassword returns a 192-bit password encoded without padding so it is safe to copy from the terminal into a browser authentication prompt.

Types

type APIError

type APIError struct {
	Error APIErrorBody `json:"error"`
}

type APIErrorBody

type APIErrorBody struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

type AddSessionFiltersRequest

type AddSessionFiltersRequest struct {
	Mode   string `json:"mode,omitempty"`
	Lines  string `json:"lines,omitempty"`
	Regexp string `json:"regexp,omitempty"`
	Size   string `json:"size,omitempty"`
	Status string `json:"status,omitempty"`
	Time   string `json:"time,omitempty"`
	Words  string `json:"words,omitempty"`
}

AddSessionFiltersRequest adds result filters to a session. Empty fields are no-ops, which makes retries idempotent. Once a scan has started filters are deliberately additive: responses rejected by the engine were never retained and therefore cannot be restored by a later removal.

type BulkSessionRequest

type BulkSessionRequest struct {
	IDs    []string `json:"ids"`
	Action string   `json:"action"`
}

type BulkSessionResult

type BulkSessionResult struct {
	Succeeded []string          `json:"succeeded"`
	Failed    map[string]string `json:"failed"`
}

type CloneSessionRequest

type CloneSessionRequest struct {
	Name          string              `json:"name,omitempty"`
	Target        *string             `json:"target,omitempty"`
	Wordlist      *string             `json:"wordlist,omitempty"`
	Profile       *string             `json:"profile,omitempty"`
	Options       *ffuf.ConfigOptions `json:"options,omitempty"`
	ExplicitFlags *[]string           `json:"explicit_flags,omitempty"`
	AutoStart     bool                `json:"auto_start"`
}

type Config

type Config struct {
	ListenAddress   string
	DatabasePath    string
	Username        string
	Password        string
	CertificatePath string
	PrivateKeyPath  string
	PlainHTTP       bool
	AllowRemote     bool
	AllowInputCmd   bool
	Assets          fs.FS
}

type CreateSessionRequest

type CreateSessionRequest struct {
	Name          string              `json:"name"`
	Target        string              `json:"target"`
	Wordlist      string              `json:"wordlist"`
	Profile       string              `json:"profile"`
	Options       *ffuf.ConfigOptions `json:"options,omitempty"`
	ExplicitFlags []string            `json:"explicit_flags,omitempty"`
	AutoStart     bool                `json:"auto_start"`
}

type Defaults

type Defaults struct {
	Wordlist      string             `json:"wordlist"`
	Profile       string             `json:"profile"`
	Options       ffuf.ConfigOptions `json:"options"`
	ExplicitFlags []string           `json:"explicit_flags"`
}

type ErrorDiagnostic

type ErrorDiagnostic struct {
	Category   string   `json:"category"`
	Count      int64    `json:"count"`
	Samples    []string `json:"samples"`
	Suggestion string   `json:"suggestion"`
}

type Event

type Event struct {
	Type      string      `json:"type"`
	SessionID string      `json:"session_id,omitempty"`
	Sequence  int64       `json:"sequence"`
	Data      interface{} `json:"data,omitempty"`
	At        time.Time   `json:"at"`
}

type ExploredResult

type ExploredResult struct {
	StoredResult
	DuplicateCount int64  `json:"duplicate_count,omitempty"`
	WildcardGroup  bool   `json:"wildcard_group,omitempty"`
	Signature      string `json:"signature,omitempty"`
}

type Hub

type Hub struct {
	// contains filtered or unexported fields
}

Hub never waits for a browser. A slow client is marked stale and receives a resync.required marker after it drains enough data; REST remains authoritative.

func NewHub

func NewHub() *Hub

func (*Hub) Broadcast

func (h *Hub) Broadcast(event Event)

func (*Hub) Close

func (h *Hub) Close()

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

func NewManager

func NewManager(store *Store, hub *Hub, allowInputCmd bool) (*Manager, error)

func (*Manager) AddFilters

func (m *Manager) AddFilters(ctx context.Context, id string, request AddSessionFiltersRequest) (Session, error)

AddFilters atomically validates and adds filters to a session. Once a scan has started only OR-mode metadata filters can be added. This guarantees that an edit can hide more findings but can never promise to restore responses that the running engine already discarded.

func (*Manager) Create

func (m *Manager) Create(ctx context.Context, request CreateSessionRequest) (Session, error)

func (*Manager) Delete

func (m *Manager) Delete(ctx context.Context, id string) error

func (*Manager) Pause

func (m *Manager) Pause(ctx context.Context, id string) error

func (*Manager) RerunPreflight

func (m *Manager) RerunPreflight(ctx context.Context, id string) (Session, error)

RerunPreflight repeats the exact bounded runner initialization used by Start without scheduling fuzz inputs. It is valid for any inactive session and persists both the in-progress and final report so REST and WebSocket clients observe one authoritative state transition.

func (*Manager) Resume

func (m *Manager) Resume(ctx context.Context, id string) error

func (*Manager) Shutdown

func (m *Manager) Shutdown(ctx context.Context) error

func (*Manager) Start

func (m *Manager) Start(ctx context.Context, id string) error

func (*Manager) Stop

func (m *Manager) Stop(ctx context.Context, id string) error

func (*Manager) StopSnapshot

func (m *Manager) StopSnapshot(ctx context.Context, id string) (Session, error)

StopSnapshot persists and broadcasts the intermediate stopping state before canceling transport work. Returning the captured snapshot lets the REST action acknowledge the operator immediately without racing the final stopped transition performed by run.

func (*Manager) Update

func (m *Manager) Update(ctx context.Context, id string, patch PatchSessionRequest) (Session, error)

type NumericFacet

type NumericFacet struct {
	Min int64 `json:"min"`
	Max int64 `json:"max"`
}

type PatchSessionOrganizationRequest

type PatchSessionOrganizationRequest struct {
	Pinned    *bool   `json:"pinned,omitempty"`
	Archived  *bool   `json:"archived,omitempty"`
	GroupName *string `json:"group_name,omitempty"`
}

type PatchSessionRequest

type PatchSessionRequest struct {
	Name          *string             `json:"name,omitempty"`
	Target        *string             `json:"target,omitempty"`
	Wordlist      *string             `json:"wordlist,omitempty"`
	Profile       *string             `json:"profile,omitempty"`
	Options       *ffuf.ConfigOptions `json:"options,omitempty"`
	ExplicitFlags *[]string           `json:"explicit_flags,omitempty"`
}

type PreflightCheck

type PreflightCheck struct {
	Attempted bool   `json:"attempted"`
	Reliable  bool   `json:"reliable"`
	Reason    string `json:"reason,omitempty"`
	Requests  int    `json:"requests"`
	ElapsedMS int64  `json:"elapsed_ms"`
}

type PreflightReport

type PreflightReport struct {
	State                string                `json:"state"`
	RanAt                *time.Time            `json:"ran_at,omitempty"`
	CompletedAt          *time.Time            `json:"completed_at,omitempty"`
	HTTP3Advertised      bool                  `json:"http3_advertised"`
	HTTP3Negotiated      bool                  `json:"http3_negotiated"`
	HTTP3Advertisement   string                `json:"http3_advertisement,omitempty"`
	AdvertisementCheck   PreflightCheck        `json:"advertisement_check"`
	NegotiationCheck     PreflightCheck        `json:"negotiation_check"`
	Fingerprint          ffuf.HTTP3Fingerprint `json:"fingerprint"`
	HEADCheck            PreflightCheck        `json:"head_check"`
	RangeCheck           PreflightCheck        `json:"range_check"`
	SelectedProtocol     string                `json:"selected_protocol"`
	SelectedStrategy     string                `json:"selected_strategy"`
	StrategyReason       string                `json:"strategy_reason,omitempty"`
	EffectiveWorkers     int                   `json:"effective_workers"`
	EffectiveConnections int                   `json:"effective_connections"`
	EffectiveStreams     int                   `json:"effective_streams"`
	StreamsPerConnection int                   `json:"streams_per_connection"`
	DowngradeReason      string                `json:"downgrade_reason,omitempty"`
	TimingsMS            PreflightTimings      `json:"timings_ms"`
	Error                string                `json:"error,omitempty"`
}

PreflightReport is deliberately shaped for the web API rather than exposing runner internals. The flattened decision fields are stable UI contracts while Fingerprint keeps detailed QUIC evidence available in the report drawer.

type PreflightTimings

type PreflightTimings struct {
	Advertisement int64 `json:"advertisement"`
	HTTP3         int64 `json:"http3"`
	Baseline      int64 `json:"baseline"`
	HEAD          int64 `json:"head"`
	Range         int64 `json:"range"`
	Total         int64 `json:"total"`
}

type Preset

type Preset struct {
	ID            string             `json:"id"`
	Name          string             `json:"name"`
	Description   string             `json:"description,omitempty"`
	Wordlist      string             `json:"wordlist"`
	Profile       string             `json:"profile"`
	Options       ffuf.ConfigOptions `json:"options"`
	ExplicitFlags []string           `json:"explicit_flags"`
	CreatedAt     time.Time          `json:"created_at"`
	UpdatedAt     time.Time          `json:"updated_at"`
}

type Profile

type Profile struct {
	ID          string   `json:"id"`
	Name        string   `json:"name"`
	Description string   `json:"description"`
	Extensions  []string `json:"extensions"`
}

func Profiles

func Profiles() []Profile

type Progress

type Progress struct {
	StartedAt               time.Time         `json:"started_at"`
	ReqCount                int               `json:"req_count"`
	RequestCount            int               `json:"request_count"`
	CompletedCount          int               `json:"completed_count"`
	ResponseCount           int               `json:"response_count"`
	ReqTotal                int               `json:"req_total"`
	ReqSec                  int64             `json:"req_sec"`
	CurrentRate             float64           `json:"current_rate"`
	Average30s              float64           `json:"average_30s"`
	OverallAverage          float64           `json:"overall_average"`
	PeakRate                float64           `json:"peak_rate"`
	ETASeconds              *int64            `json:"eta_seconds"`
	QueuePos                int               `json:"queue_pos"`
	QueueTotal              int               `json:"queue_total"`
	ErrorCount              int               `json:"error_count"`
	ResultsQueued           int               `json:"results_queued"`
	PersistenceBackpressure bool              `json:"persistence_backpressure"`
	LastBatchDurationMS     int64             `json:"last_batch_duration_ms"`
	ErrorDiagnostics        []ErrorDiagnostic `json:"error_diagnostics,omitempty"`
	StallReason             string            `json:"stall_reason,omitempty"`
	StalledForMS            int64             `json:"stalled_for_ms,omitempty"`
}

type ResultExplorerPage

type ResultExplorerPage struct {
	Results []ExploredResult `json:"results"`
	Total   int64            `json:"total"`
	Offset  int              `json:"offset"`
	Limit   int              `json:"limit"`
	HasMore bool             `json:"has_more"`
	Facets  ResultFacets     `json:"facets"`
}

type ResultExplorerQuery

type ResultExplorerQuery struct {
	Search          string
	Statuses        []int64
	ContentTypes    []string
	SizeMin         *int64
	SizeMax         *int64
	WordsMin        *int64
	WordsMax        *int64
	LinesMin        *int64
	LinesMax        *int64
	Sort            string
	Descending      bool
	Offset          int
	Limit           int
	GroupDuplicates bool
	// SnapshotID is used only by the lazy tree protocol. List exploration stays
	// live, while all pages of one expanded tree share a stable result boundary.
	SnapshotID *int64
}

type ResultFacets

type ResultFacets struct {
	Status      map[string]int64 `json:"status"`
	ContentType map[string]int64 `json:"content_type"`
	Size        NumericFacet     `json:"size"`
	Words       NumericFacet     `json:"words"`
	Lines       NumericFacet     `json:"lines"`
}

type ResultQuery

type ResultQuery struct {
	AfterID  int64
	BeforeID *int64
	Limit    int
	Latest   bool
	Search   string
	Statuses []int64
}

type ResultTreeNode

type ResultTreeNode struct {
	Key         string          `json:"key"`
	Name        string          `json:"name"`
	URL         string          `json:"url"`
	URI         string          `json:"uri"`
	Kind        string          `json:"kind"`
	Result      *ExploredResult `json:"result,omitempty"`
	ResultCount int64           `json:"result_count"`
	HasChildren bool            `json:"has_children"`
}

ResultTreeNode is one immediate child in the server-authoritative directory hierarchy. Children are loaded lazily through Key, so a large scan never has to cross the API boundary as one unbounded response.

type ResultTreePage

type ResultTreePage struct {
	Nodes      []ResultTreeNode `json:"nodes"`
	Total      int              `json:"total"`
	Offset     int              `json:"offset"`
	Limit      int              `json:"limit"`
	HasMore    bool             `json:"has_more"`
	SnapshotID int64            `json:"snapshot_id"`
}

type ResultsPage

type ResultsPage struct {
	Results         []StoredResult   `json:"results"`
	NextCursor      int64            `json:"next_cursor"`
	HasMore         bool             `json:"has_more"`
	WindowTruncated bool             `json:"window_truncated,omitempty"`
	Total           int64            `json:"total"`
	StatusCounts    map[string]int64 `json:"status_counts"`
}

type SaveResultViewRequest

type SaveResultViewRequest struct {
	Name  string          `json:"name"`
	Query json.RawMessage `json:"query"`
}

type SavedResultView

type SavedResultView struct {
	ID        string          `json:"id"`
	SessionID string          `json:"session_id"`
	Name      string          `json:"name"`
	Query     json.RawMessage `json:"query"`
	CreatedAt time.Time       `json:"created_at"`
	UpdatedAt time.Time       `json:"updated_at"`
}

type Server

type Server struct {
	// contains filtered or unexported fields
}

func New

func New(config Config) (*Server, error)

func (*Server) BasicAuthPassword

func (s *Server) BasicAuthPassword() string

BasicAuthPassword returns the credential selected during initialization so the CLI can print it. When Config.Password is empty, this is the generated password persisted in the selected web database.

func (*Server) ConsoleURL

func (s *Server) ConsoleURL(listener net.Listener) string

ConsoleURL returns a browser URL for listener. It retains a configured DNS name (rather than replacing it with the resolved IP) so it continues to match the certificate SAN, while taking the actual port from the bound listener.

func (*Server) Handler

func (s *Server) Handler() http.Handler

func (*Server) Listen

func (s *Server) Listen() (net.Listener, error)

func (*Server) Scheme

func (s *Server) Scheme() string

Scheme reports the transport selected for the web listener.

func (*Server) Serve

func (s *Server) Serve() error

func (*Server) ServeListener

func (s *Server) ServeListener(listener net.Listener) error

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

func (*Server) TLSCertificatePaths

func (s *Server) TLSCertificatePaths() (certificatePath, privateKeyPath string)

TLSCertificatePaths returns the selected PEM paths. They are empty for explicit plain HTTP and for intentionally ephemeral in-memory databases.

type Session

type Session struct {
	ID       string             `json:"id"`
	Name     string             `json:"name"`
	Target   string             `json:"target"`
	Wordlist string             `json:"wordlist"`
	Profile  string             `json:"profile"`
	Status   SessionStatus      `json:"status"`
	Options  ffuf.ConfigOptions `json:"options"`
	// ResultFilters contains only filters added after execution began. Options
	// keeps the complete effective ffuf configuration, while this subset lets
	// stored findings be filtered retroactively without reapplying filters the
	// engine had already enforced before persistence.
	ResultFilters ffuf.FilterOptions `json:"-"`
	ExplicitFlags []string           `json:"explicit_flags"`
	Progress      Progress           `json:"progress"`
	ResultCount   int64              `json:"result_count"`
	Sequence      int64              `json:"sequence"`
	Error         string             `json:"error,omitempty"`
	CreatedAt     time.Time          `json:"created_at"`
	UpdatedAt     time.Time          `json:"updated_at"`
	StartedAt     *time.Time         `json:"started_at,omitempty"`
	CompletedAt   *time.Time         `json:"completed_at,omitempty"`
	// Runtime fields report the transport and response-minimisation strategy
	// actually selected after probing. They are separate from Options, which
	// preserves the operator's requested configuration.
	RuntimeTransport             string            `json:"runtime_transport,omitempty"`
	RuntimeTransportReason       string            `json:"runtime_transport_reason,omitempty"`
	ResponseOptimizationStrategy string            `json:"response_optimization_strategy,omitempty"`
	ResponseOptimizationReason   string            `json:"response_optimization_reason,omitempty"`
	PreflightReport              PreflightReport   `json:"preflight_report"`
	ErrorDiagnostics             []ErrorDiagnostic `json:"error_diagnostics"`
	Pinned                       bool              `json:"pinned"`
	Archived                     bool              `json:"archived"`
	GroupName                    string            `json:"group_name,omitempty"`
	ClonedFromID                 string            `json:"cloned_from_id,omitempty"`
}

type SessionComparison

type SessionComparison struct {
	LeftSessionID     string         `json:"left_session_id"`
	RightSessionID    string         `json:"right_session_id"`
	Added             []StoredResult `json:"added"`
	Removed           []StoredResult `json:"removed"`
	AddedTotal        int64          `json:"added_total"`
	RemovedTotal      int64          `json:"removed_total"`
	UnchangedCount    int64          `json:"unchanged_count"`
	AddedNextCursor   string         `json:"added_next_cursor,omitempty"`
	RemovedNextCursor string         `json:"removed_next_cursor,omitempty"`
	AddedHasMore      bool           `json:"added_has_more"`
	RemovedHasMore    bool           `json:"removed_has_more"`
	Limit             int            `json:"limit"`
}

type SessionComparisonQuery

type SessionComparisonQuery struct {
	Side   string
	Cursor string
	Limit  int
}

type SessionOrganization

type SessionOrganization struct {
	Pinned       bool   `json:"pinned"`
	Archived     bool   `json:"archived"`
	GroupName    string `json:"group_name,omitempty"`
	ClonedFromID string `json:"cloned_from_id,omitempty"`
}

SessionOrganization is intentionally stored separately from the execution record. Organizing a running scan must never rewrite its scanner config or race the hot progress-update path.

type SessionStatus

type SessionStatus string
const (
	StatusIdle      SessionStatus = "idle"
	StatusStarting  SessionStatus = "starting"
	StatusRunning   SessionStatus = "running"
	StatusPaused    SessionStatus = "paused"
	StatusStopping  SessionStatus = "stopping"
	StatusCompleted SessionStatus = "completed"
	StatusStopped   SessionStatus = "stopped"
	StatusFailed    SessionStatus = "failed"
)

type Settings

type Settings struct {
	SchemaVersion int       `json:"schema_version"`
	Defaults      Defaults  `json:"defaults"`
	UpdatedAt     time.Time `json:"updated_at"`
}

func DefaultSettings

func DefaultSettings() Settings

type StorageStats

type StorageStats struct {
	DatabaseBytes         int64 `json:"database_bytes"`
	WALBytes              int64 `json:"wal_bytes"`
	TotalBytes            int64 `json:"total_bytes"`
	ReclaimableBytes      int64 `json:"reclaimable_bytes"`
	WarningThresholdBytes int64 `json:"warning_threshold_bytes"`
	Warning               bool  `json:"warning"`
	ResponseBodiesStored  bool  `json:"response_bodies_stored"`
}

StorageStats describes the durable web console store. Raw response bodies are deliberately not persisted; result metadata, optional scraper output, terminal history, scan configuration, and indexes account for the usage.

type Store

type Store struct {
	// contains filtered or unexported fields
}

func OpenStore

func OpenStore(path string) (*Store, error)

func (*Store) AllResults

func (s *Store) AllResults(ctx context.Context, sessionID string) ([]StoredResult, error)

func (*Store) Close

func (s *Store) Close() error

func (*Store) Compact

func (s *Store) Compact(ctx context.Context) error

func (*Store) CompareSessions

func (s *Store) CompareSessions(ctx context.Context, leftID, rightID string) (SessionComparison, error)

CompareSessions retains the original store API while making its response bounded. API consumers can request subsequent pages through the query-aware endpoint.

func (*Store) CompareSessionsPage

func (s *Store) CompareSessionsPage(ctx context.Context, leftID, rightID string, query SessionComparisonQuery) (SessionComparison, error)

CompareSessionsPage performs a merge over URL-ordered result rows. Unlike the original map-based implementation, memory is bounded by the requested page size. The entire comparison is read through one SQLite cursor, giving totals and both change lists one consistent database snapshot while retaining the exact semantics of retroactive session filters and duplicate URLs.

func (*Store) CreateSession

func (s *Store) CreateSession(ctx context.Context, session *Session) error

func (*Store) DeletePreset

func (s *Store) DeletePreset(ctx context.Context, id string) error

func (*Store) DeleteResultView

func (s *Store) DeleteResultView(ctx context.Context, sessionID, viewID string) error

func (*Store) DeleteSession

func (s *Store) DeleteSession(ctx context.Context, id string) error

func (*Store) ExploreResultTree

func (s *Store) ExploreResultTree(ctx context.Context, sessionID string, query ResultExplorerQuery, parent resultTreeScope) (ResultTreePage, error)

ExploreResultTree aggregates one hierarchy level in SQLite. The path index makes a deep expansion proportional to the selected subtree instead of the entire scan, while SQL grouping avoids allocating and decoding every result in Go. The id boundary keeps all lazy pages on one stable snapshot.

func (*Store) ExploreResults

func (s *Store) ExploreResults(ctx context.Context, sessionID string, query ResultExplorerQuery) (ResultExplorerPage, error)

func (*Store) ForEachResult

func (s *Store) ForEachResult(ctx context.Context, sessionID string, fn func(StoredResult) error) error

func (*Store) ForEachTerminalEntry

func (s *Store) ForEachTerminalEntry(ctx context.Context, sessionID string, fn func(TerminalEntry) error) error

func (*Store) GetSession

func (s *Store) GetSession(ctx context.Context, id string) (Session, error)

func (*Store) GetSettings

func (s *Store) GetSettings(ctx context.Context) (Settings, error)

func (*Store) InsertResultBatch

func (s *Store) InsertResultBatch(ctx context.Context, sessionID string, results []StoredResult, logs []TerminalEntry) ([]StoredResult, []TerminalEntry, error)

func (*Store) LatestResults

func (s *Store) LatestResults(ctx context.Context, sessionID string, limit int) (ResultsPage, error)

func (*Store) ListSessions

func (s *Store) ListSessions(ctx context.Context) ([]Session, error)

func (*Store) PatchSessionOrganization

func (s *Store) PatchSessionOrganization(ctx context.Context, sessionID string, patch PatchSessionOrganizationRequest) (SessionOrganization, error)

func (*Store) Preset

func (s *Store) Preset(ctx context.Context, id string) (Preset, error)

func (*Store) Presets

func (s *Store) Presets(ctx context.Context) ([]Preset, error)

func (*Store) PutPreset

func (s *Store) PutPreset(ctx context.Context, preset Preset) (Preset, error)

func (*Store) PutSettings

func (s *Store) PutSettings(ctx context.Context, settings Settings) error

func (*Store) QueryResults

func (s *Store) QueryResults(ctx context.Context, sessionID string, query ResultQuery) (ResultsPage, error)

QueryResults applies the session's persisted live filters first, then the transient UI search and status filters, and only then selects a page. Status facets intentionally ignore the transient status selection so options do not disappear merely because they are not present in the current page.

func (*Store) ResultViewByName

func (s *Store) ResultViewByName(ctx context.Context, sessionID, name string) (SavedResultView, error)

func (*Store) ResultViews

func (s *Store) ResultViews(ctx context.Context, sessionID string) ([]SavedResultView, error)

func (*Store) Results

func (s *Store) Results(ctx context.Context, sessionID string, afterID int64, limit int) (ResultsPage, error)

func (*Store) SaveResultView

func (s *Store) SaveResultView(ctx context.Context, sessionID string, request SaveResultViewRequest) (SavedResultView, error)

func (*Store) SearchTerminal

func (s *Store) SearchTerminal(ctx context.Context, sessionID string, query TerminalQuery) (TerminalSearchPage, error)

func (*Store) SessionOrganization

func (s *Store) SessionOrganization(ctx context.Context, sessionID string) (SessionOrganization, error)

func (*Store) SetClonedFrom

func (s *Store) SetClonedFrom(ctx context.Context, sessionID, sourceID string) error

func (*Store) SetSequence

func (s *Store) SetSequence(ctx context.Context, id string, sequence int64) error

func (*Store) StorageStats

func (s *Store) StorageStats(ctx context.Context) (StorageStats, error)

func (*Store) Terminal

func (s *Store) Terminal(ctx context.Context, sessionID string, afterID int64, limit int) (TerminalPage, error)

func (*Store) TerminalEntries

func (s *Store) TerminalEntries(ctx context.Context, sessionID string) ([]TerminalEntry, error)

func (*Store) TransitionSessionStatus

func (s *Store) TransitionSessionStatus(ctx context.Context, id string, from, to SessionStatus, errText string, started *time.Time) error

func (*Store) UpdateProgress

func (s *Store) UpdateProgress(ctx context.Context, id string, progress interface{}, sequence int64) error

func (*Store) UpdateProgressTelemetry

func (s *Store) UpdateProgressTelemetry(ctx context.Context, id string, progress interface{}, diagnostics []ErrorDiagnostic, sequence int64) error

func (*Store) UpdateSessionConfig

func (s *Store) UpdateSessionConfig(ctx context.Context, session Session) error

func (*Store) UpdateSessionFilters

func (s *Store) UpdateSessionFilters(ctx context.Context, id string, options ffuf.ConfigOptions, resultOptions ffuf.FilterOptions, explicitFlags []string) error

UpdateSessionFilters persists the complete ffuf filter configuration and the post-start subset used for retroactive result visibility. The visible result count is recomputed in the same transaction, so session snapshots, result pages, and exports all switch to the new filter set together.

func (*Store) UpdateSessionPreflight

func (s *Store) UpdateSessionPreflight(ctx context.Context, id string, report PreflightReport) error

func (*Store) UpdateSessionRuntime

func (s *Store) UpdateSessionRuntime(ctx context.Context, id, transport, transportReason, optimizationStrategy, optimizationReason string) error

UpdateSessionRuntime persists the effective choices made by transport and response-optimization probing. These values describe what the run used, while Session.Options continues to describe what the operator requested.

func (*Store) UpdateSessionStatus

func (s *Store) UpdateSessionStatus(ctx context.Context, id string, status SessionStatus, errText string, started, completed *time.Time) error

type StoredResult

type StoredResult struct {
	ID               int64               `json:"id"`
	SessionID        string              `json:"session_id"`
	Input            map[string][]byte   `json:"input"`
	Position         int                 `json:"position"`
	StatusCode       int64               `json:"status"`
	ContentLength    int64               `json:"length"`
	ContentWords     int64               `json:"words"`
	ContentLines     int64               `json:"lines"`
	ContentType      string              `json:"content_type"`
	RedirectLocation string              `json:"redirect_location"`
	URL              string              `json:"url"`
	DurationNS       int64               `json:"duration_ns"`
	ScraperData      map[string][]string `json:"scraper,omitempty"`
	Host             string              `json:"host"`
	// ResponseFingerprint is a SHA-256 digest of the response bytes that were
	// actually captured by the runner. It is intentionally empty for bodyless
	// responses. Explorer duplicate grouping must never infer equality from
	// status, size, word, and line counts alone.
	ResponseFingerprint string    `json:"response_fingerprint,omitempty"`
	CreatedAt           time.Time `json:"created_at"`
	// contains filtered or unexported fields
}

type TerminalEntry

type TerminalEntry struct {
	ID        int64     `json:"id"`
	SessionID string    `json:"session_id"`
	At        time.Time `json:"at"`
	Level     string    `json:"level"`
	Message   string    `json:"message"`
}

type TerminalPage

type TerminalPage struct {
	Entries    []TerminalEntry `json:"entries"`
	NextCursor int64           `json:"next_cursor"`
	HasMore    bool            `json:"has_more"`
}

type TerminalQuery

type TerminalQuery struct {
	Search     string
	Levels     []string
	Offset     int
	Limit      int
	Latest     bool
	BeforeID   *int64
	SnapshotID *int64
}

type TerminalSearchPage

type TerminalSearchPage struct {
	Entries []TerminalEntry  `json:"entries"`
	Total   int64            `json:"total"`
	Offset  int              `json:"offset"`
	Limit   int              `json:"limit"`
	HasMore bool             `json:"has_more"`
	Levels  map[string]int64 `json:"levels"`
	// Cursor fields are populated for latest=true requests. SnapshotID freezes
	// the searchable history boundary, while NextBeforeID pages backwards
	// without paying SQLite's increasingly expensive OFFSET cost.
	SnapshotID   int64 `json:"snapshot_id,omitempty"`
	NextBeforeID int64 `json:"next_before_id,omitempty"`
	HasOlder     bool  `json:"has_older,omitempty"`
}

type WordlistInspection

type WordlistInspection struct {
	Path                    string `json:"path"`
	Readable                bool   `json:"readable"`
	Entries                 int64  `json:"entries"`
	ExtensionMarkers        int64  `json:"extension_markers"`
	CommentEntries          int64  `json:"comment_entries"`
	CommentExtensionMarkers int64  `json:"comment_extension_markers"`
	SizeBytes               int64  `json:"size_bytes,omitempty"`
	Error                   string `json:"error,omitempty"`
}

Jump to

Keyboard shortcuts

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