Ejemplo n.º 1
0
HttpHandler* HttpHandlerFactory::createHandler (HttpRequest* request) {
#if 0
  READ_LOCKER(_maintenanceLock);

  if (_maintenance) {
    return ((S*) this)->createMaintenanceHandler();
  }
#endif


  map<string, create_fptr> const& ii = _constructors;
  string path = request->requestPath();
  map<string, create_fptr>::const_iterator i = ii.find(path);
  void* data = 0;


  // no direct match, check prefix matches
  if (i == ii.end()) {
    LOG_TRACE("no direct handler found, trying prefixes");

    // find longest match
    string prefix;
    vector<string> const& jj = _prefixes;
    const size_t pathLength = path.size();

    for (vector<string>::const_iterator j = jj.begin();  j != jj.end();  ++j) {
      string const& p = *j;
      const size_t pSize = p.size();

      if (path.compare(0, pSize, p) == 0) {
        if (pSize < pathLength && path[pSize] == '/') {
          if (prefix.size() < pSize) {
            prefix = p;
          }
        }
      }
    }

    if (prefix.empty()) {
      LOG_TRACE("no prefix handler found, trying catch all");

      i = ii.find("/");
      if (i != ii.end()) {
        LOG_TRACE("found catch all handler '/'");

        size_t l = 1;
        size_t n = path.find_first_of('/', l);

        while (n != string::npos) {
          request->addSuffix(path.substr(l, n - l).c_str());
          l = n + 1;
          n = path.find_first_of('/', l);
        }

        if (l < path.size()) {
          request->addSuffix(path.substr(l).c_str());
        }

        path = "/";
        request->setPrefix(path.c_str());
      }
    }

    else {
      LOG_TRACE("found prefix match '%s'", prefix.c_str());

      size_t l = prefix.size() + 1;
      size_t n = path.find_first_of('/', l);

      while (n != string::npos) {
        request->addSuffix(path.substr(l, n - l).c_str());
        l = n + 1;
        n = path.find_first_of('/', l);
      }

      if (l < path.size()) {
        request->addSuffix(path.substr(l).c_str());
      }

      path = prefix;
      request->setPrefix(path.c_str());

      i = ii.find(path);
    }
  }

  // no match
  if (i == ii.end()) {
    if (_notFound != 0) {
      HttpHandler* notFoundHandler = _notFound(request, data);
      notFoundHandler->setServer(this);

      return notFoundHandler;
    }
    else {
      LOG_TRACE("no not-found handler, giving up");
      return 0;
    }
  }


  // look up data
  map<string, void*> const& jj = _datas;
  map<string, void*>::const_iterator j = jj.find(path);

  if (j != jj.end()) {
    data = j->second;
  }

  LOG_TRACE("found handler for path '%s'", path.c_str());
  HttpHandler* handler = i->second(request, data);

  handler->setServer(this);

  return handler;
}
Ejemplo n.º 2
0
HttpHandler* HttpHandlerFactory::createHandler(HttpRequest* request) {
  std::string const& path = request->requestPath();

  // In the bootstrap phase, we would like that coordinators answer the 
  // following to endpoints, but not yet others:
  if (MaintenanceMode) {
    if ((!ServerState::instance()->isCoordinator() && 
         path.find("/_api/agency/agency-callbacks") == std::string::npos) ||
        (path != "/_api/shard-comm" && 
         path.find("/_api/agency/agency-callbacks") == std::string::npos &&
         path.find("/_api/aql") == std::string::npos)) { 
      LOG(DEBUG) << "Maintenance mode: refused path: " << path;
      return new MaintenanceHandler(request);
    }
  }

  std::unordered_map<std::string, create_fptr> const& ii = _constructors;
  std::string const* modifiedPath = &path;
  std::string prefix;

  auto i = ii.find(path);

  // no direct match, check prefix matches
  if (i == ii.end()) {
    LOG(TRACE) << "no direct handler found, trying prefixes";

    // find longest match
    size_t const pathLength = path.size();

    for (auto const& p : _prefixes) {
      size_t const pSize = p.size();

      if (path.compare(0, pSize, p) == 0) {
        if (pSize < pathLength && path[pSize] == '/') {
          if (prefix.size() < pSize) {
            prefix = p;
          }
        }
      }
    }

    if (prefix.empty()) {
      LOG(TRACE) << "no prefix handler found, trying catch all";

      i = ii.find("/");
      if (i != ii.end()) {
        LOG(TRACE) << "found catch all handler '/'";

        size_t l = 1;
        size_t n = path.find_first_of('/', l);

        while (n != std::string::npos) {
          request->addSuffix(path.substr(l, n - l));
          l = n + 1;
          n = path.find_first_of('/', l);
        }

        if (l < path.size()) {
          request->addSuffix(path.substr(l));
        }

        modifiedPath = &ROOT_PATH;
        request->setPrefix(ROOT_PATH);
      }
    }

    else {
      LOG(TRACE) << "found prefix match '" << prefix << "'";

      size_t l = prefix.size() + 1;
      size_t n = path.find_first_of('/', l);

      while (n != std::string::npos) {
        request->addSuffix(path.substr(l, n - l));
        l = n + 1;
        n = path.find_first_of('/', l);
      }

      if (l < path.size()) {
        request->addSuffix(path.substr(l));
      }

      modifiedPath = &prefix;
      
      i = ii.find(prefix);
      request->setPrefix(prefix);
    }
  }

  // no match
  void* data = nullptr;

  if (i == ii.end()) {
    if (_notFound != nullptr) {
      HttpHandler* notFoundHandler = _notFound(request, data);
      notFoundHandler->setServer(this);

      return notFoundHandler;
    }

    LOG(TRACE) << "no not-found handler, giving up";
    return nullptr;
  }

  // look up data
  {
    auto const& it = _datas.find(*modifiedPath);

    if (it != _datas.end()) {
      data = (*it).second;
    }
  }

  LOG(TRACE) << "found handler for path '" << *modifiedPath << "'";
  HttpHandler* handler = i->second(request, data);

  handler->setServer(this);

  return handler;
}
Ejemplo n.º 3
0
HttpHandler* HttpHandlerFactory::createHandler (HttpRequest* request) {
  if (MaintenanceMode) {
    return new MaintenanceHandler(request);
  }

  unordered_map<string, create_fptr> const& ii = _constructors;
  string path = request->requestPath();
  auto i = ii.find(path);
  void* data = nullptr;

  // no direct match, check prefix matches
  if (i == ii.end()) {
    LOG_TRACE("no direct handler found, trying prefixes");

    // find longest match
    string prefix;
    size_t const pathLength = path.size();

    for (auto const& p : _prefixes) {
      const size_t pSize = p.size();

      if (path.compare(0, pSize, p) == 0) {
        if (pSize < pathLength && path[pSize] == '/') {
          if (prefix.size() < pSize) {
            prefix = p;
          }
        }
      }
    }

    if (prefix.empty()) {
      LOG_TRACE("no prefix handler found, trying catch all");

      i = ii.find("/");
      if (i != ii.end()) {
        LOG_TRACE("found catch all handler '/'");

        size_t l = 1;
        size_t n = path.find_first_of('/', l);

        while (n != string::npos) {
          request->addSuffix(path.substr(l, n - l));
          l = n + 1;
          n = path.find_first_of('/', l);
        }

        if (l < path.size()) {
          request->addSuffix(path.substr(l));
        }

        path = "/";
        request->setPrefix(path.c_str());
      }
    }

    else {
      LOG_TRACE("found prefix match '%s'", prefix.c_str());

      size_t l = prefix.size() + 1;
      size_t n = path.find_first_of('/', l);

      while (n != string::npos) {
        request->addSuffix(path.substr(l, n - l));
        l = n + 1;
        n = path.find_first_of('/', l);
      }

      if (l < path.size()) {
        request->addSuffix(path.substr(l));
      }

      path = prefix;
      request->setPrefix(path.c_str());

      i = ii.find(path);
    }
  }

  // no match
  if (i == ii.end()) {
    if (_notFound != nullptr) {
      HttpHandler* notFoundHandler = _notFound(request, data);
      notFoundHandler->setServer(this);

      return notFoundHandler;
    }
    else {
      LOG_TRACE("no not-found handler, giving up");
      return nullptr;
    }
  }


  // look up data
  {
    auto const& it = _datas.find(path);

    if (it != _datas.end()) {
      data = (*it).second;
    }
  }

  LOG_TRACE("found handler for path '%s'", path.c_str());
  HttpHandler* handler = i->second(request, data);

  handler->setServer(this);

  return handler;
}