summaryrefslogtreecommitdiffhomepage
path: root/plugins/fcgi
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-05-02 22:23:11 +0200
committerRoland Reichwein <mail@reichwein.it>2020-05-02 22:23:11 +0200
commit5f39c4bcd3ea85ce6a30446d23ccae0542bfbdaf (patch)
tree44ba3d16510b1ab775a7a3ada912ce045ee6c578 /plugins/fcgi
parent17433b0cbcacc3f41fd500551baf4d52d291e0c9 (diff)
Fix FCGI with KEEP TCP open
Diffstat (limited to 'plugins/fcgi')
-rw-r--r--plugins/fcgi/fcgi.cpp79
-rw-r--r--plugins/fcgi/fcgi.h5
2 files changed, 49 insertions, 35 deletions
diff --git a/plugins/fcgi/fcgi.cpp b/plugins/fcgi/fcgi.cpp
index 23fa91e..b9e279f 100644
--- a/plugins/fcgi/fcgi.cpp
+++ b/plugins/fcgi/fcgi.cpp
@@ -4,7 +4,6 @@
#include <boost/algorithm/string/predicate.hpp>
#include <boost/array.hpp>
-#include <boost/asio.hpp>
#include <boost/endian/conversion.hpp>
#include <boost/coroutine2/coroutine.hpp>
#include <boost/process.hpp>
@@ -346,52 +345,55 @@ std::string fcgi_plugin::fcgiQuery(FCGIContext& context)
size_t pos { app_addr.find(':') };
if (pos != app_addr.npos) { // host:port
- boost::asio::io_context io_context; // TODO: member?
-
- tcp::resolver resolver(io_context);
- auto endpoints{resolver.resolve(app_addr.substr(0, pos), app_addr.substr(pos + 1))};
- tcp::socket socket(io_context);
- boost::asio::connect(socket, endpoints);
+ auto endpoints{m_resolver.resolve(app_addr.substr(0, pos), app_addr.substr(pos + 1))};
+ bool opening{false};
+ if (!m_socket.is_open()) {
+ std::cout << "FCGI: Opening new socket" << std::endl;
+ boost::asio::connect(m_socket, endpoints);
+ opening = true;
+ }
- if (!socket.is_open()) {
+ if (!m_socket.is_open()) {
return HttpStatus("500", "FCGI connection", context.SetResponseHeader);
}
- FCGI_Record get_values{FCGI_GET_VALUES, 0, system_config_bytes};
- if (socket.write_some(boost::asio::buffer(get_values.getBuffer())) != get_values.getBuffer().size())
- std::cerr << "Warning: Not all bytes written 1" << std::endl;
+ if (opening) {
+ FCGI_Record get_values{FCGI_GET_VALUES, 0, system_config_bytes};
+ if (m_socket.write_some(boost::asio::buffer(get_values.getBuffer())) != get_values.getBuffer().size())
+ std::cerr << "Warning: Not all bytes written 1" << std::endl;
+ }
FCGI_ID_Guard id_guard(m_fcgi_id);
uint16_t id {id_guard.getID()};
- FCGI_Record begin_request{FCGI_BEGIN_REQUEST, id, FCGI_RESPONDER, 0/*FCGI_KEEP_CONN*/};
- if (socket.write_some(boost::asio::buffer(begin_request.getBuffer())) != begin_request.getBuffer().size())
+ FCGI_Record begin_request{FCGI_BEGIN_REQUEST, id, FCGI_RESPONDER, FCGI_KEEP_CONN};
+ if (m_socket.write_some(boost::asio::buffer(begin_request.getBuffer())) != begin_request.getBuffer().size())
std::cerr << "Warning: Not all bytes written 3" << std::endl;
FCGI_Record params{FCGI_PARAMS, id, env_bytes};
- if (socket.write_some(boost::asio::buffer(params.getBuffer())) != params.getBuffer().size())
+ if (m_socket.write_some(boost::asio::buffer(params.getBuffer())) != params.getBuffer().size())
std::cerr << "Warning: Not all bytes written 4" << std::endl;
if (env_bytes.size()) {
FCGI_Record params_end{FCGI_PARAMS, id, std::string{}};
- if (socket.write_some(boost::asio::buffer(params_end.getBuffer())) != params_end.getBuffer().size())
+ if (m_socket.write_some(boost::asio::buffer(params_end.getBuffer())) != params_end.getBuffer().size())
std::cerr << "Warning: Not all bytes written 5" << std::endl;
}
std::string body {context.GetRequestParam("body")};
FCGI_Record stdin_{FCGI_STDIN, id, body};
- if (socket.write_some(boost::asio::buffer(stdin_.getBuffer())) != stdin_.getBuffer().size())
+ if (m_socket.write_some(boost::asio::buffer(stdin_.getBuffer())) != stdin_.getBuffer().size())
std::cerr << "Warning: Not all bytes written 6" << std::endl;
if (body.size()) {
FCGI_Record stdin_end{FCGI_STDIN, id, std::string{}};
- if (socket.write_some(boost::asio::buffer(stdin_end.getBuffer())) != stdin_end.getBuffer().size())
+ if (m_socket.write_some(boost::asio::buffer(stdin_end.getBuffer())) != stdin_end.getBuffer().size())
std::cerr << "Warning: Not all bytes written 7" << std::endl;
}
#if 0
FCGI_Record data{FCGI_DATA, id, std::string{}};
- if (socket.write_some(boost::asio::buffer(data.getBuffer())) != data.getBuffer().size())
+ if (m_socket.write_some(boost::asio::buffer(data.getBuffer())) != data.getBuffer().size())
std::cerr << "Warning: Not all bytes written 8" << std::endl;
#endif
@@ -400,7 +402,7 @@ std::string fcgi_plugin::fcgiQuery(FCGIContext& context)
std::vector<char> inbuf_part(1024);
while (!ended) {
try {
- size_t got {socket.read_some(boost::asio::buffer(inbuf_part))};
+ size_t got {m_socket.read_some(boost::asio::buffer(inbuf_part))};
inbuf.insert(inbuf.end(), inbuf_part.begin(), inbuf_part.begin() + got);
} catch (const boost::system::system_error& ex) {
if (ex.code() == boost::asio::error::eof) {
@@ -410,22 +412,26 @@ std::string fcgi_plugin::fcgiQuery(FCGIContext& context)
ended = true;
}
}
-
- try {
- FCGI_Record r{inbuf};
- if (r.getType() == FCGI_END_REQUEST) {
- ended = true;
- } else if (r.getType() == FCGI_STDOUT) {
- output_data += r.getContent();
- } else if (r.getType() == FCGI_STDERR) {
- std::cerr << "FCGI STDERR: " << r.getContent();
- } else if (r.getType() == FCGI_GET_VALUES_RESULT) {
- FCGI_DecodeEnv(r.getContent(), app_values);
- DumpAppValues(app_values);
- } else
- throw std::runtime_error("Unhandled FCGI type: "s + std::to_string(r.getType()));
- } catch (const std::length_error& ex) {
- // ignore if not enough data available yet
+
+ while (inbuf.size() > 0) {
+
+ try {
+ FCGI_Record r{inbuf};
+ if (r.getType() == FCGI_END_REQUEST) {
+ ended = true;
+ } else if (r.getType() == FCGI_STDOUT) {
+ output_data += r.getContent();
+ } else if (r.getType() == FCGI_STDERR) {
+ std::cerr << "FCGI STDERR: " << r.getContent();
+ } else if (r.getType() == FCGI_GET_VALUES_RESULT) {
+ FCGI_DecodeEnv(r.getContent(), app_values);
+ DumpAppValues(app_values);
+ } else
+ throw std::runtime_error("Unhandled FCGI type: "s + std::to_string(r.getType()));
+ } catch (const std::length_error& ex) {
+ // ignore if not enough data available yet
+ break;
+ }
}
}
} else { // Unix domain socket, or file to start
@@ -476,6 +482,9 @@ std::string fcgi_plugin::name()
}
fcgi_plugin::fcgi_plugin()
+ : m_io_context()
+ , m_resolver(m_io_context)
+ , m_socket(m_io_context)
{
//std::cout << "Plugin constructor" << std::endl;
}
diff --git a/plugins/fcgi/fcgi.h b/plugins/fcgi/fcgi.h
index 164fecb..22d7fba 100644
--- a/plugins/fcgi/fcgi.h
+++ b/plugins/fcgi/fcgi.h
@@ -2,6 +2,8 @@
#include "../../plugin_interface.h"
+#include <boost/asio.hpp>
+
#include <set>
#include <cstdint>
@@ -55,6 +57,9 @@ struct FCGIContext;
class fcgi_plugin: public webserver_plugin_interface
{
FCGI_ID m_fcgi_id;
+ boost::asio::io_context m_io_context;
+ boost::asio::ip::tcp::resolver m_resolver;
+ boost::asio::ip::tcp::socket m_socket;
public:
fcgi_plugin();