Пример #1
0
HttpsServer* ApplicationHttpsServer::buildHttpsServer (HttpHandlerFactory* httpHandlerFactory,
                                                       vector<AddressPort> const& ports) {
  Scheduler* scheduler = _applicationScheduler->scheduler();

  if (scheduler == 0) {
    LOGGER_FATAL << "no scheduler is known, cannot create https server";
    TRI_ShutdownLogging();
    exit(EXIT_FAILURE);
  }

  Dispatcher* dispatcher = 0;

  if (_applicationDispatcher != 0) {
    dispatcher = _applicationDispatcher->dispatcher();
  }

  // check the ssl context
  if (_sslContext == 0) {
    LOGGER_FATAL << "no ssl context is known, cannot create https server";
    TRI_ShutdownLogging();
    exit(EXIT_FAILURE);
  }

  // create new server
  HttpsServer* httpsServer = new HttpsServer(scheduler, dispatcher, _sslContext);

  httpsServer->setHandlerFactory(httpHandlerFactory);

  if (_requireKeepAlive) {
    httpsServer->setCloseWithoutKeepAlive(true);
  }

  // keep a list of active server
  _httpsServers.push_back(httpsServer);

  // open http ports
  deque<AddressPort> addresses;
  addresses.insert(addresses.begin(), ports.begin(), ports.end());

  _applicationServer->raisePrivileges();

  while (! addresses.empty()) {
    AddressPort ap = addresses[0];
    addresses.pop_front();

    string bindAddress = ap._address;
    int port = ap._port;

    bool result;

    if (bindAddress.empty()) {
      LOGGER_TRACE << "trying to open port " << port << " for https requests";

      result = httpsServer->addPort(port, _applicationScheduler->addressReuseAllowed());
    }
    else {
      LOGGER_TRACE << "trying to open address " << bindAddress
                   << " on port " << port
                   << " for https requests";

      result = httpsServer->addPort(bindAddress, port, _applicationScheduler->addressReuseAllowed());
    }

    if (result) {
      LOGGER_DEBUG << "opened port " << port << " for " << (bindAddress.empty() ? "any" : bindAddress);
    }
    else {
      LOGGER_TRACE << "failed to open port " << port << " for " << (bindAddress.empty() ? "any" : bindAddress);
      addresses.push_back(ap);

      if (scheduler->isShutdownInProgress()) {
        addresses.clear();
      }
      else {
        sleep(1);
      }
    }
  }

  _applicationServer->dropPrivileges();

  return httpsServer;
}