Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion LICENSE-3rdparty.csv
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
Origin,License,"License URL",Copyright
git.sr.ht/~jamesponddotco/acopw-go,MIT,https://git.sr.ht/~jamesponddotco/acopw-go/tree/v1.0.2/LICENSE.md,2024 James Pond
git.sr.ht/~jamesponddotco/credential-go,MIT,https://git.sr.ht/~jamesponddotco/credential-go/tree/v1.0.0/LICENSE.md,2024 James Pond
git.sr.ht/~jamesponddotco/xstd-go,MIT,https://git.sr.ht/~jamesponddotco/xstd-go/tree/v0.13.1/LICENSE.md,2023 James Pond
github.com/RoaringBitmap/roaring/v2,Apache-2.0,https://github.com/RoaringBitmap/roaring/blob/v2.4.5/LICENSE,2014 Daniel Lemire
github.com/alecthomas/chroma/v2,MIT,https://github.com/alecthomas/chroma/blob/v2.17.0/COPYING,2017 Alec Thomas
github.com/aymerick/douceur,MIT,https://github.com/aymerick/douceur/blob/v0.2.0/LICENSE,2015 Aymerick JEHANNE
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ go 1.24
require (
git.sr.ht/~jamesponddotco/acopw-go v1.0.2
git.sr.ht/~jamesponddotco/credential-go v1.0.0
git.sr.ht/~jamesponddotco/xstd-go v0.13.1
github.com/alecthomas/chroma/v2 v2.17.0
github.com/blevesearch/bleve/v2 v2.5.0
github.com/json-iterator/go v1.1.12
github.com/microcosm-cc/bluemonday v1.0.27
go.cipher.host/cmdkit v1.0.2
go.cipher.host/x v1.0.0
go.etcd.io/bbolt v1.4.0
golang.org/x/time v0.11.0
)

require (
git.sr.ht/~jamesponddotco/xstd-go v0.13.1 // indirect
github.com/RoaringBitmap/roaring/v2 v2.4.5 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/bits-and-blooms/bitset v1.22.0 // indirect
Expand Down Expand Up @@ -49,5 +50,5 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/sys v0.33.0 // indirect
)
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,17 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.cipher.host/cmdkit v1.0.2 h1:M06Ms0a9tZaEjZ+YK+ASMKK+VNk9pMcdEqaQLcscn+w=
go.cipher.host/cmdkit v1.0.2/go.mod h1:w9YbDUEIo/ljm7eOpnlsBRGKHJUCrQVxHCjRodIFGYs=
go.cipher.host/x v1.0.0 h1:1SoLtic2X4yGhzeivKv0Y4sd+NdvJF9eM3kV/XXttI0=
go.cipher.host/x v1.0.0/go.mod h1:x3siBGj0CadsToxdghaATU3qdmQ2NWNlAus92Fg/30c=
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
2 changes: 1 addition & 1 deletion internal/app/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import (
"os"
"strings"

"git.sr.ht/~jamesponddotco/xstd-go/xunsafe"
"github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/formatters/html"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
jsoniter "github.com/json-iterator/go"
"go.cipher.host/cmdkit"
"go.cipher.host/pkgdex/internal/errors"
"go.cipher.host/x/xunsafe"
)

const (
Expand Down
4 changes: 2 additions & 2 deletions internal/config/config_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"testing"
"time"

"git.sr.ht/~jamesponddotco/xstd-go/xtime"
"git.sr.ht/~jamesponddotco/xstd-go/xunsafe"
"go.cipher.host/pkgdex/internal/testhelper"
"go.cipher.host/x/xtime"
"go.cipher.host/x/xunsafe"
)

func TestConfig_Validate(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"testing"
"time"

"git.sr.ht/~jamesponddotco/xstd-go/xtime"
"go.cipher.host/pkgdex/internal/config"
"go.cipher.host/pkgdex/internal/testhelper"
"go.cipher.host/x/xtime"
)

func TestLoad(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/config/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"time"

"git.sr.ht/~jamesponddotco/credential-go"
"git.sr.ht/~jamesponddotco/xstd-go/xtime"
"go.cipher.host/cmdkit"
"go.cipher.host/pkgdex/internal/meta"
"go.cipher.host/x/xtime"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion internal/database/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"fmt"
"time"

"git.sr.ht/~jamesponddotco/xstd-go/xunsafe"
"go.cipher.host/cmdkit"
"go.cipher.host/x/xunsafe"
bolt "go.etcd.io/bbolt"
)

Expand Down
2 changes: 1 addition & 1 deletion internal/key/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"strings"

"git.sr.ht/~jamesponddotco/acopw-go"
"git.sr.ht/~jamesponddotco/xstd-go/xunsafe"
"go.cipher.host/pkgdex/internal/meta"
"go.cipher.host/x/xunsafe"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion internal/metric/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"fmt"
"time"

