-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathFcgi.cpp
143 lines (109 loc) · 2.32 KB
/
Fcgi.cpp
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "Fcgi.hpp"
#include "../InputStream.hpp"
#include "../OutputStream.hpp"
BEGIN_INANITY_NET
// class Fcgi::InStream
class Fcgi::InStream : public InputStream
{
private:
FCGX_Stream* stream;
public:
InStream() : stream(nullptr) {}
void SetStream(FCGX_Stream* stream)
{
this->stream = stream;
}
size_t Read(void* data, size_t size)
{
return FCGX_GetStr((char*)data, (int)size, stream);
}
};
// class Fcgi::OutStream
class Fcgi::OutStream : public OutputStream
{
private:
FCGX_Stream* stream;
public:
OutStream() : stream(nullptr) {}
void SetStream(FCGX_Stream* stream)
{
this->stream = stream;
}
void Write(const void* data, size_t size)
{
if(FCGX_PutStr((const char*)data, (int)size, stream) != (int)size)
THROW("Can't write to FCGI stream");
}
};
// class Fcgi::Request
Fcgi::Request::Request(int fd)
{
if(FCGX_InitRequest(&request, fd, 0) != 0)
THROW("Can't init request");
inputStream = NEW(InStream());
outputStream = NEW(OutStream());
}
Fcgi::Request::~Request()
{
FCGX_Free(&request, 1);
}
ptr<InputStream> Fcgi::Request::GetInputStream() const
{
return inputStream;
}
ptr<OutputStream> Fcgi::Request::GetOutputStream() const
{
return outputStream;
}
char** Fcgi::Request::GetEnv() const
{
return request.envp;
}
const char* Fcgi::Request::GetParam(const char* name) const
{
return FCGX_GetParam(name, request.envp);
}
void Fcgi::Request::OutputHeader(const char* header, const char* value)
{
FCGX_FPrintF(request.out, "%s: %s\r\n", header, value);
}
void Fcgi::Request::OutputStatus(const char* status)
{
OutputHeader("Status", status);
}
void Fcgi::Request::OutputContentType(const char* contentType)
{
OutputHeader("ContentType", contentType);
}
void Fcgi::Request::OutputBeginResponse()
{
FCGX_PutS("\r\n", request.out);
}
void Fcgi::Request::End()
{
FCGX_Finish_r(&request);
}
bool Fcgi::Request::Accept()
{
if(FCGX_Accept_r(&request) < 0)
return false;
inputStream->SetStream(request.in);
outputStream->SetStream(request.out);
return true;
}
// class Fcgi
Fcgi::Fcgi(const char* socketName, int backlogSize)
{
FCGX_Init();
fd = FCGX_OpenSocket(socketName, backlogSize);
if(fd < 0)
THROW("Can't open socket");
}
ptr<Fcgi::Request> Fcgi::Accept()
{
ptr<Request> request = NEW(Request(fd));
if(!request->Accept())
return nullptr;
return request;
}
END_INANITY_NET