Websocket socket.io json config not redirecting

1. Output of caddy version:

v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

2. How I run Caddy:

using docker serivce create with sending volume for config : /etc/config

a. System environment:

docker

b. Command:

docker inspect ca
[
    {
        "ID": "on9r4k07vpt2btgvpby0pz0os",
        "Version": {
            "Index": 29832599
        },
        "CreatedAt": "2022-11-25T11:01:35.25925543Z",
        "UpdatedAt": "2022-11-25T11:01:35.261731579Z",
        "Spec": {
            "Name": "ca",
            "Labels": {},
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": "caddy",
                    "Args": [
                        "caddy",
                        "run",
                        "--config",
                        "/etc/caddy/caddy.json"
                    ],
                    "Mounts": [
                        {
                            "Type": "bind",
                            "Source": "/mo/certsFinal",
                            "Target": "/mo/certsFinal"
                        },
                        {
                            "Type": "bind",
                            "Source": "/mo/config/caddy",
                            "Target": "/etc/caddy"
                        },
                        {
                            "Type": "bind",
                            "Source": "/mo/upload",
                            "Target": "/mo/upload"
                        }
                    ],
                    "StopGracePeriod": 10000000000,
                    "DNSConfig": {},
                    "Isolation": "default"
                },
                "Resources": {
                    "Limits": {},
                    "Reservations": {}
                },
                "RestartPolicy": {
                    "Condition": "any",
                    "Delay": 5000000000,
                    "MaxAttempts": 0
                },
                "Placement": {},
                "LogDriver": {
                    "Name": "json-file",
                    "Options": {
                        "max-file": "3",
                        "max-size": "10M"
                    }
                },
                "ForceUpdate": 0,
                "Runtime": "container"
            },
            "Mode": {
                "Replicated": {
                    "Replicas": 1
                }
            },
            "UpdateConfig": {
                "Parallelism": 0,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
            "RollbackConfig": {
                "Parallelism": 0,
                "FailureAction": "pause",
                "Monitor": 5000000000,
                "MaxFailureRatio": 0,
                "Order": "stop-first"
            },
            "Networks": [
                {
                    "Target": "l8dnnagdjobzp73vxonpwjc3l"
                }
            ],
            "EndpointSpec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 31080,
                        "PublishedPort": 31080,
                        "PublishMode": "ingress"
                    },
                    {
                        "Protocol": "tcp",
                        "TargetPort": 2019,
                        "PublishedPort": 2019,
                        "PublishMode": "ingress"
                    },
                    {
                        "Protocol": "tcp",
                        "TargetPort": 31443,
                        "PublishedPort": 31443,
                        "PublishMode": "ingress"
                    }
                ]
            }
        },
        "Endpoint": {
            "Spec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 31080,
                        "PublishedPort": 31080,
                        "PublishMode": "ingress"
                    },
                    {
                        "Protocol": "tcp",
                        "TargetPort": 2019,
                        "PublishedPort": 2019,
                        "PublishMode": "ingress"
                    },
                    {
                        "Protocol": "tcp",
                        "TargetPort": 31443,
                        "PublishedPort": 31443,
                        "PublishMode": "ingress"
                    }
                ]
            },
            "Ports": [
                {
                    "Protocol": "tcp",
                    "TargetPort": 31080,
                    "PublishedPort": 31080,
                    "PublishMode": "ingress"
                },
                {
                    "Protocol": "tcp",
                    "TargetPort": 2019,
                    "PublishedPort": 2019,
                    "PublishMode": "ingress"
                },
                {
                    "Protocol": "tcp",
                    "TargetPort": 31443,
                    "PublishedPort": 31443,
                    "PublishMode": "ingress"
                }
            ],
            "VirtualIPs": [
                {
                    "NetworkID": "hifr8m195ctdt4c8t7gabgbx7",
                    "Addr": "10.0.0.101/24"
                },
                {
                    "NetworkID": "l8dnnagdjobzp73vxonpwjc3l",
                    "Addr": "10.0.1.103/24"
                }
            ]
        }
    }
]

c. Service/unit/compose file:

docker service was created via an app, not via command line. Added service inspect above.

d. My complete Caddy config:

  {
    "admin": {
        "disabled": false
    },
    "logging": {
        "logs": {
            "": {
                "level": "DEBUG"
            }
        }
    },
    "apps": {
        "http": {
            "http_port": 80,
            "servers": {
                "example": {
                    "listen": [
                        ":443"
                    ],
                    "routes": [
                        {
                            "match": [
                                {
                                    "path": [
                                        "/chacode_mo_co_socket_4_s",
                                        "/chacode_mo_co_support_4_s"
                                    ],
                                    "header": [
                                        "Upgrade"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "reverse_proxy",
                                    "transport": {
                                        "protocol": "http"
                                    },
                                    "upstreams": [
                                        {
                                            "dial": "aman-socket-4-s:80"
                                        }
                                    ]
                                }
                            ]
                        }, 
                        {
                            "handle": [
                                {
                                    "handler": "static_response",
                                    "body": "Hello, world 23!"
                                }
                            ]
                        }
                    ],
                    "tls_connection_policies": [
                        {}
                    ],
                    "automatic_https": {
                        "disable_redirects": false
                    },
                    "logs": {}
                }
            }
        },
        "tls": {
            "automation": {
                "policies": [
                    {
                        "on_demand": true
                    }
                ],
                "on_demand": {
                    "rate_limit": {
                        "interval": "10m",
                        "burst": 2
                    }
                }
            }
        }
    }
} 

3. The problem I’m having:

“header”: [“Upgrade”] doesn’t work.
I am trying to match haproxy’s

    acl wo_websocket hdr(Upgrade) -i WebSocket
    acl urlchacode_socket path_beg /chacode_mo_co_socket_4_s
    acl urlchacode_support path_beg /chacode_mo_co_support_4_s
    use_backend backend_wss_000002 if wo_websocket urlchacode_support
    use_backend backend_wss_000002 if wo_websocket urlchacode_socket

which is basically routing socket.io to desired socket.io backend

4. Error messages and/or full log output:

{"level":"info","ts":1669577187.6146133,"msg":"using provided configuration","config_file":"/etc/caddy/caddy.json","config_adapter":""}
Error: sending configuration to instance: caddy responded with error: HTTP 400: {"error":"loading config: loading new config: loading http app module: provision http: server example: setting up route matchers: route 1: loading matcher modules: module name 'header': decoding module config: http.matchers.header: json: cannot unmarshal array into Go value of type caddyhttp.MatchHeader"}

5. What I already tried:

trying for few hours, trying to match header, protocol; but can’t find websocket here (JSON Config Structure - Caddy Documentation ).

6. Links to relevant resources:

You mean proxy, not redirect, I think. Those are completely distinct concepts, and aren’t interchangeable.

A header matcher should look like this:

"header":{"Upgrade":["websocket"]}

You need to specify a value to match for that field.

A more complete matcher for websockets would be:

{
	"header": {
		"Connection": ["*Upgrade*"],
		"Upgrade": ["websocket"]
	}
}

This matches only requests that have a header field named Connection containing the word Upgrade, and another field named Upgrade with a value of websocket.

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.