Esempio n. 1
0
void FastCGIServer::start() {
  // It's not safe to call this function more than once
  m_socket.reset(new folly::AsyncServerSocket(m_worker.getEventBase()));
  try {
    m_socket->bind(m_socketConfig.bindAddress);
  } catch (const std::system_error& ex) {
    LOG(ERROR) << ex.what();
    if (m_socketConfig.bindAddress.getFamily() == AF_UNIX) {
      throw FailedToListenException(m_socketConfig.bindAddress.getPath());
    }
    throw FailedToListenException(m_socketConfig.bindAddress.getAddressStr(),
                                  m_socketConfig.bindAddress.getPort());
  }
  if (m_socketConfig.bindAddress.getFamily() == AF_UNIX) {
    auto path = m_socketConfig.bindAddress.getPath();
    chmod(path.c_str(), 0760);
  }
  m_acceptor.reset(new FastCGIAcceptor(m_socketConfig, this));
  m_acceptor->init(m_socket.get(), m_worker.getEventBase());
  m_worker.getEventBase()->runInEventBaseThread([&] {
    if (!m_socket) {
      // Someone called stop before we got here. With the exception of a
      // second call to start being made this should be safe as any place
      // we mutate m_socket is done within the event base.
      return;
    }
    m_socket->listen(m_socketConfig.acceptBacklog);
    m_socket->startAccepting();
  });
  setStatus(RunStatus::RUNNING);
  folly::AsyncTimeout::attachEventBase(m_worker.getEventBase());
  m_worker.start();
  m_dispatcher.start();
}
void LibEventServerWithTakeover::start() {

  if (m_server_ssl) {
    // Set a flag to prevent parent class from trying to listen to ssl
    // before the old server releases the port
    m_accept_sock_ssl = -2;
  }

  LibEventServer::start();

  if (m_took_over) {
    Logger::Info("takeover: requesting shutdown of satellites");
    // Use AFDT to synchronously shut down the old server's satellites
    // so we can take their ports using accept.  The main server will be
    // stopped asynchronously.
    uint8_t shutdown_request[3] = P_VERSION C_TERM_REQ;
    uint8_t shutdown_response[3] = {0,0,0};
    uint32_t response_len = sizeof(shutdown_response);
    int should_not_receive_fd;
    afdt_error_t err = AFDT_ERROR_T_INIT;
    // TODO(dreiss): Make this timeout configurable.
    // We can aford to wait a long time here, since we've already started
    // the dispatcher for this server.  We want to give the old server
    // plenty of time to shut down all of its satellite servers.
    struct timeval timeout = { 10 , 0 };
    int ret = afdt_sync_client(
        m_transfer_fname.c_str(),
        shutdown_request,
        sizeof(shutdown_request) - 1,
        shutdown_response,
        &response_len,
        &should_not_receive_fd,
        &timeout,
        &err);
    if (ret < 0) {
      fd_transfer_error_hander(&err, nullptr);
      Logger::Warning("Failed to shut-down old server with AFDT.");
      // The higher-level start logic will try *very* hard to recover from this.
    }
    String resp((const char*)shutdown_response, response_len, CopyString);
    if (resp != P_VERSION C_TERM_OK) {
      Logger::Error(
          "Old server could not shut down: "
          "response = '%s'",
          StringUtil::CEncode(resp, null_string).data());
    } else {
      Logger::Info("takeover: old satellites have shut down");
    }
  }

  if (m_server_ssl) {
    if (getAcceptSocketSSL() != 0) {
      Logger::Error("Fail to listen on ssl port %d", m_port_ssl);
      throw FailedToListenException(m_address, m_port_ssl);
    }
    Logger::Info("Listen on ssl port %d",m_port_ssl);
  }

  setupFdServer();
}
Esempio n. 3
0
void LibEventServer::start() {
  if (getStatus() == RunStatus::RUNNING) return;

  if (getAcceptSocket() != 0) {
    throw FailedToListenException(m_address, m_port);
  }

  if (m_server_ssl != nullptr) {
    if (getAcceptSocketSSL() != 0) {
      Logger::Error("Fail to listen on ssl port %d", m_port_ssl);
      throw FailedToListenException(m_address, m_port_ssl);
    }
    Logger::Info("Listen on ssl port %d",m_port_ssl);
  }

  setStatus(RunStatus::RUNNING);
  m_dispatcher.start();
  m_dispatcherThread.start();
}
Esempio n. 4
0
void LibEventServer::start() {
  if (getStatus() == RUNNING) return;

  if (getAcceptSocket() != 0) {
    throw FailedToListenException(m_address, m_port);
  }

  setStatus(RUNNING);
  m_dispatcher.start();
  m_dispatcherThread.start();
  m_timeoutThread.start();
}
Esempio n. 5
0
void LibEventServer::start() {
  if (getStatus() == RunStatus::RUNNING) return;

  if (getAcceptSocket() != 0) {
    throw FailedToListenException(m_address, m_port);
  }

  if (m_server_ssl != nullptr && m_accept_sock_ssl != -2) {
    // m_accept_sock_ssl here serves as a flag to indicate whether it is
    // called from subclass (LibEventServerWithTakeover). If it is (==-2)
    // we delay the getAcceptSocketSSL();
    if (getAcceptSocketSSL() != 0) {
      Logger::Error("Fail to listen on ssl port %d", m_port_ssl);
      throw FailedToListenException(m_address, m_port_ssl);
    }
    Logger::Info("Listen on ssl port %d",m_port_ssl);
  }

  setStatus(RunStatus::RUNNING);
  m_dispatcher.start();
  m_dispatcherThread.start();
}
Esempio n. 6
0
void ProxygenServer::start() {
  m_httpServerSocket.reset(new AsyncServerSocket(m_worker.getEventBase()));
  bool needListen = true;
  auto failedToListen = [](const std::exception& ex,
                           const folly::SocketAddress& addr) {
    Logger::Error("failed to listen: %s", ex.what());
    throw FailedToListenException(addr.getAddressStr(), addr.getPort());
  };

  try {
    if (m_accept_sock >= 0) {
      Logger::Info("inheritfd: using inherited fd %d for server",
                   m_accept_sock);
      m_httpServerSocket->useExistingSocket(m_accept_sock);
    } else {
      // make it possible to quickly reuse the port
      m_httpServerSocket->setReusePortEnabled(RuntimeOption::StopOldServer);
      m_httpServerSocket->bind(m_httpConfig.bindAddress);
    }
  } catch (const std::system_error& ex) {
    bool takoverSucceeded = false;
    if (ex.code().value() == EADDRINUSE &&
        m_takeover_agent) {
      m_accept_sock = m_takeover_agent->takeover();
      if (m_accept_sock >= 0) {
        Logger::Info("takeover: using takeover fd %d for server",
                     m_accept_sock);
        m_httpServerSocket->useExistingSocket(m_accept_sock);
        needListen = false;
        m_takeover_agent->requestShutdown();
        takoverSucceeded = true;
      }
    }
    if (!takoverSucceeded) {
      failedToListen(ex, m_httpConfig.bindAddress);
    }
  }
  if (m_takeover_agent) {
    m_takeover_agent->setupFdServer(m_worker.getEventBase()->getLibeventBase(),
                                    m_httpServerSocket->getSocket(), this);
  }

  m_httpAcceptor.reset(new HPHPSessionAcceptor(m_httpConfig, this));
  m_httpAcceptor->init(m_httpServerSocket.get(), m_worker.getEventBase());
  if (m_httpsConfig.isSSL()) {
    m_httpsServerSocket.reset(new AsyncServerSocket(m_worker.getEventBase()));
    try {
      if (m_accept_sock_ssl >= 0) {
        Logger::Info("inheritfd: using inherited fd %d for ssl",
                     m_accept_sock_ssl);
        m_httpsServerSocket->useExistingSocket(m_accept_sock_ssl);
      } else {
        m_httpsServerSocket->setReusePortEnabled(RuntimeOption::StopOldServer);
        m_httpsServerSocket->bind(m_httpsConfig.bindAddress);
      }
    } catch (const TTransportException& ex) {
      failedToListen(ex, m_httpsConfig.bindAddress);
    }

    m_httpsAcceptor.reset(new HPHPSessionAcceptor(m_httpsConfig, this));
    try {
      m_httpsAcceptor->init(m_httpsServerSocket.get(), m_worker.getEventBase());
    } catch (const std::exception& ex) {
      // Could be some cert thing
      failedToListen(ex, m_httpsConfig.bindAddress);
    }
  }
  if (needListen) {
    try {
      m_httpServerSocket->listen(m_httpConfig.acceptBacklog);
    } catch (const std::system_error& ex) {
      failedToListen(ex, m_httpConfig.bindAddress);
    }
  }
  if (m_httpsServerSocket) {
    try {
      m_httpsServerSocket->listen(m_httpsConfig.acceptBacklog);
    } catch (const std::system_error& ex) {
      failedToListen(ex, m_httpsConfig.bindAddress);
    }
  }
  m_httpServerSocket->startAccepting();
  if (m_httpsServerSocket) {
    m_httpsServerSocket->startAccepting();
  }
  startConsuming(m_worker.getEventBase(), &m_responseQueue);

  setStatus(RunStatus::RUNNING);
  folly::AsyncTimeout::attachEventBase(m_worker.getEventBase());
  m_worker.start();
  m_dispatcher.start();
}