5

I'm trying to initiate a websocket connection between chrome browser client and server.

Overview of my implementation : There are set of different up and running projects. The main project is the hub to all other projects and it handle all http requests, routes and proxy to other sub projects. These all projects use load balancers. My attempt is to create a websocket connection from chrom browser to one sub project.

caddy version : 0.9.3
websocket library : github.com/gorilla/websocket

The main project's caddy configs :

https://{$DOMAIN_NAME}/analytics/ {
    tls ../resources/security/server.pem ../resources/security/server.key
    proxy /  https://localhost:8107/analytics {
       websocket
       insecure_skip_verify
    }
}

The sub project's caddy configs :

localhost:{$ANALYTICS_CADDY_PORT}/analytics {
    root  webapps/analytics
    gzip
    ext    .html
    tls {$ANALYTICS_CERTIFICATE_FILE} {$ANALYTICS_KEY_FILE}
    proxy  /api https://localhost:{$ANALYTICS_HTTPS_PORT} {
         websocket
         insecure_skip_verify

    }
}

Inside the analytics sub project, " /api/ws " would trigger CreateSocketConnection() method.

//Starting the API server
    router := routes.NewRouter()
    http.Handle("/", router)
    http.HandleFunc("/api/ws", api.CreateSocketConnection)

CreateSocketConnection implementation :

func CreateSocketConnection(w http.ResponseWriter, r *http.Request) {
    var upgrader = websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    }
    _, err = upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Fatal("upgrader failed :", err.Error())
    }
    //controllers.HandleSocket(ws)
}

Client side implementation :

conn = new WebSocket("wss://xxxx.com/analytics/api/ws");

Issue is I'm not getting any error log in backend, but the socket connection fails on browser.

WebSocket connection to 'wss://xxxx.com/analytics/api/ws' failed: Error during WebSocket handshake: Unexpected response code: 502

Request header :

Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:Upgrade
Cookie:username=admin; tenantid=1; tenantdomain=super.com; 
DNT:1
Host:xxxx.com
Origin:https://xxxx.com
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:O/DS1lRHzXptoWz5WR131A==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36

But the response header is as follows :

Content-Encoding:gzip
Content-Length:40
Content-Type:text/plain; charset=utf-8
Date:Sat, 29 Oct 2016 03:13:23 GMT
Server:Caddy
Vary:Accept-Encoding
X-Content-Type-Options:nosniff

Please note that I'm getting the request header inside the CreateSocketConnection method as follows :

map[
    Connection:[Upgrade] 
    X-Forwarded-For:[127.0.0.1, 127.0.0.1] Dnt:[1] 
    Origin:[https://xxxx.com] 
    Pragma:[no-cache] 
    Sec-Websocket-Extensions:[permessage-deflate; client_max_window_bits] 
    Sec-Websocket-Version:[13] 
    Accept-Encoding:[gzip] 
    User-Agent:[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36] 
    Cache-Control:[no-cache] 
    Sec-Websocket-Key:[O/DS1lRHzXptoWz5WR131A==] 
    Upgrade:[websocket] 
    Cookie:[username=admin; tenantid=1; tenantdomain=super.com; ] 
    Accept-Language:[en-US,en;q=0.8]]

Am I missing something in my implementation?

Thanks in advance

csath
  • 1,248
  • 11
  • 25

1 Answers1

0

I had a similar issue, what I was missing was the transparent tag.

Ex.

https://{$DOMAIN_NAME}/analytics/ {
    tls ../resources/security/server.pem ../resources/security/server.key
    proxy /  https://localhost:8107/analytics {
       transparent
       websocket
       insecure_skip_verify
    }
}

transparent specifies that all the headers should be sent with it, so this matters if you have authentication.

transparent:

Passes thru host information from the original request as most backend apps would expect. Shorthand for:

header_upstream Host {host}
header_upstream X-Real-IP {remote} header_upstream X-Forwarded-For {remote}
header_upstream X-Forwarded-Port {server_port}
header_upstream X-Forwarded-Proto {scheme}

Source: https://caddyserver.com/docs/proxy

Ajay
  • 437
  • 7
  • 22