// $Id$
// Author: Sergey Linev   21/12/2013

#ifndef ROOT_THttpServer
#define ROOT_THttpServer

#ifndef ROOT_TNamed
#include "TNamed.h"
#endif

#ifndef ROOT_TList
#include "TList.h"
#endif

#ifndef ROOT_TMutex
#include "TMutex.h"
#endif

#ifndef ROOT_TCondition
#include "TCondition.h"
#endif


// this class is used to deliver http request arguments to main process
// and also to return back results of processing


class THttpEngine;
class THttpTimer;
class TRootSniffer;
class THttpServer;


class THttpCallArg : public TObject {

protected:
   friend class THttpServer;

   TString fTopName;            //! top item name
   TString fPathName;           //! item path
   TString fFileName;           //! file name
   TString fQuery;              //! additional arguments

   TCondition fCond;            //! condition used to wait for processing

   TString fContentType;        //! type of content
   TString fHeader;             //! response header like ContentEncoding, Cache-Control and so on
   TString fContent;            //! text content (if any)
   Int_t   fZipping;            //! indicate if content should be zipped

   void *fBinData;              //! binary data, assigned with http call
   Long_t fBinDataLength;       //! length of binary data

   Bool_t IsBinData() const
   {
      return fBinData && fBinDataLength > 0;
   }

public:

   THttpCallArg();
   ~THttpCallArg();

   // these methods used to set http request arguments

   void SetTopName(const char *topname)
   {
      // set engine-specific top-name

      fTopName = topname;
   }

   void SetPathAndFileName(const char *fullpath);

   void SetPathName(const char *p)
   {
      // set request path name

      fPathName = p;
   }

   void SetFileName(const char *f)
   {
      // set request file name

      fFileName = f;
   }

   void SetQuery(const char *q)
   {
      // set request query

      fQuery = q;
   }

   const char *GetTopName() const
   {
      // returns engine-specific top-name

      return fTopName.Data();
   }

   const char *GetPathName() const
   {
      // returns path name from request URL

      return fPathName.Data();
   }

   const char *GetFileName() const
   {
      // returns file name from request URL

      return fFileName.Data();
   }

   const char *GetQuery() const
   {
      // returns request query (string after ? in request URL)

      return fQuery.Data();
   }

   // these methods used in THttpServer to set results of request processing

   void SetContentType(const char *typ)
   {
      // set content type like "text/xml" or "application/json"

      fContentType = typ;
   }

   void Set404()
   {
      // mark reply as 404 error - page/request not exists

      SetContentType("_404_");
   }

   void SetFile(const char* filename = 0)
   {
      // indicate that http request should response with file content

      SetContentType("_file_");
      if (filename!=0) fContent = filename;
   }

   void SetXml()
   {
      // set content type as JSON

      SetContentType("text/xml");
   }

   void SetJson()
   {
      // set content type as JSON

      SetContentType("application/json");
   }

   void AddHeader(const char* name, const char* value)
   {
      // Add name:value pair to reply header
      // Same header can be specified only once

      fHeader.Append(TString::Format("%s: %s\r\n", name, value));
   }

   void SetEncoding(const char *typ)
   {
      // Set Content-Encoding header like gzip

      AddHeader("Content-Encoding", typ);
   }

   void SetContent(const char *c)
   {
      // Set content directly

      fContent = c;
   }

   Bool_t CompressWithGzip();

   void SetZipping(Int_t kind)
   {
      // Set kind of content zipping
      // 0 - none
      // 1 - only when supported in request header
      // 2 - if supported and content size bigger than 10K
      // 3 - always

      fZipping = kind;
   }

   Int_t GetZipping() const
   {
      // return kind of content zipping

      return fZipping;
   }

   void SetExtraHeader(const char* name, const char* value)
   {
      AddHeader(name, value);
   }

   // Fill http header
   void FillHttpHeader(TString &buf, const char* header = 0);

   // these methods used to return results of http request processing

   Bool_t IsContentType(const char *typ) const
   {
      return fContentType == typ;
   }