"git.sr.ht/~jamesponddotco/xstd-go/xunsafe"
"go.cipher.host/cmdkit"
"go.cipher.host/pkgdex/internal/database"
"go.cipher.host/x/xunsafe"
bolt "go.etcd.io/bbolt"
)

Expand Down
16 changes: 10 additions & 6 deletions internal/server/handler/downloads.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"log/slog"
"net/http"

"git.sr.ht/~jamesponddotco/xstd-go/xnet/xhttp"
jsoniter "github.com/json-iterator/go"
"go.cipher.host/pkgdex/internal/config"
"go.cipher.host/pkgdex/internal/metric"
"go.cipher.host/pkgdex/internal/server/model"
"go.cipher.host/x/xnet/xhttp"
)

// DownloadsHandler is the HTTP handler for the /meta/downloads endpoint.
Expand All @@ -33,7 +33,7 @@ func NewDownloadsHandler(logger *slog.Logger, metrics *metric.Store, packages []
}

// ServeHTTP handles HTTP requests for the /meta/downloads endpoint.
func (d *DownloadsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (d *DownloadsHandler) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
report := &model.Report{
Packages: make([]model.Package, 0, len(d.packages)),
}
Expand Down Expand Up @@ -68,12 +68,16 @@ func (d *DownloadsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
slog.Any("error", err),
)

response := xhttp.ResponseError{
Message: "Internal server error. Failed to encode download report response.",
Code: http.StatusInternalServerError,
response := xhttp.DetailError{
Detail: "Failed to encode download report response.",
Status: http.StatusInternalServerError,
}

response.Write(r.Context(), d.logger, w)
if err = response.WriteJSON(w); err != nil {
d.logger.Error("failed to write error response",
slog.Any("error", err),
)
}

return
}
Expand Down
16 changes: 10 additions & 6 deletions internal/server/handler/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import (
"net/http"
"time"

"git.sr.ht/~jamesponddotco/xstd-go/xnet/xhttp"
jsoniter "github.com/json-iterator/go"
"go.cipher.host/pkgdex/internal/meta"
"go.cipher.host/pkgdex/internal/server/model"
"go.cipher.host/x/xnet/xhttp"
)

const (
Expand All @@ -34,7 +34,7 @@ func NewHealthHandler(logger *slog.Logger) *HealthHandler {
}

// ServeHTTP handles HTTP requests for the /health endpoint.
func (h *HealthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (h *HealthHandler) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
health := model.Health{
FinishedAt: time.Now().Unix(),
CheckResults: []model.Result{
Expand All @@ -60,12 +60,16 @@ func (h *HealthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
slog.Any("error", err),
)

response := xhttp.ResponseError{
Message: "Internal server error. Failed to encode health response.",
Code: http.StatusInternalServerError,
response := xhttp.DetailError{
Detail: "Failed to encode health response.",
Status: http.StatusInternalServerError,
}

response.Write(r.Context(), h.logger, w)
if err = response.WriteJSON(w); err != nil {
h.logger.Error("failed to write error response",
slog.Any("error", err),
)
}

return
}
Expand Down
19 changes: 4 additions & 15 deletions internal/server/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import (
"net/http/pprof"
"time"

"git.sr.ht/~jamesponddotco/xstd-go/xcrypto/xtls"
"git.sr.ht/~jamesponddotco/xstd-go/xnet/xhttp/xmiddleware"
"go.cipher.host/cmdkit"
"go.cipher.host/pkgdex/internal/config"
"go.cipher.host/pkgdex/internal/database"
Expand All @@ -30,6 +28,8 @@ import (
"go.cipher.host/pkgdex/internal/version"
"go.cipher.host/pkgdex/internal/wayback"
"go.cipher.host/pkgdex/static"
"go.cipher.host/x/xcrypto/xtls"
"go.cipher.host/x/xnet/xhttp/xmiddleware"
)

const (
Expand Down Expand Up @@ -95,23 +95,12 @@ func NewInstance(ctx context.Context, cfg *config.Config, db *database.Store, lo
return nil, fmt.Errorf("%w: %w", ErrTLSCertificates, err)
}

tlsConfig := xtls.ModernServerConfig()
tlsConfig := xtls.ModernConfig()
tlsConfig.Certificates = []tls.Certificate{cert}

middlewares := []func(http.Handler) http.Handler{
func(h http.Handler) http.Handler { return xmiddleware.PanicRecovery(logger, h) },
func(h http.Handler) http.Handler { return xmiddleware.UserAgent(logger, h) },
func(h http.Handler) http.Handler {
return xmiddleware.AcceptRequests(
[]string{
http.MethodGet,
http.MethodHead,
http.MethodOptions,
},
logger,
h,
)
},
xmiddleware.UserAgent,
middleware.CSP,
}

Expand Down
18 changes: 11 additions & 7 deletions internal/server/middleware/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,31 @@ import (
"log/slog"
"net/http"

"git.sr.ht/~jamesponddotco/xstd-go/xcrypto/xsubtle"
"git.sr.ht/~jamesponddotco/xstd-go/xnet/xhttp"
"go.cipher.host/x/xcrypto/xsubtle"
"go.cipher.host/x/xnet/xhttp"
)

// Authorization ensures that the request has a valid API key.
func Authorization(apiKey string, logger *slog.Logger, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !xsubtle.ConstantTimeStringEqual(r.Header.Get("Authorization"), "Bearer "+apiKey) {
if !xsubtle.ConstantTimeCompareString(r.Header.Get("Authorization"), "Bearer "+apiKey) {
logger.Warn("unauthorized API access attempt",
slog.String("remote_addr", r.RemoteAddr),
slog.String("user_agent", r.UserAgent()),
slog.String("path", r.URL.Path),
slog.String("key", r.Header.Get("Authorization")),
)

response := xhttp.ResponseError{
Code: http.StatusUnauthorized,
Message: "Access denied. Please provide a valid API key in the Authorization header.",
response := xhttp.DetailError{
Status: http.StatusUnauthorized,
Detail: "Access denied. Please provide a valid API key in the Authorization header.",
}

response.Write(r.Context(), logger, w)
if err := response.WriteJSON(w); err != nil {
logger.Error("failed to write response",
slog.Any("error", err),
)
}

return
}
Expand Down
5 changes: 2 additions & 3 deletions internal/server/middleware/csp.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ package middleware

import (
"net/http"

"git.sr.ht/~jamesponddotco/xstd-go/xstrings"
"strings"
)

// CSP ensures that the Content-Security-Policy header is set.
Expand Down Expand Up @@ -37,7 +36,7 @@ func CSP(next http.Handler) http.Handler {
"block-all-mixed-content",
"upgrade-insecure-requests",
}
csp = xstrings.JoinWithSeparator("; ", directives...)
csp = strings.Join(directives, "; ")
)

w.Header().Set("Content-Security-Policy", csp)
Expand Down
2 changes: 1 addition & 1 deletion internal/version/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"fmt"
"time"

"git.sr.ht/~jamesponddotco/xstd-go/xunsafe"
jsoniter "github.com/json-iterator/go"
"go.cipher.host/cmdkit"
"go.cipher.host/pkgdex/internal/config"
"go.cipher.host/pkgdex/internal/database"
"go.cipher.host/x/xunsafe"
bolt "go.etcd.io/bbolt"
)

Expand Down
8 changes: 6 additions & 2 deletions internal/wayback/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ func (a *Archive) Save(ctx context.Context, uri string) error {
// already archived.
func (a *Archive) SavePackages(ctx context.Context, cfg *config.Config) error {
for _, pkg := range cfg.Packages {
uri := PackageURI("https://"+cfg.Service.BaseURL, pkg.Name)
uri, err := PackageURI("https://"+cfg.Service.BaseURL, pkg.Name)
if err != nil {
return err
}

if err := a.Save(ctx, uri); err != nil {
err = a.Save(ctx, uri)
if err != nil {
return err
}
}
Expand Down
12 changes: 7 additions & 5 deletions internal/wayback/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ import (
"strings"
"time"

"git.sr.ht/~jamesponddotco/xstd-go/xnet/xhttp"
"git.sr.ht/~jamesponddotco/xstd-go/xstrings"
jsoniter "github.com/json-iterator/go"
"go.cipher.host/cmdkit"
"go.cipher.host/x/xnet/xhttp"
"golang.org/x/time/rate"
)

Expand Down Expand Up @@ -51,7 +50,7 @@ type (
// New returns a new instance of Client.
func NewClient(httpClient Doer) *Client {
if httpClient == nil {
httpClient = xhttp.NewClient(15 * time.Second)
httpClient = xhttp.NewModernClient(15 * time.Second)
}

return &Client{
Expand All @@ -62,9 +61,12 @@ func NewClient(httpClient Doer) *Client {

// Archive attempts to save the given URI to the Wayback Machine.
func (c *Client) Archive(ctx context.Context, uri string) error {
reqURI := xstrings.JoinWithSeparator("/", archiveBaseURL, "save", uri)
reqURI, err := url.JoinPath(archiveBaseURL, "save", uri)
if err != nil {
return fmt.Errorf("%w", err)
}

if _, err := url.ParseRequestURI(reqURI); err != nil {
if _, err = url.ParseRequestURI(reqURI); err != nil {
return fmt.Errorf("%w", err)
}

Expand Down
Loading
Loading