summaryrefslogtreecommitdiffhomepage
path: root/plugins/fcgi/socket.h
blob: ceee2a4f88a752bcebc89db8d47ae4ac6c947f45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#pragma once

#include "fastcgiprocess.h"
#include "fcgiid.h"

#include <boost/asio.hpp>

#include <cstdint>
#include <mutex>
#include <set>
#include <string>

class fcgi_eof_error: public std::runtime_error
{
public:
 fcgi_eof_error(const std::string& what_arg): std::runtime_error(what_arg) {}
};

class fcgi_broken_pipe_error: public std::runtime_error
{
public:
 fcgi_broken_pipe_error(const std::string& what_arg): std::runtime_error(what_arg) {}
};

class Socket
{
 std::mutex m_mutex; // guard socket use in different threads
 FCGI_ID m_fcgi_id;

public:
 virtual ~Socket() {}

 std::mutex& getMutex();

 FCGI_ID& fcgi_id();

 virtual void open() = 0;
 virtual void close() = 0;
 virtual bool is_open() = 0;
 virtual size_t write(const std::vector<char>& data) = 0;
 virtual size_t read(std::vector<char>& data) = 0;
};

class SocketFactory
{
 boost::asio::io_context m_io_context;

public:
 SocketFactory();
 std::shared_ptr<Socket> create(const std::string& name);
};

class TCPSocket: public Socket
{
 boost::asio::io_context& m_io_context;
 std::string m_host;
 std::string m_port;
 boost::asio::ip::tcp::socket m_socket;

public:
 TCPSocket(const std::string& host, const std::string& port, boost::asio::io_context& io_context);
 ~TCPSocket() override;
 
 void open() override;
 void close() override;
 bool is_open() override;
 size_t write(const std::vector<char>& data) override;
 size_t read(std::vector<char>& data) override;
};

class FileSocket: public Socket
{
 std::string m_app_addr;
 boost::asio::local::stream_protocol::socket m_socket;

public:
 FileSocket(const std::string& app_addr, boost::asio::io_context& io_context);
 ~FileSocket() override;
 
 void open() override;
 void close() override;
 bool is_open() override;
 size_t write(const std::vector<char>& data) override;
 size_t read(std::vector<char>& data) override;
};

// File Socket, with Application started by us
class FileSocketApp: public Socket
{
public:
 FileSocketApp(const std::string& app_addr, boost::asio::io_context& io_context);
 ~FileSocketApp() override;
 
 void open() override;
 void close() override;
 bool is_open() override;
 size_t write(const std::vector<char>& data) override;
 size_t read(std::vector<char>& data) override;

private:
 std::string m_socket_file;
 FastCGIProcess m_fcgi_process; // Application server
 FileSocket m_file_socket; // Connection from client side
};