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

http_proxy: support multi-addresses listening #654

Closed
wants to merge 8 commits into from

Conversation

Choraden
Copy link
Contributor

@Choraden Choraden commented Jan 17, 2024

This patch adds multi-addresses listener.

Fixes #629

bind/flag.go Outdated Show resolved Hide resolved
@mmatczuk
Copy link
Contributor

mmatczuk commented Jan 18, 2024

I'd suggest to extend the port syntax we use in the current flag

flag := [<host>]:<port_expr>
port_expr := <port>|<port-range>,...
port-range := <port>-<port>

Example:

--address localhost:50,60,70-80

Maybe the port range is too much and can be ignored.

The logic should be that we shall always be able to listen to one or more ports.

@@ -89,24 +91,64 @@ type ListenerCallbacks interface {

// OnTLSHandshakeError is called after a TLS handshake errors out.
OnTLSHandshakeError(*tls.Conn, error)

// OnBindError is called when a listener fails to bind to an address.
OnBindError(address string, err error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should go before TLS things.

net.go Outdated
type Listener struct {
Address string
Addresses []string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Listener changes should be in a separate commit.

net.go Outdated
Log log.Logger
TLSConfig *tls.Config
HandshakeTimeout time.Duration
ReadLimit int64
WriteLimit int64
Callbacks ListenerCallbacks

listener net.Listener
ls []net.Listener
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not listeners

net.go Outdated
if l.Callbacks != nil {
l.Callbacks.OnBindError(addr, err)
}
if i == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that when using more than one port they are all equal.

return ll, nil
}

func (l *Listener) acceptLoop(ll net.Listener) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use errgroup with anonymous function instead of creating this and closeCh.

net_test.go Outdated
@@ -70,3 +122,6 @@ func (m *mockListenerCallback) OnTLSHandshakeError(_ *tls.Conn, err error) {
}
m.donec <- struct{}{}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Order.

@mmatczuk
Copy link
Contributor

As for the integration, the main part should be in the listener and it should go to the HttpServer.

@Choraden Choraden force-pushed the hg/multi_listen_v2 branch 7 times, most recently from 966c19a to e8fde91 Compare January 19, 2024 14:41
@Choraden Choraden marked this pull request as ready for review January 19, 2024 14:51
@Choraden Choraden requested a review from a team as a code owner January 19, 2024 14:51
@mmatczuk
Copy link
Contributor

We have Listen and Listener struct, http server using the former http proxy using the latter.
This is ok but you can see that the responsibility is duplicated.

I suggest the following refactoring

  • Make Listener based on net.Listener not Address
  • Add MultiListener like https://github.com/daniel-garcia/multilistener, can be our own - the idea here is seal the hanging multiple listeners in one place and avoid using it if not needed
  • Use MultiListener in http proxy only if absolutely needed.

The MultiListeners idea may not be the best in general

  • Connection can be accepted and not read from - blocked on channel put
  • Channel is a bottleneck and a back pressure mechanism at the same time
    It's hard to tell it's definitely bad without any benchmarks, but we should be aware of it and maybe add some benchmarks?
    The good thing about it is that it allows for easy reuse of our other code in Listener.

Having said that maybe the Listener struct should be removed altogether.
The rate limiting is already a net.Listener wrapper, how about we refactored the Listener tls code into a net.Listener wrapper?

I'm thinking we should move net.go to a dedicated package ex. utils/netx, the rate limit could go under it.

@mmatczuk
Copy link
Contributor

mmatczuk commented Jan 29, 2024

The --address and --optional-addresses is a usability mess it immediately raises questions like why would you ever need that.

All of that would not be a problem if we focused on file based configuration only - say we would have listener config object like Envoy. Then you could add optional field to it. We also have protocol and bunch of other stuff that make adding multiple addresses imbalance other configurations.

Maybe we are solving wrong problem and this should be done on a script level?

@waggledans
Copy link
Contributor

Maybe we are solving wrong problem and this should be done on a script level?

What do you have in mind? The problem is described in #629

The --address and --optional-addresses is a usability mess

I'd rather have some way to assign properties to listeners, not sure how to make it work with CLI.

it immediately raises questions like why would you ever need that.

hmm... #629 ?

@mmatczuk
Copy link
Contributor

mmatczuk commented Jan 30, 2024

@waggledans #629 points to a doc that says

Microsoft Edge, Chrome 71+, and the Safari browser on OS X 10.10+ and mobile iOS 8+ proxy these common ports

What that even means?
Why we should so easily give up on the ports.
What's the purpose?

Why not use a script to launch a bunch of forwarders instead - what it the benefit of integrating it.

@waggledans
Copy link
Contributor

What that even means?, Why we should so easily give up on the ports, What's the purpose?

All these questions indicate that we need to improve Sauce Labs docs if it's not clear from the description. Let's have this discussion elsewhere (we should have had it BEFORE the implementation).

Why not use a script to launch a bunch of forwarders instead

Absolutely not. It's 20-30 ports, I don't think so.

@mmatczuk
Copy link
Contributor

mmatczuk commented Feb 2, 2024

Let's split the work and move the port forwarding to separate feature #669

@Choraden Choraden closed this Feb 7, 2024
@Choraden Choraden deleted the hg/multi_listen_v2 branch February 7, 2024 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support multiple ports binding
3 participants