   Bool_t Is404() const
   {
      return IsContentType("_404_");
   }

   Bool_t IsFile() const
   {
      return IsContentType("_file_");
   }

   const char *GetContentType() const
   {
      return fContentType.Data();
   }

   void SetBinData(void* data, Long_t length);

   Long_t GetContentLength() const
   {
      return IsBinData() ? fBinDataLength : fContent.Length();
   }

   const void *GetContent() const
   {
      return IsBinData() ? fBinData : fContent.Data();
   }

   ClassDef(THttpCallArg, 0) // Arguments for single HTTP call
};


class THttpServer : public TNamed {

protected:

   TList        fEngines;     //! engines which runs http server
   THttpTimer  *fTimer;       //! timer used to access main thread
   TRootSniffer *fSniffer;    //! sniffer provides access to ROOT objects hierarchy

   Long_t       fMainThrdId;  //! id of the main ROOT process

   TString      fJsRootSys;   //! location of JSROOT files
   TString      fTopName;     //! name of top folder, default - "ROOT"

   TString      fDefaultPage; //! file name for default page name
   TString      fDefaultPageCont; //! content of the file content
   TString      fDrawPage;    //! file name for drawing of single element
   TString      fDrawPageCont; //! content of draw page

   TMutex       fMutex;       //! mutex to protect list with arguments
   TList        fCallArgs;    //! submitted arguments

   // Here any request can be processed
   virtual void ProcessRequest(THttpCallArg *arg);

   static Bool_t VerifyFilePath(const char* fname);

public:

   THttpServer(const char *engine = "civetweb:8080");
   virtual ~THttpServer();

   Bool_t CreateEngine(const char *engine);

   TRootSniffer *GetSniffer() const
   {
      return fSniffer;
   }

   void SetSniffer(TRootSniffer *sniff);

   Bool_t IsReadOnly() const;

   void SetReadOnly(Bool_t readonly);

   void SetTopName(const char *top)
   {
      fTopName = top;
   }

   const char *GetTopName() const
   {
      return fTopName.Data();
   }

   void SetTimer(Long_t milliSec = 100, Bool_t mode = kTRUE);

   /** Check if file is requested, thread safe */
   Bool_t  IsFileRequested(const char *uri, TString &res) const;

   /** Execute HTTP request */
   Bool_t ExecuteHttp(THttpCallArg *arg);

   /** Process submitted requests, must be called from main thread */
   void ProcessRequests();

   /** Register object in subfolder */
   Bool_t Register(const char *subfolder, TObject *obj);

   /** Unregister object */
   Bool_t Unregister(TObject *obj);

   /** Guess mime type base on file extension */
   static const char *GetMimeType(const char *path);

   /** Reads content of file from the disk */
   static char* ReadFileContent(const char* filename, Int_t& len);

   ClassDef(THttpServer, 0) // HTTP server for ROOT analysis
};

