Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

invalid websocket frame #549

Open
eaziz4 opened this issue Feb 5, 2025 · 0 comments
Open

invalid websocket frame #549

eaziz4 opened this issue Feb 5, 2025 · 0 comments

Comments

@eaziz4
Copy link

eaziz4 commented Feb 5, 2025

I'm getting the following errors with my web socket handler code. This was essentially completely copied from the sample websocket handler. I was getting wss:// errors so this is all from connecting with ws://

Error: Invalid WebSocket frame: MASK must be clear
Error: Invalid WebSocket frame: RSV2 and RSV3 must be clear

It looks like this error is happening due to the body being encoded or compressed as I get this error in onData

WebSocketStream::onData: ����ݓ�Ȼ

this is my server configuration

DEFINE_int32(http_port, 11000, "Port to listen on with HTTP protocol");
DEFINE_int32(h2_port, 11001, "Port to listen on with HTTP/2 protocol");
DEFINE_int32(https_port, 443, "Port to listen on with HTTPS protocol");
DEFINE_string(ip, "0.0.0.0", "IP/Hostname to bind to");
DEFINE_int32(threads,
             0,
             "Number of threads to listen on. Numbers <= 0 "
             "will use the number of cores on this machine.");

void Server::start() {
    google::InitGoogleLogging("server");
    folly::EventBase evb;
    proxygen::HTTPServerOptions options;
    options.handlerFactories = proxygen::RequestHandlerChain().addThen<HandlerFactory>().build();
    options.threads = static_cast<size_t>(FLAGS_threads);
    options.idleTimeout = std::chrono::milliseconds(60000);
    options.supportsConnect = true;

    proxygen::HTTPServer server(std::move(options));

    const std::vector<proxygen::HTTPServer::IPConfig> ips = {
        {folly::SocketAddress(FLAGS_ip, FLAGS_http_port, true), proxygen::HTTPServer::Protocol::HTTP},
        {folly::SocketAddress(FLAGS_ip, FLAGS_h2_port, true), proxygen::HTTPServer::Protocol::HTTP2}
        ,/*httpsConfig*/
    };
    server.bind(ips);
    server.start([] () -> void {
        XLOG(INFO) << "Server started successfully.";
    });

    evb.loop();
}

this is my websocket handler

std::string WebSocketHandler::kWSKeyHeader = "Sec-WebSocket-Key";
std::string WebSocketHandler::kWSProtocolHeader = "Sec-WebSocket-Protocol";
std::string WebSocketHandler::kWSExtensionsHeader = "Sec-WebSocket-Extensions";
std::string WebSocketHandler::kWSAcceptHeader = "Sec-WebSocket-Accept";
std::string WebSocketHandler::kWSVersionHeader = "Sec-WebSocket-Version";
std::string WebSocketHandler::kWSVersion = "13";
std::string WebSocketHandler::kUpgradeTo = "websocket";


void WebSocketHandler::onRequest(
    std::unique_ptr<proxygen::HTTPMessage> request) noexcept {

  XLOG(INFO) << " New incoming request" << *request;
  // Check if Upgrade and Connection headers are present.
  if (!request->getHeaders().exists(proxygen::HTTP_HEADER_UPGRADE) ||
      !request->getHeaders().exists(proxygen::HTTP_HEADER_CONNECTION)) {
    LOG(ERROR) << " Missing Upgrade/Connection header";
    proxygen::ResponseBuilder(downstream_).rejectUpgradeRequest();
    return;
  }

  // Make sure we are requesting an upgrade to websocket.
  const std::string& proto =
      request->getHeaders().getSingleOrEmpty(proxygen::HTTP_HEADER_UPGRADE);
  if (!proxygen::caseInsensitiveEqual(proto, kUpgradeTo)) {
    LOG(ERROR) << "Provided upgrade protocol: '" << proto << "', expected: '"
               << kUpgradeTo << "'";
    proxygen::ResponseBuilder(downstream_).rejectUpgradeRequest();
    return;
  }

  // Build the upgrade response.
  proxygen::ResponseBuilder response(downstream_);
  response.status(101, "Switching Protocols")
      .setEgressWebsocketHeaders()
      .header(kWSVersionHeader, kWSVersion)
      .send();
}

void WebSocketHandler::onEgressPaused() noexcept {
  XLOG(INFO) << "WebSocketHandler egress paused";
}

void WebSocketHandler::onEgressResumed() noexcept {
  XLOG(INFO) << "WebSocketHandler resumed";
}

void WebSocketHandler::onBody(std::unique_ptr<folly::IOBuf> body) noexcept {
  XLOG(INFO) << "WebsocketHandler::onBody";
  auto res = wsStream_->onData(std::move(body));
  if (res.hasError()) {
    proxygen::ResponseBuilder response(downstream_);
    response.status(400, "Bad Request");
    response.sendWithEOM();
  } else {
    proxygen::ResponseBuilder(downstream_).body(std::move(*res)).send();
  }
}

void WebSocketHandler::onEOM() noexcept {
  proxygen::ResponseBuilder(downstream_).sendWithEOM();
}

void WebSocketHandler::onUpgrade(proxygen::UpgradeProtocol /*protocol*/) noexcept {
  XLOG(INFO) << "WebSocketHandler onUpgrade";
  wsStream_ = std::make_unique<WebSocketStream>();
}

void WebSocketHandler::requestComplete() noexcept {
  XLOG(INFO) << " WebSocketHandler::requestComplete";
  delete this;
}

void WebSocketHandler::onError(proxygen::ProxygenError err) noexcept {
  XLOG(INFO) << " WebSocketHandler::onError: " << err;
  delete this;
}

folly::Expected<std::unique_ptr<folly::IOBuf>, WebSocketStream::WebSocketStreamError>
WebSocketStream::onData(std::unique_ptr<folly::IOBuf> chain) {
  XLOG(INFO) << "WebSocketStream::onData: " << chain->clone()->moveToFbString();
  // Parse websocket framing here etc.
  return std::move(chain);
 // with this I get Error: Invalid WebSocket frame: MASK must be clear.  if instead of echoing the message back I do anything custom, I get Error: Invalid WebSocket frame: RSV2 and RSV3 must be clear
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant