<commit_before>/**
 * Copyright (c) 2016 DeepCortex GmbH <<EMAIL>>
 * Authors:
 *   - <NAME> <<EMAIL>>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include <thread>

#include "eventql/eventql.h"
#include "eventql/transport/http/api_servlet.h"
#include "eventql/util/Language.h"
#include "eventql/util/human.h"
#include "eventql/util/wallclock.h"
#include "eventql/util/io/fileutil.h"
#include "eventql/util/util/Base64.h"
#include "eventql/util/logging.h"
#include "eventql/util/assets.h"
#include "eventql/util/protobuf/msg.h"
#include "eventql/util/http/cookies.h"
#include "eventql/util/protobuf/DynamicMessage.h"
#include "eventql/util/protobuf/MessageEncoder.h"
#include "eventql/util/csv/CSVInputStream.h"
#include "eventql/util/csv/BinaryCSVInputStream.h"
#include "eventql/db/table_config.pb.h"
#include "eventql/server/sql/codec/json_codec.h"
#include "eventql/server/sql/codec/json_sse_codec.h"
#include "eventql/server/sql/codec/binary_codec.h"
#include "eventql/transport/http/http_auth.h"
#include <eventql/io/cstable/cstable_writer.h>
#include <eventql/io/cstable/RecordShredder.h>

namespace eventql {

APIServlet::APIServlet(Database* db) : db_(db) {}

void APIServlet::handleHTTPRequest(
    RefPtr<http::HTTPRequestStream> req_stream,
    RefPtr<http::HTTPResponseStream> res_stream) {
  try {
    handle(req_stream, res_stream);
  } catch (const StandardException& e) {
    logError("eventql", e, "error while handling HTTP request");
    req_stream->discardBody();

    http::HTTPResponse res;
    res.populateFromRequest(req_stream->request());
    res.setStatus(http::kStatusInternalServerError);
    res.addHeader("Content-Type", "text/html; charset=utf-8");
    res.addBody(Assets::getAsset("eventql/webui/500.html"));
    res_stream->writeResponse(res);
  }
}

void APIServlet::handle(
    RefPtr<http::HTTPRequestStream> req_stream,
    RefPtr<http::HTTPResponseStream> res_stream) {
  const auto& req = req_stream->request();
  URI uri(req.uri());

  logDebug("eventql", "HTTP Request: $0 $1", req.method(), req.uri());
  auto session = db_->getSession();
  auto dbctx = session->getDatabaseContext();

  http::HTTPResponse res;
  res.populateFromRequest(req);
  res.addHeader("Access-Control-Allow-Origin", "*");
  res.addHeader("Access-Control-Allow-Methods", "GET, POST");
  res.addHeader("Access-Control-Allow-Headers", "Authorization");

  if (req.method() == http::HTTPMessage::M_OPTIONS) {
    req_stream->readBody();
    res.setStatus(http::kStatusOK);
    res_stream->writeResponse(res);
    return;
  }

  auto auth_rc = HTTPAuth::authenticateRequest(
        session,
        dbctx->client_auth,
        req);

  if (!auth_rc.isSuccess()) {
    res.setStatus(http::kStatusForbidden);
    res.addHeader("WWW-Authenticate", "Token");
    res.addHeader("Content-Type", "text/plain; charset=utf-8");
    res.addBody(auth_rc.message());
    res_stream->writeResponse(res);
    return;
  }

  if (session->getEffectiveNamespace().empty() &&
      !dbctx->config->getBool("cluster.allow_anonymous")) {<commit_msg>don't return 403 if cluster.allow_anonymous is true<commit_after>/**
 * Copyright (c) 2016 DeepCortex GmbH <<EMAIL>>
 * Authors:
 *   - <NAME> <<EMAIL>>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include <thread>

#include "eventql/eventql.h"
#include "eventql/transport/http/api_servlet.h"
#include "eventql/util/Language.h"
#include "eventql/util/human.h"
#include "eventql/util/wallclock.h"
#include "eventql/util/io/fileutil.h"
#include "eventql/util/util/Base64.h"
#include "eventql/util/logging.h"
#include "eventql/util/assets.h"
#include "eventql/util/protobuf/msg.h"
#include "eventql/util/http/cookies.h"
#include "eventql/util/protobuf/DynamicMessage.h"
#include "eventql/util/protobuf/MessageEncoder.h"
#include "eventql/util/csv/CSVInputStream.h"
#include "eventql/util/csv/BinaryCSVInputStream.h"
#include "eventql/db/table_config.pb.h"
#include "eventql/server/sql/codec/json_codec.h"
#include "eventql/server/sql/codec/json_sse_codec.h"
#include "eventql/server/sql/codec/binary_codec.h"
#include "eventql/transport/http/http_auth.h"
#include <eventql/io/cstable/cstable_writer.h>
#include <eventql/io/cstable/RecordShredder.h>

namespace eventql {

APIServlet::APIServlet(Database* db) : db_(db) {}

void APIServlet::handleHTTPRequest(
    RefPtr<http::HTTPRequestStream> req_stream,
    RefPtr<http::HTTPResponseStream> res_stream) {
  try {
    handle(req_stream, res_stream);
  } catch (const StandardException& e) {
    logError("eventql", e, "error while handling HTTP request");
    req_stream->discardBody();

    http::HTTPResponse res;
    res.populateFromRequest(req_stream->request());
    res.setStatus(http::kStatusInternalServerError);
    res.addHeader("Content-Type", "text/html; charset=utf-8");
    res.addBody(Assets::getAsset("eventql/webui/500.html"));
    res_stream->writeResponse(res);
  }
}

void APIServlet::handle(
    RefPtr<http::HTTPRequestStream> req_stream,
    RefPtr<http::HTTPResponseStream> res_stream) {
  const auto& req = req_stream->request();
  URI uri(req.uri());

  logDebug("eventql", "HTTP Request: $0 $1", req.method(), req.uri());
  auto session = db_->getSession();
  auto dbctx = session->getDatabaseContext();

  http::HTTPResponse res;
  res.populateFromRequest(req);
  res.addHeader("Access-Control-Allow-Origin", "*");
  res.addHeader("Access-Control-Allow-Methods", "GET, POST");
  res.addHeader("Access-Control-Allow-Headers", "Authorization");

  if (req.method() == http::HTTPMessage::M_OPTIONS) {
    req_stream->readBody();
    res.setStatus(http::kStatusOK);
    res_stream->writeResponse(res);
    return;
  }

  auto auth_rc = HTTPAuth::authenticateRequest(
        session,
        dbctx->client_auth,
        req);

  if (!auth_rc.isSuccess() &&
      !dbctx->config->getBool("cluster.allow_anonymous")) {
    res.setStatus(http::kStatusForbidden);
    res.addHeader("WWW-Authenticate", "Token");
    res.addHeader("Content-Type", "text/plain; charset=utf-8");
    res.addBody(auth_rc.message());
    res_stream->writeResponse(res);
    return;
  }

  if (session->getEffectiveNamespace().empty() &&
      !dbctx->config->getBool("cluster.allow_anonymous")) {
{'fraction_non_alphanumeric': 0.13348192174343734, 'fraction_numerical': 0.004086181277860327, 'mean_word_length': 4.773409578270193, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '920845', 'n_tokens_mistral': 2580, 'n_tokens_neox': 2527, 'n_words': 613}