Skip to content

Commit 9dba1e7

Browse files
committed
[http] add websocket handler tests
Introduce simple websocket handler and verify that response is received. Use 5 seconds timeout - curl has no option to break data receiving with other methods
1 parent 41f622e commit 9dba1e7

1 file changed

Lines changed: 66 additions & 5 deletions

File tree

net/http/test/test_server.cxx

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <fstream>
55

66
#include "THttpServer.h"
7+
#include "THttpWSHandler.h"
78
#include "TROOT.h"
89

910
#include "TSystem.h"
@@ -15,8 +16,52 @@
1516
Int_t httpport = 0;
1617
TString server_url;
1718

19+
class TUserHandler : public THttpWSHandler {
20+
public:
21+
UInt_t fWSId{0};
22+
Int_t fServCnt{0};
23+
24+
TUserHandler(const char *name = nullptr, const char *title = nullptr) : THttpWSHandler(name, title) {}
25+
26+
// load custom HTML page when open correspondent address
27+
TString GetDefaultPageContent() override { return "dummy_page_content"; }
28+
29+
Bool_t ProcessWS(THttpCallArg *arg) override
30+
{
31+
if (!arg || (arg->GetWSId() == 0))
32+
return kTRUE;
33+
34+
if (arg->IsMethod("WS_CONNECT"))
35+
// accept only if connection not established
36+
return fWSId == 0;
37+
38+
if (arg->IsMethod("WS_READY")) {
39+
fWSId = arg->GetWSId();
40+
return kTRUE;
41+
}
42+
43+
if (arg->IsMethod("WS_CLOSE")) {
44+
fWSId = 0;
45+
return kTRUE;
46+
}
47+
48+
if (arg->IsMethod("WS_DATA")) {
49+
TString str;
50+
str.Append((const char *)arg->GetPostData(), arg->GetPostDataLength());
51+
if ((str == "DataRequest") && (arg->GetWSId() == fWSId))
52+
SendCharStarWS(arg->GetWSId(), "DataResponse");
53+
else
54+
SendCharStarWS(arg->GetWSId(), "DataRejected");
55+
return kTRUE;
56+
}
57+
58+
return kFALSE;
59+
}
60+
};
61+
62+
1863
// main http server
19-
std::string execute_request(const char *url, const char *post = nullptr)
64+
std::string execute_request(const char *url, const char *post = nullptr, Bool_t ws = kFALSE)
2065
{
2166
TString fname = TString::Format("http_server_%d.output", httpport),
2267
pname, exec;
@@ -25,16 +70,21 @@ std::string execute_request(const char *url, const char *post = nullptr)
2570
pname = TString::Format("http_server_%d.post", httpport);
2671
std::ofstream f(pname.Data());
2772
f << post;
73+
}
74+
75+
if (post && ws)
76+
exec = TString::Format("curl -sS --max-time 5 -N -T - 'ws://localhost:%d%s' < %s > %s", httpport, url, pname.Data(), fname.Data());
77+
else if (post)
2878
exec = TString::Format("curl -sS -X POST '%s%s' --data-binary @%s -o %s", server_url.Data(), url, pname.Data(), fname.Data());
29-
} else {
79+
else
3080
exec = TString::Format("curl -sS '%s%s' -o %s", server_url.Data(), url, fname.Data());
31-
}
3281

3382
printf("Execute %s\n", exec.Data());
3483

3584
std::string res;
3685

37-
if (gSystem->Exec(exec) != 0)
86+
// websocket ends with timeout - ignore failure for it
87+
if ((gSystem->Exec(exec) != 0) && !ws)
3888
res = "<fail>";
3989
else
4090
res = THttpServer::ReadFileContent(fname.Data());
@@ -56,7 +106,7 @@ TEST(THttpServer, main)
56106
for(int ntry = 0; ntry < 100; ++ntry) {
57107
Int_t port = (Int_t) (25000 + gRandom->Rndm() * 1000);
58108
// only two threads, bind to loopback address only
59-
TString arg = TString::Format("http:%d?loopback&thrds=2", port);
109+
TString arg = TString::Format("http:%d?loopback&thrds=3", port);
60110
if (serv.CreateEngine(arg)) {
61111
httpport = port;
62112
break;
@@ -70,9 +120,12 @@ TEST(THttpServer, main)
70120

71121
server_url = TString::Format("http:/localhost:%d", httpport);
72122

123+
TUserHandler handler("ws", "Test WebSocket handler");
124+
73125
TNamed obj1("obj1", "title1");
74126
TNamed obj2("obj2", "title2");
75127

128+
serv.Register("/", &handler);
76129
serv.Register("/", &obj1);
77130
serv.Register("/", &obj2);
78131

@@ -154,4 +207,12 @@ TEST(THttpServer, main)
154207
EXPECT_EQ(res, "null") << "returns null when executes void method";
155208
EXPECT_EQ(std::string("NewTitle"), obj1.GetTitle()) << "title must match with submitted value";
156209
obj1.SetTitle("title1");
210+
211+
212+
// test websocket functionality
213+
res = execute_request("/ws/index.htm");
214+
EXPECT_EQ(res, "dummy_page_content") << "default html page for webcosket handler";
215+
216+
res = execute_request("/ws/root.websocket", "DataRequest", kTRUE);
217+
EXPECT_EQ(res, "DataResponse") << "check data after websocket communication";
157218
}

0 commit comments

Comments
 (0)