[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/stjordanis/expresscpp/master/src/layer.cpp [Back]  [Original]

#include "expresscpp/layer.hpp"

#include 

#include "boost/uuid/uuid_generators.hpp"
#include "boost/uuid/uuid_io.hpp"
#include "expresscpp/console.hpp"
#include "expresscpp/impl/utils.hpp"
#include "expresscpp/path_to_regexp.hpp"

namespace expresscpp {

Layer::Layer(const std::string_view registered_path) {
  path_ = registered_path;
  Init();
  PathToRegExpOptions default_options;
  regexp_ = pathToRegExpString(path_, keys_, default_options);
}

Layer::Layer(const std::string_view registered_path, PathToRegExpOptions options, std::string_view parent_path,
             handler_wn_t handler)
    : handler_(handler) {
  path_ = registered_path;
  Init();

  options_ = options;
  regexp_ = pathToRegExpString(path_, keys_, options, parent_path);
}

Layer::Layer(const std::string_view registered_path, PathToRegExpOptions options, std::string_view parent_path,
             handler_t handler)
    : handler_(handler) {
  path_ = registered_path;
  Init();

  options_ = options;
  regexp_ = pathToRegExpString(path_, keys_, options, parent_path);
}

void Layer::SetParentPath(const std::string_view parent_path) {
  regexp_ = pathToRegExpString(path_, keys_, options_, parent_path);
}

void Layer::Init() {
  uuid_ = boost::uuids::random_generator()();
  Console::Debug(fmt::format(R"(Layer created for path: "{}", uuid: "{}")", path_, boostUUIDToString(uuid_)));
}

std::vector Layer::GetKeys() const {
  return keys_;
}

void Layer::SetKeys(const std::vector &keys) {
  keys_ = keys;
}

const std::string_view Layer::GetPath() const {
  return path_;
}

std::map Layer::ParseQueryString(std::string_view requested_path, size_t key_start_pos) {
  size_t param_pair_end_pos = 0;
  size_t equal_sign_pos = 0;
  std::map result;
  while (equal_sign_pos != std::string::npos) {
    equal_sign_pos = requested_path.find("=", equal_sign_pos + 1);
    param_pair_end_pos = requested_path.find("&", param_pair_end_pos + 1);
    if (equal_sign_pos < param_pair_end_pos) {
      auto key = requested_path.substr(key_start_pos + 1, equal_sign_pos - key_start_pos - 1);
      key_start_pos = requested_path.find("&", key_start_pos + 1);
      auto value = requested_path.substr(equal_sign_pos + 1, key_start_pos - equal_sign_pos - 1);
      result.insert({std::string(key), std::string(value)});
    }
  }
  return result;
}

bool Layer::Match(std::shared_ptr request) {
  if (request->getPath().empty()) {
    return false;
  }
  auto requested_path = request->getPath();
  const auto query_param_pos = requested_path.find("?");
  if (query_param_pos != std::string::npos) {
    request->SetQueryParams(ParseQueryString(requested_path, query_param_pos));
    request->SetQueryString(requested_path.substr(query_param_pos + 1).data());
  }
  std::string current_path;
  current_path = requested_path.substr(0, query_param_pos);
  std::smatch smatch;
  bool match = std::regex_search(current_path, smatch, regexp_);
  if (smatch.size() > 1) {
    std::map params;
    for (const auto &key : keys_) {
      auto val = smatch[key.index_ + 1].str();
      Console::Debug(fmt::format(R"(val, "{}")", val));
      params.insert({key.name_, val});
    }
    request->SetParams(params);
  }
  return match;
}

void Layer::HandleRequest(request_t req, response_t res, next_t next) {
  Console::Debug("Layer handling request");
  if (route_ == nullptr) {
    if (handler_.getWith_next()) {
      handler_(req, res, next);
    } else {
      handler_(req, res);
    }
  } else {
    route_->Dispatch(req, res, next);
  }
}

std::shared_ptr Layer::GetRoute() const {
  return route_;
}

void Layer::SetRoute(const std::shared_ptr &new_route) {
  route_ = new_route;
}

HttpMethod Layer::GetMethod() const {
  return method_;
}

void Layer::SetMethod(const HttpMethod &method) {
  method_ = method;
}

}  // namespace expresscpp

Web Proxy Viewer  |  New URL  |  Original Page