blob: d690305a60bd2e63e7d73c905a4fe1c6e56b86fb [file] [log] [blame]
Ed Tanous9140a672017-04-24 17:01:32 -07001#include <iostream>
2#include <sstream>
3#include <vector>
4#include "test_utils.hpp"
5#include "web_kvm.hpp"
6#include "crow.h"
7#include <gmock/gmock.h>
8#include <gtest/gtest.h>
9
10using namespace crow;
11using namespace testing;
12
13// Tests static files are loaded correctly
14TEST(Kvm, BasicRfb) {
15 SimpleApp app;
16
17 crow::kvm::request_routes(app);
18 app.bindaddr("127.0.0.1").port(45451);
19 CROW_ROUTE(app, "/")([]() { return 200; });
20 auto _ = async(std::launch::async, [&] { app.run(); });
21 auto routes = app.get_routes();
22 asio::io_service is;
23
24 {
25 // Retry a couple of times waiting for the server to come up
26 // TODO(ed) This is really unfortunate, and should use some form of mock
27 asio::ip::tcp::socket c(is);
28 for (int i = 0; i < 200; i++) {
29 try {
30 c.connect(asio::ip::tcp::endpoint(
31 asio::ip::address::from_string("127.0.0.1"), 45451));
32 c.close();
33 break;
34 } catch (std::exception e) {
35 // do nothing. We expect this to fail while the server is starting up
36 }
37 }
38 }
39
40 // Get the websocket
41 std::string sendmsg =
42 ("GET /kvmws HTTP/1.1\r\n"
43 "Host: localhost:45451\r\n"
44 "Connection: Upgrade\r\n"
45 "Upgrade: websocket\r\n"
46 "Sec-WebSocket-Version: 13\r\n"
47 "Sec-WebSocket-Key: aLeGkmLPZmdv5tTyEpJ3jQ==\r\n"
48 "Sec-WebSocket-Extensions: permessage-deflate; "
49 "client_max_window_bits\r\n"
50 "Sec-WebSocket-Protocol: binary\r\n"
51 "\r\n");
52
53 asio::ip::tcp::socket socket(is);
54 socket.connect(asio::ip::tcp::endpoint(
55 asio::ip::address::from_string("127.0.0.1"), 45451));
56 socket.send(asio::buffer(sendmsg));
57
58 // Read the response status line. The response streambuf will automatically
59 // grow to accommodate the entire line. The growth may be limited by passing
60 // a maximum size to the streambuf constructor.
61 boost::asio::streambuf response;
62 boost::asio::read_until(socket, response, "\r\n");
63
64 // Check that response is OK.
65 std::istream response_stream(&response);
66 std::string http_response;
67 std::getline(response_stream, http_response);
68
69 EXPECT_EQ(http_response, "HTTP/1.1 101 Switching Protocols\r");
70
71 // Read the response headers, which are terminated by a blank line.
72 boost::asio::read_until(socket, response, "\r\n\r\n");
73
74 // Process the response headers.
75 std::string header;
76 std::vector<std::string> headers;
77 while (std::getline(response_stream, header) && header != "\r") {
78 headers.push_back(header);
79 }
80
81 EXPECT_THAT(headers, Contains("Upgrade: websocket\r"));
82 EXPECT_THAT(headers, Contains("Connection: Upgrade\r"));
83 EXPECT_THAT(headers, Contains("Sec-WebSocket-Protocol: binary\r"));
84 // TODO(ed) This is the result that it gives today. Need to check websocket
85 // docs and make
86 // sure that this calclution is actually being done to spec
87 EXPECT_THAT(headers,
88 Contains("Sec-WebSocket-Accept: /CnDM3l79rIxniLNyxMryXbtLEU=\r"));
89 std::array<char, 13> rfb_open_string;
90
91 //
92 // socket.receive(rfb_open_string.data(), rfb_open_string.size());
93 boost::asio::read(socket, boost::asio::buffer(rfb_open_string));
94 auto open_string =
95 std::string(std::begin(rfb_open_string), std::end(rfb_open_string));
96 // Todo(ed) find out what the two characters at the end of the websocket
97 // stream are
98 open_string = open_string.substr(2);
99 EXPECT_EQ(open_string, "RFB 003.008");
100
101 app.stop();
102}