-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathHttpSrv.h
More file actions
355 lines (301 loc) · 10.6 KB
/
HttpSrv.h
File metadata and controls
355 lines (301 loc) · 10.6 KB
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
// ======================================================================================
// File : HttpSrv.h
// Author : Li Chen
// Last Change : 01/21/2011 | 15:37:43 PM | Friday,January
// Description :
// ======================================================================================
#ifndef GAMESERVICE_HTTPSRV_H
#define GAMESERVICE_HTTPSRV_H
namespace GameService
{
#if defined(_XBOX)
//-----------------------------------------------------------------------------
// Internal buffer length
//-----------------------------------------------------------------------------
#define HTTP_HOST_IP_STRING_LENGTH 128
#define INIT_BUFFER_SIZE 512
#define TCP_RECV_BUFFER_SIZE 512
#define HTTP_COMMAND_BUFFER_SIZE 512
//--------------------------------------------------------------------------------------
// Name: class MemoryBuffer
// Desc: Memory buffer, automatically expands as needed to hold more data
//--------------------------------------------------------------------------------------
class MemoryBuffer
{
public:
MemoryBuffer( GS_DWORD dwSize = INIT_BUFFER_SIZE )
{
m_pBuffer = NULL;
m_dwDataLength = 0;
m_dwBufferSize = 0;
if( ( dwSize < UINT_MAX ) && ( dwSize != 0 ) )
{
// remain malloc for pairing realloc - LiChen
m_pBuffer = ( BYTE* )malloc( dwSize + 1 ); // one more char, in case when using string funcions
if( m_pBuffer )
{
m_dwBufferSize = dwSize;
m_pBuffer[0] = 0;
}
}
};
~MemoryBuffer()
{
Clear();
};
// Add chunk of memory to buffer
BOOL Add( const void* p, GS_DWORD dwSize )
{
if( CheckSize( dwSize ) )
{
memcpy( m_pBuffer + m_dwDataLength, p, dwSize );
m_dwDataLength += dwSize;
*( m_pBuffer + m_dwDataLength ) = 0; // fill end zero
return TRUE;
}
else
{
return FALSE;
}
};
// Get the data in buffer
BYTE* GetData() const
{
return m_pBuffer;
};
// Get the lenght of data in buffer
GS_DWORD GetDataLength() const
{
return m_dwDataLength;
};
// Rewind the data pointer to the begining
void Rewind()
{
m_dwDataLength = 0; m_pBuffer[ 0 ] = 0;
};
GS_VOID Clear()
{
if( m_pBuffer )
// remain free for pairing realloc - LiChen
free( m_pBuffer );
m_pBuffer = NULL;
m_dwDataLength = 0;
m_dwBufferSize = 0;
}
private:
BYTE* m_pBuffer;
GS_DWORD m_dwDataLength;
GS_DWORD m_dwBufferSize;
// Automatically adjust increase buffer size if necessary
BOOL CheckSize( GS_DWORD dwSize )
{
if( m_dwBufferSize >= ( m_dwDataLength + dwSize ) )
{
return TRUE; // Enough space
}
else
{
// Try to double it
GS_DWORD dwNewSize = max( m_dwDataLength + dwSize, m_dwBufferSize * 2 );
BYTE* pNewBuffer = ( UCHAR* )realloc( m_pBuffer, dwNewSize + 1 ); // one more char
if( pNewBuffer )
{
m_pBuffer = pNewBuffer;
m_dwBufferSize = dwNewSize;
return TRUE;
}
else
{
// Failed
return FALSE;
}
}
}
};
//-----------------------------------------------------------------------------
// Internal Http buffer
//-----------------------------------------------------------------------------
struct HTTP_BUFFER
{
MemoryBuffer MB_request;
MemoryBuffer MB_response;
CHAR serverName[ HTTP_HOST_IP_STRING_LENGTH ];
GS_DWORD port;
WSAOVERLAPPED overlapped;
};
#elif defined(_PS3)
#define USE_PROXY (0)
#define PROXY_SERVER "proxy.hq.scei.sony.co.jp:10080"
#define HTTP_POOL_SIZE (128 * 1024)
#define INIT_QUEUE_SIZE (64)
#define BUFFER_SIZE (512)
#define HTML_BUFFER_MAX_SIZE (256 * 1024)
#define CONTENT_TYPE_TEXT_HTML "text/html"
/*E depth of links to follow */
#define MAX_DEPTH (1)
/*E enable/disable pipelining */
#define USE_PIPELINING (1)
/*E follow images */
#define PARSE_IMG (1)
/*E follow links */
#define PARSE_HREF (0)
/*E returns number of elements in array (x) */
#define ArrayCount(x) (sizeof(x)/sizeof(*x))
/* *** */
/*E HTTP Transaction states */
typedef enum {
HttpTransactionState_Free = 0, /* available */
HttpTransactionState_Create, /* newly created */
HttpTransactionState_Send, /* sending request */
HttpTransactionState_Receive, /* receiving response */
HttpTransactionState_Parse, /* parsing response */
HttpTransactionState_Destroy, /* destroying transaction */
HttpTransactionState_Unknown
} EHttpTransactionState;
/*E HTTP Transaction Management */
typedef struct {
size_t depth; /* */
uint64_t nContentLength; /* reported content-length */
uint64_t nBytesReceived; /* number of bytes received -- will cancel if > 8MB and HTML */
size_t bufferSize; /* current buffer size */
CellHttpTransId transID; /* transaction ID (NULL if available) */
CellHttpUri uri; /* transaction URI */
char *uriPool; /* */
char *buffer; /* receive buffer -- realloc'ed for HTML only */
int32_t cellState; /* current state */
int32_t code; /* status code */
EHttpTransactionState state;
bool bIsHtml; /* TRUE if content-type is text/html */
bool bHasContentLength; /* True if content-length available */
uint8_t reserved[2];
} CHttpTransaction;
/* *** */
/*E HTML parse state manager */
/*E note: not an exhaustive HTML parse state manager,
* by design, invalid HTML will break state manager
*/
typedef struct {
CHttpTransaction *httpTrans;
bool bInHtml;
bool bInHead;
bool bInBody;
bool bInScript;
uint8_t reserved[4];
} CHtmlParser;
/* *** */
/*E HTTP Pipeline Queue local state */
/*E !!! Could be instanced instead of static */
typedef struct lsv {
// intialized in SignIn.cpp:
// void *httpPool; /* libhttp memory pool */
size_t nNumBytesReceived; /* total number of bytes received */
char* baseURI; /* base URI for initial request */
CellHttpClientId clientID;
CHttpTransaction *transactionQueue; /* array of in-progress transactions */
int nNumTransactions; /* number of pending transactions */
int nMaxNumTransactions; /* current array extent */
int nTotalTransactions; /* total number of queued transactions */
} CLSV;
#endif
class HttpSrv
{
public:
HttpSrv();
virtual ~HttpSrv();
GS_BOOL Initialize();
GS_VOID Finalize();
GS_VOID AllocSpace(GS_DWORD size)
{
GS_Assert(m_pRecvData == NULL);
m_pRecvData = GS_NEW GS_BYTE[size];
m_iRecvSize = 0;
}
GS_VOID RecordBuffer(GS_DWORD bytesReceived, GS_BYTE* buffer, GS_DWORD bufSize)
{
memcpy(m_pRecvData + bytesReceived, buffer, bufSize);
}
#if defined(_XBOX)
enum HTTP_STATUS
{
HTTP_STATUS_READY,
HTTP_STATUS_BUSY,
HTTP_STATUS_DONE,
HTTP_STATUS_ERROR
};
// Content Data, exclude the HTTP header
BYTE* GetResponseContentData() const { return m_pResponseContentData; };
// Content Data Length, exclude the HTTP header
GS_DWORD GetResponseContentDataLength() const { return m_dwResponseContentDataLength; };
// Simple status, HTTP_STATUS_BUSY means it's still waiting for the last HTTP response
HTTP_STATUS GetStatus() { return m_status; };
VOID SetStatus( HTTP_STATUS status ) { m_status = status; };
// HTTP 200, 500 etc
GS_DWORD GetResponseCode() { return m_dwResponseCode; };
// Socket level error
GS_VOID ReportError(GS_DWORD errorCode);
GS_DWORD GetSocketErrorCode() { return m_dwSocketErrorCode; };
VOID SetSocketErrorCode( GS_DWORD dwCode ) { m_dwSocketErrorCode = dwCode; };
// Internal http buffer
HTTP_BUFFER& GetInternalBuffer() { return m_buffer; };
#elif defined(_PS3)
GS_INT HttpTransactionDelete(CHttpTransaction* httpTrans);
GS_INT HttpTransactionNew(CHttpTransaction* httpTrans, const char* uri, const char* method, size_t depth);
GS_INT HttpTransactionSend(CHttpTransaction* httpTrans);
GS_INT QueueUri(const char *uri, const char *method, size_t depth);
GS_INT RequeueUri(CHttpTransaction* httpTrans, const char *method, const char *problem);
GS_INT HttpTransactionCheck(CHttpTransaction* httpTrans);
GS_INT HttpTransactionReceive(CHttpTransaction* httpTrans);
// GS_BOOL isAbsolutePath(const char* path);
CHttpTransaction* HttpTransactionFindByID(CellHttpTransId transID);
GS_INT HttpTransactionParse(CHttpTransaction* httpTrans);
GS_VOID HtmlReferenceEnqueue(CHttpTransaction* httpTrans, const char* path);
GS_INT QueueProcess(void);
#endif
GS_VOID ClearData();
const GS_CHAR* GetURL() { return m_cURL; }
GS_VOID StartQuery();
GS_VOID EndQuery();
// User interface
GS_BOOL QueryURL(const char* url);
GS_BOOL IsLastQueryFinished()
{
if (m_bIsQueryStarted)
{
if (!m_bIsInQuery)
{
m_bIsQueryStarted = FALSE;
return TRUE;
}
}
return FALSE;
}
GS_BYTE* GetRecvData() { return m_pRecvData; }
GS_UINT64 GetRecvSize() { return m_iRecvSize; }
private:
char m_cURL[256];
#if defined(_XBOX)
HTTP_STATUS m_status;
// HTTP buffer, include outgoing and incoming buffer
HTTP_BUFFER m_buffer;
BYTE* m_pResponseContentData;
GS_DWORD m_dwResponseContentDataLength;
GS_DWORD m_dwResponseCode;
GS_DWORD m_dwSocketErrorCode;
#elif defined(_PS3)
GS_INT m_iFullQueueWarned;
CLSV m_lsv;
system_time_t m_iQueryStartTime;
#endif
GS_BYTE* m_pRecvData;
GS_UINT64 m_iRecvSize;
GS_BOOL m_bIsQueryStarted;
GS_BOOL m_bIsInQuery;
};
#if defined(_XBOX)
// Worker thread entrance or main processing routine
static GS_DWORD WINAPI HttpSendCommand( LPVOID lpParameter );
#elif defined(_PS3)
static void GS_HttpQueueProcess_Thread(uint64_t instance);
#endif
}
#endif