From a4d51b1657ee7ec9616bd9bca8648c8c9e006733 Mon Sep 17 00:00:00 2001 From: Gus Date: Thu, 16 Oct 2025 15:21:03 +0800 Subject: [PATCH 1/2] Use endpoint package name without alias --- handler/categories.go | 8 ++--- handler/education.go | 8 ++--- handler/experience.go | 8 ++--- handler/file_handler_test.go | 4 +-- handler/keep_alive.go | 10 +++---- handler/keep_alive_db.go | 12 ++++---- handler/posts.go | 20 ++++++------- handler/profile.go | 8 ++--- handler/projects.go | 8 ++--- handler/recommendations.go | 8 ++--- handler/signatures.go | 16 +++++----- handler/signatures_test.go | 4 +-- handler/social.go | 8 ++--- handler/talks.go | 8 ++--- metal/cli/seo/client_test.go | 10 +++---- metal/kernel/kernel_test.go | 4 +-- metal/router/router.go | 14 ++++----- metal/router/static.go | 4 +-- pkg/{http => endpoint}/handler.go | 2 +- pkg/{http => endpoint}/handler_test.go | 2 +- pkg/{http => endpoint}/request.go | 2 +- pkg/{http => endpoint}/request_test.go | 2 +- pkg/{http => endpoint}/response.go | 2 +- pkg/{http => endpoint}/response_test.go | 2 +- pkg/{http => endpoint}/schema.go | 2 +- pkg/{http => endpoint}/schema_test.go | 2 +- pkg/{http => endpoint}/scope_api_error.go | 2 +- .../mwguards/mw_response_messages.go | 30 +++++++++---------- .../mwguards/valid_timestamp_guard.go | 8 ++--- pkg/middleware/pipeline.go | 4 +-- pkg/middleware/pipeline_test.go | 12 ++++---- pkg/middleware/public_middleware.go | 10 +++---- pkg/middleware/public_middleware_test.go | 12 ++++---- pkg/middleware/token_middleware.go | 14 ++++----- .../token_middleware_additional_test.go | 12 ++++---- pkg/middleware/token_middleware_test.go | 12 ++++---- 36 files changed, 147 insertions(+), 147 deletions(-) rename pkg/{http => endpoint}/handler.go (98%) rename pkg/{http => endpoint}/handler_test.go (99%) rename pkg/{http => endpoint}/request.go (97%) rename pkg/{http => endpoint}/request_test.go (97%) rename pkg/{http => endpoint}/response.go (99%) rename pkg/{http => endpoint}/response_test.go (99%) rename pkg/{http => endpoint}/schema.go (97%) rename pkg/{http => endpoint}/schema_test.go (97%) rename pkg/{http => endpoint}/scope_api_error.go (99%) diff --git a/handler/categories.go b/handler/categories.go index 4f7fbb2f..13dea903 100644 --- a/handler/categories.go +++ b/handler/categories.go @@ -10,7 +10,7 @@ import ( "github.com/oullin/database/repository/pagination" "github.com/oullin/handler/paginate" "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" ) type CategoriesHandler struct { @@ -23,14 +23,14 @@ func MakeCategoriesHandler(categories *repository.Categories) CategoriesHandler } } -func (h *CategoriesHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h *CategoriesHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { result, err := h.Categories.GetAll( paginate.MakeFrom(r.URL, 5), ) if err != nil { slog.Error("Error getting categories", "err", err) - return http.InternalError("Error getting categories") + return endpoint.InternalError("Error getting categories") } items := pagination.HydratePagination( @@ -48,7 +48,7 @@ func (h *CategoriesHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request if err := json.NewEncoder(w).Encode(items); err != nil { slog.Error("failed to encode response", "err", err) - return http.InternalError("There was an issue processing the response. Please, try later.") + return endpoint.InternalError("There was an issue processing the response. Please, try later.") } return nil diff --git a/handler/education.go b/handler/education.go index fabad168..3a35bc62 100644 --- a/handler/education.go +++ b/handler/education.go @@ -2,7 +2,7 @@ package handler import ( "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "log/slog" @@ -19,16 +19,16 @@ func MakeEducationHandler(filePath string) EducationHandler { } } -func (h EducationHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h EducationHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.EducationResponse](h.filePath) if err != nil { slog.Error("Error reading education file", "error", err) - return http.InternalError("could not read education data") + return endpoint.InternalError("could not read education data") } - resp := http.MakeResponseFrom(data.Version, w, r) + resp := endpoint.MakeResponseFrom(data.Version, w, r) if resp.HasCache() { resp.RespondWithNotModified() diff --git a/handler/experience.go b/handler/experience.go index 95bc5253..dd3f1c6f 100644 --- a/handler/experience.go +++ b/handler/experience.go @@ -2,7 +2,7 @@ package handler import ( "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "log/slog" @@ -19,16 +19,16 @@ func MakeExperienceHandler(filePath string) ExperienceHandler { } } -func (h ExperienceHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h ExperienceHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.ExperienceResponse](h.filePath) if err != nil { slog.Error("Error reading experience file", "error", err) - return http.InternalError("could not read experience data") + return endpoint.InternalError("could not read experience data") } - resp := http.MakeResponseFrom(data.Version, w, r) + resp := endpoint.MakeResponseFrom(data.Version, w, r) if resp.HasCache() { resp.RespondWithNotModified() diff --git a/handler/file_handler_test.go b/handler/file_handler_test.go index c2906682..60ae648f 100644 --- a/handler/file_handler_test.go +++ b/handler/file_handler_test.go @@ -8,11 +8,11 @@ import ( "testing" handlertests "github.com/oullin/handler/tests" - pkgHttp "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" ) type fileHandler interface { - Handle(baseHttp.ResponseWriter, *baseHttp.Request) *pkgHttp.ApiError + Handle(baseHttp.ResponseWriter, *baseHttp.Request) *endpoint.ApiError } type fileHandlerTestCase struct { diff --git a/handler/keep_alive.go b/handler/keep_alive.go index 7b1209a0..286d10c7 100644 --- a/handler/keep_alive.go +++ b/handler/keep_alive.go @@ -7,7 +7,7 @@ import ( "github.com/oullin/handler/payload" "github.com/oullin/metal/env" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" ) @@ -19,17 +19,17 @@ func MakeKeepAliveHandler(e *env.PingEnvironment) KeepAliveHandler { return KeepAliveHandler{env: e} } -func (h KeepAliveHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h KeepAliveHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { user, pass, ok := r.BasicAuth() if !ok || h.env.HasInvalidCreds(user, pass) { - return http.LogUnauthorisedError( + return endpoint.LogUnauthorisedError( "invalid credentials", fmt.Errorf("invalid credentials"), ) } - resp := http.MakeNoCacheResponse(w, r) + resp := endpoint.MakeNoCacheResponse(w, r) now := time.Now().UTC() data := payload.KeepAliveResponse{ @@ -38,7 +38,7 @@ func (h KeepAliveHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) } if err := resp.RespondOk(data); err != nil { - return http.LogInternalError("could not encode keep-alive response", err) + return endpoint.LogInternalError("could not encode keep-alive response", err) } return nil diff --git a/handler/keep_alive_db.go b/handler/keep_alive_db.go index cc7ab05c..f26938a6 100644 --- a/handler/keep_alive_db.go +++ b/handler/keep_alive_db.go @@ -8,7 +8,7 @@ import ( "github.com/oullin/database" "github.com/oullin/handler/payload" "github.com/oullin/metal/env" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" ) @@ -21,21 +21,21 @@ func MakeKeepAliveDBHandler(e *env.PingEnvironment, db *database.Connection) Kee return KeepAliveDBHandler{env: e, db: db} } -func (h KeepAliveDBHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h KeepAliveDBHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { user, pass, ok := r.BasicAuth() if !ok || h.env.HasInvalidCreds(user, pass) { - return http.LogUnauthorisedError( + return endpoint.LogUnauthorisedError( "invalid credentials", fmt.Errorf("invalid credentials"), ) } if err := h.db.Ping(); err != nil { - return http.LogInternalError("database ping failed", err) + return endpoint.LogInternalError("database ping failed", err) } - resp := http.MakeNoCacheResponse(w, r) + resp := endpoint.MakeNoCacheResponse(w, r) now := time.Now().UTC() data := payload.KeepAliveResponse{ @@ -44,7 +44,7 @@ func (h KeepAliveDBHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Reques } if err := resp.RespondOk(data); err != nil { - return http.LogInternalError("could not encode keep-alive response", err) + return endpoint.LogInternalError("could not encode keep-alive response", err) } return nil diff --git a/handler/posts.go b/handler/posts.go index 84d626bc..8a31d041 100644 --- a/handler/posts.go +++ b/handler/posts.go @@ -8,7 +8,7 @@ import ( "github.com/oullin/database/repository/pagination" "github.com/oullin/handler/paginate" "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "log/slog" @@ -23,15 +23,15 @@ func MakePostsHandler(repo *repository.Posts) PostsHandler { return PostsHandler{Posts: repo} } -func (h *PostsHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h *PostsHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { defer portal.CloseWithLog(r.Body) - requestBody, err := http.ParseRequestBody[payload.IndexRequestBody](r) + requestBody, err := endpoint.ParseRequestBody[payload.IndexRequestBody](r) if err != nil { slog.Error("failed to parse request body", "err", err) - return http.InternalError("There was an issue reading the request. Please, try again later.") + return endpoint.InternalError("There was an issue reading the request. Please, try again later.") } result, err := h.Posts.GetAll( @@ -42,7 +42,7 @@ func (h *PostsHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *ht if err != nil { slog.Error("failed to fetch posts", "err", err) - return http.InternalError("There was an issue reading the posts. Please, try again later.") + return endpoint.InternalError("There was an issue reading the posts. Please, try again later.") } items := pagination.HydratePagination( @@ -53,29 +53,29 @@ func (h *PostsHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *ht if err := json.NewEncoder(w).Encode(items); err != nil { slog.Error("failed to encode response", "err", err) - return http.InternalError("There was an issue processing the response. Please, try later.") + return endpoint.InternalError("There was an issue processing the response. Please, try later.") } return nil } -func (h *PostsHandler) Show(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h *PostsHandler) Show(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { slug := payload.GetSlugFrom(r) if slug == "" { - return http.BadRequestError("Slugs are required to show posts content") + return endpoint.BadRequestError("Slugs are required to show posts content") } post := h.Posts.FindBy(slug) if post == nil { - return http.NotFound(fmt.Sprintf("The given post '%s' was not found", slug)) + return endpoint.NotFound(fmt.Sprintf("The given post '%s' was not found", slug)) } items := payload.GetPostsResponse(*post) if err := json.NewEncoder(w).Encode(items); err != nil { slog.Error(err.Error()) - return http.InternalError("There was an issue processing the response. Please, try later.") + return endpoint.InternalError("There was an issue processing the response. Please, try later.") } return nil diff --git a/handler/profile.go b/handler/profile.go index 396e177e..d80f6ce8 100644 --- a/handler/profile.go +++ b/handler/profile.go @@ -2,7 +2,7 @@ package handler import ( "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "log/slog" @@ -19,16 +19,16 @@ func MakeProfileHandler(filePath string) ProfileHandler { } } -func (h ProfileHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h ProfileHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.ProfileResponse](h.filePath) if err != nil { slog.Error("Error reading profile file", "error", err) - return http.InternalError("could not read profile data") + return endpoint.InternalError("could not read profile data") } - resp := http.MakeResponseFrom(data.Version, w, r) + resp := endpoint.MakeResponseFrom(data.Version, w, r) if resp.HasCache() { resp.RespondWithNotModified() diff --git a/handler/projects.go b/handler/projects.go index 6cb7c8c9..5ab38f18 100644 --- a/handler/projects.go +++ b/handler/projects.go @@ -2,7 +2,7 @@ package handler import ( "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "log/slog" @@ -19,16 +19,16 @@ func MakeProjectsHandler(filePath string) ProjectsHandler { } } -func (h ProjectsHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h ProjectsHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.ProjectsResponse](h.filePath) if err != nil { slog.Error("Error reading projects file", "error", err) - return http.InternalError("could not read projects data") + return endpoint.InternalError("could not read projects data") } - resp := http.MakeResponseFrom(data.Version, w, r) + resp := endpoint.MakeResponseFrom(data.Version, w, r) if resp.HasCache() { resp.RespondWithNotModified() diff --git a/handler/recommendations.go b/handler/recommendations.go index dbb80d15..e93e5ffc 100644 --- a/handler/recommendations.go +++ b/handler/recommendations.go @@ -2,7 +2,7 @@ package handler import ( "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "log/slog" @@ -19,16 +19,16 @@ func MakeRecommendationsHandler(filePath string) RecommendationsHandler { } } -func (h RecommendationsHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h RecommendationsHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.RecommendationsResponse](h.filePath) if err != nil { slog.Error("Error reading recommendations file", "error", err) - return http.InternalError("could not read recommendations data") + return endpoint.InternalError("could not read recommendations data") } - resp := http.MakeResponseFrom(data.Version, w, r) + resp := endpoint.MakeResponseFrom(data.Version, w, r) if resp.HasCache() { resp.RespondWithNotModified() diff --git a/handler/signatures.go b/handler/signatures.go index 1e080f92..9056a153 100644 --- a/handler/signatures.go +++ b/handler/signatures.go @@ -12,7 +12,7 @@ import ( "github.com/oullin/database/repository/repoentity" "github.com/oullin/handler/payload" "github.com/oullin/pkg/auth" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" ) @@ -28,7 +28,7 @@ func MakeSignaturesHandler(validator *portal.Validator, ApiKeys *repository.ApiK } } -func (s *SignaturesHandler) Generate(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (s *SignaturesHandler) Generate(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { defer portal.CloseWithLog(r.Body) var ( @@ -36,15 +36,15 @@ func (s *SignaturesHandler) Generate(w baseHttp.ResponseWriter, r *baseHttp.Requ req payload.SignatureRequest ) - r.Body = baseHttp.MaxBytesReader(w, r.Body, http.MaxRequestSize) + r.Body = baseHttp.MaxBytesReader(w, r.Body, endpoint.MaxRequestSize) dec := json.NewDecoder(r.Body) dec.DisallowUnknownFields() if err = dec.Decode(&req); err != nil { - return http.LogBadRequestError("could not parse the given data.", err) + return endpoint.LogBadRequestError("could not parse the given data.", err) } if _, err = s.Validator.Rejects(req); err != nil { - return http.UnprocessableEntity("The given fields are invalid", s.Validator.GetErrors()) + return endpoint.UnprocessableEntity("The given fields are invalid", s.Validator.GetErrors()) } serverTime := time.Now() @@ -53,7 +53,7 @@ func (s *SignaturesHandler) Generate(w baseHttp.ResponseWriter, r *baseHttp.Requ var keySignature *database.APIKeySignatures if keySignature, err = s.CreateSignature(req, serverTime); err != nil { - return http.LogInternalError(err.Error(), err) + return endpoint.LogInternalError(err.Error(), err) } response := payload.SignatureResponse{ @@ -66,11 +66,11 @@ func (s *SignaturesHandler) Generate(w baseHttp.ResponseWriter, r *baseHttp.Requ }, } - resp := http.MakeResponseFrom("0.0.1", w, r) + resp := endpoint.MakeResponseFrom("0.0.1", w, r) if err = resp.RespondOk(response); err != nil { slog.Error("Error marshaling JSON for signatures response", "error", err) - return http.LogInternalError("could not encode signatures response", err) + return endpoint.LogInternalError("could not encode signatures response", err) } return nil // A nil return indicates success. diff --git a/handler/signatures_test.go b/handler/signatures_test.go index 7a9ff2aa..82f18c5b 100644 --- a/handler/signatures_test.go +++ b/handler/signatures_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - apih "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" ) @@ -38,7 +38,7 @@ func TestSignaturesHandlerGenerate_UnknownField(t *testing.T) { func TestSignaturesHandlerGenerate_BodyTooLarge(t *testing.T) { h := SignaturesHandler{Validator: portal.GetDefaultValidator()} - large := `{"nonce":"` + strings.Repeat("a", apih.MaxRequestSize+1) + `"}` + large := `{"nonce":"` + strings.Repeat("a", endpoint.MaxRequestSize+1) + `"}` req := httptest.NewRequest("POST", "/signatures", strings.NewReader(large)) rec := httptest.NewRecorder() if err := h.Generate(rec, req); err == nil || err.Status != nethttp.StatusBadRequest { diff --git a/handler/social.go b/handler/social.go index 158e48f4..b5ab8a13 100644 --- a/handler/social.go +++ b/handler/social.go @@ -2,7 +2,7 @@ package handler import ( "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "log/slog" @@ -19,16 +19,16 @@ func MakeSocialHandler(filePath string) SocialHandler { } } -func (h SocialHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h SocialHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.SocialResponse](h.filePath) if err != nil { slog.Error("Error reading social file", "error", err) - return http.InternalError("could not read social data") + return endpoint.InternalError("could not read social data") } - resp := http.MakeResponseFrom(data.Version, w, r) + resp := endpoint.MakeResponseFrom(data.Version, w, r) if resp.HasCache() { resp.RespondWithNotModified() diff --git a/handler/talks.go b/handler/talks.go index 8d44e89d..11e0ef01 100644 --- a/handler/talks.go +++ b/handler/talks.go @@ -2,7 +2,7 @@ package handler import ( "github.com/oullin/handler/payload" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "log/slog" @@ -19,16 +19,16 @@ func MakeTalksHandler(filePath string) TalksHandler { } } -func (h TalksHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (h TalksHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.TalksResponse](h.filePath) if err != nil { slog.Error("Error reading talks file", "error", err) - return http.InternalError("could not read talks data") + return endpoint.InternalError("could not read talks data") } - resp := http.MakeResponseFrom(data.Version, w, r) + resp := endpoint.MakeResponseFrom(data.Version, w, r) if resp.HasCache() { resp.RespondWithNotModified() diff --git a/metal/cli/seo/client_test.go b/metal/cli/seo/client_test.go index cfaee9f3..5eb01a15 100644 --- a/metal/cli/seo/client_test.go +++ b/metal/cli/seo/client_test.go @@ -9,18 +9,18 @@ import ( "github.com/oullin/handler/payload" "github.com/oullin/metal/env" "github.com/oullin/metal/router" - basehttp "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" ) -type failingRoute struct{ err *basehttp.ApiError } +type failingRoute struct{ err *endpoint.ApiError } type invalidJSONRoute struct{ body string } -func (f failingRoute) Handle(http.ResponseWriter, *http.Request) *basehttp.ApiError { +func (f failingRoute) Handle(http.ResponseWriter, *http.Request) *endpoint.ApiError { return f.err } -func (i invalidJSONRoute) Handle(w http.ResponseWriter, r *http.Request) *basehttp.ApiError { +func (i invalidJSONRoute) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { _, _ = w.Write([]byte(i.body)) return nil @@ -30,7 +30,7 @@ func TestFetchPropagatesHandlerErrors(t *testing.T) { err := fetch[payload.ProfileResponse]( &payload.ProfileResponse{}, func() router.StaticRouteResource { - return failingRoute{err: basehttp.InternalError("boom")} + return failingRoute{err: endpoint.InternalError("boom")} }, ) diff --git a/metal/kernel/kernel_test.go b/metal/kernel/kernel_test.go index c87d3443..6401ad77 100644 --- a/metal/kernel/kernel_test.go +++ b/metal/kernel/kernel_test.go @@ -16,7 +16,7 @@ import ( "github.com/oullin/metal/env" "github.com/oullin/metal/router" "github.com/oullin/pkg/auth" - metalhttp "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/llogs" "github.com/oullin/pkg/middleware" "github.com/oullin/pkg/portal" @@ -368,7 +368,7 @@ func TestAppNewRouterSuccess(t *testing.T) { }) t.Run("PublicMiddleware", func(t *testing.T) { - handler := modem.Pipeline.PublicMiddleware.Handle(func(http.ResponseWriter, *http.Request) *metalhttp.ApiError { + handler := modem.Pipeline.PublicMiddleware.Handle(func(http.ResponseWriter, *http.Request) *endpoint.ApiError { return nil }) diff --git a/metal/router/router.go b/metal/router/router.go index 5b175f74..217679f2 100644 --- a/metal/router/router.go +++ b/metal/router/router.go @@ -8,7 +8,7 @@ import ( "github.com/oullin/database/repository" "github.com/oullin/handler" "github.com/oullin/metal/env" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/middleware" "github.com/oullin/pkg/portal" ) @@ -22,8 +22,8 @@ type Router struct { Db *database.Connection } -func (r *Router) PublicPipelineFor(apiHandler http.ApiHandler) baseHttp.HandlerFunc { - return http.MakeApiHandler( +func (r *Router) PublicPipelineFor(apiHandler endpoint.ApiHandler) baseHttp.HandlerFunc { + return endpoint.MakeApiHandler( r.Pipeline.Chain( apiHandler, r.Pipeline.PublicMiddleware.Handle, @@ -31,13 +31,13 @@ func (r *Router) PublicPipelineFor(apiHandler http.ApiHandler) baseHttp.HandlerF ) } -func (r *Router) PipelineFor(apiHandler http.ApiHandler) baseHttp.HandlerFunc { +func (r *Router) PipelineFor(apiHandler endpoint.ApiHandler) baseHttp.HandlerFunc { tokenMiddleware := middleware.MakeTokenMiddleware( r.Pipeline.TokenHandler, r.Pipeline.ApiKeys, ) - return http.MakeApiHandler( + return endpoint.MakeApiHandler( r.Pipeline.Chain( apiHandler, tokenMiddleware.Handle, @@ -75,7 +75,7 @@ func (r *Router) Signature() { func (r *Router) KeepAlive() { abstract := handler.MakeKeepAliveHandler(&r.Env.Ping) - apiHandler := http.MakeApiHandler( + apiHandler := endpoint.MakeApiHandler( r.Pipeline.Chain(abstract.Handle), ) @@ -85,7 +85,7 @@ func (r *Router) KeepAlive() { func (r *Router) KeepAliveDB() { abstract := handler.MakeKeepAliveDBHandler(&r.Env.Ping, r.Db) - apiHandler := http.MakeApiHandler( + apiHandler := endpoint.MakeApiHandler( r.Pipeline.Chain(abstract.Handle), ) diff --git a/metal/router/static.go b/metal/router/static.go index 7ffcc511..dec6c3ed 100644 --- a/metal/router/static.go +++ b/metal/router/static.go @@ -4,11 +4,11 @@ import ( baseHttp "net/http" "github.com/oullin/metal/env" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" ) type StaticRouteResource interface { - Handle(baseHttp.ResponseWriter, *baseHttp.Request) *http.ApiError + Handle(baseHttp.ResponseWriter, *baseHttp.Request) *endpoint.ApiError } type WebsiteRoutes struct { diff --git a/pkg/http/handler.go b/pkg/endpoint/handler.go similarity index 98% rename from pkg/http/handler.go rename to pkg/endpoint/handler.go index 278f0545..b56e24d8 100644 --- a/pkg/http/handler.go +++ b/pkg/endpoint/handler.go @@ -1,4 +1,4 @@ -package http +package endpoint import ( "encoding/json" diff --git a/pkg/http/handler_test.go b/pkg/endpoint/handler_test.go similarity index 99% rename from pkg/http/handler_test.go rename to pkg/endpoint/handler_test.go index cbc8d603..d9b93e8a 100644 --- a/pkg/http/handler_test.go +++ b/pkg/endpoint/handler_test.go @@ -1,4 +1,4 @@ -package http +package endpoint import ( "context" diff --git a/pkg/http/request.go b/pkg/endpoint/request.go similarity index 97% rename from pkg/http/request.go rename to pkg/endpoint/request.go index 5218ac04..1fd8168b 100644 --- a/pkg/http/request.go +++ b/pkg/endpoint/request.go @@ -1,4 +1,4 @@ -package http +package endpoint import ( "encoding/json" diff --git a/pkg/http/request_test.go b/pkg/endpoint/request_test.go similarity index 97% rename from pkg/http/request_test.go rename to pkg/endpoint/request_test.go index afb105ac..fce9c13f 100644 --- a/pkg/http/request_test.go +++ b/pkg/endpoint/request_test.go @@ -1,4 +1,4 @@ -package http +package endpoint import ( "net/http/httptest" diff --git a/pkg/http/response.go b/pkg/endpoint/response.go similarity index 99% rename from pkg/http/response.go rename to pkg/endpoint/response.go index ffeb7548..976090bf 100644 --- a/pkg/http/response.go +++ b/pkg/endpoint/response.go @@ -1,4 +1,4 @@ -package http +package endpoint import ( "encoding/json" diff --git a/pkg/http/response_test.go b/pkg/endpoint/response_test.go similarity index 99% rename from pkg/http/response_test.go rename to pkg/endpoint/response_test.go index a505543d..b1214f09 100644 --- a/pkg/http/response_test.go +++ b/pkg/endpoint/response_test.go @@ -1,4 +1,4 @@ -package http +package endpoint import ( "net/http" diff --git a/pkg/http/schema.go b/pkg/endpoint/schema.go similarity index 97% rename from pkg/http/schema.go rename to pkg/endpoint/schema.go index 5492fd36..5cec081a 100644 --- a/pkg/http/schema.go +++ b/pkg/endpoint/schema.go @@ -1,4 +1,4 @@ -package http +package endpoint import baseHttp "net/http" diff --git a/pkg/http/schema_test.go b/pkg/endpoint/schema_test.go similarity index 97% rename from pkg/http/schema_test.go rename to pkg/endpoint/schema_test.go index 9a2d9bd8..aafb5cc4 100644 --- a/pkg/http/schema_test.go +++ b/pkg/endpoint/schema_test.go @@ -1,4 +1,4 @@ -package http +package endpoint import ( "errors" diff --git a/pkg/http/scope_api_error.go b/pkg/endpoint/scope_api_error.go similarity index 99% rename from pkg/http/scope_api_error.go rename to pkg/endpoint/scope_api_error.go index 34b10a6c..5bd08068 100644 --- a/pkg/http/scope_api_error.go +++ b/pkg/endpoint/scope_api_error.go @@ -1,4 +1,4 @@ -package http +package endpoint import ( "errors" diff --git a/pkg/middleware/mwguards/mw_response_messages.go b/pkg/middleware/mwguards/mw_response_messages.go index 04694216..b4d3ed92 100644 --- a/pkg/middleware/mwguards/mw_response_messages.go +++ b/pkg/middleware/mwguards/mw_response_messages.go @@ -5,7 +5,7 @@ import ( baseHttp "net/http" "strings" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" ) func normaliseData(data ...map[string]any) map[string]any { @@ -33,91 +33,91 @@ func normaliseMessages(message, logMessage string) (string, string) { return message, logMessage } -func InvalidRequestError(message, logMessage string, data ...map[string]any) *http.ApiError { +func InvalidRequestError(message, logMessage string, data ...map[string]any) *endpoint.ApiError { message, logMessage = normaliseMessages(message, logMessage) d := normaliseData(data...) slog.Error(logMessage, "data", d) - return &http.ApiError{ + return &endpoint.ApiError{ Message: message, Status: baseHttp.StatusUnauthorized, Data: d, } } -func InvalidTokenFormatError(message, logMessage string, data ...map[string]any) *http.ApiError { +func InvalidTokenFormatError(message, logMessage string, data ...map[string]any) *endpoint.ApiError { message, logMessage = normaliseMessages(message, logMessage) d := normaliseData(data...) slog.Error(logMessage, "data", d) - return &http.ApiError{ + return &endpoint.ApiError{ Message: message, Status: baseHttp.StatusUnauthorized, Data: d, } } -func UnauthenticatedError(message, logMessage string, data ...map[string]any) *http.ApiError { +func UnauthenticatedError(message, logMessage string, data ...map[string]any) *endpoint.ApiError { message, logMessage = normaliseMessages(message, logMessage) d := normaliseData(data...) slog.Error(logMessage, "data", d) - return &http.ApiError{ + return &endpoint.ApiError{ Message: "2- Invalid credentials: " + logMessage, Status: baseHttp.StatusUnauthorized, Data: d, } } -func RateLimitedError(message, logMessage string, data ...map[string]any) *http.ApiError { +func RateLimitedError(message, logMessage string, data ...map[string]any) *endpoint.ApiError { message, logMessage = normaliseMessages(message, logMessage) d := normaliseData(data...) slog.Error(logMessage, "data", d) - return &http.ApiError{ + return &endpoint.ApiError{ Message: "Too many authentication attempts", Status: baseHttp.StatusTooManyRequests, Data: d, } } -func NotFound(message, logMessage string, data ...map[string]any) *http.ApiError { +func NotFound(message, logMessage string, data ...map[string]any) *endpoint.ApiError { message, logMessage = normaliseMessages(message, logMessage) d := normaliseData(data...) slog.Error(logMessage, "data", d) - return &http.ApiError{ + return &endpoint.ApiError{ Message: message, Status: baseHttp.StatusNotFound, Data: d, } } -func TimestampTooOldError(message, logMessage string, data ...map[string]any) *http.ApiError { +func TimestampTooOldError(message, logMessage string, data ...map[string]any) *endpoint.ApiError { message, logMessage = normaliseMessages(message, logMessage) d := normaliseData(data...) slog.Error(logMessage, "data", d) - return &http.ApiError{ + return &endpoint.ApiError{ Message: "Request timestamp expired", Status: baseHttp.StatusUnauthorized, Data: d, } } -func TimestampTooNewError(message, logMessage string, data ...map[string]any) *http.ApiError { +func TimestampTooNewError(message, logMessage string, data ...map[string]any) *endpoint.ApiError { message, logMessage = normaliseMessages(message, logMessage) d := normaliseData(data...) slog.Error(logMessage, "data", d) - return &http.ApiError{ + return &endpoint.ApiError{ Message: "Request timestamp invalid", Status: baseHttp.StatusUnauthorized, Data: d, diff --git a/pkg/middleware/mwguards/valid_timestamp_guard.go b/pkg/middleware/mwguards/valid_timestamp_guard.go index a90c58cd..15074333 100644 --- a/pkg/middleware/mwguards/valid_timestamp_guard.go +++ b/pkg/middleware/mwguards/valid_timestamp_guard.go @@ -5,7 +5,7 @@ import ( "strconv" "time" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" ) type ValidTimestamp struct { @@ -20,14 +20,14 @@ func NewValidTimestamp(ts string, now func() time.Time) ValidTimestamp { } } -func (v ValidTimestamp) Validate(skew time.Duration, disallowFuture bool) *http.ApiError { +func (v ValidTimestamp) Validate(skew time.Duration, disallowFuture bool) *endpoint.ApiError { if v.ts == "" { - return &http.ApiError{Message: "Invalid authentication headers", Status: baseHttp.StatusUnauthorized} + return &endpoint.ApiError{Message: "Invalid authentication headers", Status: baseHttp.StatusUnauthorized} } epoch, err := strconv.ParseInt(v.ts, 10, 64) if err != nil { - return &http.ApiError{Message: "Invalid authentication headers", Status: baseHttp.StatusUnauthorized} + return &endpoint.ApiError{Message: "Invalid authentication headers", Status: baseHttp.StatusUnauthorized} } nowFn := v.now diff --git a/pkg/middleware/pipeline.go b/pkg/middleware/pipeline.go index 080aa6a3..6a212bb0 100644 --- a/pkg/middleware/pipeline.go +++ b/pkg/middleware/pipeline.go @@ -4,7 +4,7 @@ import ( "github.com/oullin/database/repository" "github.com/oullin/metal/env" "github.com/oullin/pkg/auth" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" ) type Pipeline struct { @@ -14,7 +14,7 @@ type Pipeline struct { PublicMiddleware PublicMiddleware } -func (m Pipeline) Chain(h http.ApiHandler, handlers ...http.Middleware) http.ApiHandler { +func (m Pipeline) Chain(h endpoint.ApiHandler, handlers ...endpoint.Middleware) endpoint.ApiHandler { for i := len(handlers) - 1; i >= 0; i-- { h = handlers[i](h) } diff --git a/pkg/middleware/pipeline_test.go b/pkg/middleware/pipeline_test.go index 69b18d42..dad2126d 100644 --- a/pkg/middleware/pipeline_test.go +++ b/pkg/middleware/pipeline_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - pkgHttp "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" ) func TestPipelineChainOrder(t *testing.T) { @@ -14,25 +14,25 @@ func TestPipelineChainOrder(t *testing.T) { order := []string{} - m1 := func(next pkgHttp.ApiHandler) pkgHttp.ApiHandler { + m1 := func(next endpoint.ApiHandler) endpoint.ApiHandler { - return func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + return func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { order = append(order, "m1") return next(w, r) } } - m2 := func(next pkgHttp.ApiHandler) pkgHttp.ApiHandler { + m2 := func(next endpoint.ApiHandler) endpoint.ApiHandler { - return func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + return func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { order = append(order, "m2") return next(w, r) } } - final := func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + final := func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { order = append(order, "final") return nil diff --git a/pkg/middleware/public_middleware.go b/pkg/middleware/public_middleware.go index 7481b754..6c521871 100644 --- a/pkg/middleware/public_middleware.go +++ b/pkg/middleware/public_middleware.go @@ -7,7 +7,7 @@ import ( "time" "github.com/oullin/pkg/cache" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/limiter" "github.com/oullin/pkg/middleware/mwguards" "github.com/oullin/pkg/portal" @@ -41,8 +41,8 @@ func MakePublicMiddleware(allowedIP string, isProduction bool) PublicMiddleware } } -func (p PublicMiddleware) Handle(next http.ApiHandler) http.ApiHandler { - return func(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (p PublicMiddleware) Handle(next endpoint.ApiHandler) endpoint.ApiHandler { + return func(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { if err := p.GuardDependencies(); err != nil { return err } @@ -83,7 +83,7 @@ func (p PublicMiddleware) Handle(next http.ApiHandler) http.ApiHandler { } } -func (p PublicMiddleware) GuardDependencies() *http.ApiError { +func (p PublicMiddleware) GuardDependencies() *endpoint.ApiError { missing := []string{} if p.requestCache == nil { @@ -96,7 +96,7 @@ func (p PublicMiddleware) GuardDependencies() *http.ApiError { if len(missing) > 0 { err := fmt.Errorf("public middleware missing dependencies: %s", strings.Join(missing, ",")) - return http.LogInternalError("public middleware missing dependencies", err) + return endpoint.LogInternalError("public middleware missing dependencies", err) } return nil diff --git a/pkg/middleware/public_middleware_test.go b/pkg/middleware/public_middleware_test.go index fc04866f..fcd7a550 100644 --- a/pkg/middleware/public_middleware_test.go +++ b/pkg/middleware/public_middleware_test.go @@ -7,14 +7,14 @@ import ( "testing" "time" - pkgHttp "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/limiter" "github.com/oullin/pkg/portal" ) func TestPublicMiddleware_InvalidHeaders(t *testing.T) { pm := MakePublicMiddleware("", false) - handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil }) + handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil }) base := time.Unix(1_700_000_000, 0) cases := []struct { @@ -61,7 +61,7 @@ func TestPublicMiddleware_TimestampExpired(t *testing.T) { pm := MakePublicMiddleware("", false) base := time.Unix(1_700_000_000, 0) pm.now = func() time.Time { return base } - handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil }) + handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil }) rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) @@ -79,7 +79,7 @@ func TestPublicMiddleware_RateLimitAndReplay(t *testing.T) { pm.rateLimiter = limiter.NewMemoryLimiter(time.Minute, 1) base := time.Unix(1_700_000_000, 0) pm.now = func() time.Time { return base } - handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil }) + handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil }) // First request succeeds rec1 := httptest.NewRecorder() @@ -112,7 +112,7 @@ func TestPublicMiddleware_IPWhitelist(t *testing.T) { base := time.Unix(1_700_000_000, 0) pm := MakePublicMiddleware("31.97.60.190", true) pm.now = func() time.Time { return base } - handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil }) + handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil }) t.Run("allowed ip passes", func(t *testing.T) { rec := httptest.NewRecorder() @@ -139,7 +139,7 @@ func TestPublicMiddleware_IPWhitelist(t *testing.T) { t.Run("non-production skips restriction", func(t *testing.T) { pm := MakePublicMiddleware("31.97.60.190", false) pm.now = func() time.Time { return base } - handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil }) + handler := pm.Handle(func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil }) rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) req.Header.Set(portal.RequestIDHeader, "req-1") diff --git a/pkg/middleware/token_middleware.go b/pkg/middleware/token_middleware.go index d3415908..8dcf0fe5 100644 --- a/pkg/middleware/token_middleware.go +++ b/pkg/middleware/token_middleware.go @@ -13,7 +13,7 @@ import ( "github.com/oullin/database/repository/repoentity" "github.com/oullin/pkg/auth" "github.com/oullin/pkg/cache" - "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/limiter" "github.com/oullin/pkg/middleware/mwguards" "github.com/oullin/pkg/portal" @@ -47,8 +47,8 @@ func MakeTokenMiddleware(tokenHandler *auth.TokenHandler, apiKeys *repository.Ap } } -func (t TokenCheckMiddleware) Handle(next http.ApiHandler) http.ApiHandler { - return func(w baseHttp.ResponseWriter, r *baseHttp.Request) *http.ApiError { +func (t TokenCheckMiddleware) Handle(next endpoint.ApiHandler) endpoint.ApiHandler { + return func(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { reqID := strings.TrimSpace(r.Header.Get(portal.RequestIDHeader)) if reqID == "" { @@ -85,7 +85,7 @@ func (t TokenCheckMiddleware) Handle(next http.ApiHandler) http.ApiHandler { } } -func (t TokenCheckMiddleware) GuardDependencies() *http.ApiError { +func (t TokenCheckMiddleware) GuardDependencies() *endpoint.ApiError { missing := make([]string, 0, 4) if t.ApiKeys == nil { @@ -117,7 +117,7 @@ func (t TokenCheckMiddleware) GuardDependencies() *http.ApiError { return nil } -func (t TokenCheckMiddleware) ValidateAndGetHeaders(r *baseHttp.Request, requestId string) (AuthTokenHeaders, *http.ApiError) { +func (t TokenCheckMiddleware) ValidateAndGetHeaders(r *baseHttp.Request, requestId string) (AuthTokenHeaders, *endpoint.ApiError) { intendedOriginURL := strings.TrimSpace(r.Header.Get(portal.IntendedOriginHeader)) accountName := strings.TrimSpace(r.Header.Get(portal.UsernameHeader)) signature := strings.TrimSpace(r.Header.Get(portal.SignatureHeader)) @@ -156,7 +156,7 @@ func (t TokenCheckMiddleware) AttachContext(r *baseHttp.Request, headers AuthTok return r.WithContext(ctx) } -func (t TokenCheckMiddleware) HasInvalidFormat(headers AuthTokenHeaders) (*database.APIKey, *http.ApiError) { +func (t TokenCheckMiddleware) HasInvalidFormat(headers AuthTokenHeaders) (*database.APIKey, *endpoint.ApiError) { limiterKey := headers.ClientIP + "|" + strings.ToLower(headers.AccountName) if t.rateLimiter.TooMany(limiterKey) { @@ -200,7 +200,7 @@ func (t TokenCheckMiddleware) HasInvalidFormat(headers AuthTokenHeaders) (*datab return guard.ApiKey, nil } -func (t TokenCheckMiddleware) HasInvalidSignature(headers AuthTokenHeaders, apiKey *database.APIKey) *http.ApiError { +func (t TokenCheckMiddleware) HasInvalidSignature(headers AuthTokenHeaders, apiKey *database.APIKey) *endpoint.ApiError { var err error var byteSignature []byte limiterKey := headers.ClientIP + "|" + strings.ToLower(headers.AccountName) diff --git a/pkg/middleware/token_middleware_additional_test.go b/pkg/middleware/token_middleware_additional_test.go index edffd390..ff397a6f 100644 --- a/pkg/middleware/token_middleware_additional_test.go +++ b/pkg/middleware/token_middleware_additional_test.go @@ -14,7 +14,7 @@ import ( "github.com/oullin/database/repository" "github.com/oullin/pkg/auth" "github.com/oullin/pkg/cache" - pkgHttp "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/limiter" "github.com/testcontainers/testcontainers-go" postgrescontainer "github.com/testcontainers/testcontainers-go/modules/postgres" @@ -103,7 +103,7 @@ func TestTokenMiddleware_PublicTokenMismatch(t *testing.T) { repo, th, seed, _ := makeRepo(t, "mismatch") tm := MakeTokenMiddleware(th, repo) tm.clockSkew = time.Minute - next := func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil } + next := func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil } handler := tm.Handle(next) req := makeSignedRequest(t, http.MethodGet, "https://api.test.local/v1/x", "", seed.AccountName, "wrong-"+seed.PublicKey, seed.PublicKey, time.Now(), "nonce-mm", "req-mm") @@ -118,7 +118,7 @@ func TestTokenMiddleware_SignatureMismatch(t *testing.T) { repo, th, seed, key := makeRepo(t, "siggy") tm := MakeTokenMiddleware(th, repo) tm.clockSkew = time.Minute - next := func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil } + next := func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil } handler := tm.Handle(next) req := makeSignedRequest(t, http.MethodPost, "https://api.test.local/v1/x", "body", seed.AccountName, seed.PublicKey, seed.PublicKey, time.Now(), "nonce-sig", "req-sig") @@ -145,7 +145,7 @@ func TestTokenMiddleware_NonceReplay(t *testing.T) { tm.clockSkew = time.Minute tm.nonceTTL = time.Minute nextCalled := 0 - next := func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + next := func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { nextCalled++ return nil } @@ -172,7 +172,7 @@ func TestTokenMiddleware_RateLimiter(t *testing.T) { tm := MakeTokenMiddleware(th, repo) tm.clockSkew = time.Minute nextCalled := 0 - next := func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + next := func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { nextCalled++ return nil } @@ -217,7 +217,7 @@ func TestTokenMiddleware_CustomClockValidatesSignature(t *testing.T) { tm.now = func() time.Time { return past } nextCalled := false - handler := tm.Handle(func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + handler := tm.Handle(func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { nextCalled = true return nil }) diff --git a/pkg/middleware/token_middleware_test.go b/pkg/middleware/token_middleware_test.go index d71c429c..249cf56e 100644 --- a/pkg/middleware/token_middleware_test.go +++ b/pkg/middleware/token_middleware_test.go @@ -18,7 +18,7 @@ import ( "github.com/oullin/database/repository" "github.com/oullin/database/repository/repoentity" "github.com/oullin/pkg/auth" - pkgHttp "github.com/oullin/pkg/http" + "github.com/oullin/pkg/endpoint" "github.com/oullin/pkg/portal" "gorm.io/driver/postgres" "gorm.io/gorm" @@ -27,7 +27,7 @@ import ( func TestTokenMiddlewareHandle_RequiresRequestID(t *testing.T) { tm := MakeTokenMiddleware(nil, nil) - handler := tm.Handle(func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil }) + handler := tm.Handle(func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil }) rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) @@ -40,7 +40,7 @@ func TestTokenMiddlewareHandle_RequiresRequestID(t *testing.T) { func TestTokenMiddlewareHandleInvalid(t *testing.T) { tm := MakeTokenMiddleware(nil, nil) - handler := tm.Handle(func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { return nil }) + handler := tm.Handle(func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { return nil }) rec := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) @@ -226,7 +226,7 @@ func TestTokenMiddleware_DB_Integration(t *testing.T) { tm.nonceTTL = 1 * time.Minute nextCalled := false - next := func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + next := func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { nextCalled = true return nil } @@ -307,7 +307,7 @@ func TestTokenMiddleware_DB_Integration_HappyPath(t *testing.T) { tm.nonceTTL = 1 * time.Minute nextCalled := false - next := func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + next := func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { nextCalled = true return nil } @@ -372,7 +372,7 @@ func TestTokenMiddleware_RejectsFutureTimestamps(t *testing.T) { tm := MakeTokenMiddleware(th, repo) nextCalled := false - next := func(w http.ResponseWriter, r *http.Request) *pkgHttp.ApiError { + next := func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { nextCalled = true return nil } From 3f850b59ac8e0384b7bdc65cf1cef8fe463fb1bf Mon Sep 17 00:00:00 2001 From: Gus Date: Thu, 16 Oct 2025 15:30:14 +0800 Subject: [PATCH 2/2] Use net/http without alias --- handler/categories.go | 4 +-- handler/education.go | 4 +-- handler/experience.go | 4 +-- handler/file_handler_test.go | 8 ++--- handler/keep_alive.go | 4 +-- handler/keep_alive_db.go | 4 +-- handler/payload/posts.go | 4 +-- handler/posts.go | 6 ++-- handler/profile.go | 4 +-- handler/projects.go | 4 +-- handler/recommendations.go | 4 +-- handler/signatures.go | 6 ++-- handler/social.go | 4 +-- handler/talks.go | 4 +-- main.go | 12 +++---- metal/kernel/app.go | 4 +-- metal/kernel/helpers.go | 4 +-- metal/router/router.go | 8 ++--- metal/router/static.go | 4 +-- pkg/endpoint/handler.go | 8 ++--- pkg/endpoint/request.go | 4 +-- pkg/endpoint/response.go | 36 +++++++++---------- pkg/endpoint/schema.go | 4 +-- pkg/endpoint/scope_api_error.go | 10 +++--- .../mwguards/mw_response_messages.go | 16 ++++----- .../mwguards/valid_timestamp_guard.go | 6 ++-- .../mwguards/valid_timestamp_guard_test.go | 10 +++--- pkg/middleware/public_middleware.go | 4 +-- pkg/middleware/token_middleware.go | 8 ++--- pkg/portal/support.go | 6 ++-- 30 files changed, 104 insertions(+), 104 deletions(-) diff --git a/handler/categories.go b/handler/categories.go index 13dea903..87f45161 100644 --- a/handler/categories.go +++ b/handler/categories.go @@ -3,7 +3,7 @@ package handler import ( "encoding/json" "log/slog" - baseHttp "net/http" + "net/http" "github.com/oullin/database" "github.com/oullin/database/repository" @@ -23,7 +23,7 @@ func MakeCategoriesHandler(categories *repository.Categories) CategoriesHandler } } -func (h *CategoriesHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h *CategoriesHandler) Index(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { result, err := h.Categories.GetAll( paginate.MakeFrom(r.URL, 5), ) diff --git a/handler/education.go b/handler/education.go index 3a35bc62..a34f9a6c 100644 --- a/handler/education.go +++ b/handler/education.go @@ -6,7 +6,7 @@ import ( "github.com/oullin/pkg/portal" "log/slog" - baseHttp "net/http" + "net/http" ) type EducationHandler struct { @@ -19,7 +19,7 @@ func MakeEducationHandler(filePath string) EducationHandler { } } -func (h EducationHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h EducationHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.EducationResponse](h.filePath) if err != nil { diff --git a/handler/experience.go b/handler/experience.go index dd3f1c6f..b0a6656b 100644 --- a/handler/experience.go +++ b/handler/experience.go @@ -6,7 +6,7 @@ import ( "github.com/oullin/pkg/portal" "log/slog" - baseHttp "net/http" + "net/http" ) type ExperienceHandler struct { @@ -19,7 +19,7 @@ func MakeExperienceHandler(filePath string) ExperienceHandler { } } -func (h ExperienceHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h ExperienceHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.ExperienceResponse](h.filePath) if err != nil { diff --git a/handler/file_handler_test.go b/handler/file_handler_test.go index 60ae648f..81755bc2 100644 --- a/handler/file_handler_test.go +++ b/handler/file_handler_test.go @@ -2,7 +2,7 @@ package handler import ( "encoding/json" - baseHttp "net/http" + "net/http" "net/http/httptest" "os" "testing" @@ -12,7 +12,7 @@ import ( ) type fileHandler interface { - Handle(baseHttp.ResponseWriter, *baseHttp.Request) *endpoint.ApiError + Handle(http.ResponseWriter, *http.Request) *endpoint.ApiError } type fileHandlerTestCase struct { @@ -44,7 +44,7 @@ func runFileHandlerTest(t *testing.T, tc fileHandlerTestCase) { t.Fatalf("err: %v", err) } - if rec.Code != baseHttp.StatusOK { + if rec.Code != http.StatusOK { t.Fatalf("status %d", rec.Code) } @@ -68,7 +68,7 @@ func runFileHandlerTest(t *testing.T, tc fileHandlerTestCase) { t.Fatalf("err: %v", err) } - if rec2.Code != baseHttp.StatusNotModified { + if rec2.Code != http.StatusNotModified { t.Fatalf("status %d", rec2.Code) } diff --git a/handler/keep_alive.go b/handler/keep_alive.go index 286d10c7..b2439299 100644 --- a/handler/keep_alive.go +++ b/handler/keep_alive.go @@ -2,7 +2,7 @@ package handler import ( "fmt" - baseHttp "net/http" + "net/http" "time" "github.com/oullin/handler/payload" @@ -19,7 +19,7 @@ func MakeKeepAliveHandler(e *env.PingEnvironment) KeepAliveHandler { return KeepAliveHandler{env: e} } -func (h KeepAliveHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h KeepAliveHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { user, pass, ok := r.BasicAuth() if !ok || h.env.HasInvalidCreds(user, pass) { diff --git a/handler/keep_alive_db.go b/handler/keep_alive_db.go index f26938a6..215364e3 100644 --- a/handler/keep_alive_db.go +++ b/handler/keep_alive_db.go @@ -2,7 +2,7 @@ package handler import ( "fmt" - baseHttp "net/http" + "net/http" "time" "github.com/oullin/database" @@ -21,7 +21,7 @@ func MakeKeepAliveDBHandler(e *env.PingEnvironment, db *database.Connection) Kee return KeepAliveDBHandler{env: e, db: db} } -func (h KeepAliveDBHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h KeepAliveDBHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { user, pass, ok := r.BasicAuth() if !ok || h.env.HasInvalidCreds(user, pass) { diff --git a/handler/payload/posts.go b/handler/payload/posts.go index 51e12141..a377e863 100644 --- a/handler/payload/posts.go +++ b/handler/payload/posts.go @@ -5,7 +5,7 @@ import ( "github.com/oullin/database/repository/queries" "github.com/oullin/pkg/portal" - baseHttp "net/http" + "net/http" "strings" "time" ) @@ -45,7 +45,7 @@ func GetPostsFiltersFrom(request IndexRequestBody) queries.PostFilters { } } -func GetSlugFrom(r *baseHttp.Request) string { +func GetSlugFrom(r *http.Request) string { str := portal.MakeStringable(r.PathValue("slug")) return strings.TrimSpace(str.ToLower()) diff --git a/handler/posts.go b/handler/posts.go index 8a31d041..cb41e782 100644 --- a/handler/posts.go +++ b/handler/posts.go @@ -12,7 +12,7 @@ import ( "github.com/oullin/pkg/portal" "log/slog" - baseHttp "net/http" + "net/http" ) type PostsHandler struct { @@ -23,7 +23,7 @@ func MakePostsHandler(repo *repository.Posts) PostsHandler { return PostsHandler{Posts: repo} } -func (h *PostsHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h *PostsHandler) Index(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { defer portal.CloseWithLog(r.Body) requestBody, err := endpoint.ParseRequestBody[payload.IndexRequestBody](r) @@ -59,7 +59,7 @@ func (h *PostsHandler) Index(w baseHttp.ResponseWriter, r *baseHttp.Request) *en return nil } -func (h *PostsHandler) Show(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h *PostsHandler) Show(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { slug := payload.GetSlugFrom(r) if slug == "" { diff --git a/handler/profile.go b/handler/profile.go index d80f6ce8..3762841a 100644 --- a/handler/profile.go +++ b/handler/profile.go @@ -6,7 +6,7 @@ import ( "github.com/oullin/pkg/portal" "log/slog" - baseHttp "net/http" + "net/http" ) type ProfileHandler struct { @@ -19,7 +19,7 @@ func MakeProfileHandler(filePath string) ProfileHandler { } } -func (h ProfileHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h ProfileHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.ProfileResponse](h.filePath) if err != nil { diff --git a/handler/projects.go b/handler/projects.go index 5ab38f18..044c9e8e 100644 --- a/handler/projects.go +++ b/handler/projects.go @@ -6,7 +6,7 @@ import ( "github.com/oullin/pkg/portal" "log/slog" - baseHttp "net/http" + "net/http" ) type ProjectsHandler struct { @@ -19,7 +19,7 @@ func MakeProjectsHandler(filePath string) ProjectsHandler { } } -func (h ProjectsHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h ProjectsHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.ProjectsResponse](h.filePath) if err != nil { diff --git a/handler/recommendations.go b/handler/recommendations.go index e93e5ffc..d2ca1de1 100644 --- a/handler/recommendations.go +++ b/handler/recommendations.go @@ -6,7 +6,7 @@ import ( "github.com/oullin/pkg/portal" "log/slog" - baseHttp "net/http" + "net/http" ) type RecommendationsHandler struct { @@ -19,7 +19,7 @@ func MakeRecommendationsHandler(filePath string) RecommendationsHandler { } } -func (h RecommendationsHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h RecommendationsHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.RecommendationsResponse](h.filePath) if err != nil { diff --git a/handler/signatures.go b/handler/signatures.go index 9056a153..73d0ea9e 100644 --- a/handler/signatures.go +++ b/handler/signatures.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" "log/slog" - baseHttp "net/http" + "net/http" "time" "github.com/oullin/database" @@ -28,7 +28,7 @@ func MakeSignaturesHandler(validator *portal.Validator, ApiKeys *repository.ApiK } } -func (s *SignaturesHandler) Generate(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (s *SignaturesHandler) Generate(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { defer portal.CloseWithLog(r.Body) var ( @@ -36,7 +36,7 @@ func (s *SignaturesHandler) Generate(w baseHttp.ResponseWriter, r *baseHttp.Requ req payload.SignatureRequest ) - r.Body = baseHttp.MaxBytesReader(w, r.Body, endpoint.MaxRequestSize) + r.Body = http.MaxBytesReader(w, r.Body, endpoint.MaxRequestSize) dec := json.NewDecoder(r.Body) dec.DisallowUnknownFields() if err = dec.Decode(&req); err != nil { diff --git a/handler/social.go b/handler/social.go index b5ab8a13..0b7b59dc 100644 --- a/handler/social.go +++ b/handler/social.go @@ -6,7 +6,7 @@ import ( "github.com/oullin/pkg/portal" "log/slog" - baseHttp "net/http" + "net/http" ) type SocialHandler struct { @@ -19,7 +19,7 @@ func MakeSocialHandler(filePath string) SocialHandler { } } -func (h SocialHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h SocialHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.SocialResponse](h.filePath) if err != nil { diff --git a/handler/talks.go b/handler/talks.go index 11e0ef01..3ca45fd1 100644 --- a/handler/talks.go +++ b/handler/talks.go @@ -6,7 +6,7 @@ import ( "github.com/oullin/pkg/portal" "log/slog" - baseHttp "net/http" + "net/http" ) type TalksHandler struct { @@ -19,7 +19,7 @@ func MakeTalksHandler(filePath string) TalksHandler { } } -func (h TalksHandler) Handle(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { +func (h TalksHandler) Handle(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { data, err := portal.ParseJsonFile[payload.TalksResponse](h.filePath) if err != nil { diff --git a/main.go b/main.go index 0af25ae6..ab2fa1a9 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "fmt" "log/slog" - baseHttp "net/http" + "net/http" "time" "github.com/getsentry/sentry-go" @@ -42,20 +42,20 @@ func main() { slog.Info("Starting new server on :" + app.GetEnv().Network.HttpPort) // --- - if err := baseHttp.ListenAndServe(app.GetEnv().Network.GetHostURL(), serverHandler()); err != nil { + if err := http.ListenAndServe(app.GetEnv().Network.GetHostURL(), serverHandler()); err != nil { sentry.CurrentHub().CaptureException(err) slog.Error("Error starting server", "error", err) panic("Error starting server." + err.Error()) } } -func serverHandler() baseHttp.Handler { +func serverHandler() http.Handler { mux := app.GetMux() if mux == nil { - return baseHttp.NotFoundHandler() + return http.NotFoundHandler() } - var handler baseHttp.Handler = mux + var handler http.Handler = mux if !app.IsProduction() { // Caddy handles CORS. localhost := app.GetEnv().Network.GetHostURL() @@ -78,7 +78,7 @@ func serverHandler() baseHttp.Handler { c := cors.New(cors.Options{ AllowedOrigins: []string{localhost, "http://localhost:5173"}, - AllowedMethods: []string{baseHttp.MethodGet, baseHttp.MethodPost, baseHttp.MethodPut, baseHttp.MethodDelete, baseHttp.MethodOptions}, + AllowedMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodOptions}, AllowedHeaders: headers, AllowCredentials: true, Debug: true, diff --git a/metal/kernel/app.go b/metal/kernel/app.go index 4629210f..4f57287b 100644 --- a/metal/kernel/app.go +++ b/metal/kernel/app.go @@ -2,7 +2,7 @@ package kernel import ( "fmt" - baseHttp "net/http" + "net/http" "github.com/oullin/database" "github.com/oullin/database/repository" @@ -71,7 +71,7 @@ func (a *App) NewRouter() (*router.Router, error) { Db: a.db, Pipeline: pipe, Validator: a.validator, - Mux: baseHttp.NewServeMux(), + Mux: http.NewServeMux(), WebsiteRoutes: router.NewWebsiteRoutes(envi), } diff --git a/metal/kernel/helpers.go b/metal/kernel/helpers.go index 4cda0948..8e9926ff 100644 --- a/metal/kernel/helpers.go +++ b/metal/kernel/helpers.go @@ -1,7 +1,7 @@ package kernel import ( - baseHttp "net/http" + "net/http" "github.com/getsentry/sentry-go" "github.com/oullin/database" @@ -68,7 +68,7 @@ func (a *App) GetSentry() *portal.Sentry { return a.sentry } -func (a *App) GetMux() *baseHttp.ServeMux { +func (a *App) GetMux() *http.ServeMux { if a.router == nil { return nil } diff --git a/metal/router/router.go b/metal/router/router.go index 217679f2..dcd87e0a 100644 --- a/metal/router/router.go +++ b/metal/router/router.go @@ -1,7 +1,7 @@ package router import ( - baseHttp "net/http" + "net/http" "strings" "github.com/oullin/database" @@ -17,12 +17,12 @@ type Router struct { WebsiteRoutes *WebsiteRoutes Env *env.Environment Validator *portal.Validator - Mux *baseHttp.ServeMux + Mux *http.ServeMux Pipeline middleware.Pipeline Db *database.Connection } -func (r *Router) PublicPipelineFor(apiHandler endpoint.ApiHandler) baseHttp.HandlerFunc { +func (r *Router) PublicPipelineFor(apiHandler endpoint.ApiHandler) http.HandlerFunc { return endpoint.MakeApiHandler( r.Pipeline.Chain( apiHandler, @@ -31,7 +31,7 @@ func (r *Router) PublicPipelineFor(apiHandler endpoint.ApiHandler) baseHttp.Hand ) } -func (r *Router) PipelineFor(apiHandler endpoint.ApiHandler) baseHttp.HandlerFunc { +func (r *Router) PipelineFor(apiHandler endpoint.ApiHandler) http.HandlerFunc { tokenMiddleware := middleware.MakeTokenMiddleware( r.Pipeline.TokenHandler, r.Pipeline.ApiKeys, diff --git a/metal/router/static.go b/metal/router/static.go index dec6c3ed..f9d55060 100644 --- a/metal/router/static.go +++ b/metal/router/static.go @@ -1,14 +1,14 @@ package router import ( - baseHttp "net/http" + "net/http" "github.com/oullin/metal/env" "github.com/oullin/pkg/endpoint" ) type StaticRouteResource interface { - Handle(baseHttp.ResponseWriter, *baseHttp.Request) *endpoint.ApiError + Handle(http.ResponseWriter, *http.Request) *endpoint.ApiError } type WebsiteRoutes struct { diff --git a/pkg/endpoint/handler.go b/pkg/endpoint/handler.go index b56e24d8..760e8825 100644 --- a/pkg/endpoint/handler.go +++ b/pkg/endpoint/handler.go @@ -3,13 +3,13 @@ package endpoint import ( "encoding/json" "log/slog" - baseHttp "net/http" + "net/http" "github.com/getsentry/sentry-go" ) -func MakeApiHandler(fn ApiHandler) baseHttp.HandlerFunc { - return func(w baseHttp.ResponseWriter, r *baseHttp.Request) { +func MakeApiHandler(fn ApiHandler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { if err := fn(w, r); err != nil { slog.Error("API Error", "message", err.Message, "status", err.Status) @@ -31,7 +31,7 @@ func MakeApiHandler(fn ApiHandler) baseHttp.HandlerFunc { } } -func captureApiError(r *baseHttp.Request, apiErr *ApiError) { +func captureApiError(r *http.Request, apiErr *ApiError) { if apiErr == nil { return } diff --git a/pkg/endpoint/request.go b/pkg/endpoint/request.go index 1fd8168b..67c93543 100644 --- a/pkg/endpoint/request.go +++ b/pkg/endpoint/request.go @@ -4,12 +4,12 @@ import ( "encoding/json" "fmt" "io" - baseHttp "net/http" + "net/http" ) const MaxRequestSize = 1 << 20 // 1MB limit -func ParseRequestBody[T any](r *baseHttp.Request) (T, error) { +func ParseRequestBody[T any](r *http.Request) (T, error) { var err error var request T var data []byte diff --git a/pkg/endpoint/response.go b/pkg/endpoint/response.go index 976090bf..2d90f0ae 100644 --- a/pkg/endpoint/response.go +++ b/pkg/endpoint/response.go @@ -5,19 +5,19 @@ import ( "errors" "fmt" "log/slog" - baseHttp "net/http" + "net/http" "strings" ) type Response struct { etag string cacheControl string - writer baseHttp.ResponseWriter - request *baseHttp.Request - headers func(w baseHttp.ResponseWriter) + writer http.ResponseWriter + request *http.Request + headers func(w http.ResponseWriter) } -func MakeResponseFrom(salt string, writer baseHttp.ResponseWriter, request *baseHttp.Request) *Response { +func MakeResponseFrom(salt string, writer http.ResponseWriter, request *http.Request) *Response { etag := fmt.Sprintf( `"%s"`, strings.TrimSpace(salt), @@ -30,7 +30,7 @@ func MakeResponseFrom(salt string, writer baseHttp.ResponseWriter, request *base request: request, etag: strings.TrimSpace(etag), cacheControl: cacheControl, - headers: func(w baseHttp.ResponseWriter) { + headers: func(w http.ResponseWriter) { w.Header().Set("Content-Type", "application/json") w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("Cache-Control", cacheControl) @@ -39,14 +39,14 @@ func MakeResponseFrom(salt string, writer baseHttp.ResponseWriter, request *base } } -func MakeNoCacheResponse(writer baseHttp.ResponseWriter, request *baseHttp.Request) *Response { +func MakeNoCacheResponse(writer http.ResponseWriter, request *http.Request) *Response { cacheControl := "no-store" return &Response{ writer: writer, request: request, cacheControl: cacheControl, - headers: func(w baseHttp.ResponseWriter) { + headers: func(w http.ResponseWriter) { w.Header().Set("Content-Type", "application/json") w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("Cache-Control", cacheControl) @@ -54,7 +54,7 @@ func MakeNoCacheResponse(writer baseHttp.ResponseWriter, request *baseHttp.Reque } } -func (r *Response) WithHeaders(callback func(w baseHttp.ResponseWriter)) { +func (r *Response) WithHeaders(callback func(w http.ResponseWriter)) { callback(r.writer) } @@ -63,7 +63,7 @@ func (r *Response) RespondOk(payload any) error { headers := r.headers headers(w) - w.WriteHeader(baseHttp.StatusOK) + w.WriteHeader(http.StatusOK) return json.NewEncoder(r.writer).Encode(payload) } @@ -83,7 +83,7 @@ func (r *Response) HasCache() bool { } func (r *Response) RespondWithNotModified() { - r.writer.WriteHeader(baseHttp.StatusNotModified) + r.writer.WriteHeader(http.StatusNotModified) } func InternalError(msg string) *ApiError { @@ -91,7 +91,7 @@ func InternalError(msg string) *ApiError { return &ApiError{ Message: message, - Status: baseHttp.StatusInternalServerError, + Status: http.StatusInternalServerError, Err: errors.New(message), } } @@ -101,7 +101,7 @@ func LogInternalError(msg string, err error) *ApiError { return &ApiError{ Message: fmt.Sprintf("Internal server error: %s", msg), - Status: baseHttp.StatusInternalServerError, + Status: http.StatusInternalServerError, Err: err, } } @@ -111,7 +111,7 @@ func BadRequestError(msg string) *ApiError { return &ApiError{ Message: message, - Status: baseHttp.StatusBadRequest, + Status: http.StatusBadRequest, Err: errors.New(message), } } @@ -121,7 +121,7 @@ func LogBadRequestError(msg string, err error) *ApiError { return &ApiError{ Message: fmt.Sprintf("Bad request error: %s", msg), - Status: baseHttp.StatusBadRequest, + Status: http.StatusBadRequest, Err: err, } } @@ -131,7 +131,7 @@ func LogUnauthorisedError(msg string, err error) *ApiError { return &ApiError{ Message: fmt.Sprintf("Unauthorised request: %s", msg), - Status: baseHttp.StatusUnauthorized, + Status: http.StatusUnauthorized, Err: err, } } @@ -141,7 +141,7 @@ func UnprocessableEntity(msg string, errs map[string]any) *ApiError { return &ApiError{ Message: message, - Status: baseHttp.StatusUnprocessableEntity, + Status: http.StatusUnprocessableEntity, Data: errs, Err: errors.New(message), } @@ -152,7 +152,7 @@ func NotFound(msg string) *ApiError { return &ApiError{ Message: message, - Status: baseHttp.StatusNotFound, + Status: http.StatusNotFound, Err: errors.New(message), } } diff --git a/pkg/endpoint/schema.go b/pkg/endpoint/schema.go index 5cec081a..d2f6dd88 100644 --- a/pkg/endpoint/schema.go +++ b/pkg/endpoint/schema.go @@ -1,6 +1,6 @@ package endpoint -import baseHttp "net/http" +import "net/http" type ErrorResponse struct { Error string `json:"error"` @@ -31,6 +31,6 @@ func (e *ApiError) Unwrap() error { return e.Err } -type ApiHandler func(baseHttp.ResponseWriter, *baseHttp.Request) *ApiError +type ApiHandler func(http.ResponseWriter, *http.Request) *ApiError type Middleware func(ApiHandler) ApiHandler diff --git a/pkg/endpoint/scope_api_error.go b/pkg/endpoint/scope_api_error.go index 5bd08068..624191a0 100644 --- a/pkg/endpoint/scope_api_error.go +++ b/pkg/endpoint/scope_api_error.go @@ -3,7 +3,7 @@ package endpoint import ( "errors" "fmt" - baseHttp "net/http" + "net/http" "strconv" "strings" @@ -13,11 +13,11 @@ import ( type ScopeApiError struct { scope *sentry.Scope - request *baseHttp.Request + request *http.Request apiErr *ApiError } -func NewScopeApiError(scope *sentry.Scope, r *baseHttp.Request, apiErr *ApiError) *ScopeApiError { +func NewScopeApiError(scope *sentry.Scope, r *http.Request, apiErr *ApiError) *ScopeApiError { return &ScopeApiError{scope: scope, request: r, apiErr: apiErr} } @@ -41,7 +41,7 @@ func (s *ScopeApiError) Enrich() { } level := sentry.LevelWarning - if s.apiErr.Status >= baseHttp.StatusInternalServerError { + if s.apiErr.Status >= http.StatusInternalServerError { level = sentry.LevelError } @@ -51,7 +51,7 @@ func (s *ScopeApiError) Enrich() { s.scope.SetTag("http.route", s.request.URL.Path) s.scope.SetRequest(s.request) - s.scope.SetExtra("api_error_status_text", baseHttp.StatusText(s.apiErr.Status)) + s.scope.SetExtra("api_error_status_text", http.StatusText(s.apiErr.Status)) s.scope.SetExtra("api_error_message", s.apiErr.Message) if requestID := s.RequestID(); requestID != "" { diff --git a/pkg/middleware/mwguards/mw_response_messages.go b/pkg/middleware/mwguards/mw_response_messages.go index b4d3ed92..6fedcd67 100644 --- a/pkg/middleware/mwguards/mw_response_messages.go +++ b/pkg/middleware/mwguards/mw_response_messages.go @@ -2,7 +2,7 @@ package mwguards import ( "log/slog" - baseHttp "net/http" + "net/http" "strings" "github.com/oullin/pkg/endpoint" @@ -41,7 +41,7 @@ func InvalidRequestError(message, logMessage string, data ...map[string]any) *en return &endpoint.ApiError{ Message: message, - Status: baseHttp.StatusUnauthorized, + Status: http.StatusUnauthorized, Data: d, } } @@ -54,7 +54,7 @@ func InvalidTokenFormatError(message, logMessage string, data ...map[string]any) return &endpoint.ApiError{ Message: message, - Status: baseHttp.StatusUnauthorized, + Status: http.StatusUnauthorized, Data: d, } } @@ -67,7 +67,7 @@ func UnauthenticatedError(message, logMessage string, data ...map[string]any) *e return &endpoint.ApiError{ Message: "2- Invalid credentials: " + logMessage, - Status: baseHttp.StatusUnauthorized, + Status: http.StatusUnauthorized, Data: d, } } @@ -80,7 +80,7 @@ func RateLimitedError(message, logMessage string, data ...map[string]any) *endpo return &endpoint.ApiError{ Message: "Too many authentication attempts", - Status: baseHttp.StatusTooManyRequests, + Status: http.StatusTooManyRequests, Data: d, } } @@ -93,7 +93,7 @@ func NotFound(message, logMessage string, data ...map[string]any) *endpoint.ApiE return &endpoint.ApiError{ Message: message, - Status: baseHttp.StatusNotFound, + Status: http.StatusNotFound, Data: d, } } @@ -106,7 +106,7 @@ func TimestampTooOldError(message, logMessage string, data ...map[string]any) *e return &endpoint.ApiError{ Message: "Request timestamp expired", - Status: baseHttp.StatusUnauthorized, + Status: http.StatusUnauthorized, Data: d, } } @@ -119,7 +119,7 @@ func TimestampTooNewError(message, logMessage string, data ...map[string]any) *e return &endpoint.ApiError{ Message: "Request timestamp invalid", - Status: baseHttp.StatusUnauthorized, + Status: http.StatusUnauthorized, Data: d, } } diff --git a/pkg/middleware/mwguards/valid_timestamp_guard.go b/pkg/middleware/mwguards/valid_timestamp_guard.go index 15074333..dca89076 100644 --- a/pkg/middleware/mwguards/valid_timestamp_guard.go +++ b/pkg/middleware/mwguards/valid_timestamp_guard.go @@ -1,7 +1,7 @@ package mwguards import ( - baseHttp "net/http" + "net/http" "strconv" "time" @@ -22,12 +22,12 @@ func NewValidTimestamp(ts string, now func() time.Time) ValidTimestamp { func (v ValidTimestamp) Validate(skew time.Duration, disallowFuture bool) *endpoint.ApiError { if v.ts == "" { - return &endpoint.ApiError{Message: "Invalid authentication headers", Status: baseHttp.StatusUnauthorized} + return &endpoint.ApiError{Message: "Invalid authentication headers", Status: http.StatusUnauthorized} } epoch, err := strconv.ParseInt(v.ts, 10, 64) if err != nil { - return &endpoint.ApiError{Message: "Invalid authentication headers", Status: baseHttp.StatusUnauthorized} + return &endpoint.ApiError{Message: "Invalid authentication headers", Status: http.StatusUnauthorized} } nowFn := v.now diff --git a/pkg/middleware/mwguards/valid_timestamp_guard_test.go b/pkg/middleware/mwguards/valid_timestamp_guard_test.go index f0e251ce..53f74ac1 100644 --- a/pkg/middleware/mwguards/valid_timestamp_guard_test.go +++ b/pkg/middleware/mwguards/valid_timestamp_guard_test.go @@ -1,7 +1,7 @@ package mwguards import ( - baseHttp "net/http" + "net/http" "strconv" "testing" "time" @@ -24,7 +24,7 @@ func TestNewValidTimestampConstructor(t *testing.T) { func TestValidate_EmptyTimestamp(t *testing.T) { vt := NewValidTimestamp("", fixedClock(time.Unix(1_700_000_000, 0))) err := vt.Validate(5*time.Minute, false) - if err == nil || err.Status != baseHttp.StatusUnauthorized || err.Message != "Invalid authentication headers" { + if err == nil || err.Status != http.StatusUnauthorized || err.Message != "Invalid authentication headers" { t.Fatalf("expected invalid request error for empty timestamp, got %#v", err) } } @@ -32,7 +32,7 @@ func TestValidate_EmptyTimestamp(t *testing.T) { func TestValidate_NonNumericTimestamp(t *testing.T) { vt := NewValidTimestamp("abc", fixedClock(time.Unix(1_700_000_000, 0))) err := vt.Validate(5*time.Minute, false) - if err == nil || err.Status != baseHttp.StatusUnauthorized || err.Message != "Invalid authentication headers" { + if err == nil || err.Status != http.StatusUnauthorized || err.Message != "Invalid authentication headers" { t.Fatalf("expected invalid request error for non-numeric timestamp, got %#v", err) } } @@ -43,7 +43,7 @@ func TestValidate_TooOldTimestamp(t *testing.T) { oldTs := strconv.FormatInt(base.Add(-skew).Add(-1*time.Second).Unix(), 10) vt := NewValidTimestamp(oldTs, fixedClock(base)) err := vt.Validate(skew, false) - if err == nil || err.Status != baseHttp.StatusUnauthorized || err.Message != "Request timestamp expired" { + if err == nil || err.Status != http.StatusUnauthorized || err.Message != "Request timestamp expired" { t.Fatalf("expected unauthenticated for too old timestamp, got %#v", err) } } @@ -62,7 +62,7 @@ func TestValidate_FutureWithinSkew_Behavior(t *testing.T) { // Rejected when disallowFuture=true vt = NewValidTimestamp(futureWithin, fixedClock(base)) err := vt.Validate(skew, true) - if err == nil || err.Status != baseHttp.StatusUnauthorized || err.Message != "Request timestamp invalid" { + if err == nil || err.Status != http.StatusUnauthorized || err.Message != "Request timestamp invalid" { t.Fatalf("expected unauthenticated for future timestamp when disallowFuture=true, got %#v", err) } } diff --git a/pkg/middleware/public_middleware.go b/pkg/middleware/public_middleware.go index 6c521871..c7771b62 100644 --- a/pkg/middleware/public_middleware.go +++ b/pkg/middleware/public_middleware.go @@ -2,7 +2,7 @@ package middleware import ( "fmt" - baseHttp "net/http" + "net/http" "strings" "time" @@ -42,7 +42,7 @@ func MakePublicMiddleware(allowedIP string, isProduction bool) PublicMiddleware } func (p PublicMiddleware) Handle(next endpoint.ApiHandler) endpoint.ApiHandler { - return func(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { + return func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { if err := p.GuardDependencies(); err != nil { return err } diff --git a/pkg/middleware/token_middleware.go b/pkg/middleware/token_middleware.go index 8dcf0fe5..08bcf1d3 100644 --- a/pkg/middleware/token_middleware.go +++ b/pkg/middleware/token_middleware.go @@ -4,7 +4,7 @@ import ( "context" "encoding/hex" "fmt" - baseHttp "net/http" + "net/http" "strings" "time" @@ -48,7 +48,7 @@ func MakeTokenMiddleware(tokenHandler *auth.TokenHandler, apiKeys *repository.Ap } func (t TokenCheckMiddleware) Handle(next endpoint.ApiHandler) endpoint.ApiHandler { - return func(w baseHttp.ResponseWriter, r *baseHttp.Request) *endpoint.ApiError { + return func(w http.ResponseWriter, r *http.Request) *endpoint.ApiError { reqID := strings.TrimSpace(r.Header.Get(portal.RequestIDHeader)) if reqID == "" { @@ -117,7 +117,7 @@ func (t TokenCheckMiddleware) GuardDependencies() *endpoint.ApiError { return nil } -func (t TokenCheckMiddleware) ValidateAndGetHeaders(r *baseHttp.Request, requestId string) (AuthTokenHeaders, *endpoint.ApiError) { +func (t TokenCheckMiddleware) ValidateAndGetHeaders(r *http.Request, requestId string) (AuthTokenHeaders, *endpoint.ApiError) { intendedOriginURL := strings.TrimSpace(r.Header.Get(portal.IntendedOriginHeader)) accountName := strings.TrimSpace(r.Header.Get(portal.UsernameHeader)) signature := strings.TrimSpace(r.Header.Get(portal.SignatureHeader)) @@ -149,7 +149,7 @@ func (t TokenCheckMiddleware) ValidateAndGetHeaders(r *baseHttp.Request, request }, nil } -func (t TokenCheckMiddleware) AttachContext(r *baseHttp.Request, headers AuthTokenHeaders) *baseHttp.Request { +func (t TokenCheckMiddleware) AttachContext(r *http.Request, headers AuthTokenHeaders) *http.Request { ctx := context.WithValue(r.Context(), portal.AuthAccountNameKey, headers.AccountName) ctx = context.WithValue(r.Context(), portal.RequestIDKey, headers.RequestID) diff --git a/pkg/portal/support.go b/pkg/portal/support.go index 874fa4f8..cf39ec42 100644 --- a/pkg/portal/support.go +++ b/pkg/portal/support.go @@ -8,7 +8,7 @@ import ( "io" "log/slog" "net" - baseHttp "net/http" + "net/http" "net/url" "sort" "strings" @@ -99,7 +99,7 @@ func CloseWithLog(c io.Closer) { } } -func GenerateURL(r *baseHttp.Request) string { +func GenerateURL(r *http.Request) string { scheme := "http" if r.TLS != nil { scheme = "https" @@ -168,7 +168,7 @@ func BuildCanonical(method string, u *url.URL, username, public, ts, nonce, body return strings.Join(parts, "\n") } -func ParseClientIP(r *baseHttp.Request) string { +func ParseClientIP(r *http.Request) string { // prefer X-Forwarded-For if present xff := strings.TrimSpace(r.Header.Get("X-Forwarded-For"))