Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛 BUG]: Embedded server doesn't apply middlewares #2079

Closed
1 task done
hotrush opened this issue Dec 3, 2024 · 3 comments
Closed
1 task done

[🐛 BUG]: Embedded server doesn't apply middlewares #2079

hotrush opened this issue Dec 3, 2024 · 3 comments
Assignees
Labels
B-bug Bug: bug, exception F-need-verification

Comments

@hotrush
Copy link

hotrush commented Dec 3, 2024

No duplicates 🥲.

  • I have searched for a similar issue in our bug tracker and didn't find any solutions.

What happened?

Middlewares are not applied when running an embedded server as described here https://docs.roadrunner.dev/docs/customization/embedding

Plugin is loaded/initialized, but middlewares are not

Ref: #1214

P.S. there is also a mistake in docs, rr.CurrentState() method is not available anymore

Version (rr --version)

2024.2.1

How to reproduce the issue?

package foo

import (
	"bytes"
	httpPlugin "github.com/roadrunner-server/http/v5"
	"github.com/roadrunner-server/logger/v5"
	"github.com/roadrunner-server/roadrunner/v2024/lib"
	"github.com/roadrunner-server/server/v5"
	"github.com/zeebo/assert"
	"go.uber.org/zap"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"
)

type CustomLogger interface {
	NamedLogger(name string) *zap.Logger
}

type CustomPlugin struct {
	// logger
	log *zap.Logger
}

func (p *CustomPlugin) Init(log CustomLogger) error {
	p.log = log.NamedLogger("foo")
	return nil
}

func (p *CustomPlugin) Middleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		p.log.Debug("handling request", zap.String("method", r.Method), zap.String("url", r.URL.String()))
		http.Error(w, "foo", http.StatusInternalServerError)
	})
}

func (p *CustomPlugin) Name() string {
	return "foo"
}

func TestEmbed(t *testing.T) {
	httpP := &httpPlugin.Plugin{}
	plugins := []interface{}{
		&logger.Plugin{},
		&server.Plugin{},
		httpP,
		&CustomPlugin{},
	}

	rr, err := lib.NewRR(".rr.yaml", []string{}, plugins)
	if err != nil {
		t.Fatal(err)
	}
	errCh := make(chan error, 1)
	go func() {
		errCh <- rr.Serve()
	}()
	defer rr.Stop()
	time.Sleep(1 * time.Second)

	req, err := http.NewRequest(http.MethodGet, "http://localhost:8080/items/1", bytes.NewBuffer([]byte("")))
	if err != nil {
		t.Fatal(err)
	}
	wr := httptest.NewRecorder()
	httpP.ServeHTTP(wr, req)

	assert.Equal(t, http.StatusInternalServerError, wr.Code)
}

and

version: "3"

server:
  command: "php ./testing/server/worker.php"

http:
  address: :8080
  middleware: ["foo"]
  pool:
    debug: false
    num_workers: 1

Relevant log output

2024-12-03T16:17:48+0000	DEBUG	server      	worker is allocated	{"pid": 13105, "max_execs": 0, "internal_event_name": "EventWorkerConstruct"}
2024-12-03T16:17:48+0000	DEBUG	http        	http server was started	{"address": ":8080"}
2024-12-03T16:17:49+0000	DEBUG	server      	req-resp mode	{"pid": 13105}
--- FAIL: TestEmbed (1.06s)
    embed_test.go:75: 500 != 200
FAIL
FAIL	github.com/owner/repo	1.600s
FAIL
@rustatian
Copy link
Member

Hey @hotrush 👋🏻
You're not allowed to use http plugin like you used in that example, because it'll lead to race conditions.
2. When you calling ServeHTTP directly, you're calling HTTP plugin w/o middleware.

@hotrush
Copy link
Author

hotrush commented Dec 3, 2024

@rustatian what the approach then? I found only this in docs and issues

@rustatian
Copy link
Member

I've updated the docs. If you wanted to use your custom middleware, just add it to the plugins list and use endpoint specified in the configuration to call your application with RR embedded in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-bug Bug: bug, exception F-need-verification
Projects
None yet
Development

No branches or pull requests

2 participants