#include "test.h"
#include <set>
#include <fstream>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#define TEST(name) TEST_CASE("regression: " name, "[regression]")
const string ROOT = "tests/regression/";
#ifndef WIN32
inline std::set<string> read_directory (const string& name = ".") {
DIR* dirp = opendir(name.c_str());
struct dirent* dp;
std::set<string> v;
while ((dp = readdir(dirp)) != NULL) {
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
v.insert(string(dp->d_name, strlen(dp->d_name)));
}
closedir(dirp);
return v;
}
#endif
TEST("additional final chunk before other chunks") {
RequestParser p;
string raw =
"GET / HTTP/1.1\r\n"
"Transfer-Encoding: chunked\r\n"
"Connection: keep-alive\r\n"
"\r\n"
"0\r\n"
"\r\n"
"2\r\n"
"12\r\n"
"2\r\n"
"34\r\n"
"2\r\n"
"56\r\n"
"0\r\n"
"\r\n"
;
auto result = p.parse(raw);
auto req = result.request;
CHECK(result.position == 75); //stoped at first final chunk
CHECK_FALSE(result.error);
CHECK(result.state == State::done);
CHECK(req->body.to_string() == "");
}
TEST("response chunks #1") {
ResponseParser p;
RequestSP req = new Request();
req->method_raw(Method::Get);
p.set_context_request(req);
std::vector<string> v = {
"HTTP/1.1 200 OK\r\n"
"Transfer-Encoding: chunked\r\n"
"Connection: keep-alive\r\n"
"\r\n",
"4\r\n"
"ans1\r\n",
"0\r\n"
"\r\n"
"HTTP/1.1 200 OK\r\n"
"Content-Length: 4\r\n"
"Connection: close\r\n"
"\r\n"
"ans2"
};
auto result = p.parse_shift(v[0]);
CHECK(result.state != State::done);
CHECK(result.response->body.to_string() == "");
CHECK_FALSE(v[0]);
result = p.parse_shift(v[1]);
CHECK(result.state != State::done);
CHECK(result.response->body.to_string() == "ans1");
CHECK_FALSE(v[1]);
result = p.parse_shift(v[2]);
CHECK(result.state == State::done);
CHECK(result.response->body.to_string() == "ans1");
CHECK(v[2][0] == 'H');
p.set_context_request(req);
result = p.parse_shift(v[2]);
CHECK(result.state == State::done);
CHECK_FALSE(result.error);
CHECK(result.response->body.to_string() == "ans2");
CHECK_FALSE(v[2]);
}
TEST("google response 0") {
ResponseParser p;
RequestSP req = new Request();
req->method_raw(Method::Get);
p.set_context_request(req);
string raw =
"HTTP/1.1 302 Found\r\n"
"Cache-Control: private\r\n"
"Content-Type: text/html; charset=UTF-8\r\n"
"Referrer-Policy: no-referrer\r\n"
"Location: http://www.google.ru/?gfe_rd=cr&dcr=0&ei=dlSVWsfRFMiG7gT1wK8Q\r\n"
"Content-Length: 266\r\n"
"Date: Tue, 27 Feb 2018 12:52:06 GMT\r\n"
"\r\n"
"<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\r\n"
"<TITLE>302 Moved</TITLE></HEAD><BODY>\r\n"
"<H1>302 Moved</H1>\r\n"
"The document has moved\r\n"
"<A HREF=\"http://www.google.ru/?gfe_rd=cr&dcr=0&ei=dlSVWsfRFMiG7gT1wK8Q\">here</A>.\r\n"
"</BODY></HTML>\r\n";
auto result = p.parse_shift(raw);
CHECK(result.state == State::done);
CHECK(result.response->http_version == 11);
}
#ifndef WIN32
TEST("google response 1") {
ResponseParser p;
RequestSP req = new Request();
req->method_raw(Method::Get);
p.set_context_request(req);
ResponseParser::Result result;
auto DIR = ROOT+"1";
for (auto fname : read_directory(DIR)) {
if (result.response) CHECK(result.state != State::done);
std::ifstream file(DIR+"/"+fname, std::ios::binary);
std::string str((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
result = p.parse(string(str.c_str()));
}
CHECK(result.state == State::done);
CHECK(result.response->http_version == 11);
}
#endif