#endif
 THttpServer.h:1
 THttpServer.h:2
 THttpServer.h:3
 THttpServer.h:4
 THttpServer.h:5
 THttpServer.h:6
 THttpServer.h:7
 THttpServer.h:8
 THttpServer.h:9
 THttpServer.h:10
 THttpServer.h:11
 THttpServer.h:12
 THttpServer.h:13
 THttpServer.h:14
 THttpServer.h:15
 THttpServer.h:16
 THttpServer.h:17
 THttpServer.h:18
 THttpServer.h:19
 THttpServer.h:20
 THttpServer.h:21
 THttpServer.h:22
 THttpServer.h:23
 THttpServer.h:24
 THttpServer.h:25
 THttpServer.h:26
 THttpServer.h:27
 THttpServer.h:28
 THttpServer.h:29
 THttpServer.h:30
 THttpServer.h:31
 THttpServer.h:32
 THttpServer.h:33
 THttpServer.h:34
 THttpServer.h:35
 THttpServer.h:36
 THttpServer.h:37
 THttpServer.h:38
 THttpServer.h:39
 THttpServer.h:40
 THttpServer.h:41
 THttpServer.h:42
 THttpServer.h:43
 THttpServer.h:44
 THttpServer.h:45
 THttpServer.h:46
 THttpServer.h:47
 THttpServer.h:48
 THttpServer.h:49
 THttpServer.h:50
 THttpServer.h:51
 THttpServer.h:52
 THttpServer.h:53
 THttpServer.h:54
 THttpServer.h:55
 THttpServer.h:56
 THttpServer.h:57
 THttpServer.h:58
 THttpServer.h:59
 THttpServer.h:60
 THttpServer.h:61
 THttpServer.h:62
 THttpServer.h:63
 THttpServer.h:64
 THttpServer.h:65
 THttpServer.h:66
 THttpServer.h:67
 THttpServer.h:68
 THttpServer.h:69
 THttpServer.h:70
 THttpServer.h:71
 THttpServer.h:72
 THttpServer.h:73
 THttpServer.h:74
 THttpServer.h:75
 THttpServer.h:76
 THttpServer.h:77
 THttpServer.h:78
 THttpServer.h:79
 THttpServer.h:80
 THttpServer.h:81
 THttpServer.h:82
 THttpServer.h:83
 THttpServer.h:84
 THttpServer.h:85
 THttpServer.h:86
 THttpServer.h:87
 THttpServer.h:88
 THttpServer.h:89
 THttpServer.h:90
 THttpServer.h:91
 THttpServer.h:92
 THttpServer.h:93
 THttpServer.h:94
 THttpServer.h:95
 THttpServer.h:96
 THttpServer.h:97
 THttpServer.h:98
 THttpServer.h:99
 THttpServer.h:100
 THttpServer.h:101
 THttpServer.h:102
 THttpServer.h:103
 THttpServer.h:104
 THttpServer.h:105
 THttpServer.h:106
 THttpServer.h:107
 THttpServer.h:108
 THttpServer.h:109
 THttpServer.h:110
 THttpServer.h:111
 THttpServer.h:112
 THttpServer.h:113
 THttpServer.h:114
 THttpServer.h:115
 THttpServer.h:116
 THttpServer.h:117
 THttpServer.h:118
 THttpServer.h:119
 THttpServer.h:120
 THttpServer.h:121
 THttpServer.h:122
 THttpServer.h:123
 THttpServer.h:124
 THttpServer.h:125
 THttpServer.h:126
 THttpServer.h:127
 THttpServer.h:128
 THttpServer.h:129
 THttpServer.h:130
 THttpServer.h:131
 THttpServer.h:132
 THttpServer.h:133
 THttpServer.h:134
 THttpServer.h:135
 THttpServer.h:136
 THttpServer.h:137
 THttpServer.h:138
 THttpServer.h:139
 THttpServer.h:140
 THttpServer.h:141
 THttpServer.h:142
 THttpServer.h:143
 THttpServer.h:144
 THttpServer.h:145
 THttpServer.h:146
 THttpServer.h:147
 THttpServer.h:148
 THttpServer.h:149
 THttpServer.h:150
 THttpServer.h:151
 THttpServer.h:152
 THttpServer.h:153
 THttpServer.h:154
 THttpServer.h:155
 THttpServer.h:156
 THttpServer.h:157
 THttpServer.h:158
 THttpServer.h:159
 THttpServer.h:160
 THttpServer.h:161
 THttpServer.h:162
 THttpServer.h:163
 THttpServer.h:164
 THttpServer.h:165
 THttpServer.h:166
 THttpServer.h:167
 THttpServer.h:168
 THttpServer.h:169
 THttpServer.h:170
 THttpServer.h:171
 THttpServer.h:172
 THttpServer.h:173
 THttpServer.h:174
 THttpServer.h:175
 THttpServer.h:176
 THttpServer.h:177
 THttpServer.h:178
 THttpServer.h:179
 THttpServer.h:180
 THttpServer.h:181
 THttpServer.h:182
 THttpServer.h:183
 THttpServer.h:184
 THttpServer.h:185
 THttpServer.h:186
 THttpServer.h:187
 THttpServer.h:188
 THttpServer.h:189
 THttpServer.h:190
 THttpServer.h:191
 THttpServer.h:192
 THttpServer.h:193
 THttpServer.h:194
 THttpServer.h:195
 THttpServer.h:196
 THttpServer.h:197
 THttpServer.h:198
 THttpServer.h:199
 THttpServer.h:200
 THttpServer.h:201
 THttpServer.h:202
 THttpServer.h:203
 THttpServer.h:204
 THttpServer.h:205
 THttpServer.h:206
 THttpServer.h:207
 THttpServer.h:208
 THttpServer.h:209
 THttpServer.h:210
 THttpServer.h:211
 THttpServer.h:212
 THttpServer.h:213
 THttpServer.h:214
 THttpServer.h:215
 THttpServer.h:216
 THttpServer.h:217
 THttpServer.h:218
 THttpServer.h:219
 THttpServer.h:220
 THttpServer.h:221
 THttpServer.h:222
 THttpServer.h:223
 THttpServer.h:224
 THttpServer.h:225
 THttpServer.h:226
 THttpServer.h:227
 THttpServer.h:228
 THttpServer.h:229
 THttpServer.h:230
 THttpServer.h:231
 THttpServer.h:232
 THttpServer.h:233
 THttpServer.h:234
 THttpServer.h:235
 THttpServer.h:236
 THttpServer.h:237
 THttpServer.h:238
 THttpServer.h:239
 THttpServer.h:240
 THttpServer.h:241
 THttpServer.h:242
 THttpServer.h:243
 THttpServer.h:244
 THttpServer.h:245
 THttpServer.h:246
 THttpServer.h:247
 THttpServer.h:248
 THttpServer.h:249
 THttpServer.h:250
 THttpServer.h:251
 THttpServer.h:252
 THttpServer.h:253
 THttpServer.h:254
 THttpServer.h:255
 THttpServer.h:256
 THttpServer.h:257
 THttpServer.h:258
 THttpServer.h:259
 THttpServer.h:260
 THttpServer.h:261
 THttpServer.h:262
 THttpServer.h:263
 THttpServer.h:264
 THttpServer.h:265
 THttpServer.h:266
 THttpServer.h:267
 THttpServer.h:268
 THttpServer.h:269
 THttpServer.h:270
 THttpServer.h:271
 THttpServer.h:272
 THttpServer.h:273
 THttpServer.h:274
 THttpServer.h:275
 THttpServer.h:276
 THttpServer.h:277
 THttpServer.h:278
 THttpServer.h:279
 THttpServer.h:280
 THttpServer.h:281
 THttpServer.h:282
 THttpServer.h:283
 THttpServer.h:284
 THttpServer.h:285
 THttpServer.h:286
 THttpServer.h:287
 THttpServer.h:288
 THttpServer.h:289
 THttpServer.h:290
 THttpServer.h:291
 THttpServer.h:292
 THttpServer.h:293
 THttpServer.h:294
 THttpServer.h:295
 THttpServer.h:296
 THttpServer.h:297
 THttpServer.h:298
 THttpServer.h:299
 THttpServer.h:300
 THttpServer.h:301
 THttpServer.h:302
 THttpServer.h:303
 THttpServer.h:304
 THttpServer.h:305
 THttpServer.h:306
 THttpServer.h:307
 THttpServer.h:308
 THttpServer.h:309
 THttpServer.h:310
 THttpServer.h:311
 THttpServer.h:312
 THttpServer.h:313
 THttpServer.h:314
 THttpServer.h:315
 THttpServer.h:316
 THttpServer.h:317
 THttpServer.h:318
 THttpServer.h:319
 THttpServer.h:320
 THttpServer.h:321
 THttpServer.h:322
 THttpServer.h:323
 THttpServer.h:324
 THttpServer.h:325
 THttpServer.h:326
 THttpServer.h:327
 THttpServer.h:328
 THttpServer.h:329
 THttpServer.h:330