summaryrefslogtreecommitdiff
path: root/src/net/HttpParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/HttpParser.cpp')
-rw-r--r--src/net/HttpParser.cpp314
1 files changed, 150 insertions, 164 deletions
diff --git a/src/net/HttpParser.cpp b/src/net/HttpParser.cpp
index 3dd9215..41dec14 100644
--- a/src/net/HttpParser.cpp
+++ b/src/net/HttpParser.cpp
@@ -31,182 +31,168 @@ using namespace boost;
namespace TgBot {
-HttpParser& HttpParser::getInstance() {
- static HttpParser result;
- return result;
+string HttpParser::generateRequest(const Url& url, const vector<HttpReqArg>& args, bool isKeepAlive) const {
+ string result;
+ if (args.empty()) {
+ result += "GET ";
+ } else {
+ result += "POST ";
+ }
+ result += url.path;
+ result += url.query.empty() ? "" : "?" + url.query;
+ result += " HTTP/1.1\r\n";
+ result += "Host: ";
+ result += url.host;
+ result += "\r\nConnection: ";
+ if (isKeepAlive) {
+ result += "keep-alive";
+ } else {
+ result += "close";
+ }
+ result += "\r\n";
+ if (args.empty()) {
+ result += "\r\n";
+ } else {
+ string requestData;
+
+ string bondary = generateMultipartBoundary(args);
+ if (bondary.empty()) {
+ result += "Content-Type: application/x-www-form-urlencoded\r\n";
+ requestData = generateWwwFormUrlencoded(args);
+ } else {
+ result += "Content-Type: multipart/form-data; boundary=";
+ result += bondary;
+ result += "\r\n";
+ requestData = generateMultipartFormData(args, bondary);
+ }
+
+ result += "Content-Length: ";
+ result += std::to_string(requestData.length());
+ result += "\r\n\r\n";
+ result += requestData;
+ }
+ return result;
}
-string HttpParser::generateRequest(const Url& url, const vector<HttpReqArg>& args, bool isKeepAlive) {
- string result;
- if (args.empty()) {
- result += "GET ";
- } else {
- result += "POST ";
- }
- result += url.path;
- result += url.query.empty() ? "" : "?" + url.query;
- result += " HTTP/1.1\r\n";
- result += "Host: ";
- result += url.host;
- result += "\r\nConnection: ";
- if (isKeepAlive) {
- result += "keep-alive";
- } else {
- result += "close";
- }
- result += "\r\n";
- if (args.empty()) {
- result += "\r\n";
- } else {
- string requestData;
-
- string bondary = generateMultipartBoundary(args);
- if (bondary.empty()) {
- result += "Content-Type: application/x-www-form-urlencoded\r\n";
- requestData = generateWwwFormUrlencoded(args);
- } else {
- result += "Content-Type: multipart/form-data; boundary=";
- result += bondary;
- result += "\r\n";
- requestData = generateMultipartFormData(args, bondary);
- }
-
- result += "Content-Length: ";
- result += lexical_cast<string>(requestData.length());
- result += "\r\n\r\n";
- result += requestData;
- }
- return result;
+string HttpParser::generateMultipartFormData(const vector<HttpReqArg>& args, const string& bondary) const {
+ string result;
+ for (const HttpReqArg& item : args) {
+ result += "--";
+ result += bondary;
+ result += "\r\nContent-Disposition: form-data; name=\"";
+ result += item.name;
+ if (item.isFile) {
+ result += "\"; filename=\"" + item.fileName;
+ }
+ result += "\"\r\n";
+ if (item.isFile) {
+ result += "Content-Type: ";
+ result += item.mimeType;
+ result += "\r\n";
+ }
+ result += "\r\n";
+ result += item.value;
+ result += "\r\n";
+ }
+ result += "--" + bondary + "--\r\n";
+ return result;
}
-string HttpParser::generateMultipartFormData(const vector<HttpReqArg>& args, const string& bondary) {
- string result;
- for (const HttpReqArg& item : args) {
- result += "--";
- result += bondary;
- result += "\r\nContent-Disposition: form-data; name=\"";
- result += item.name;
- if (item.isFile) {
- result += "\"; filename=\"" + item.fileName;
- }
- result += "\"\r\n";
- if (item.isFile) {
- result += "Content-Type: ";
- result += item.mimeType;
- result += "\r\n";
- }
- result += "\r\n";
- result += item.value;
- result += "\r\n";
- }
- result += "--" + bondary + "--\r\n";
- return result;
+string HttpParser::generateMultipartBoundary(const vector<HttpReqArg>& args) const {
+ string result;
+ srand((unsigned int) time(nullptr));
+ for (const HttpReqArg& item : args) {
+ if (item.isFile) {
+ while (result.empty() || item.value.find(result) != string::npos) {
+ result += StringTools::generateRandomString(4);
+ }
+ }
+ }
+ return result;
}
-string HttpParser::generateMultipartBoundary(const vector<HttpReqArg>& args) {
- string result;
- srand((unsigned int) time(nullptr));
- for (const HttpReqArg& item : args) {
- if (item.isFile) {
- while (result.empty() || item.value.find(result) != item.value.npos) {
- result += StringTools::generateRandomString(4);
- }
- }
- }
- return result;
+string HttpParser::generateWwwFormUrlencoded(const vector<HttpReqArg>& args) const {
+ string result;
+
+ bool firstRun = true;
+ for (const HttpReqArg& item : args) {
+ if (firstRun) {
+ firstRun = false;
+ } else {
+ result += '&';
+ }
+ result += StringTools::urlEncode(item.name);
+ result += '=';
+ result += StringTools::urlEncode(item.value);
+ }
+
+ return result;
}
-string HttpParser::generateWwwFormUrlencoded(const vector<HttpReqArg>& args) {
- string result;
-
- bool firstRun = true;
- for (const HttpReqArg& item : args) {
- if (firstRun) {
- firstRun = false;
- } else {
- result += '&';
- }
- result += StringTools::urlEncode(item.name);
- result += '=';
- result += StringTools::urlEncode(item.value);
- }
-
- return result;
+string HttpParser::generateResponse(const string& data, const string& mimeType, unsigned short statusCode, const string& statusStr, bool isKeepAlive) const {
+ string result;
+ result += "HTTP/1.1 ";
+ result += std::to_string(statusCode);
+ result += ' ';
+ result += statusStr;
+ result += "\r\nContent-Type: ";
+ result += mimeType;
+ result += "\r\nContent-Length: ";
+ result += std::to_string(data.length());
+ result += "\r\nConnection: ";
+ if (isKeepAlive) {
+ result += "keep-alive";
+ } else {
+ result += "close";
+ }
+ result += "\r\n\r\n";
+ result += data;
+ return result;
}
-string HttpParser::generateResponse(const string& data, const string& mimeType, unsigned short statusCode, const string& statusStr, bool isKeepAlive) {
- string result;
- result += "HTTP/1.1 ";
- result += lexical_cast<string>(statusCode);
- result += ' ';
- result += statusStr;
- result += "\r\nContent-Type: ";
- result += mimeType;
- result += "\r\nContent-Length: ";
- result += lexical_cast<string>(data.length());
- result += "\r\n\r\n";
- result += data;
- return result;
+unordered_map<string, string> HttpParser::parseHeader(const string& data, bool isRequest) const {
+ unordered_map<string, string> headers;
+
+ size_t lineStart = 0;
+ size_t lineEnd = 0;
+ size_t lineSepPos = 0;
+ size_t lastLineEnd = string::npos;
+ while (lastLineEnd != lineEnd) {
+ lastLineEnd = lineEnd;
+ bool isFirstLine = lineEnd == 0;
+ if (isFirstLine) {
+ if (isRequest) {
+ lineSepPos = data.find(' ');
+ lineEnd = data.find("\r\n");
+ headers["_method"] = data.substr(0, lineSepPos);
+ headers["_path"] = data.substr(lineSepPos + 1, data.find(' ', lineSepPos + 1) - lineSepPos - 1);
+ } else {
+ lineSepPos = data.find(' ');
+ lineEnd = data.find("\r\n");
+ headers["_status"] = data.substr(lineSepPos + 1, data.find(' ', lineSepPos + 1) - lineSepPos - 1);
+ }
+ } else {
+ lineStart = lineEnd;
+ lineStart += 2;
+ lineEnd = data.find("\r\n", lineStart);
+ lineSepPos = data.find(':', lineStart);
+ if (lastLineEnd == lineEnd || lineEnd == string::npos) {
+ break;
+ }
+ headers[data.substr(lineStart, lineSepPos - lineStart)] = trim_copy(data.substr(lineSepPos + 1, lineEnd - lineSepPos - 1));
+ }
+ }
+
+ return headers;
}
-string HttpParser::parseHttp(bool isRequest, const string& data, unordered_map<string, string>& headers) {
- bool onlyNewLineChar = false;
- size_t headerEnd = data.find("\r\n\r\n");
- if (headerEnd == data.npos) {
- headerEnd = data.find("\n\n");
- if (headerEnd != data.npos) {
- onlyNewLineChar = true;
- headerEnd += 2;
- }
- } else {
- headerEnd += 4;
- }
-
- size_t lineStart = 0;
- size_t lineEnd = 0;
- size_t lineSepPos = 0;
- size_t lastLineEnd = data.npos;
- while (lastLineEnd != lineEnd) {
- lastLineEnd = lineEnd;
- if (lineEnd == 0) {
- if (isRequest) {
- lineSepPos = data.find(' ');
- lineEnd = data.find(onlyNewLineChar ? "\n" : "\r\n");
- headers["method"] = data.substr(0, lineSepPos);
- headers["path"] = data.substr(lineSepPos + 1, data.find(' ', lineSepPos + 1) - lineSepPos - 1);
- } else {
- lineSepPos = data.find(' ');
- lineEnd = data.find(onlyNewLineChar ? "\n" : "\r\n");
- headers["status"] = data.substr(lineSepPos + 1, data.find(' ', lineSepPos + 1) - lineSepPos - 1);
- }
- } else {
- lineStart = lineEnd;
- lineStart += onlyNewLineChar ? 1 : 2;
- lineEnd = data.find(onlyNewLineChar ? "\n" : "\r\n", lineStart);
- lineSepPos = data.find(':', lineStart);
- if (lineEnd >= headerEnd || lastLineEnd == lineEnd || lineSepPos >= headerEnd) {
- break;
- }
- headers[to_lower_copy(data.substr(lineStart, lineSepPos - lineStart))] = trim_copy(data.substr(lineSepPos + 1, lineEnd - lineSepPos - 1));
- }
- }
-
- return headerEnd == data.npos ? "" : data.substr(headerEnd);
-}
-
-string HttpParser::parseHttp(bool isRequest, const string& data) {
- size_t headerEnd = data.find("\r\n\r\n");
- if (headerEnd != data.npos) {
- headerEnd += 4;
- } else {
- headerEnd = data.find("\n\n");
- if (headerEnd != data.npos) {
- headerEnd += 2;
- } else {
- headerEnd = 0;
- }
- }
- return data.substr(headerEnd);
+string HttpParser::extractBody(const string& data) const {
+ size_t headerEnd = data.find("\r\n\r\n");
+ if (headerEnd == string::npos) {
+ return data;
+ }
+ headerEnd += 4;
+ return data.substr(headerEnd);
}
}