44#include < fstream>
55
66#include " THttpServer.h"
7+ #include " THttpWSHandler.h"
78#include " TROOT.h"
89
910#include " TSystem.h"
1516Int_t httpport = 0 ;
1617TString 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