mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 00:57:44 +01:00
Unify the method/style to handle error in handler/middleware
This commit provides a "SendError" method to unify the way to handle error in handlers/middlewares Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
parent
8a74fcb074
commit
af4dd142bc
@ -317,7 +317,7 @@ responses:
|
|||||||
description: The ID of the corresponding request for the response
|
description: The ID of the corresponding request for the response
|
||||||
type: string
|
type: string
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Errors'
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized
|
description: Unauthorized
|
||||||
headers:
|
headers:
|
||||||
@ -325,7 +325,7 @@ responses:
|
|||||||
description: The ID of the corresponding request for the response
|
description: The ID of the corresponding request for the response
|
||||||
type: string
|
type: string
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Errors'
|
||||||
'403':
|
'403':
|
||||||
description: Forbidden
|
description: Forbidden
|
||||||
headers:
|
headers:
|
||||||
@ -333,7 +333,7 @@ responses:
|
|||||||
description: The ID of the corresponding request for the response
|
description: The ID of the corresponding request for the response
|
||||||
type: string
|
type: string
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Errors'
|
||||||
'404':
|
'404':
|
||||||
description: Not found
|
description: Not found
|
||||||
headers:
|
headers:
|
||||||
@ -341,7 +341,7 @@ responses:
|
|||||||
description: The ID of the corresponding request for the response
|
description: The ID of the corresponding request for the response
|
||||||
type: string
|
type: string
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Errors'
|
||||||
'409':
|
'409':
|
||||||
description: Conflict
|
description: Conflict
|
||||||
headers:
|
headers:
|
||||||
@ -349,7 +349,7 @@ responses:
|
|||||||
description: The ID of the corresponding request for the response
|
description: The ID of the corresponding request for the response
|
||||||
type: string
|
type: string
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Errors'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
headers:
|
headers:
|
||||||
@ -357,8 +357,13 @@ responses:
|
|||||||
description: The ID of the corresponding request for the response
|
description: The ID of the corresponding request for the response
|
||||||
type: string
|
type: string
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Errors'
|
||||||
definitions:
|
definitions:
|
||||||
|
Errors:
|
||||||
|
description: The error array that describe the errors got during the handling of request
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/Error'
|
||||||
Error:
|
Error:
|
||||||
description: a model for all the error response coming from harbor
|
description: a model for all the error response coming from harbor
|
||||||
type: object
|
type: object
|
||||||
@ -369,11 +374,6 @@ definitions:
|
|||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
description: The error message
|
description: The error message
|
||||||
x-go-type:
|
|
||||||
import:
|
|
||||||
package: "github.com/goharbor/harbor/src/internal/error"
|
|
||||||
alias: "ierrors"
|
|
||||||
type: "Error"
|
|
||||||
Artifact:
|
Artifact:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -262,6 +262,5 @@ func (b *BaseAPI) SendStatusServiceUnavailableError(err error) {
|
|||||||
// ]
|
// ]
|
||||||
// }
|
// }
|
||||||
func (b *BaseAPI) SendError(err error) {
|
func (b *BaseAPI) SendError(err error) {
|
||||||
statusCode, payload := serror.APIError(err)
|
serror.SendError(b.Ctx.ResponseWriter, err)
|
||||||
b.RenderError(statusCode, payload)
|
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,14 @@ package error
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"fmt"
|
||||||
|
openapi "github.com/go-openapi/errors"
|
||||||
"github.com/go-openapi/runtime"
|
"github.com/go-openapi/runtime"
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -28,25 +31,57 @@ var (
|
|||||||
ierror.BadRequestCode: http.StatusBadRequest,
|
ierror.BadRequestCode: http.StatusBadRequest,
|
||||||
ierror.UnAuthorizedCode: http.StatusUnauthorized,
|
ierror.UnAuthorizedCode: http.StatusUnauthorized,
|
||||||
ierror.ForbiddenCode: http.StatusForbidden,
|
ierror.ForbiddenCode: http.StatusForbidden,
|
||||||
|
ierror.DENIED: http.StatusForbidden,
|
||||||
ierror.NotFoundCode: http.StatusNotFound,
|
ierror.NotFoundCode: http.StatusNotFound,
|
||||||
ierror.ConflictCode: http.StatusConflict,
|
ierror.ConflictCode: http.StatusConflict,
|
||||||
ierror.PreconditionCode: http.StatusPreconditionFailed,
|
ierror.PreconditionCode: http.StatusPreconditionFailed,
|
||||||
ierror.ViolateForeignKeyConstraintCode: http.StatusPreconditionFailed,
|
ierror.ViolateForeignKeyConstraintCode: http.StatusPreconditionFailed,
|
||||||
|
ierror.PROJECTPOLICYVIOLATION: http.StatusPreconditionFailed,
|
||||||
ierror.GeneralCode: http.StatusInternalServerError,
|
ierror.GeneralCode: http.StatusInternalServerError,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// APIError generates the HTTP status code and error payload based on the input err
|
// TODO use "SendError" instead in the v1 APIs?
|
||||||
func APIError(err error) (int, string) {
|
|
||||||
return getHTTPStatusCode(ierror.ErrCode(err)), ierror.NewErrs(err).Error()
|
// SendError tries to parse the HTTP status code from the specified error, envelops it into
|
||||||
|
// an error array as the error payload and returns the code and payload to the response.
|
||||||
|
// And the error is logged as well
|
||||||
|
func SendError(w http.ResponseWriter, err error) {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
statusCode, errPayload := apiError(err)
|
||||||
|
// the error detail is logged only, and will not be sent to the client to avoid leaking server information
|
||||||
|
if statusCode >= http.StatusInternalServerError {
|
||||||
|
log.Error(errPayload)
|
||||||
|
err = ierror.New(nil).WithCode(ierror.GeneralCode).WithMessage("internal server error")
|
||||||
|
errPayload = ierror.NewErrs(err).Error()
|
||||||
|
} else {
|
||||||
|
// only log the error whose status code < 500 when debugging to avoid log flooding
|
||||||
|
log.Debug(errPayload)
|
||||||
|
}
|
||||||
|
w.WriteHeader(statusCode)
|
||||||
|
fmt.Fprintln(w, errPayload)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHTTPStatusCode(errCode string) int {
|
// generates the HTTP status code based on the specified error,
|
||||||
statusCode, ok := codeMap[errCode]
|
// envelops the error into an error array as the payload and return them
|
||||||
if !ok {
|
func apiError(err error) (statusCode int, errPayload string) {
|
||||||
statusCode = http.StatusInternalServerError
|
code := 0
|
||||||
|
var openAPIErr openapi.Error
|
||||||
|
if errors.As(err, &openAPIErr) {
|
||||||
|
// Before executing operation handler, go-swagger will bind a parameters object to a request and validate the request,
|
||||||
|
// it will return directly when bind and validate failed.
|
||||||
|
// The response format of the default ServeError implementation does not match the internal error response format.
|
||||||
|
// So we needed to convert the format to the internal error response format.
|
||||||
|
code = int(openAPIErr.Code())
|
||||||
|
errCode := strings.Replace(strings.ToUpper(http.StatusText(code)), " ", "_", -1)
|
||||||
|
err = ierror.New(nil).WithCode(errCode).WithMessage(openAPIErr.Error())
|
||||||
|
} else {
|
||||||
|
code = codeMap[ierror.ErrCode(err)]
|
||||||
}
|
}
|
||||||
return statusCode
|
if code == 0 {
|
||||||
|
code = http.StatusInternalServerError
|
||||||
|
}
|
||||||
|
return code, ierror.NewErrs(err).Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ middleware.Responder = &ErrResponder{}
|
var _ middleware.Responder = &ErrResponder{}
|
||||||
@ -58,20 +93,7 @@ type ErrResponder struct {
|
|||||||
|
|
||||||
// WriteResponse ...
|
// WriteResponse ...
|
||||||
func (r *ErrResponder) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
func (r *ErrResponder) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
code := ierror.ErrCode(r.err)
|
SendError(rw, r.err)
|
||||||
rw.WriteHeader(getHTTPStatusCode(code))
|
|
||||||
|
|
||||||
var e *ierror.Error
|
|
||||||
if !errors.As(r.err, &e) {
|
|
||||||
e = &ierror.Error{
|
|
||||||
Code: code,
|
|
||||||
Message: r.err.Error(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := producer.Produce(rw, e); err != nil {
|
|
||||||
panic(err) // let the recovery middleware deal with this
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewErrResponder returns responder for err
|
// NewErrResponder returns responder for err
|
||||||
|
@ -16,38 +16,51 @@ package error
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
openapi "github.com/go-openapi/errors"
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetHTTPStatusCode(t *testing.T) {
|
func TestSendError(t *testing.T) {
|
||||||
// pre-defined error code
|
// internal server error
|
||||||
errCode := ierror.NotFoundCode
|
rw := httptest.NewRecorder()
|
||||||
statusCode := getHTTPStatusCode(errCode)
|
err := ierror.New(nil).WithCode(ierror.GeneralCode).WithMessage("unknown")
|
||||||
assert.Equal(t, http.StatusNotFound, statusCode)
|
SendError(rw, err)
|
||||||
|
assert.Equal(t, http.StatusInternalServerError, rw.Code)
|
||||||
|
assert.Equal(t, `{"errors":[{"code":"UNKNOWN","message":"internal server error"}]}`+"\n", rw.Body.String())
|
||||||
|
|
||||||
// not-defined error code
|
// not internal server error
|
||||||
errCode = "NOT_DEFINED_ERROR_CODE"
|
rw = httptest.NewRecorder()
|
||||||
statusCode = getHTTPStatusCode(errCode)
|
err = ierror.New(nil).WithCode(ierror.NotFoundCode).WithMessage("object not found")
|
||||||
assert.Equal(t, http.StatusInternalServerError, statusCode)
|
SendError(rw, err)
|
||||||
|
assert.Equal(t, http.StatusNotFound, rw.Code)
|
||||||
|
assert.Equal(t, `{"errors":[{"code":"NOT_FOUND","message":"object not found"}]}`+"\n", rw.Body.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPIError(t *testing.T) {
|
func TestAPIError(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
// open API error: github.com/go-openapi/errors.Error
|
||||||
|
err = openapi.New(400, "bad request")
|
||||||
|
statusCode, payload := apiError(err)
|
||||||
|
assert.Equal(t, http.StatusBadRequest, statusCode)
|
||||||
|
assert.Equal(t, `{"errors":[{"code":"BAD_REQUEST","message":"bad request"}]}`, payload)
|
||||||
|
|
||||||
// ierror.Error
|
// ierror.Error
|
||||||
err := &ierror.Error{
|
err = &ierror.Error{
|
||||||
Cause: nil,
|
Cause: nil,
|
||||||
Code: ierror.NotFoundCode,
|
Code: ierror.NotFoundCode,
|
||||||
Message: "resource not found",
|
Message: "resource not found",
|
||||||
}
|
}
|
||||||
statusCode, payload := APIError(err)
|
statusCode, payload = apiError(err)
|
||||||
assert.Equal(t, http.StatusNotFound, statusCode)
|
assert.Equal(t, http.StatusNotFound, statusCode)
|
||||||
assert.Equal(t, `{"errors":[{"code":"NOT_FOUND","message":"resource not found"}]}`, payload)
|
assert.Equal(t, `{"errors":[{"code":"NOT_FOUND","message":"resource not found"}]}`, payload)
|
||||||
|
|
||||||
// common error
|
// common error
|
||||||
e := errors.New("customized error")
|
e := errors.New("customized error")
|
||||||
statusCode, payload = APIError(e)
|
statusCode, payload = apiError(e)
|
||||||
assert.Equal(t, http.StatusInternalServerError, statusCode)
|
assert.Equal(t, http.StatusInternalServerError, statusCode)
|
||||||
assert.Equal(t, `{"errors":[{"code":"UNKNOWN","message":"customized error"}]}`, payload)
|
assert.Equal(t, `{"errors":[{"code":"UNKNOWN","message":"customized error"}]}`, payload)
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,15 @@ package artifactinfo
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
|
||||||
reg_err "github.com/goharbor/harbor/src/server/registry/error"
|
|
||||||
"github.com/opencontainers/go-digest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -58,7 +57,7 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
repo := m[middleware.RepositorySubexp]
|
repo := m[middleware.RepositorySubexp]
|
||||||
pn, err := projectNameFromRepo(repo)
|
pn, err := projectNameFromRepo(repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_err.Handle(rw, req, ierror.BadRequestError(err))
|
serror.SendError(rw, ierror.BadRequestError(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
art := &middleware.ArtifactInfo{
|
art := &middleware.ArtifactInfo{
|
||||||
@ -77,7 +76,7 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
// it's not clear in OCI spec how to handle invalid from parm
|
// it's not clear in OCI spec how to handle invalid from parm
|
||||||
bmp, err := projectNameFromRepo(bmr)
|
bmp, err := projectNameFromRepo(bmr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_err.Handle(rw, req, ierror.BadRequestError(err))
|
serror.SendError(rw, ierror.BadRequestError(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
art.BlobMountDigest = m[blobMountDigest]
|
art.BlobMountDigest = m[blobMountDigest]
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/core/config"
|
"github.com/goharbor/harbor/src/core/config"
|
||||||
"github.com/goharbor/harbor/src/core/middlewares/util"
|
"github.com/goharbor/harbor/src/core/middlewares/util"
|
||||||
internal_errors "github.com/goharbor/harbor/src/internal/error"
|
internal_errors "github.com/goharbor/harbor/src/internal/error"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@ -28,16 +29,12 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
if rec.Result().StatusCode == http.StatusOK {
|
if rec.Result().StatusCode == http.StatusOK {
|
||||||
match, err := matchNotaryDigest(mf)
|
match, err := matchNotaryDigest(mf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pkgE := internal_errors.New(nil).WithCode(internal_errors.PROJECTPOLICYVIOLATION).WithMessage("Failed in communication with Notary please check the log")
|
serror.SendError(rw, err)
|
||||||
msg := internal_errors.NewErrs(pkgE).Error()
|
|
||||||
http.Error(rw, msg, http.StatusInternalServerError)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !match {
|
if !match {
|
||||||
log.Debugf("digest mismatch, failing the response.")
|
|
||||||
pkgE := internal_errors.New(nil).WithCode(internal_errors.PROJECTPOLICYVIOLATION).WithMessage("The image is not signed in Notary.")
|
pkgE := internal_errors.New(nil).WithCode(internal_errors.PROJECTPOLICYVIOLATION).WithMessage("The image is not signed in Notary.")
|
||||||
msg := internal_errors.NewErrs(pkgE).Error()
|
serror.SendError(rw, pkgE)
|
||||||
http.Error(rw, msg, http.StatusPreconditionFailed)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/api/artifact"
|
"github.com/goharbor/harbor/src/api/artifact"
|
||||||
common_util "github.com/goharbor/harbor/src/common/utils"
|
common_util "github.com/goharbor/harbor/src/common/utils"
|
||||||
internal_errors "github.com/goharbor/harbor/src/internal/error"
|
internal_errors "github.com/goharbor/harbor/src/internal/error"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@ -18,13 +19,12 @@ func MiddlewareDelete() func(http.Handler) http.Handler {
|
|||||||
var e *ErrImmutable
|
var e *ErrImmutable
|
||||||
if errors.As(err, &e) {
|
if errors.As(err, &e) {
|
||||||
pkgE := internal_errors.New(e).WithCode(internal_errors.PreconditionCode)
|
pkgE := internal_errors.New(e).WithCode(internal_errors.PreconditionCode)
|
||||||
msg := internal_errors.NewErrs(pkgE).Error()
|
serror.SendError(rw, pkgE)
|
||||||
http.Error(rw, msg, http.StatusPreconditionFailed)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pkgE := internal_errors.New(fmt.Errorf("error occurred when to handle request in immutable handler: %v", err)).WithCode(internal_errors.GeneralCode)
|
pkgE := internal_errors.New(fmt.Errorf("error occurred when to handle request in immutable handler: %v", err)).WithCode(internal_errors.GeneralCode)
|
||||||
msg := internal_errors.NewErrs(pkgE).Error()
|
serror.SendError(rw, pkgE)
|
||||||
http.Error(rw, msg, http.StatusInternalServerError)
|
return
|
||||||
}
|
}
|
||||||
next.ServeHTTP(rw, req)
|
next.ServeHTTP(rw, req)
|
||||||
})
|
})
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/api/artifact"
|
"github.com/goharbor/harbor/src/api/artifact"
|
||||||
common_util "github.com/goharbor/harbor/src/common/utils"
|
common_util "github.com/goharbor/harbor/src/common/utils"
|
||||||
internal_errors "github.com/goharbor/harbor/src/internal/error"
|
internal_errors "github.com/goharbor/harbor/src/internal/error"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@ -18,13 +19,12 @@ func MiddlewarePush() func(http.Handler) http.Handler {
|
|||||||
var e *ErrImmutable
|
var e *ErrImmutable
|
||||||
if errors.As(err, &e) {
|
if errors.As(err, &e) {
|
||||||
pkgE := internal_errors.New(e).WithCode(internal_errors.PreconditionCode)
|
pkgE := internal_errors.New(e).WithCode(internal_errors.PreconditionCode)
|
||||||
msg := internal_errors.NewErrs(pkgE).Error()
|
serror.SendError(rw, pkgE)
|
||||||
http.Error(rw, msg, http.StatusPreconditionFailed)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pkgE := internal_errors.New(fmt.Errorf("error occurred when to handle request in immutable handler: %v", err)).WithCode(internal_errors.GeneralCode)
|
pkgE := internal_errors.New(fmt.Errorf("error occurred when to handle request in immutable handler: %v", err)).WithCode(internal_errors.GeneralCode)
|
||||||
msg := internal_errors.NewErrs(pkgE).Error()
|
serror.SendError(rw, pkgE)
|
||||||
http.Error(rw, msg, http.StatusInternalServerError)
|
return
|
||||||
}
|
}
|
||||||
next.ServeHTTP(rw, req)
|
next.ServeHTTP(rw, req)
|
||||||
})
|
})
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/common/utils"
|
"github.com/goharbor/harbor/src/common/utils"
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
project2 "github.com/goharbor/harbor/src/pkg/project"
|
project2 "github.com/goharbor/harbor/src/pkg/project"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
reg_err "github.com/goharbor/harbor/src/server/registry/error"
|
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -23,7 +23,7 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
mf, err := parseManifestInfoFromPath(req)
|
mf, err := parseManifestInfoFromPath(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_err.Handle(rw, req, err)
|
serror.SendError(rw, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*req = *(req.WithContext(middleware.NewManifestInfoContext(req.Context(), mf)))
|
*req = *(req.WithContext(middleware.NewManifestInfoContext(req.Context(), mf)))
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
package readonly
|
package readonly
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
|
||||||
"github.com/goharbor/harbor/src/core/config"
|
"github.com/goharbor/harbor/src/core/config"
|
||||||
internal_errors "github.com/goharbor/harbor/src/internal/error"
|
internal_errors "github.com/goharbor/harbor/src/internal/error"
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
@ -67,9 +67,8 @@ func MiddlewareWithConfig(config Config, skippers ...middleware.Skipper) func(ht
|
|||||||
|
|
||||||
return middleware.New(func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
return middleware.New(func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||||
if config.ReadOnly(r) {
|
if config.ReadOnly(r) {
|
||||||
log.Warningf("The request is prohibited in readonly mode, url is: %s", r.URL.Path)
|
|
||||||
pkgE := internal_errors.New(nil).WithCode(internal_errors.DENIED).WithMessage("The system is in read only mode. Any modification is prohibited.")
|
pkgE := internal_errors.New(nil).WithCode(internal_errors.DENIED).WithMessage("The system is in read only mode. Any modification is prohibited.")
|
||||||
http.Error(w, internal_errors.NewErrs(pkgE).Error(), http.StatusForbidden)
|
serror.SendError(w, pkgE)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
pkg_token "github.com/goharbor/harbor/src/pkg/token"
|
pkg_token "github.com/goharbor/harbor/src/pkg/token"
|
||||||
"github.com/goharbor/harbor/src/pkg/token/claims/registry"
|
"github.com/goharbor/harbor/src/pkg/token/claims/registry"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
reg_err "github.com/goharbor/harbor/src/server/registry/error"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -19,7 +19,7 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
err := parseToken(req)
|
err := parseToken(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_err.Handle(rw, req, err)
|
serror.SendError(rw, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
next.ServeHTTP(rw, req)
|
next.ServeHTTP(rw, req)
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
@ -77,7 +78,7 @@ func Middleware(skippers ...middleware.Skipper) func(http.Handler) http.Handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := orm.WithTransaction(h)(r.Context()); err != nil && err != errNonSuccess {
|
if err := orm.WithTransaction(h)(r.Context()); err != nil && err != errNonSuccess {
|
||||||
log.Errorf("deal with %s request in transaction failed: %v", r.URL.Path, err)
|
err = fmt.Errorf("deal with %s request in transaction failed: %v", r.URL.Path, err)
|
||||||
|
|
||||||
// begin, commit or rollback transaction db error happened,
|
// begin, commit or rollback transaction db error happened,
|
||||||
// reset the response and set status code to 500
|
// reset the response and set status code to 500
|
||||||
@ -85,7 +86,7 @@ func Middleware(skippers ...middleware.Skipper) func(http.Handler) http.Handler
|
|||||||
log.Errorf("reset the response failed: %v", err)
|
log.Errorf("reset the response failed: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res.WriteHeader(http.StatusInternalServerError)
|
serror.SendError(res, err)
|
||||||
}
|
}
|
||||||
}, skippers...)
|
}, skippers...)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package v2auth
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -27,7 +28,6 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/core/promgr"
|
"github.com/goharbor/harbor/src/core/promgr"
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
reg_err "github.com/goharbor/harbor/src/server/registry/error"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type reqChecker struct {
|
type reqChecker struct {
|
||||||
@ -131,7 +131,7 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
return func(next http.Handler) http.Handler {
|
return func(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
if err := checker.check(req); err != nil {
|
if err := checker.check(req); err != nil {
|
||||||
reg_err.Handle(rw, req, ierror.UnauthorizedError(err).WithMessage(err.Error()))
|
serror.SendError(rw, ierror.UnauthorizedError(err).WithMessage(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
next.ServeHTTP(rw, req)
|
next.ServeHTTP(rw, req)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/pkg/scan/report"
|
"github.com/goharbor/harbor/src/pkg/scan/report"
|
||||||
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
|
v1 "github.com/goharbor/harbor/src/pkg/scan/rest/v1"
|
||||||
"github.com/goharbor/harbor/src/pkg/scan/vuln"
|
"github.com/goharbor/harbor/src/pkg/scan/vuln"
|
||||||
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/middleware"
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -30,7 +31,8 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
// Invalid project ID
|
// Invalid project ID
|
||||||
if wl.ProjectID == 0 {
|
if wl.ProjectID == 0 {
|
||||||
err := errors.Errorf("project verification error: project %s", img.ProjectName)
|
err := errors.Errorf("project verification error: project %s", img.ProjectName)
|
||||||
sendError(err, rw)
|
pkgE := internal_errors.New(err).WithCode(internal_errors.PROJECTPOLICYVIOLATION)
|
||||||
|
serror.SendError(rw, pkgE)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +54,8 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "middleware: vulnerable handler")
|
err = errors.Wrap(err, "middleware: vulnerable handler")
|
||||||
sendError(err, rw)
|
pkgE := internal_errors.New(err).WithCode(internal_errors.PROJECTPOLICYVIOLATION)
|
||||||
|
serror.SendError(rw, pkgE)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +63,8 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
// No report yet?
|
// No report yet?
|
||||||
if !ok {
|
if !ok {
|
||||||
err = errors.Errorf("no scan report existing for the artifact: %s:%s@%s", img.Repository, img.Tag, img.Digest)
|
err = errors.Errorf("no scan report existing for the artifact: %s:%s@%s", img.Repository, img.Tag, img.Digest)
|
||||||
sendError(err, rw)
|
pkgE := internal_errors.New(err).WithCode(internal_errors.PROJECTPOLICYVIOLATION)
|
||||||
|
serror.SendError(rw, pkgE)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +74,8 @@ func Middleware() func(http.Handler) http.Handler {
|
|||||||
if summary.Severity.Code() >= projectVulnerableSeverity.Code() {
|
if summary.Severity.Code() >= projectVulnerableSeverity.Code() {
|
||||||
err = errors.Errorf("current image with '%q vulnerable' cannot be pulled due to configured policy in 'Prevent images with vulnerability severity of %q from running.' "+
|
err = errors.Errorf("current image with '%q vulnerable' cannot be pulled due to configured policy in 'Prevent images with vulnerability severity of %q from running.' "+
|
||||||
"Please contact your project administrator for help'", summary.Severity, projectVulnerableSeverity)
|
"Please contact your project administrator for help'", summary.Severity, projectVulnerableSeverity)
|
||||||
sendError(err, rw)
|
pkgE := internal_errors.New(err).WithCode(internal_errors.PROJECTPOLICYVIOLATION)
|
||||||
|
serror.SendError(rw, pkgE)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,10 +115,3 @@ func validate(req *http.Request) (bool, *middleware.ManifestInfo, vuln.Severity,
|
|||||||
}
|
}
|
||||||
return true, mf, projectVulnerableSeverity, wl
|
return true, mf, projectVulnerableSeverity, wl
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendError(err error, rw http.ResponseWriter) {
|
|
||||||
log.Error(err)
|
|
||||||
pkgE := internal_errors.New(err).WithCode(internal_errors.PROJECTPOLICYVIOLATION)
|
|
||||||
msg := internal_errors.NewErrs(pkgE).Error()
|
|
||||||
http.Error(rw, msg, http.StatusPreconditionFailed)
|
|
||||||
}
|
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/goharbor/harbor/src/api/repository"
|
"github.com/goharbor/harbor/src/api/repository"
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
reg_error "github.com/goharbor/harbor/src/server/registry/error"
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/registry/util"
|
"github.com/goharbor/harbor/src/server/registry/util"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
@ -47,7 +47,7 @@ func (r *repositoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)
|
|||||||
maxEntries, err = strconv.Atoi(reqQ.Get("n"))
|
maxEntries, err = strconv.Atoi(reqQ.Get("n"))
|
||||||
if err != nil || maxEntries < 0 {
|
if err != nil || maxEntries < 0 {
|
||||||
err := ierror.New(err).WithCode(ierror.BadRequestCode).WithMessage("the N must be a positive int type")
|
err := ierror.New(err).WithCode(ierror.BadRequestCode).WithMessage("the N must be a positive int type")
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ func (r *repositoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)
|
|||||||
// ToDo filter out the untagged repos
|
// ToDo filter out the untagged repos
|
||||||
total, repoRecords, err := r.repoCtl.List(req.Context(), nil)
|
total, repoRecords, err := r.repoCtl.List(req.Context(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if total <= 0 {
|
if total <= 0 {
|
||||||
@ -81,7 +81,7 @@ func (r *repositoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)
|
|||||||
lastEntryIndex := util.IndexString(repoNames, lastEntry)
|
lastEntryIndex := util.IndexString(repoNames, lastEntry)
|
||||||
if lastEntryIndex == -1 {
|
if lastEntryIndex == -1 {
|
||||||
err := ierror.New(nil).WithCode(ierror.BadRequestCode).WithMessage(fmt.Sprintf("the last: %s should be a valid repository name.", lastEntry))
|
err := ierror.New(nil).WithCode(ierror.BadRequestCode).WithMessage(fmt.Sprintf("the last: %s should be a valid repository name.", lastEntry))
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resRepos = repoNames[lastEntryIndex+1 : lastEntryIndex+maxEntries]
|
resRepos = repoNames[lastEntryIndex+1 : lastEntryIndex+maxEntries]
|
||||||
@ -94,7 +94,7 @@ func (r *repositoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)
|
|||||||
if repoNames[len(repoNames)-1] != resRepos[len(resRepos)-1] {
|
if repoNames[len(repoNames)-1] != resRepos[len(resRepos)-1] {
|
||||||
urlStr, err := util.SetLinkHeader(req.URL.String(), maxEntries, resRepos[len(resRepos)-1])
|
urlStr, err := util.SetLinkHeader(req.URL.String(), maxEntries, resRepos[len(resRepos)-1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Link", urlStr)
|
w.Header().Set("Link", urlStr)
|
||||||
@ -111,7 +111,7 @@ func (r *repositoryHandler) sendResponse(w http.ResponseWriter, req *http.Reques
|
|||||||
if err := enc.Encode(catalogAPIResponse{
|
if err := enc.Encode(catalogAPIResponse{
|
||||||
Repositories: repositoryNames,
|
Repositories: repositoryNames,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright Project Harbor Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package error
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
|
||||||
serror "github.com/goharbor/harbor/src/server/error"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Handle generates the HTTP status code and error payload and writes them to the response
|
|
||||||
func Handle(w http.ResponseWriter, req *http.Request, err error) {
|
|
||||||
log.Errorf("failed to handle the request %s %s: %v", req.Method, req.URL, err)
|
|
||||||
statusCode, payload := serror.APIError(err)
|
|
||||||
w.WriteHeader(statusCode)
|
|
||||||
w.Write([]byte(payload))
|
|
||||||
}
|
|
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/api/repository"
|
"github.com/goharbor/harbor/src/api/repository"
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
"github.com/goharbor/harbor/src/internal"
|
"github.com/goharbor/harbor/src/internal"
|
||||||
"github.com/goharbor/harbor/src/server/registry/error"
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/router"
|
"github.com/goharbor/harbor/src/server/router"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -32,7 +32,7 @@ func getManifest(w http.ResponseWriter, req *http.Request) {
|
|||||||
reference := router.Param(req.Context(), ":reference")
|
reference := router.Param(req.Context(), ":reference")
|
||||||
artifact, err := artifact.Ctl.GetByReference(req.Context(), repository, reference, nil)
|
artifact, err := artifact.Ctl.GetByReference(req.Context(), repository, reference, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,11 +53,11 @@ func deleteManifest(w http.ResponseWriter, req *http.Request) {
|
|||||||
reference := router.Param(req.Context(), ":reference")
|
reference := router.Param(req.Context(), ":reference")
|
||||||
art, err := artifact.Ctl.GetByReference(req.Context(), repository, reference, nil)
|
art, err := artifact.Ctl.GetByReference(req.Context(), repository, reference, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = artifact.Ctl.Delete(req.Context(), art.ID); err != nil {
|
if err = artifact.Ctl.Delete(req.Context(), art.ID); err != nil {
|
||||||
error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusAccepted)
|
w.WriteHeader(http.StatusAccepted)
|
||||||
@ -72,7 +72,7 @@ func putManifest(w http.ResponseWriter, req *http.Request) {
|
|||||||
// make sure the repository exist before pushing the manifest
|
// make sure the repository exist before pushing the manifest
|
||||||
_, repositoryID, err := repository.Ctl.Ensure(req.Context(), repo)
|
_, repositoryID, err := repository.Ctl.Ensure(req.Context(), repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ func putManifest(w http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
_, _, err = artifact.Ctl.Ensure(req.Context(), repositoryID, dgt, tags...)
|
_, _, err = artifact.Ctl.Ensure(req.Context(), repositoryID, dgt, tags...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/api/repository"
|
"github.com/goharbor/harbor/src/api/repository"
|
||||||
ierror "github.com/goharbor/harbor/src/internal/error"
|
ierror "github.com/goharbor/harbor/src/internal/error"
|
||||||
"github.com/goharbor/harbor/src/pkg/q"
|
"github.com/goharbor/harbor/src/pkg/q"
|
||||||
reg_error "github.com/goharbor/harbor/src/server/registry/error"
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"github.com/goharbor/harbor/src/server/registry/util"
|
"github.com/goharbor/harbor/src/server/registry/util"
|
||||||
"github.com/goharbor/harbor/src/server/router"
|
"github.com/goharbor/harbor/src/server/router"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -65,7 +65,7 @@ func (t *tagHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
maxEntries, err = strconv.Atoi(reqQ.Get("n"))
|
maxEntries, err = strconv.Atoi(reqQ.Get("n"))
|
||||||
if err != nil || maxEntries < 0 {
|
if err != nil || maxEntries < 0 {
|
||||||
err := ierror.New(err).WithCode(ierror.BadRequestCode).WithMessage("the N must be a positive int type")
|
err := ierror.New(err).WithCode(ierror.BadRequestCode).WithMessage("the N must be a positive int type")
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ func (t *tagHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
t.repositoryName = router.Param(req.Context(), ":splat")
|
t.repositoryName = router.Param(req.Context(), ":splat")
|
||||||
repository, err := t.repoCtl.GetByName(req.Context(), t.repositoryName)
|
repository, err := t.repoCtl.GetByName(req.Context(), t.repositoryName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ func (t *tagHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
"RepositoryID": repository.RepositoryID,
|
"RepositoryID": repository.RepositoryID,
|
||||||
}}, nil)
|
}}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if total == 0 {
|
if total == 0 {
|
||||||
@ -110,7 +110,7 @@ func (t *tagHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
lastEntryIndex := util.IndexString(tagNames, lastEntry)
|
lastEntryIndex := util.IndexString(tagNames, lastEntry)
|
||||||
if lastEntryIndex == -1 {
|
if lastEntryIndex == -1 {
|
||||||
err := ierror.New(nil).WithCode(ierror.BadRequestCode).WithMessage(fmt.Sprintf("the last: %s should be a valid tag name.", lastEntry))
|
err := ierror.New(nil).WithCode(ierror.BadRequestCode).WithMessage(fmt.Sprintf("the last: %s should be a valid tag name.", lastEntry))
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resTags = tagNames[lastEntryIndex+1 : lastEntryIndex+maxEntries]
|
resTags = tagNames[lastEntryIndex+1 : lastEntryIndex+maxEntries]
|
||||||
@ -123,7 +123,7 @@ func (t *tagHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
if tagNames[len(tagNames)-1] != resTags[len(resTags)-1] {
|
if tagNames[len(tagNames)-1] != resTags[len(resTags)-1] {
|
||||||
urlStr, err := util.SetLinkHeader(req.URL.String(), maxEntries, resTags[len(resTags)-1])
|
urlStr, err := util.SetLinkHeader(req.URL.String(), maxEntries, resTags[len(resTags)-1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Link", urlStr)
|
w.Header().Set("Link", urlStr)
|
||||||
@ -140,7 +140,7 @@ func (t *tagHandler) sendResponse(w http.ResponseWriter, req *http.Request, tagN
|
|||||||
Name: t.repositoryName,
|
Name: t.repositoryName,
|
||||||
Tags: tagNames,
|
Tags: tagNames,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
reg_error.Handle(w, req, err)
|
serror.SendError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,16 +15,10 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
serror "github.com/goharbor/harbor/src/server/error"
|
||||||
"fmt"
|
"github.com/goharbor/harbor/src/server/v2.0/restapi"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-openapi/errors"
|
|
||||||
ierrors "github.com/goharbor/harbor/src/internal/error"
|
|
||||||
"github.com/goharbor/harbor/src/server/v2.0/restapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns http handler for API V2.0
|
// New returns http handler for API V2.0
|
||||||
@ -42,31 +36,10 @@ func New() http.Handler {
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiError struct {
|
|
||||||
Code int32 `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Before executing operation handler, go-swagger will bind a parameters object to a request and validate the request,
|
// Before executing operation handler, go-swagger will bind a parameters object to a request and validate the request,
|
||||||
// it will return directly when bind and validate failed.
|
// it will return directly when bind and validate failed.
|
||||||
// The response format of the default ServeError implementation does not match the internal error response format.
|
// The response format of the default ServeError implementation does not match the internal error response format.
|
||||||
// So we needed to convert the format to the internal error response format.
|
// So we needed to convert the format to the internal error response format.
|
||||||
func serveError(rw http.ResponseWriter, r *http.Request, err error) {
|
func serveError(rw http.ResponseWriter, r *http.Request, err error) {
|
||||||
w := httptest.NewRecorder()
|
serror.SendError(rw, err)
|
||||||
errors.ServeError(w, r, err)
|
|
||||||
|
|
||||||
rw.WriteHeader(w.Code)
|
|
||||||
for key, values := range w.Header() {
|
|
||||||
for _, value := range values {
|
|
||||||
rw.Header().Add(key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var er apiError
|
|
||||||
json.Unmarshal(w.Body.Bytes(), &er)
|
|
||||||
|
|
||||||
code := strings.Replace(strings.ToUpper(http.StatusText(w.Code)), " ", "_", -1)
|
|
||||||
|
|
||||||
e := ierrors.New(fmt.Errorf(er.Message)).WithCode(code)
|
|
||||||
rw.Write([]byte(e.Error()))
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user