<commit_before>#include "HttpRequest.h"

#include <QBuffer>
#include <QTcpSocket>

namespace FastCgiQt
{
	HttpRequest::HttpRequest(QTcpSocket* socket, QObject* parent)
	: ClientIODevice(parent)
	, m_requestState(WaitingForRequest)
	, m_responseState(WaitingForResponseHeaders)
	, m_socket(socket)
	{
		open(QIODevice::ReadWrite | QIODevice::Unbuffered);
		socket->setParent(this);
		Q_ASSERT(socket->isOpen());
		Q_ASSERT(socket->isWritable());
		Q_ASSERT(socket->isReadable());
		connect(
			socket,
			SIGNAL(readyRead()),
			this,
			SLOT(readSocketData())
		);
	}

	HttpRequest::~HttpRequest()
	{
		m_socket->flush();
		m_socket->close();
	}

	ClientIODevice::HeaderMap HttpRequest::requestHeaders() const
	{
		return m_requestHeaders;
	}

	void HttpRequest::readSocketData()
	{
		if(m_requestState == WaitingForRequest)
		{
			if(!m_socket->canReadLine())
			{
				return;
			}
			const QByteArray line = m_socket->readLine();
			const QList<QByteArray> parts = line.split(' ');
			Q_ASSERT(parts.count() == 3);
			m_requestHeaders.insert("REQUEST_METHOD", parts.at(0));
			m_requestHeaders.insert("SERVER_PROTOCOL", parts.at(2));
			const QByteArray uri = parts.at(1);
			m_requestHeaders.insert("REQUEST_URI", uri);
			m_requestHeaders.insert("QUERY_STRING", uri.mid(uri.indexOf('?') + 1));
			m_requestState = WaitingForRequestHeaders;
			readSocketData();
			return;
		}
		if(m_requestState == WaitingForRequestHeaders)
		{
			while(m_socket->canReadLine())
			{
				const QByteArray line = m_socket->readLine().trimmed();
				if(line.isEmpty())
				{
					m_requestState = WaitingForRequestBody;
					emit gotHeaders(this);
					readSocketData();
					return;
				}
				const int lengthOfName = line.indexOf(':');
				const QByteArray name = line.left(lengthOfName);
				const QByteArray value = line.mid(lengthOfName + 2); // ": " after the name == 2 chars
				qDebug() << "REQUEST HEADER" << name << value;
				m_requestHeaders.insert(name, value);
			}
			return;
		}
		emit readyRead();
	}

	qint64 HttpRequest::readData(char* data, qint64 maxSize)
	{
		Q_ASSERT(m_requestState == WaitingForRequestBody);
		return m_socket->read(data, maxSize);
	}

	qint64 HttpRequest::writeData(const char* data, qint64 maxSize)
	{
		if(m_responseState == WaitingForResponseHeaders)
		{
			// We need to buffer the headers, so we can use the STATUS header appropriately
			QBuffer buffer;
			buffer.setData(data, maxSize);
			buffer.open(QIODevice::ReadOnly);
			while(buffer.canReadLine())
			{
				const QByteArray line = buffer.readLine().trimmed();
				if(line.isEmpty())
				{
					Q_ASSERT(m_responseHeaders.contains("STATUS"));
					Q_ASSERT(m_requestHeaders.contains("SERVER_PROTOCOL"));
					m_responseState = WaitingForResponseBody;
					const QByteArray status = m_responseHeaders.take("STATUS");
					qDebug() << "Responding with status" << status;
					m_socket->write(m_requestHeaders.value("SERVER_PROTOCOL"));
					m_socket->write(" ", 1);
					m_socket->write(status);
					m_socket->write("\r\n", 2);

					for(
						HeaderMap::ConstIterator it = m_responseHeaders.constBegin();
						it != m_responseHeaders.constEnd();
						++it
					)
					{
						m_socket->write(it.key());
						m_socket->write(": ");
						m_socket->write(it.value());
						m_socket->write("\r\n");
					}
					m_socket->write("\r\n");
					m_socket->write(buffer.readAll());
					return maxSize;
				}
				const int lengthOfName = line.indexOf(':');
				const QByteArray name = line.left(lengthOfName);
				const QByteArray value = line.mid(lengthOfName + 2); // ": " after the name == 2 chars
				qDebug() << "RESPONSE HEADER:" << name << value;
				m_responseHeaders.insert(name, value);
			}
			return maxSize;
		}
		Q_ASSERT(m_responseState == WaitingForResponseBody);
		return m_socket->write(data, maxSize);
	}<commit_msg>remove some debugging spam<commit_after>#include "HttpRequest.h"

#include <QBuffer>
#include <QTcpSocket>

namespace FastCgiQt
{
	HttpRequest::HttpRequest(QTcpSocket* socket, QObject* parent)
	: ClientIODevice(parent)
	, m_requestState(WaitingForRequest)
	, m_responseState(WaitingForResponseHeaders)
	, m_socket(socket)
	{
		open(QIODevice::ReadWrite | QIODevice::Unbuffered);
		socket->setParent(this);
		Q_ASSERT(socket->isOpen());
		Q_ASSERT(socket->isWritable());
		Q_ASSERT(socket->isReadable());
		connect(
			socket,
			SIGNAL(readyRead()),
			this,
			SLOT(readSocketData())
		);
	}

