question. I am trying to add a custom middleware which changes both method and path (I know there are existing middlewares for both and I checked their source)
req := c.Request()
req.Method = "PUT"
path := req.URL.Path
url, _ := req.URL.Parse(path + "/9")
req.URL = url
This succeeds in changing the method, but it fails changing the path, any idea what's up with that?
I am facing the "No token found " when I try to use echo framework for expositioning my metrics and using prometheus to scrape them.
While instrumenting my labstack echo web server with prometheus, I followed the example here: https://echo.labstack.com/middleware/prometheus/
and didnt instrument any custom metrics yet, still not able to get it to work with prometheus scraper with just the basic echo framework metrics. Following is the scrape config that I used:
- job_name: 'nebula-staging'
static_configs:
- targets: ['10.X.Y.Z:8000']
labels:
instance: 'nebula'
Also, I am able to curl to this address and get the metrics, when I use promtool to check the metrics for any inconsistency I dont find any. Not too sure what to do, does anyone have any clue? Would be of great help, thanks!
Hi, I have been stuck trying to configure my echo app to serve with https, but have no success. I've read and tried this: https://echo.labstack.com/cookbook/auto-tls ..
So at this point i am getting following error:
echo: http: TLS handshake error from {some-ip}:27002: acme/autocert: unable to satisfy "https://acme-v02.api.letsencrypt.org/acme/authz-v3/53188301650" for domain "mydomain.com": no viable challenge type found
func GETTER(path string, params []string, paramValues []string) string {
e := echo.New()
req := httptest.NewRequest(http.MethodGet, path, nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
c.SetParamNames(params...)
//res := rec.Result()
defer rec.Result().Body.Close()
c.SetParamValues(ClientIdString)
//controllers.GetFullProfile(c)
return rec.Body.String()
}
func login(c echo.Context) error {
validate := validator.New()
u := new(Auth)
if err := c.Bind(u); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
err := validate.Struct(u)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
user , err := domain.GetAuthByUsername(u.Username,u.Password)
if user.Id == 0 {
return echo.ErrUnauthorized
}
claims := &jwtCustomClaims{ user.Username,*user.Active,*user.Admin,user.Roles,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Hour * 72).Unix(),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
t, err := token.SignedString([]byte(os.Getenv("ACCESS_SECRET")))
if err != nil {
return err
}
return c.JSON(http.StatusOK, echo.Map{
"token": t,"roles":user.Roles,"username": user.Username,
})
}
func startAuthRouters(app *echo.Echo){
auth := app.Group("/auth/login")
auth.POST("", login)
}
package controllers
import (
"testing"
"net/http"
"net/http/httptest"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
"fmt"
)
func TestAuth(t *testing.T) {
// t.Parallel()
// Start()
t.Run("Controllers ECHO", func(t *testing.T) {
req := httptest.NewRequest(echo.POST, "/auth/login",nil)
rec := httptest.NewRecorder()
// // req.Header.Set("Content-Type", "application/json")
fmt.Println(req)
fmt.Println(rec)
// // req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
// c.SetPath("/auth/login")
// h := login(c)
// fmt.Println(h)
// fmt.Println(rec)
// assert.Equal(t, http.StatusBadRequest, rec.Code)
assert.Equal(t, http.StatusBadRequest, rec.Code)
})
}
func TestHandler(t *testing.T) {
e := echo.New()
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
handler := func(c echo.Context) error {
return c.String(http.StatusOK, "OK")
}
err := handler(c)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, rec.Code)
}
lets say your code is
type authService interface {
GetAuthByUsername(username string, password string) (string, error)
}
type AuthRoutes struct {
auth authService
}
func (a AuthRoutes) login(c echo.Context) error {
auth, err := a.auth.GetAuthByUsername("user", "pass")
if err != nil {
return err
}
return c.JSON(http.StatusCreated, map[string]string{"auth": auth})
}
then you would create something like that for test
type authServiceMock struct {
mock.Mock
}
func (m *authServiceMock) GetAuthByUsername(username string, password string) (string, error) {
args := m.Called(username, password)
return args.String(0), args.Error(1)
}
func TestHandler(t *testing.T) {
e := echo.New()
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
serviceMock := new(authServiceMock)
serviceMock.On("GetAuthByUsername", "user", "pass").Return("myauth", nil)
auth := AuthRoutes{auth: serviceMock}
err := auth.login(c)
assert.NoError(t, err)
assert.Equal(t, http.StatusCreated, rec.Code)
serviceMock.AssertExpectations(t)
}
in that way you can mock that auth service inside your handler
"github.com/stretchr/testify/mock"
hi guys. I am using the proxy module and am proxying some "blocking requests" meaning requests that live for 5 minutes. my clients (that are connecting to the echo proxy) are killing them if they don't need them anymore, but on the echo proxy side, those requests seem to stay open. is that a bug, or expected behaviour?
how can I make sure that those cancelled requests are properly cleaned up?
/proxy/server1/foo
I want to proxy http://server1/foo
and if I have /proxy/server2/foo
I want to proxy http://server2/foo
. server1 and server2 can be anything in this scenario