#pragma once #include #include #include #include #include #include #include #include struct TMonitor; namespace NMonitoring { struct IHttpRequest { virtual ~IHttpRequest() { } virtual const char* GetURI() const = 0; virtual const char* GetPath() const = 0; virtual const TCgiParameters& GetParams() const = 0; virtual const TCgiParameters& GetPostParams() const = 0; virtual TStringBuf GetPostContent() const = 0; virtual HTTP_METHOD GetMethod() const = 0; virtual const THttpHeaders& GetHeaders() const = 0; virtual TString GetRemoteAddr() const = 0; }; // first param - output stream to write result to // second param - URL of request typedef std::function THandler; class TCoHttpServer: private TContListener::ICallBack { public: // initialize and schedule coroutines for execution TCoHttpServer(TContExecutor& executor, const TString& bindAddr, TIpPort port, THandler handler); void Start(); void Stop(); // this function implements THandler interface // by forwarding it to the httpserver // @note this call may be blocking; don't use inside coroutines // @throws may throw in case of connection error, etc void ProcessRequest(IOutputStream&, const IHttpRequest&); private: class TConnection; // ICallBack implementation void OnAcceptFull(const TAcceptFull& a) override; void OnError() override; private: TContExecutor& Executor; TContListener Listener; THandler Handler; TString BindAddr; TIpPort Port; }; class TMtHttpServer: public THttpServer, private THttpServer::ICallBack { public: TMtHttpServer(const TOptions& options, THandler handler, IThreadFactory* pool = nullptr); TMtHttpServer(const TOptions& options, THandler handler, TSimpleSharedPtr pool); ~TMtHttpServer() override { Stop(); } /** * This will cause the server start to accept incoming connections. * * @return true if the port binding was successfull, * false otherwise. */ bool Start(); /** * Same as Start() member-function, but will throw TSystemError if * there were some errors. */ void StartOrThrow(); /** * Stops the server from accepting new connections. */ void Stop(); private: class TConnection; TClientRequest* CreateClient() override; THandler Handler; }; // this class implements hybrid coroutine and threaded approach // requests for main page which holds counters and simple tables are served in a thread // requests for other pages which include access with inter-thread synchonization // will be served in a coroutine context class TMonService { public: TMonService(TContExecutor& executor, TIpPort internalPort, TIpPort externalPort, THandler coHandler, THandler mtHandler); void Start(); void Stop(); protected: void DispatchRequest(IOutputStream& out, const IHttpRequest&); private: TCoHttpServer CoServer; TMtHttpServer MtServer; THandler MtHandler; }; }