summaryrefslogtreecommitdiff
path: root/src/fastcgi.h
blob: 83e9b83e076bd787be270625ef3ca826cc8bd19a (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#ifndef BU_FAST_CGI_H
#define BU_FAST_CGI_H

#include "bu/fstring.h"
#include "bu/hash.h"
#include "bu/array.h"
#include "bu/socket.h"
#include "bu/serversocket.h"

namespace Bu
{
	class Stream;

	class FastCgi
	{
	public:
		FastCgi( int iPort );
		FastCgi();
		virtual ~FastCgi();

		static bool isEmbedded();

		typedef Bu::Hash<Bu::FString, Bu::FString> StrHash;
		enum RequestType
		{
			typeBeginRequest	= 1,
			typeAbortRequest	= 2,
			typeEndRequest		= 3,
			typeParams			= 4,
			typeStdIn			= 5,
			typeStdOut			= 6,
			typeStdErr			= 7,
			typeData			= 8,
			typeGetValues		= 9,
			typeGetValuesResult	= 10
		};

		enum Role
		{
			roleResponder		= 1,
			roleAuthorizer		= 2,
			roleFilter			= 3
		};

		enum Flags
		{
			flagsKeepConn		= 1
		};

		enum Status
		{
			statusRequestComplete	= 0,
			statusCantMpxConn		= 1,
			statusOverloaded		= 2,
			statusUnknownRole		= 3
		};

		typedef struct {
			uint8_t uVersion;
			uint8_t uType;
			uint16_t uRequestId;
			uint16_t uContentLength;
			uint8_t uPaddingLength;
			uint8_t uReserved;
		} Record;

		typedef struct {
			uint16_t uRole;
			uint8_t uFlags;
			uint8_t reserved[5];
		} BeginRequestBody;

		typedef struct {
			uint32_t uStatus;
			uint8_t uProtocolStatus;
			uint8_t reserved[3];
		} EndRequestBody;

		typedef struct Channel {
			Channel() : uFlags( 0 ) { }
			StrHash hParams;
			Bu::FString sStdIn;
			Bu::FString sData;
			uint8_t uFlags;
		} Channel;

		enum ChannelFlags
		{
			chflgParamsDone		= 0x01,
			chflgStdInDone		= 0x02,
			chflgDataDone		= 0x04,

			chflgAllDone		= 0x03
		};

		virtual void run();

		virtual void init() { };
		virtual int request( const StrHash &hParams,
			const Bu::FString &sStdIn, Bu::Stream &sStdOut,
			Bu::Stream &sStdErr )=0;
		virtual void deinit() { };

	private:
		void read( Bu::Socket &s, Record &r );
		void read( Bu::Socket &s, BeginRequestBody &b );
		uint32_t readLen( Bu::Socket &s, uint16_t &uUsed );
		void readPair( Bu::Socket &s, StrHash &hParams, uint16_t &uUsed );

		void write( Bu::Socket &s, Record r );
		void write( Bu::Socket &s, EndRequestBody b );

	private:
		Bu::ServerSocket *pSrv;
		bool bRunning;
		Bu::Array<Channel *> aChannel;
	};
};

#endif