Roxen.git / server / modules / misc / websocket.pike

version» Context lines:

Roxen.git/server/modules/misc/websocket.pike:27:      void create()   {   }      void start(int q, Configuration c)   {    conf = c;   }    + protected int is_connection_upgrade(string path, RequestID id) + { +  return has_value(lower_case(id->request_headers->connection||"")/",", +  "upgrade"); + } +  + protected int is_upgrade_websocket(string path, RequestID id) + { +  return has_value(lower_case(id->request_headers->upgrade||"")/",", +  "websocket"); + } +  + protected int is_websocket_version_13(string path, RequestID id) + { +  return id->request_headers["sec-websocket-version"] == "13"; + } +  + protected int has_valid_websocket_key(string path, RequestID id) + { +  string raw_key = ""; +  catch { +  raw_key = MIME.decode_base64(id->request_headers["sec-websocket-key"]); +  }; +  return sizeof(raw_key) >= 16; + } +    // Operation:   //   // * For syntactically valid WebSocket requests, the   // method field in the RequestID is set to "WebSocketOpen",   // the default error_code set to HTTP_BAD and zero returned.   //   // * For requests that don't seem to be WebSocket requests   // nothing is done, and zero is returned.   //   // * For requests that are upgrade requests to other than
Roxen.git/server/modules/misc/websocket.pike:60:    if (id->misc->internal_get) {    TRACE_LEAVE("No - internal request.");    return 0;    }       if (id->method != "GET") {    TRACE_LEAVE("No - wrong method.");    return 0;    }    -  if (!has_prefix(id->prot, "HTTP/") || -  (id->prot[sizeof("HTTP/")..] < "1.1")) { -  // HTTP/1.1 or later required. -  TRACE_LEAVE("No - not HTTP/1.1 or later."); -  return 0; -  } +  id->register_vary_callback("connection", is_connection_upgrade);    -  if (!has_value(lower_case(id->request_headers->connection||"")/",", -  "upgrade")) { +  if (!is_connection_upgrade("", id)) {    TRACE_LEAVE("No - no connection: upgrade.");    return 0;    }    -  if (!has_value(lower_case(id->request_headers->upgrade||"")/",", -  "websocket")) { +  id->register_vary_callback("connection", is_upgrade_websocket); +  +  if (!is_upgrade_websocket("", id)) {    // Unsupported upgrade header.    id->misc->error_code = id->misc->error_code || Protocols.HTTP.HTTP_BAD;    TRACE_LEAVE("No - Unsupported or missing upgrade header.");    return 0;    }    -  if (id->request_headers["sec-websocket-version"] != -  (string)13/*Protocols.WebSocket.websocket_version*/) { +  id->register_vary_callback("sec-websocket-version", is_websocket_version_13); +  +  if (!is_websocket_version_13("", id)) {    // Unsupported WebSocket version.    TRACE_LEAVE("No - Unsupported websocket version.");    return Roxen.http_status(Protocols.HTTP.HTTP_BAD,    "Unsupported WebSocket version.") + ([    "extra_heads": ([    "Sec-WebSocket-Version": (string)13/*Protocols.WebSocket.websocket_version*/,    ]),    ]);    }    -  string raw_key = ""; -  catch { -  raw_key = MIME.decode_base64(id->request_headers["sec-websocket-key"]); -  }; -  if (sizeof(raw_key) < 16) { +  id->register_vary_callback("sec-websocket-key", has_valid_websocket_key); +  +  if (!has_valid_websocket_key("", id)) {    // Invalid Sec-WebSocet-Key.    TRACE_LEAVE("No - Invalid Sec-WebSocket-Key.");    return Roxen.http_status(Protocols.HTTP.HTTP_BAD,    "Invalid Sec-WebSocket-Key.");    }    -  +  // FIXME: Fix vary support for http version. +  if (!has_prefix(id->prot, "HTTP/") || +  (id->prot[sizeof("HTTP/")..] < "1.1")) { +  // HTTP/1.1 or later required. +  NOCACHE(); +  TRACE_LEAVE("No - not HTTP/1.1 or later."); +  return 0; +  } +     TRACE_LEAVE("Yes.");       // NB: The mixed case in the method ensures that it can't be    // set directly from the http request.    id->method = "WebSocketOpen";    id->misc->error_code = Protocols.HTTP.HTTP_BAD;       // Continue request processing.    return 0;   }