<commit_before>// This file is part of the "x0" project
//   (c) 2009-2015 <NAME> <https://github.com/christianparpart>
//
// x0 is free software: you can redistribute it and/or modify it under
// the terms of the GNU Affero General Public License v3.0.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "XzeroContext.h"
#include <xzero/http/HttpRequest.h>
#include <xzero/http/HttpResponse.h>
#include <xzero/http/HttpStatus.h>
#include <xzero/net/IPAddress.h>
#include <xzero/WallClock.h>
#include <xzero/UnixTime.h>
#include <xzero/logging.h>

using namespace xzero;
using namespace xzero::http;

namespace x0d {

XzeroContext::XzeroContext(
    xzero::flow::vm::Handler* entrypoint,
    xzero::http::HttpRequest* request,
    xzero::http::HttpResponse* response)
    : runner_(entrypoint->createRunner()),
      createdAt_(now()),
      request_(request),
      response_(response),
      documentRoot_(),
      pathInfo_(),
      file_(),
      errorHandler_(nullptr) {
  runner_->setUserData(this);
  response_->onResponseEnd([this] {
    // explicitely wipe customdata before we're actually deleting the context
    clearCustomData();
    delete this;
  });
}

xzero::UnixTime XzeroContext::now() const {
  return WallClock::now();
}

xzero::Duration XzeroContext::duration() const {
  return now() - createdAt();
}

const IPAddress& XzeroContext::remoteIP() const {
  if (request_->remoteIP().isSome())
    return request_->remoteIP().get();

  RAISE(RuntimeError, "Non-IP transport channels not supported");
}

int XzeroContext::remotePort() const {
  return -1; // TODO
}

size_t XzeroContext::bytesReceived() const {
  return request_->bytesReceived();
}

size_t XzeroContext::bytesTransmitted() const {
  return response_->bytesTransmitted();
}

bool XzeroContext::verifyDirectoryDepth() {
  if (request()->directoryDepth() < 0) {
    logError("x0d", "Directory traversal detected: $0", request()->path());
    // TODO: why not throwing BadMessage here (anymore?) ?
    //throw BadMessage(HttpStatus::BadRequest, "Directory traversal detected");
    response()->setStatus(HttpStatus::BadRequest);
    response()->setReason("Directory traversal detected");
    response()->completed();
    return false;
  }
  return true;
}

void XzeroContext::onContentAvailable() {
}

void XzeroContext::onAllDataRead() {
  bool handled = runner_->run();
  if (!handled) {
    response_->setStatus(HttpStatus::NotFound);
    response_->completed();
  }
}

void XzeroContext::run() {
  if (request_->expect100Continue()) {
    response_->send100Continue(
        std::bind(&HttpInput::setListener, request_->input(), this));
  }
}<commit_msg>bugfix<commit_after>// This file is part of the "x0" project
//   (c) 2009-2015 <NAME> <https://github.com/christianparpart>
//
// x0 is free software: you can redistribute it and/or modify it under
// the terms of the GNU Affero General Public License v3.0.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "XzeroContext.h"
#include <xzero/http/HttpRequest.h>
#include <xzero/http/HttpResponse.h>
#include <xzero/http/HttpStatus.h>
#include <xzero/net/IPAddress.h>
#include <xzero/WallClock.h>
#include <xzero/UnixTime.h>
#include <xzero/logging.h>

using namespace xzero;
using namespace xzero::http;

namespace x0d {

XzeroContext::XzeroContext(
    xzero::flow::vm::Handler* entrypoint,
    xzero::http::HttpRequest* request,
    xzero::http::HttpResponse* response)
    : runner_(entrypoint->createRunner()),
      createdAt_(now()),
      request_(request),
      response_(response),
      documentRoot_(),
      pathInfo_(),
      file_(),
      errorHandler_(nullptr) {
  runner_->setUserData(this);
  response_->onResponseEnd([this] {
    // explicitely wipe customdata before we're actually deleting the context
    clearCustomData();
    delete this;
  });
}

xzero::UnixTime XzeroContext::now() const {
  return WallClock::now();
}

xzero::Duration XzeroContext::duration() const {
  return now() - createdAt();
}

const IPAddress& XzeroContext::remoteIP() const {
  if (request_->remoteIP().isSome())
    return request_->remoteIP().get();

  RAISE(RuntimeError, "Non-IP transport channels not supported");
}

int XzeroContext::remotePort() const {
  return -1; // TODO
}

size_t XzeroContext::bytesReceived() const {
  return request_->bytesReceived();
}

size_t XzeroContext::bytesTransmitted() const {
  return response_->bytesTransmitted();
}

bool XzeroContext::verifyDirectoryDepth() {
  if (request()->directoryDepth() < 0) {
    logError("x0d", "Directory traversal detected: $0", request()->path());
    // TODO: why not throwing BadMessage here (anymore?) ?
    //throw BadMessage(HttpStatus::BadRequest, "Directory traversal detected");
    response()->setStatus(HttpStatus::BadRequest);
    response()->setReason("Directory traversal detected");
    response()->completed();
    return false;
  }
  return true;
}

void XzeroContext::onContentAvailable() {
}

void XzeroContext::onAllDataRead() {
  bool handled = runner_->run();
  if (!handled) {
    response_->setStatus(HttpStatus::NotFound);
    response_->completed();
  }
}

void XzeroContext::run() {
  if (request_->expect100Continue()) {
    response_->send100Continue(
        std::bind(&HttpInput::setListener, request_->input(), this));
  } else {
    onAllDataRead();
  }
}
{'fraction_non_alphanumeric': 0.14808772883813667, 'fraction_numerical': 0.008337864781584194, 'mean_word_length': 4.4579624134520275, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 59, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7356414', 'n_tokens_mistral': 1712, 'n_tokens_neox': 1666, 'n_words': 404}