1 // Copyright (c) 2018 IIS (The Internet Foundation in Sweden)
2 // Written by Göran Andersson <initgoran@gmail.com>
3 
4 #pragma once
5 
6 #include <string>
7 #include <map>
8 #include <sstream>
9 
10 #include "../framework/bridgetask.h"
11 #include "../json11/json11.hpp"
12 #include "../http/httphost.h"
13 #include "../http/cookiefile.h"
14 
15 class SpeedTest;
16 
17 class MeasurementAgent : public Task {
18 public:
19     MeasurementAgent(const TaskConfig &config, const HttpHost &webserver);
20     void taskMessage(Task *task) override;
21     void taskFinished(Task *task) override;
22 
23     void handleExecution(Task *sender, const std::string &msg) override;
24     void sendToClient(const std::string &method,
25                       const std::string &jsonobj = "{}") {
26         if (bridge)
27             bridge->sendMsgToClient(method, jsonobj);
28     }
29     void sendTaskComplete(const std::string &t, const std::string &res = "");
30     void sendTaskProgress(const std::string &taskname,
31                           double speed, double progress);
32 private:
33     std::string getDefaultConfig();
34     bool isValidHashkey(const std::string &key);
35     void pollBridge(const std::string &msg);
isValidJson(const std::string & s)36     static bool isValidJson(const std::string &s) {
37         std::string err;
38         auto obj = json11::Json::parse(s, err);
39         return err.empty();
40     }
41 
42     void handleMsgFromClient(const std::string &method,
43                              const json11::Json &args);
44     void handleConfigurationOption(const std::string &name,
45                                    const std::string &value);
46     void uploadComplete();
47     void doSaveReport();
48     void resetCurrentTest();
49     BridgeTask *bridge = nullptr;
50     SpeedTest *current_test = nullptr;
51     std::string current_ticket;
52 
53     // Initial state is IDLE. When client says "startTest", state becomes
54     // STARTED. When test is done, we send "testComplete global" to client
55     // and set state to FINISHED. When client sends resetTest, state will
56     // be reset to IDLE.
57     // If client sends abortTest in state STARTED, state becomes ABORTED.
58     enum class MeasurementState { IDLE, STARTED, FINISHED, ABORTED };
59     MeasurementState state = MeasurementState::IDLE;
60 
61     // If the client doesn't manage keys, we store them here:
62     CookieManager *key_store;
63 
64     std::string force_key;
65 
66     // The web server and the measurement server:
67     HttpHost wserv, mserv;
68 
69     // Default value, might be modified by the client
70     std::string wserv_contentsurl = "/api/content";
71     std::string wserv_measurementsurl = "/api/measurements";
72     std::string wserv_settingsurl = "/api/servers";
73     std::string settings_result;
74 
75     // Info to be included each time measurement result is sent:
76     std::map<std::string, std::string> report_template;
77 };
78