	HttpRequest::~HttpRequest()
	{
		m_socket->flush();
		m_socket->close();
	}

	ClientIODevice::HeaderMap HttpRequest::requestHeaders() const
	{
		return m_requestHeaders;
	}

	void HttpRequest::readSocketData()
	{
		if(m_requestState == WaitingForRequest)
		{
			if(!m_socket->canReadLine())
			{
				return;
			}
			const QByteArray line = m_socket->readLine();
			const QList<QByteArray> parts = line.split(' ');
			Q_ASSERT(parts.count() == 3);
			m_requestHeaders.insert("REQUEST_METHOD", parts.at(0));
			m_requestHeaders.insert("SERVER_PROTOCOL", parts.at(2));
			const QByteArray uri = parts.at(1);
			m_requestHeaders.insert("REQUEST_URI", uri);
			m_requestHeaders.insert("QUERY_STRING", uri.mid(uri.indexOf('?') + 1));
			m_requestState = WaitingForRequestHeaders;
			readSocketData();
			return;
		}
		if(m_requestState == WaitingForRequestHeaders)
		{
			while(m_socket->canReadLine())
			{
				const QByteArray line = m_socket->readLine().trimmed();
				if(line.isEmpty())
				{
					m_requestState = WaitingForRequestBody;
					emit gotHeaders(this);
					readSocketData();
					return;
				}
				const int lengthOfName = line.indexOf(':');
				const QByteArray name = line.left(lengthOfName);
				const QByteArray value = line.mid(lengthOfName + 2); // ": " after the name == 2 chars
				m_requestHeaders.insert(name, value);
			}
			return;
		}
		emit readyRead();
	}

	qint64 HttpRequest::readData(char* data, qint64 maxSize)
	{
		Q_ASSERT(m_requestState == WaitingForRequestBody);
		return m_socket->read(data, maxSize);
	}

	qint64 HttpRequest::writeData(const char* data, qint64 maxSize)
	{
		if(m_responseState == WaitingForResponseHeaders)
		{
			// We need to buffer the headers, so we can use the STATUS header appropriately
			QBuffer buffer;
			buffer.setData(data, maxSize);
			buffer.open(QIODevice::ReadOnly);
			while(buffer.canReadLine())
			{
				const QByteArray line = buffer.readLine().trimmed();
				if(line.isEmpty())
				{
					Q_ASSERT(m_responseHeaders.contains("STATUS"));
					Q_ASSERT(m_requestHeaders.contains("SERVER_PROTOCOL"));
					m_responseState = WaitingForResponseBody;
					const QByteArray status = m_responseHeaders.take("STATUS");
					m_socket->write(m_requestHeaders.value("SERVER_PROTOCOL"));
					m_socket->write(" ", 1);
					m_socket->write(status);
					m_socket->write("\r\n", 2);

					for(
						HeaderMap::ConstIterator it = m_responseHeaders.constBegin();
						it != m_responseHeaders.constEnd();
						++it
					)
					{
						m_socket->write(it.key());
						m_socket->write(": ");
						m_socket->write(it.value());
						m_socket->write("\r\n");
					}
					m_socket->write("\r\n");
					m_socket->write(buffer.readAll());
					return maxSize;
				}
				const int lengthOfName = line.indexOf(':');
				const QByteArray name = line.left(lengthOfName);
				const QByteArray value = line.mid(lengthOfName + 2); // ": " after the name == 2 chars
				m_responseHeaders.insert(name, value);
			}
			return maxSize;
		}
		Q_ASSERT(m_responseState == WaitingForResponseBody);
		return m_socket->write(data, maxSize);
	}
{'fraction_non_alphanumeric': 0.144, 'fraction_numerical': 0.005066666666666666, 'mean_word_length': 4.0477792732166895, 'pattern_counts': {'":': 6, '<': 25, '<?xml version=': 0, '>': 53, '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': '1071438', 'n_tokens_mistral': 3063, 'n_tokens_neox': 2514, 'n_words': 426}