This is an automated email from the ASF dual-hosted git repository.
chenjunxu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new 6fa6a16 fix: when enable or disable existing SSL, an error occurred
(#1064)
6fa6a16 is described below
commit 6fa6a16559a1c1d0e90de4a3277a3db6e73cb9fc
Author: nic-chen <[email protected]>
AuthorDate: Fri Dec 25 07:56:57 2020 +0800
fix: when enable or disable existing SSL, an error occurred (#1064)
* fix: when enable or disable existing SSL, an error occurred
* fix: keep the code uniform
* fix: lint
* fix: keep the code uniform
* fix: license
* chore: add comment to note that json.Marshal and json.Unmarshal may cause
the precision loss
Co-authored-by: 琚致远 <[email protected]>
Co-authored-by: YuanSheng Wang <[email protected]>
---
api/internal/handler/ssl/ssl.go | 10 +++--
api/internal/utils/consts/api_error.go | 26 ++++++++++--
api/internal/utils/consts/api_error_test.go | 62 +++++++++++++++++++++++++++++
api/internal/utils/utils.go | 12 ++++++
api/internal/utils/utils_test.go | 18 +++++++++
api/test/e2e/ssl_test.go | 8 ++++
6 files changed, 130 insertions(+), 6 deletions(-)
diff --git a/api/internal/handler/ssl/ssl.go b/api/internal/handler/ssl/ssl.go
index 1900995..36d8efa 100644
--- a/api/internal/handler/ssl/ssl.go
+++ b/api/internal/handler/ssl/ssl.go
@@ -86,7 +86,11 @@ func (h *Handler) Get(c droplet.Context) (interface{},
error) {
}
//format respond
- ssl := ret.(*entity.SSL)
+ ssl := &entity.SSL{}
+ err = utils.ObjectClone(ret, ssl)
+ if err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
ssl.Key = ""
ssl.Keys = nil
@@ -160,9 +164,9 @@ func (h *Handler) List(c droplet.Context) (interface{},
error) {
//format respond
var list []interface{}
- var ssl *entity.SSL
for _, item := range ret.Rows {
- ssl = item.(*entity.SSL)
+ ssl := &entity.SSL{}
+ _ = utils.ObjectClone(item, ssl)
ssl.Key = ""
ssl.Keys = nil
list = append(list, ssl)
diff --git a/api/internal/utils/consts/api_error.go
b/api/internal/utils/consts/api_error.go
index 608ad0e..4e2a0c0 100644
--- a/api/internal/utils/consts/api_error.go
+++ b/api/internal/utils/consts/api_error.go
@@ -17,8 +17,10 @@
package consts
import (
- "github.com/gin-gonic/gin"
"net/http"
+ "strings"
+
+ "github.com/gin-gonic/gin"
)
type WrapperHandle func(c *gin.Context) (interface{}, error)
@@ -27,7 +29,21 @@ func ErrorWrapper(handle WrapperHandle) gin.HandlerFunc {
return func(c *gin.Context) {
data, err := handle(c)
if err != nil {
- apiError := err.(*ApiError)
+ apiError, ok := err.(*ApiError)
+ if !ok {
+ errMsg := err.Error()
+ if strings.Contains(errMsg, "required") ||
+ strings.Contains(errMsg, "conflicted")
||
+ strings.Contains(errMsg, "invalid") ||
+ strings.Contains(errMsg, "missing") ||
+ strings.Contains(errMsg, "validate
failed") {
+ apiError = InvalidParam(errMsg)
+ } else if strings.Contains(errMsg, "not found")
{
+ apiError = NotFound(errMsg)
+ } else {
+ apiError = SystemError(errMsg)
+ }
+ }
c.JSON(apiError.Status, apiError)
return
}
@@ -53,5 +69,9 @@ func InvalidParam(message string) *ApiError {
}
func SystemError(message string) *ApiError {
- return &ApiError{500, 500, message}
+ return &ApiError{500, 10001, message}
+}
+
+func NotFound(message string) *ApiError {
+ return &ApiError{404, 10002, message}
}
diff --git a/api/internal/utils/consts/api_error_test.go
b/api/internal/utils/consts/api_error_test.go
new file mode 100644
index 0000000..9be241e
--- /dev/null
+++ b/api/internal/utils/consts/api_error_test.go
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 consts
+
+import (
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/gin-gonic/gin"
+ "github.com/stretchr/testify/assert"
+)
+
+func performRequest(r http.Handler, method, path string)
*httptest.ResponseRecorder {
+ req := httptest.NewRequest(method, path, nil)
+ w := httptest.NewRecorder()
+ r.ServeHTTP(w, req)
+ return w
+}
+
+func TestRequestLogHandler(t *testing.T) {
+ r := gin.New()
+ r.GET("/", ErrorWrapper(func(c *gin.Context) (interface{}, error) {
+ return nil, nil
+ }))
+ r.GET("/notfound", ErrorWrapper(func(c *gin.Context) (interface{},
error) {
+ return nil, fmt.Errorf("data not found")
+ }))
+ r.GET("/invalid", ErrorWrapper(func(c *gin.Context) (interface{},
error) {
+ return nil, fmt.Errorf("schema validate failed")
+ }))
+ r.GET("/error", ErrorWrapper(func(c *gin.Context) (interface{}, error) {
+ return nil, fmt.Errorf("internal system error")
+ }))
+
+ w := performRequest(r, "GET", "/")
+ assert.Equal(t, 200, w.Code)
+
+ w = performRequest(r, "GET", "/notfound")
+ assert.Equal(t, 404, w.Code)
+
+ w = performRequest(r, "GET", "/invalid")
+ assert.Equal(t, 400, w.Code)
+
+ w = performRequest(r, "GET", "/error")
+ assert.Equal(t, 500, w.Code)
+}
diff --git a/api/internal/utils/utils.go b/api/internal/utils/utils.go
index ad47792..b8d192c 100644
--- a/api/internal/utils/utils.go
+++ b/api/internal/utils/utils.go
@@ -17,6 +17,7 @@
package utils
import (
+ "encoding/json"
"errors"
"fmt"
"net"
@@ -97,6 +98,17 @@ func InterfaceToString(val interface{}) string {
return str
}
+// Note: json.Marshal and json.Unmarshal may cause the precision loss
+func ObjectClone(origin, copy interface{}) error {
+ byt, err := json.Marshal(origin)
+ if err != nil {
+ return err
+ }
+
+ err = json.Unmarshal(byt, copy)
+ return err
+}
+
func GenLabelMap(label string) (map[string]string, error) {
var err = errors.New("malformed label")
mp := make(map[string]string)
diff --git a/api/internal/utils/utils_test.go b/api/internal/utils/utils_test.go
index 0d8427d..8da295f 100644
--- a/api/internal/utils/utils_test.go
+++ b/api/internal/utils/utils_test.go
@@ -44,6 +44,24 @@ func TestSumIPs_with_nil(t *testing.T) {
assert.Equal(t, uint16(0), total)
}
+func TestObjectClone(t *testing.T) {
+ type test struct {
+ Str string
+ Num int
+ }
+
+ origin := &test{Str: "a", Num: 1}
+ copy := &test{}
+ err := ObjectClone(origin, copy)
+ assert.Nil(t, err)
+ assert.Equal(t, origin, copy)
+
+ // change value of the copy, should not change value of origin
+ copy.Num = 2
+ assert.NotEqual(t, copy.Num, origin.Num)
+ assert.Equal(t, 1, origin.Num)
+}
+
func TestGenLabelMap(t *testing.T) {
expectedErr := errors.New("malformed label")
mp, err := GenLabelMap("l1")
diff --git a/api/test/e2e/ssl_test.go b/api/test/e2e/ssl_test.go
index add6380..9dc3b80 100644
--- a/api/test/e2e/ssl_test.go
+++ b/api/test/e2e/ssl_test.go
@@ -102,6 +102,14 @@ func TestSSL_Basic(t *testing.T) {
ExpectStatus: http.StatusOK,
},
{
+ Desc: "get the route just created to trigger
removing `key`",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodGet,
+ Path: "/apisix/admin/routes/r1",
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ },
+ {
Desc: "hit the route just created using HTTPS",
Object: APISIXHTTPSExpect(t),
Method: http.MethodGet,