dunglas / mercure

🪽 An open, easy, fast, reliable and battery-efficient solution for real-time communications
https://mercure.rocks
GNU Affero General Public License v3.0
3.99k stars 297 forks source link

Issue on multiple connections with proxy Apache #830

Open DARDORKE opened 1 year ago

DARDORKE commented 1 year ago

In my application, I have a local Mercure hub connected via proxy to my Apache server:

Here's the proxy on my Apache server:

ProxyPass "/hub/" http://localhost:3000/
ProxyPassReverse "/hub/" http://localhost:3000/

The connection between the client and the hub works very well when querying my Apache server.

Here's the client-side code connecting to the hub:

const eventSource = new EventSourcePolyfill(url, {
headers: {
Authorization: token,
},
});

The 'url' is the link to the Mercure topic.

I can open multiple tabs; each tab establishes a connection to the hub by connecting to the Apache proxy which redirects to the Mercure hub from the same client. However, when I try to refresh one of the tabs in the browser, it goes into a loop until I close one of the other tabs.

image

Here's my Mercure config:

{
{$GLOBAL_OPTIONS}
auto_https off
}

{$SERVER_NAME:http://localhost:3000}

log {
level WARN
format filter {
wrap console
fields {
uri query {
replace authorization REDACTED
}
}
}
}

{$EXTRA_DIRECTIVES}

route {
encode zstd gzip
mercure {
    # Transport to use (default to Bolt)
    transport_url {$MERCURE_TRANSPORT_URL:bolt://mercure.db}
    # Publisher JWT key
    publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
    # Subscriber JWT key
    subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
    # Extra directives
    {$MERCURE_EXTRA_DIRECTIVES}
    publish_origins *
    ui
    anonymous
    subscriptions
    cors_origins https://productions.ats-dev.fr
    {$MERCURE_EXTRA_DIRECTIVES}
}

Locally, I don't have this problem, and the only difference is the use of an Apache proxy on the remote server and the addition of the 'auto_https off' directive in the Mercure configuration to prevent it from interfering with port 80 on my server.

frizquierdo commented 1 year ago

Apache proxy must be configured with h2 (http2) protocol

DARDORKE commented 1 year ago

I tried using http2 protocol by modifying proxy config :

ProxyPass "/hub/" h2c://localhost:3000/
ProxyPassReverse "/hub/" http://localhost:3000/

But now, client's connections don't work. I found the next error on apache logs :

[http2:warn] [pid 1046] AH10034: The mpm module (prefork.c) is not supported by mod_http2. The mpm determines how things are processed in your server. HTTP/2 has more demands in this regard and the currently selected mpm will just not do. This is an advisory warning. Your server will continue to work, but the HTTP/2 protocol will be inactive.

I changed MPM from prefork to event. Now http2 seems to be activated but client has 503 error on connection.

Here my mercure logs :

{"level":"info","ts":1698049979.7189612,"logger":"http.log.access","msg":"handled request","request":{"remote_ip":"::1","remote_port":"57958","client_ip":"::1","proto":"HTTP/2.0","method":"PRI","host":"","uri":"*","headers":{}},"bytes_read":0,"user_id":"","duration":0.000001473,"size":0,"status":0,"resp_headers":{"Server":["Caddy"]}}

Apache tries request on mercure hub but I don't get why connection fail. :/

DARDORKE commented 1 year ago

I found solution, problem came from SSL config.

Config proxy apache :

SSLProxyCACertificateFile "/etc/ssl/GandiRSADomainValidationSecureServerCA3.pem"
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyEngine on
<LocationMatch "/hub/">
    ProxyPass h2://localhost:3000/
    ProxyPassReverse https://localhost:3000/
</LocationMatch>

Mercure config :

{
    {$GLOBAL_OPTIONS}
    https_port 3000
    auto_https off  
    admin off
}

{$SERVER_NAME::3000}

tls /etc/ssl/atsapp.ats-dev.fr.crt /etc/ssl/atsapp.ats-dev.fr.key

Now it works. :)

DARDORKE commented 1 year ago

Hi !

I reopen this issue cause I still have problems on multiple connections. When I open several tabs who connect on Mercure by the h2 proxy everything work but when I try to refresh a tab it loads during a long time before getting an answer (about 30sec-1min).

Is it coming from Apache configuration or from the client front ? 🫤

Thx.