18 #include <gtest/gtest.h>
20 #include <boost/asio.hpp>
21 #include <boost/bind.hpp>
22 #include <boost/lexical_cast.hpp>
23 #include <gutil/strings/substitute.h>
30 using boost::asio::ip::tcp;
31 using namespace impala;
32 using namespace rapidjson;
33 using namespace strings;
40 const string ESCAPED_VALUE =
"<script language='javascript'>";
44 Status HttpGet(
const string& host,
const int32_t& port,
const string& url_path,
45 ostream* out,
int expected_code = 200) {
47 tcp::iostream request_stream;
48 request_stream.connect(host, lexical_cast<string>(port));
49 if (!request_stream)
return Status(
"Could not connect request_stream");
51 request_stream <<
"GET " << url_path <<
" HTTP/1.0\r\n";
52 request_stream <<
"Host: " << host <<
"\r\n";
53 request_stream <<
"Accept: */*\r\n";
54 request_stream <<
"Cache-Control: no-cache\r\n";
55 request_stream <<
"Connection: close\r\n\r\n";
56 request_stream.flush();
59 getline(request_stream, line1);
60 if (!request_stream)
return Status(
"No response");
62 stringstream response_stream(line1);
64 response_stream >> http_version;
66 unsigned int status_code;
67 response_stream >> status_code;
69 string status_message;
70 getline(response_stream,status_message);
71 if (!response_stream || http_version.substr(0,5) !=
"HTTP/") {
72 return Status(
"Malformed response");
75 if (status_code != expected_code) {
76 return Status(Substitute(
"Unexpected status code: $0", status_code));
79 (*out) << request_stream.rdbuf();
81 }
catch (
const std::exception& e){
87 Webserver webserver(FLAGS_webserver_port);
88 ASSERT_TRUE(webserver.
Start().
ok());
90 stringstream contents;
91 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port,
"/", &contents).ok());
96 *success = args.find(
TEST_ARG) != args.end();
100 Webserver webserver(FLAGS_webserver_port);
102 const string ARGS_TEST_PATH =
"/args-test";
103 bool success =
false;
107 ASSERT_TRUE(webserver.
Start().
ok());
108 stringstream contents;
109 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port, ARGS_TEST_PATH, &contents).ok());
110 ASSERT_FALSE(success) <<
"Unexpectedly found " <<
TEST_ARG;
112 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port,
113 Substitute(
"$0?$1", ARGS_TEST_PATH,
TEST_ARG), &contents).ok());
114 ASSERT_TRUE(success) <<
"Did not find " <<
TEST_ARG;
118 Document* document) {
120 document->GetAllocator());
122 document->GetAllocator());
129 Webserver webserver(FLAGS_webserver_port);
131 const string JSON_TEST_PATH =
"/json-test";
132 const string RAW_TEXT_PATH =
"/text";
133 const string NO_TEMPLATE_PATH =
"/no-template";
140 ASSERT_TRUE(webserver.
Start().
ok());
142 stringstream contents;
143 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port, JSON_TEST_PATH, &contents).ok());
147 stringstream json_contents;
148 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port,
149 Substitute(
"$0?json", JSON_TEST_PATH), &json_contents).ok());
150 ASSERT_TRUE(json_contents.str().find(
"\"Salutation\": \"Hello!\"") != string::npos);
152 stringstream error_contents;
154 HttpGet(
"localhost", FLAGS_webserver_port, NO_TEMPLATE_PATH, &error_contents).ok());
155 ASSERT_TRUE(error_contents.str().find(
"Could not open template: ") != string::npos);
158 stringstream raw_contents;
159 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port,
160 Substitute(
"$0?raw", JSON_TEST_PATH), &raw_contents).ok());
161 ASSERT_TRUE(raw_contents.str().find(
"text/plain") != string::npos);
164 stringstream raw_cb_contents;
165 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port, RAW_TEXT_PATH,
166 &raw_cb_contents).ok());
167 ASSERT_TRUE(raw_cb_contents.str().find(
"text/plain") != string::npos);
171 Webserver webserver(FLAGS_webserver_port);
173 const string JSON_TEST_PATH =
"/json-test";
176 ASSERT_TRUE(webserver.
Start().
ok());
177 stringstream contents;
178 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port, JSON_TEST_PATH, &contents).ok());
179 ASSERT_TRUE(contents.str().find(
ESCAPED_VALUE) != string::npos);
184 Webserver webserver(FLAGS_webserver_port);
185 ASSERT_TRUE(webserver.
Start().
ok());
186 stringstream contents;
187 ASSERT_TRUE(
HttpGet(
"localhost", FLAGS_webserver_port,
188 "/dont-exist<script>alert(42);</script>", &contents, 404).ok());
189 ASSERT_EQ(contents.str().find(
"<script>alert(42);</script>"), string::npos);
190 ASSERT_TRUE(contents.str().find(
"dont-exist<script>alert(42);</script>") !=
195 stringstream password_file;
196 password_file << getenv(
"IMPALA_HOME") <<
"/be/src/testutil/htpasswd";
197 FLAGS_webserver_password_file = password_file.str();
199 Webserver webserver(FLAGS_webserver_port);
200 ASSERT_TRUE(webserver.
Start().
ok());
203 stringstream contents;
204 ASSERT_FALSE(
HttpGet(
"localhost", FLAGS_webserver_port,
"/", &contents).ok());
208 stringstream password_file;
209 password_file << getenv(
"IMPALA_HOME") <<
"/be/src/testutil/doesntexist";
210 FLAGS_webserver_password_file = password_file.str();
212 Webserver webserver(FLAGS_webserver_port);
213 ASSERT_FALSE(webserver.
Start().
ok());
216 int main(
int argc,
char **argv) {
218 ::testing::InitGoogleTest(&argc, argv);
219 return RUN_ALL_TESTS();
const string TO_ESCAPE_VALUE
static const char * ENABLE_RAW_JSON_KEY
const string TO_ESCAPE_KEY
boost::function< void(const ArgumentMap &args, rapidjson::Document *json)> UrlCallback
DECLARE_int32(webserver_port)
void InitCommonRuntime(int argc, char **argv, bool init_jvm, TestInfo::Mode m=TestInfo::NON_TEST)
void RegisterUrlCallback(const std::string &path, const std::string &template_filename, const UrlCallback &callback, bool is_on_nav_bar=true)
Only one callback may be registered per URL.
std::map< std::string, std::string > ArgumentMap
const string SALUTATION_KEY
Status HttpGet(const string &host, const int32_t &port, const string &url_path, ostream *out, int expected_code=200)
const string SALUTATION_VALUE
void JsonCallback(bool always_text, const Webserver::ArgumentMap &args, Document *document)
DECLARE_string(webserver_password_file)
int main(int argc, char **argv)
const string ESCAPED_VALUE
void AssertArgsCallback(bool *success, const Webserver::ArgumentMap &args, Document *document)