<commit_before>#include "Common.h"
#include "SSEChannel.h"
#include "SSEClient.h"
#include "SSEClientHandler.h"
#include "SSEEvent.h"
#include "SSEConfig.h"
#include "HTTPRequest.h"
#include "HTTPResponse.h"
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

using namespace std;
extern int stop;

/**
  Constructor.
  @param conf Pointer to SSEConfig instance holding our configuration.
  @param id Unique identifier for this channel.
*/
SSEChannel::SSEChannel(ChannelConfig conf, string id) {
  _config = conf;
  _config.id = id;

  _efd = epoll_create1(0);
  LOG_IF(FATAL, _efd == -1) << "epoll_create1 failed.";

  // Initialize counters.
  _stats.num_clients            = 0;
  _stats.num_connects           = 0;
  _stats.num_disconnects        = 0;
  _stats.num_errors             = 0;
  _stats.num_cached_events      = 0;
  _stats.num_broadcasted_events = 0;
  _stats.cache_size             = _config.cacheLength;


  LOG(INFO) << "Initializing channel " << _config.id;
  LOG(INFO) << "Cache Adapter: " << _config.cacheAdapter;
  LOG(INFO) << "Cache length: " << _config.cacheLength;
  LOG(INFO) << "Threads per channel: " << _config.server->GetValue("server.threadsPerChannel");

  _allow_all_origins = (_config.allowedOrigins.size() < 1) ? true : false;

  BOOST_FOREACH(const std::string& origin, _config.allowedOrigins) {
    DLOG(INFO) << "Allowed origin: " << origin;
  }

  // Internet Explorer has a problem receiving data when using XDomainRequest before it has received 2KB of data.
  // The polyfills that account for this send a query parameter, evs_preamble to inform the server about this so it can respond with some initial data.
  // Initialize a buffer containing our response for this case.
  _evs_preamble_data[0] = ':';
  for (int i = 1; i <= 2048; i++) { _evs_preamble_data[i] = '.'; }
  _evs_preamble_data[2049] = '\n';
  _evs_preamble_data[2050] = '\n';
  _evs_preamble_data[2051] = '\0';

  InitializeCache();
  InitializeThreads();
}

/**
  Destructor.
*/
SSEChannel::~SSEChannel() {
  DLOG(INFO) << "SSEChannel destructor called.";
  CleanupThreads();
}

/*
  Initialize the configured cacheadapter for this channel
*/
void SSEChannel::InitializeCache() {
  const string adapter = _config.cacheAdapter;
  if (adapter == "redis") {
    _cache_adapter = new Redis(_config.id, _config);
  } else if (adapter == "memory") {
    _cache_adapter = new Memory(_config);
  } else if (adapter == "leveldb") {
    _cache_adapter = new LevelDB(_config);
  }

  if (_cache_adapter) {
    _stats.num_cached_events = _cache_adapter->GetSizeOfCachedEvents();
  }
}

/**
  Initialize client handler threads and also the thread that
  pings all connected clients on _config.red interval.
*/
void SSEChannel::InitializeThreads() {
  int i;

  _cleanupthread = boost::thread(boost::bind(&SSEChannel::CleanupMain, this));

  for (i = 0; i < _config.server->GetValueInt("server.threadsPerChannel"); i++) {
    _clientpool.push_back(ClientHandlerPtr(new SSEClientHandler(i)));
  }

  curthread = _clientpool.begin();
  _pingthread = boost::thread(boost::bind(&SSEChannel::Ping, this));
}

/**
  Stop and free up all running threads.
  Called by destructor.
*/
void SSEChannel::CleanupThreads() {
  pthread_cancel(_pingthread.native_handle());
  pthread_cancel(_cleanupthread.native_handle());
}

/**
  Return the id of this channel.
*/
string SSEChannel::GetId() {
  return _config.id;
}

