Ejemplo n.º 1
0
void HttpRequest::_on_request_read(uv_stream_t*, ssize_t nread, uv_buf_t buf) {
  if (nread > 0) {
    //std::cerr << nread << " bytes read\n";
    if (_ignoreNewData) {
      // Do nothing
    } else if (_protocol == HTTP) {
      int parsed = http_parser_execute(&_parser, &request_settings(), buf.base, nread);
      if (_parser.upgrade) {
        char* pData = buf.base + parsed;
        size_t pDataLen = nread - parsed;

        if (_pWebSocketConnection->accept(_headers, pData, pDataLen)) {
          // Freed in on_response_written
          InMemoryDataSource* pDS = new InMemoryDataSource();
          HttpResponse* pResp = new HttpResponse(this, 101, "Switching Protocols",
            pDS);

          std::vector<uint8_t> body;
          _pWebSocketConnection->handshake(_url, _headers, &pData, &pDataLen,
                                           &pResp->headers(), &body);
          if (body.size() > 0) {
            pDS->add(body);
          }
          body.empty();

          pResp->writeResponse();

          _protocol = WebSockets;
          _pWebApplication->onWSOpen(this);

          _pWebSocketConnection->read(pData, pDataLen);
        }

        if (_protocol != WebSockets) {
          // TODO: Write failure
          close();
        }
      } else if (parsed < nread) {
        if (!_ignoreNewData) {
          fatal_error("on_request_read", "parse error");
          uv_read_stop((uv_stream_t*)handle());
          close();
        }
      }
    } else if (_protocol == WebSockets) {
      _pWebSocketConnection->read(buf.base, nread);
    }
  } else if (nread < 0) {
    uv_err_t err = uv_last_error(_pLoop);
    if (err.code == UV_EOF /*|| err.code == UV_ECONNRESET*/) {
    } else {
      fatal_error("on_request_read", uv_strerror(err));
    }
    close();
  } else {
    // It's normal for nread == 0, it's when uv requests a buffer then
    // decides it doesn't need it after all
  }

  free(buf.base);
}
Ejemplo n.º 2
0
void HttpRequest::_on_request_read(uv_stream_t*, ssize_t nread, uv_buf_t buf) {
  if (nread > 0) {
    //std::cerr << nread << " bytes read\n";
    if (_ignoreNewData) {
      // Do nothing
    } else if (_protocol == HTTP) {
      int parsed = http_parser_execute(&_parser, &request_settings(), buf.base, nread);
      if (_parser.upgrade) {
        char* pData = buf.base + parsed;
        ssize_t pDataLen = nread - parsed;

        if (_headers.find("upgrade") != _headers.end() &&
            _headers["upgrade"] == std::string("websocket") &&
            _headers.find("sec-websocket-key") != _headers.end()) {

          // Freed in on_response_written
          HttpResponse* pResp = new HttpResponse(this, 101, "Switching Protocols",
            NULL);
          pResp->addHeader("Upgrade", "websocket");
          pResp->addHeader("Connection", "Upgrade");
          pResp->addHeader(
            "Sec-WebSocket-Accept",
            createHandshakeResponse(_headers["sec-websocket-key"]));
          // TODO: Consult app about supported WS protocol
          //pResp->addHeader("Sec-WebSocket-Protocol", "");

          pResp->writeResponse();

          _protocol = WebSockets;
          _pWebApplication->onWSOpen(this);

          read(pData, pDataLen);
        }

        if (_protocol != WebSockets) {
          // TODO: Write failure
          close();
        }
      } else if (parsed < nread) {
        if (!_ignoreNewData) {
          fatal_error("on_request_read", "parse error");
          uv_read_stop((uv_stream_t*)handle());
          close();
        }
      }
    } else if (_protocol == WebSockets) {
      read(buf.base, nread);
    }
  } else if (nread < 0) {
    uv_err_t err = uv_last_error(_pLoop);
    if (err.code == UV_EOF /*|| err.code == UV_ECONNRESET*/) {
    } else {
      fatal_error("on_request_read", uv_strerror(err));
    }
    close();
  } else {
    // It's normal for nread == 0, it's when uv requests a buffer then
    // decides it doesn't need it after all
  }

  free(buf.base);
}