{"record":{"id":"6adf64ba4eda6a23","repo":"XX-net/XX-Net","slug":"notsupported","errorCode":null,"errorMessage":"NotSupported","messagePattern":"NotSupported","errorType":"exception","errorClass":"NotSupported","httpStatus":null,"severity":"info","filePath":"code/default/smart_router/local/smart_route.py","lineNumber":344,"sourceCode":"    if req.path[0] == b'/':\n        url = b'%s://%s%s' % (schema, req.headers[b'Host'], req.path)\n    else:\n        url = req.path\n\n    if url in [b\"http://www.twitter.com/xxnet\",\n                    b\"https://www.twitter.com/xxnet\",\n                    b\"http://www.deja.com/xxnet\",\n                    b\"https://www.deja.com/xxnet\"\n                    ]:\n        # for web_ui status page\n        # auto detect browser proxy setting is work\n        xlog.debug(\"CONNECT %s %s\", req.command, req.path)\n        req.wfile.write(req.self_check_response_data)\n        return\n\n    if req.upgrade == b\"websocket\":\n        xlog.debug(\"gae %s not support WebSocket\", req.path)\n        raise NotSupported(req, sock)\n\n    if len(req.path) >= 2048:\n        xlog.debug(\"gae %s path len exceed 1024 limit\", req.path)\n        raise NotSupported(req, sock)\n\n    if req.command not in req.gae_support_methods:\n        xlog.debug(\"gae %s %s, method not supported\", req.command, req.path)\n        raise NotSupported(req, sock)\n\n    req.parsed_url = urlparse(req.path)\n    req.do_METHOD()\n\n\ndef try_loop(scense, rule_list, sock, host, port, client_address, left_buf=\"\"):\n    xlog.debug(\"try_loop %s %s to %s:%d\", scense, rule_list, host, port)\n\n    start_time = time.time()\n","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/XX-net/XX-Net/blob/cfa5bc17b67676e467f37ec50766127e0ab5f0aa/code/default/smart_router/local/smart_route.py#L326-L362","documentation":"NotSupported(req, sock) is raised from do_gae when the incoming HTTP request asks for a WebSocket upgrade (req.upgrade == b'websocket'). GAE operates as an HTTP/HTTPS relay over Google App Engine and cannot carry raw bidirectional WebSocket frames, so the router raises NotSupported to signal try_loop to try a different strategy (e.g. direct or X-Tunnel).","triggerScenarios":"A client opens a WebSocket connection (Upgrade: websocket header) and the smart router routes it to the GAE strategy.","commonSituations":"Browsers/applications using WebSocket-based services (chat, live feeds) while GAE is the first matching routing rule.","solutions":["Add a routing rule that sends WebSocket traffic to direct or X-Tunnel instead of GAE","Catch NotSupported in try_loop so the connection falls back to a WebSocket-capable strategy (designed behavior)","If WebSockets are essential, consider disabling the GAE strategy for the affected hosts"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if req.headers.get('Upgrade','').lower() == 'websocket':\n    skip_strategy('gae')","typeGuard":null,"tryCatchPattern":"try:\n    do_gae(...)\nexcept NotSupported:\n    try_next_strategy(sock, host, port)  # direct/X-Tunnel support websockets","preventionTips":["Add a pre-routing rule sending Upgrade: websocket to a WebSocket-capable strategy","Treat NotSupported from do_gae as a normal fallback signal, not a crash"],"tags":["websocket","gae-proxy","unsupported-protocol"],"backgroundTag":"protocol-not-supported","analyzedSha":"cfa5bc17b67676e467f37ec50766127e0ab5f0aa","analyzedAt":"2026-08-27T19:28:28.225Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}