/**
 Set correct CORS headers.
 @param req Request object.
 @param res Response object.
*/
void SSEChannel::SetCorsHeaders(HTTPRequest* req, HTTPResponse& res) {
  // Set allowed headers for the EventSource IE polyfill
  res.SetHeader("Access-Control-Allow-Headers", "X-Requested-With, Last-Event-ID");

  if (_allow_all_origins) {
    DLOG(INFO) << "All origins allowed.";
    res.SetHeader("Access-Control-Allow-Origin", "*");
    return;
  }
<commit_msg>Added Accept and cache-control to allowed headers<commit_after>#include "Common.h"
#include "SSEChannel.h"
#include "SSEClient.h"
#include "SSEClientHandler.h"
#include "SSEEvent.h"
#include "SSEConfig.h"
#include "HTTPRequest.h"
#include "HTTPResponse.h"
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

using namespace std;
extern int stop;

/**
  Constructor.
  @param conf Pointer to SSEConfig instance holding our configuration.
  @param id Unique identifier for this channel.
*/
SSEChannel::SSEChannel(ChannelConfig conf, string id) {
  _config = conf;
  _config.id = id;

  _efd = epoll_create1(0);
  LOG_IF(FATAL, _efd == -1) << "epoll_create1 failed.";

  // Initialize counters.
  _stats.num_clients            = 0;
  _stats.num_connects           = 0;
  _stats.num_disconnects        = 0;
  _stats.num_errors             = 0;
  _stats.num_cached_events      = 0;
  _stats.num_broadcasted_events = 0;
  _stats.cache_size             = _config.cacheLength;


  LOG(INFO) << "Initializing channel " << _config.id;
  LOG(INFO) << "Cache Adapter: " << _config.cacheAdapter;
  LOG(INFO) << "Cache length: " << _config.cacheLength;
  LOG(INFO) << "Threads per channel: " << _config.server->GetValue("server.threadsPerChannel");

  _allow_all_origins = (_config.allowedOrigins.size() < 1) ? true : false;

  BOOST_FOREACH(const std::string& origin, _config.allowedOrigins) {
    DLOG(INFO) << "Allowed origin: " << origin;
  }

  // Internet Explorer has a problem receiving data when using XDomainRequest before it has received 2KB of data.
  // The polyfills that account for this send a query parameter, evs_preamble to inform the server about this so it can respond with some initial data.
  // Initialize a buffer containing our response for this case.
  _evs_preamble_data[0] = ':';
  for (int i = 1; i <= 2048; i++) { _evs_preamble_data[i] = '.'; }
  _evs_preamble_data[2049] = '\n';
  _evs_preamble_data[2050] = '\n';
  _evs_preamble_data[2051] = '\0';

  InitializeCache();
  InitializeThreads();
}

/**
  Destructor.
*/
SSEChannel::~SSEChannel() {
  DLOG(INFO) << "SSEChannel destructor called.";
  CleanupThreads();
}

/*
  Initialize the configured cacheadapter for this channel
*/
void SSEChannel::InitializeCache() {
  const string adapter = _config.cacheAdapter;
  if (adapter == "redis") {
    _cache_adapter = new Redis(_config.id, _config);
  } else if (adapter == "memory") {
    _cache_adapter = new Memory(_config);
  } else if (adapter == "leveldb") {
    _cache_adapter = new LevelDB(_config);
  }

  if (_cache_adapter) {
    _stats.num_cached_events = _cache_adapter->GetSizeOfCachedEvents();
  }
}

/**
  Initialize client handler threads and also the thread that
  pings all connected clients on _config.red interval.
*/
void SSEChannel::InitializeThreads() {
  int i;

  _cleanupthread = boost::thread(boost::bind(&SSEChannel::CleanupMain, this));

  for (i = 0; i < _config.server->GetValueInt("server.threadsPerChannel"); i++) {
    _clientpool.push_back(ClientHandlerPtr(new SSEClientHandler(i)));
  }

  curthread = _clientpool.begin();
  _pingthread = boost::thread(boost::bind(&SSEChannel::Ping, this));
}

/**
  Stop and free up all running threads.
  Called by destructor.
*/
void SSEChannel::CleanupThreads() {
  pthread_cancel(_pingthread.native_handle());
  pthread_cancel(_cleanupthread.native_handle());
}

/**
  Return the id of this channel.
*/
string SSEChannel::GetId() {
  return _config.id;
}

/**
 Set correct CORS headers.
 @param req Request object.
 @param res Response object.
*/
void SSEChannel::SetCorsHeaders(HTTPRequest* req, HTTPResponse& res) {
  // Set allowed headers for the EventSource IE polyfill
  res.SetHeader("Access-Control-Allow-Headers", "Accept, Cache-Control, X-Requested-With, Last-Event-ID");

  if (_allow_all_origins) {
    DLOG(INFO) << "All origins allowed.";
    res.SetHeader("Access-Control-Allow-Origin", "*");
    return;
  }

{'fraction_non_alphanumeric': 0.13273771537970644, 'fraction_numerical': 0.00816847479259732, 'mean_word_length': 4.104885993485342, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 15, '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': '2596887', 'n_tokens_mistral': 2667, 'n_tokens_neox': 2606, 'n_words': 638}