<commit_before>/* <x0/response.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 <NAME> <<EMAIL>>
 */

#include <x0/response.hpp>
#include <x0/server.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
#include <strings.h>						// strcasecmp

namespace x0 {

using boost::algorithm::iequals;

char response::status_codes[512][4];

response::~response()
{
	//DEBUG("~response(%p, conn=%p)", this, connection_.get());
	delete request_;
}

response& response::operator+=(const x0::response_header& value)
{
	headers.push_back(value);

	return *this;
}

response& response::operator*=(const x0::response_header& in)
{
	for (std::vector<x0::response_header>::iterator i = headers.begin(); i != headers.end(); ++i)
	{
#if 0
		if (iequals(i->name, in.name))
#else
		if (strcasecmp(i->name.c_str(), in.name.c_str()) == 0)
#endif
		{
			i->value = in.value;
			return *this;
		}
	}

	headers.push_back(in);
	return *this;
}


bool response::has_header(const std::string& name) const
{
	for (std::vector<x0::response_header>::const_iterator i = headers.begin(); i != headers.end(); ++i)
	{
#if 0
		if (iequals(i->name, name))
#else
		if (strcasecmp(i->name.c_str(), name.c_str()) == 0)
#endif
		{
			return true;
		}
	}

	return false;
}

std::string response::header(const std::string& name) const
{
	for (std::vector<x0::response_header>::const_iterator i = headers.begin(); i != headers.end(); ++i)
	{
		if (strcasecmp(i->name.c_str(), name.c_str()) == 0)
		{
			return i->value;
		}
	}

	return std::string();
}

const std::string& response::header(const std::string& name, const std::string& value)
{
	for (std::vector<x0::response_header>::iterator i = headers.begin(); i != headers.end(); ++i)
	{
		if (strcasecmp(i->name.c_str(), name.c_str()) == 0)
		{
			return i->value = value;
		}
	}

	headers.push_back(x0::response_header(name, value));
	return headers[headers.size() - 1].value;
}

/** checks wether given code MUST NOT have a response body. */
static inline bool content_forbidden(int code)
{
	switch (code)
	{
		case response::continue_:
		case response::switching_protocols:
		case response::no_content:
		case response::reset_content:
		case response::not_modified:
			return true;
		default:
			return false;
	}
}

composite_buffer response::serialize()
{
	composite_buffer buffers;

	if (!serializing_)
	{
		if (!status)
		{
			status = response::ok;
		}

		if (content.empty() && !content_forbidden(status))
		{
			const char *codeStr = status_cstr(status);<commit_msg>core: do generate default response content only on method GET<commit_after>/* <x0/response.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 <NAME> <<EMAIL>>
 */

#include <x0/response.hpp>
#include <x0/server.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
#include <strings.h>						// strcasecmp

namespace x0 {

using boost::algorithm::iequals;

char response::status_codes[512][4];

response::~response()
{
	//DEBUG("~response(%p, conn=%p)", this, connection_.get());
	delete request_;
}

response& response::operator+=(const x0::response_header& value)
{
	headers.push_back(value);

	return *this;
}

response& response::operator*=(const x0::response_header& in)
{
	for (std::vector<x0::response_header>::iterator i = headers.begin(); i != headers.end(); ++i)
	{
#if 0
		if (iequals(i->name, in.name))
#else
		if (strcasecmp(i->name.c_str(), in.name.c_str()) == 0)
#endif
		{
			i->value = in.value;
			return *this;
		}
	}

	headers.push_back(in);
	return *this;
}


bool response::has_header(const std::string& name) const
{
	for (std::vector<x0::response_header>::const_iterator i = headers.begin(); i != headers.end(); ++i)
	{
#if 0
		if (iequals(i->name, name))
#else
		if (strcasecmp(i->name.c_str(), name.c_str()) == 0)
#endif
		{
			return true;
		}
	}

	return false;
}

std::string response::header(const std::string& name) const
{
	for (std::vector<x0::response_header>::const_iterator i = headers.begin(); i != headers.end(); ++i)
	{
		if (strcasecmp(i->name.c_str(), name.c_str()) == 0)
		{
			return i->value;
		}
	}

	return std::string();
}

const std::string& response::header(const std::string& name, const std::string& value)
{
	for (std::vector<x0::response_header>::iterator i = headers.begin(); i != headers.end(); ++i)
	{
		if (strcasecmp(i->name.c_str(), name.c_str()) == 0)
		{
			return i->value = value;
		}
	}

	headers.push_back(x0::response_header(name, value));
	return headers[headers.size() - 1].value;
}

/** checks wether given code MUST NOT have a response body. */
static inline bool content_forbidden(int code)
{
	switch (code)
	{
		case response::continue_:
		case response::switching_protocols:
		case response::no_content:
		case response::reset_content:
		case response::not_modified:
			return true;
		default:
			return false;
	}
}

composite_buffer response::serialize()
{
	composite_buffer buffers;

	if (!serializing_)
	{
		if (!status)
		{
			status = response::ok;
		}

		if (content.empty() && !content_forbidden(status) && equals(request_->method, "GET"))
		{
			const char *codeStr = status_cstr(status);
{'fraction_non_alphanumeric': 0.1785513756316676, 'fraction_numerical': 0.011229646266142616, 'mean_word_length': 4.578288100208768, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 54, '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': '5406520', 'n_tokens_mistral': 2085, 'n_tokens_neox': 1950, 'n_words': 430}