32 bool fCanPostpone{
false};
38 std::string search =
"JSROOT.connectWebWindow({";
39 std::string replace = search +
"socket_kind:\"longpoll\",";
44 TFastCgiCallArg(
bool can_postpone) :
THttpCallArg(), fCanPostpone(can_postpone) {};
53#ifndef HTTP_WITHOUT_FASTCGI
64 FCGX_FPrintF(request->out,
65 "Status: 404 Not Found\r\n"
66 "Content-Length: 0\r\n"
67 "Connection: close\r\n\r\n");
70 FCGX_FPrintF(request->out,
72 "Content-Type: %s\r\n"
73 "Content-Length: %d\r\n"
77 FCGX_PutStr(buf.c_str(), buf.length(), request->out);
87 const char *inp_path = FCGX_GetParam(
"PATH_INFO", request->envp);
88 if (!inp_path) inp_path = FCGX_GetParam(
"SCRIPT_FILENAME", request->envp);
89 const char *inp_query = FCGX_GetParam(
"QUERY_STRING", request->envp);
90 const char *inp_method = FCGX_GetParam(
"REQUEST_METHOD", request->envp);
91 const char *inp_length = FCGX_GetParam(
"CONTENT_LENGTH", request->envp);
93 auto arg = std::make_shared<TFastCgiCallArg>(can_postpone);
95 arg->SetPathAndFileName(inp_path);
97 arg->SetQuery(inp_query);
99 arg->SetMethod(inp_method);
104 len = strtol(inp_length,
nullptr, 10);
108 int nread = FCGX_GetStr((
char *)buf.data(), len, request->in);
110 arg->SetPostData(std::move(buf));
114 for (
char **envp = request->envp; *envp !=
nullptr; envp++) {
117 if (entry[
n] ==
'=') {
124 arg->SetRequestHeader(header);
126 TString username = arg->GetRequestHeader(
"REMOTE_USER");
127 if ((username.
Length() > 0) && (arg->GetRequestHeader(
"AUTH_TYPE").Length() > 0))
128 arg->SetUserName(username);
131 FCGX_FPrintF(request->out,
"Status: 200 OK\r\n"
132 "Content-type: text/html\r\n"
134 "<title>FastCGI echo</title>"
135 "<h1>FastCGI echo</h1>\n");
137 FCGX_FPrintF(request->out,
"Request %d:<br/>\n<pre>\n", count);
138 FCGX_FPrintF(request->out,
" Method : %s\n", arg->GetMethod());
139 FCGX_FPrintF(request->out,
" PathName : %s\n", arg->GetPathName());
140 FCGX_FPrintF(request->out,
" FileName : %s\n", arg->GetFileName());
141 FCGX_FPrintF(request->out,
" Query : %s\n", arg->GetQuery());
142 FCGX_FPrintF(request->out,
" PostData : %ld\n", arg->GetPostDataLength());
143 FCGX_FPrintF(request->out,
"</pre><p>\n");
145 FCGX_FPrintF(request->out,
"Environment:<br/>\n<pre>\n");
146 for (
char **envp = request->envp; *envp !=
nullptr; envp++)
147 FCGX_FPrintF(request->out,
" %s\n", *envp);
148 FCGX_FPrintF(request->out,
"</pre><p>\n");
161 std::string hdr = arg->FillHttpHeader(
"Status:");
162 FCGX_FPrintF(request->out, hdr.c_str());
163 }
else if (arg->IsFile()) {
169 arg->CompressWithGzip();
171 std::string hdr = arg->FillHttpHeader(
"Status:");
172 FCGX_FPrintF(request->out, hdr.c_str());
174 FCGX_PutStr((
const char *)arg->GetContent(), (
int)arg->GetContentLength(), request->out);
180 std::condition_variable cond;
182 std::unique_ptr<FCGX_Request> arg;
185 auto worker_func = [engine, &cond, &
m, &arg, &nwaiting]() {
189 std::unique_ptr<FCGX_Request> request;
191 bool can_postpone =
false;
194 std::unique_lock<std::mutex> lk(
m);
198 can_postpone = (nwaiting > 5);
199 std::swap(arg, request);
205 FCGX_Finish_r(request.get());
212 std::vector<std::thread> workers;
213 for (
int n=0;
n< nthrds; ++
n)
214 workers.emplace_back(worker_func);
217 auto request = std::make_unique<FCGX_Request>();
219 FCGX_InitRequest(request.get(), engine->
GetSocket(), 0);
221 int rc = FCGX_Accept_r(request.get());
227 std::lock_guard<std::mutex> lk(
m);
229 std::swap(request, arg);
238 FCGX_Finish_r(request.get());
246 for (
auto & thrd : workers)
256 FCGX_Request request;
258 FCGX_InitRequest(&request, engine->
GetSocket(), 0);
262 int rc = FCGX_Accept_r(&request);
269 FCGX_Finish_r(&request);
319 :
THttpEngine(
"fastcgi",
"fastcgi interface to webserver")
347#ifndef HTTP_WITHOUT_FASTCGI
353 if ((args != 0) && (strlen(args) > 0)) {
357 while ((*args != 0) && (*args >=
'0') && (*args <=
'9'))
361 while ((*args != 0) && (*args !=
'?'))
384 Info(
"Create",
"Starting FastCGI server on port %s", sport.
Data() + 1);
397 Error(
"Create",
"ROOT compiled without fastcgi support");
void process_request(TFastCgi *engine, FCGX_Request *request, bool can_postpone)
void run_single_thread(TFastCgi *engine)
void run_multi_threads(TFastCgi *engine, Int_t nthrds)
void FCGX_ROOT_send_file(FCGX_Request *request, const char *fname)
typedef void((*Func_t)())
TFastCgi()
normal constructor
Bool_t IsTerminating() const
TString fTopName
! name of top item
std::unique_ptr< std::thread > fThrd
! thread which takes requests, can be many later
Bool_t fDebugMode
! debug mode, may required for fastcgi debugging in other servers
const char * GetTopName() const
virtual ~TFastCgi()
destructor
Bool_t Create(const char *args) override
initializes fastcgi variables and start thread, which will process incoming http requests
Int_t fSocket
! socket used by fastcgi
Bool_t IsDebugMode() const
Bool_t fTerminating
! set when http server wants to terminate all engines
virtual Bool_t CanPostpone() const
Return true if reply can be postponed by server
void ReplaceAllinContent(const std::string &from, const std::string &to, bool once=false)
Replace all occurrences of.
virtual void CheckWSPageContent(THttpWSHandler *)
Method used to modify content of web page used by web socket handler.
THttpServer * GetServer() const
Returns pointer to THttpServer associated with engine.
Bool_t IsFileRequested(const char *uri, TString &res) const
Check if file is requested, thread safe.
Bool_t ExecuteHttp(std::shared_ptr< THttpCallArg > arg)
Execute HTTP request.
static char * ReadFileContent(const char *filename, Int_t &len)
Reads content of file from the disk.
static const char * GetMimeType(const char *path)
Guess mime type base on file extension.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
const char * Data() const
TString & Append(const char *cs)
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
This class represents a WWW compatible URL.
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
Int_t GetIntValueFromOptions(const char *key) const
Return a value for a given key from the URL options as an Int_t, a missing key returns -1.
void ParseOptions() const
Parse URL options into a key/value map.
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.