Skip to content

Commit

Permalink
v 2.5.5
Browse files Browse the repository at this point in the history
- fixed a bug when HTTP request is not standard like the wrk one.
- clean code in Socket lib
  • Loading branch information
M4iKZ committed Aug 2, 2023
1 parent 5a6c809 commit b3cbd89
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 204 deletions.
3 changes: 1 addition & 2 deletions source/Common/ISockets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ namespace Orpy
public:
virtual ~ISockets() = default;

virtual bool start(bool = false) = 0;
virtual void close(int, bool = false) = 0;
virtual bool start(bool = false) = 0;
};

extern "C"
Expand Down
307 changes: 140 additions & 167 deletions source/Parser/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ namespace Orpy
FINISH
};

std::string getKey(std::vector<char>& buffer, int& position)
{
std::string key;
while (buffer[position] != ':')
{
key.push_back(buffer[position]);

position++;
}

position += 2; //Remove : + space

return key;
}

std::string getValue(std::vector<char> buffer, int& position, bool check = false)
{
std::string Value;
Expand Down Expand Up @@ -221,203 +236,161 @@ namespace Orpy

break;
case READ_HEADERS:
if ((data->buffer[data->position] == 'H' || data->buffer[data->position] == 'h') && data->buffer[data->position + 1] == 'o' && data->buffer[data->position + 3] == 't')
{
//Host
data->position += 6;

data->request.Host = getValue(data->buffer, data->position, true);

if (!_confs->Get(data->request.Host, data->Conf))
{
data->response.status = 444;

return ERROR;
}

if (data->Conf.redirect != "")
{
data->response.status = 303;
data->response.location = data->Conf.redirect + data->request.URI;

return ERROR;
}

return READ_HEADERS;
}
else if ((data->buffer[data->position] == 'A' || data->buffer[data->position] == 'a') && data->buffer[data->position + 13] == 'n' && data->buffer[data->position + 14] == 'g')
if (data->buffer.size() - data->position < 4)
return DONE;
else if (data->buffer[data->position] == '\r' && data->buffer[data->position + 1] == '\n' && data->buffer[data->position + 2] == '\r' && data->buffer[data->position + 3] == '\n')
{
//Accept-Encoding: gzip, deflate, br
data->position += 16;

while (data->buffer[data->position] != '\r' && data->buffer[data->position + 1] != '\n')
{
if (data->buffer[data->position] == 'b' && data->buffer[data->position + 1] == 'r')
data->request.br = true;

++data->position;
}

data->position += 2; //Remove \r\n
data->position += 4;

return READ_HEADERS;
return DONE;
}
else if (data->request.isPOST && (data->buffer[data->position] == 'C' || data->buffer[data->position] == 'c') && data->buffer[data->position + 7] == '-' && data->buffer[data->position + 8] == 'T' && data->buffer[data->position + 9] == 'y' && data->buffer[data->position + 10] == 'p' && data->buffer[data->position + 11] == 'e')
else
{
// Content-Type: application/x-www-form-urlencoded
data->position += 14;

/*
0 : application/x-www-form-urlencoded
1 : multipart/form-data
2 : application/json
3 : application/xml
4 : application/pdf
5 : application/octet-stream
*/

// Content-Type: multipart/form-data; boundary=[boundary string]

if (data->buffer[data->position] == 'm' && data->buffer[data->position + 18] == 'a')
std::string key = getKey(data->buffer, data->position);
if (key == "Host")
{
data->position += 30;
//Host: localhost
data->request.Host = getValue(data->buffer, data->position, true);

if (!_confs->Get(data->request.Host, data->Conf))
{
data->response.status = 444;

data->request.isMultipart = true;
data->request.boundary = "--";
data->request.boundary += getValue(data->buffer, data->position);
}
else
{
data->request.contentType = getValue(data->buffer, data->position);
return ERROR;
}

if (data->request.contentType.find("application/x-www-form-urlencoded") != 0)
if (data->Conf.redirect != "")
{
data->request.isPOST = false;
data->response.status = 501; //not implemented
data->response.status = 303;
data->response.location = data->Conf.redirect + data->request.URI;

return ERROR;
}
}
else if (key == "User-Agent")
{
//User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
data->request.useragent = getValue(data->buffer, data->position);

return READ_HEADERS;
}
else if (data->request.isPOST && (data->buffer[data->position] == 'C' || data->buffer[data->position] == 'c') && data->buffer[data->position + 12] == 't' && data->buffer[data->position + 13] == 'h')
{
//Content-Length: 37
data->position += 16;
std::string useragent = data->request.useragent;
std::transform(useragent.begin(), useragent.end(), useragent.begin(), ::tolower); // find() is case sensitive, check lower string instead

data->request.contentLength = std::stoi(getValue(data->buffer, data->position));
if (useragent.find("bot") != std::string::npos || useragent.find("crawler") != std::string::npos || useragent.find("spider") != std::string::npos)
data->request.isBot = true;
}
else if (key == "Accept-Encoding")
{
//Accept-Encoding: gzip, deflate, br
while (data->buffer[data->position] != '\r' && data->buffer[data->position + 1] != '\n')
{
if (data->buffer[data->position] == 'b' && data->buffer[data->position + 1] == 'r')
data->request.br = true;

return READ_HEADERS;
}
else if ((data->buffer[data->position] == 'C' || data->buffer[data->position] == 'c') && data->buffer[data->position + 4] == 'i' && data->buffer[data->position + 5] == 'e')
{
//Cookie: session_id=abc123; user_id=1;
data->position += 8;
++data->position;
}

std::string value;
std::string key;
while (1)
data->position += 2; //Remove \r\n
}
else if (key == "Content-Length")
{
if (data->buffer[data->position] == '=')
//Content-Length: 37
data->request.contentLength = std::stoi(getValue(data->buffer, data->position));
}
else if (key == "Content-Type")
{
/*
0 : application/x-www-form-urlencoded
1 : multipart/form-data
2 : application/json
3 : application/xml
4 : application/pdf
5 : application/octet-stream
*/

// Content-Type: multipart/form-data; boundary=[boundary string]
if (data->buffer[data->position] == 'm' && data->buffer[data->position + 18] == 'a')
{
data->request.cookies[value] = "";
key = value;
value = "";
data->position += 30;

data->request.isMultipart = true;
data->request.boundary = "--";
data->request.boundary += getValue(data->buffer, data->position);
}
else if (data->buffer[data->position] == ';' || data->buffer[data->position] == '\r')
// Content-Type: application/x-www-form-urlencoded
else
{
data->request.cookies[key] = value;
value = "";
data->request.contentType = getValue(data->buffer, data->position);

if (data->buffer[data->position] == '\r')
break;
if (data->request.contentType.find("application/x-www-form-urlencoded") != 0)
{
data->request.isPOST = false;
data->response.status = 501; //not implemented

data->position++; //jump the space?
}
else
{
value.push_back(data->buffer[data->position]);
return ERROR;
}
}

data->position++;
}
else if (key == "Origin")
{
//Origin: http://localhost:8888
std::string url = getValue(data->buffer, data->position);
std::string http = "http://";
std::string https = "https://";

return READ_HEADERS;
}
else if ((data->buffer[data->position] == 'O' || data->buffer[data->position] == 'o') && data->buffer[data->position + 1] == 'r' && data->buffer[data->position + 2] == 'i' && data->buffer[data->position + 3] == 'g' && data->buffer[data->position + 4] == 'i' && data->buffer[data->position + 6] == ':')
{
//Origin: http://localhost:8888
data->position += 8;

std::string url = getValue(data->buffer, data->position);
std::string http = "http://";
std::string https = "https://";

if (url.find(http) == 0)
url.erase(0, http.length());
else if (url.find(https) == 0)
url.erase(0, https.length());

if (url.find(":") != std::string::npos)
url.erase(url.find(":"), 1);

data->request.Origin = url;

return READ_HEADERS;
}
else if ((data->buffer[data->position] == 'R' || data->buffer[data->position] == 'r') && data->buffer[data->position + 6] == 'r')
{
//Referer: http://localhost:8888/
data->position += 9;

data->request.Referer = getValue(data->buffer, data->position);

return READ_HEADERS;
}
else if ((data->buffer[data->position] == 'I' || data->buffer[data->position] == 'i') && data->buffer[data->position + 2] == '-' && data->buffer[data->position + 11] == '-')
{
//If-Modified-Since
data->position += 19;

data->request.fileModifiedSince = getValue(data->buffer, data->position);

return READ_HEADERS;
}
else if (data->buffer[data->position] == 'I' && data->buffer[data->position + 1] == 'P')
{
//IP
data->position += 4;

data->request.clientIP = getValue(data->buffer, data->position);

return READ_HEADERS;
}
else if ((data->buffer[data->position] == 'U' || data->buffer[data->position] == 'u') && data->buffer[data->position + 4] == '-')
{
//User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
data->position += 12;

data->request.useragent = getValue(data->buffer, data->position);
if (url.find(http) == 0)
url.erase(0, http.length());
else if (url.find(https) == 0)
url.erase(0, https.length());

std::string useragent = data->request.useragent;
std::transform(useragent.begin(), useragent.end(), useragent.begin(), ::tolower); // find() is case sensitive, check lower string instead
if (url.find(":") != std::string::npos)
url.erase(url.find(":"), 1);

if (useragent.find("bot") != std::string::npos || useragent.find("crawler") != std::string::npos || useragent.find("spider") != std::string::npos)
data->request.isBot = true;
data->request.Origin = url;
}
else if (key == "Referer")
{
//Referer: http://localhost:8888/
data->request.Referer = getValue(data->buffer, data->position);
}
else if (key == "IP")
{
//IP my nginx custom header
data->IP = getValue(data->buffer, data->position);
}
else if (key == "Cookie")
{
//Cookie: session_id=abc123; user_id=1;
std::string value;
std::string key;
while (1)
{
if (data->buffer[data->position] == '=')
{
data->request.cookies[value] = "";
key = value;
value = "";
}
else if (data->buffer[data->position] == ';' || data->buffer[data->position] == '\r')
{
data->request.cookies[key] = value;
value = "";

return READ_HEADERS;
}
else if (data->buffer[data->position] == '\r' && data->buffer[data->position + 1] == '\n' && data->buffer[data->position + 2] == '\r' && data->buffer[data->position + 3] == '\n')
{
data->position += 4;
if (data->buffer[data->position] == '\r')
break;

return DONE;
}
else
{
++data->position;
data->position++; //jump the space?
}
else
{
value.push_back(data->buffer[data->position]);
}

data->position++;
}
}
else
getValue(data->buffer, data->position);

return READ_HEADERS;
}

Expand Down
14 changes: 8 additions & 6 deletions source/Pool/Synchronization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,28 @@ namespace Orpy
public:
void push(std::unique_ptr<T> data)
{
std::lock_guard<std::mutex> lock(mut);
q.push(std::move(data));
{
std::lock_guard<std::mutex> lock(mut);
q.push(std::move(data));
}

con.notify_one();
}

std::unique_ptr<T> pop()
{
std::unique_ptr<T> data;
{
std::unique_lock<std::mutex> lock(mut);
con.wait(lock, [this]() { return !q.empty() || !isRunning; });

if (!isRunning)
return nullptr;

data = std::move(q.front());
std::unique_ptr<T> data = std::move(q.front());
q.pop();
}

return data;
return data;
}
}

bool empty() const
Expand Down
Loading

0 comments on commit b3cbd89

Please sign in to comment.