summaryrefslogtreecommitdiff
path: root/public/gcsdk/http.h
blob: b766ca276a6af18a87f03fbd734766f4f1f07475 (plain) (blame)
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
//====== Copyright � 1996-2010, Valve Corporation, All rights reserved. =======
//
// Purpose: HTTP related enums and objects, stuff that both clients and server use should go here
//
//=============================================================================

#ifndef HTTP_H
#define HTTP_H
#ifdef _WIN32
#pragma once
#endif

#include "steam/steamhttpenums.h"
#include "tier1/KeyValues.h"
#include "tier1/netadr.h"
#include "gcsdk/bufferpool.h"

class CMsgHttpRequest;
class CMsgHttpResponse;
#include "tier0/memdbgon.h"

namespace GCSDK
{

// Container class for useful parsing methods and other utility code used by client or server http code
class CHTTPUtil
{
public:
	// Check if a status code allows a body to exist
	static bool BStatusCodeAllowsBody( EHTTPStatusCode eHTTPStatus );

};


class CHTTPRequest;
class CHTTPResponse;
class CHTTPServerClientConnection;

class CHTTPRequest
{
public:

	CHTTPRequest();
	CHTTPRequest( CMsgHttpRequest* pProto );
	CHTTPRequest( EHTTPMethod eMethod, const char *pchHost, const char *pchRelativeURL );
	CHTTPRequest( EHTTPMethod eMethod, const char *pchAbsoluteURL );
	~CHTTPRequest();

	// Get the method type for the request (ie, GET, POST, etc)
	EHTTPMethod GetEHTTPMethod() const { return ( EHTTPMethod )m_pProto->request_method(); }

	// Get the relative URL for the request
	const char *GetURL() const { return m_pProto->url().c_str(); }

	// Get the value of a GET parameter, using the default value if not set.  This is case-insensitive by default.
	const CMsgHttpRequest_QueryParam *GetGETParam( const char *pchGetParamName, bool bMatchCase = false ) const;
	const char *GetGETParamString( const char *pchGetParamName, const char *pchDefault, bool bMatchCase = false ) const;
	bool	GetGETParamBool( const char *pchGetParamName, bool bDefault, bool bMatchCase = false ) const;
	int32	GetGETParamInt32( const char *pchGetParamName, int32 nDefault, bool bMatchCase = false ) const;
	uint32	GetGETParamUInt32( const char *pchGetParamName, uint32 unDefault, bool bMatchCase = false ) const;
	int64	GetGETParamInt64( const char *pchGetParamName, int64 nDefault, bool bMatchCase = false ) const;
	uint64	GetGETParamUInt64( const char *pchGetParamName, uint64 unDefault, bool bMatchCase = false ) const;
	float	GetGETParamFloat( const char *pchGetParamName, float fDefault, bool bMatchCase = false ) const;


	// Get the value of a POST parameter, using the default value if not set.  This is case-insensitive by default.
	const CMsgHttpRequest_QueryParam *GetPOSTParam( const char *pchPostParamName, bool bMatchCase = false ) const;
	const char *GetPOSTParamString( const char *pchGetParamName, const char *pchDefault, bool bMatchCase = false ) const;
	bool	GetPOSTParamBool( const char *pchGetParamName, bool bDefault, bool bMatchCase = false ) const;
	int32	GetPOSTParamInt32( const char *pchGetParamName, int32 nDefault, bool bMatchCase = false ) const;
	uint32	GetPOSTParamUInt32( const char *pchGetParamName, uint32 unDefault, bool bMatchCase = false ) const;
	int64	GetPOSTParamInt64( const char *pchGetParamName, int64 nDefault, bool bMatchCase = false ) const;
	uint64	GetPOSTParamUInt64( const char *pchGetParamName, uint64 unDefault, bool bMatchCase = false ) const;
	float	GetPOSTParamFloat( const char *pchGetParamName, float fDefault, bool bMatchCase = false ) const;

	// Add a GET param to the request
	void SetGETParamString( const char *pchGetParamName, const char *pString ) { SetGETParamRaw( pchGetParamName, (uint8*)pString, Q_strlen(pString) ); }
	void SetGETParamBool( const char *pchPostParamName, bool bValue ) { SetGETParamRaw( pchPostParamName, (uint8*)(bValue ? "1" : "0"), 1 ); }
	void SetGETParamInt32( const char *pchPostParamName, int32 nValue ) { CNumStr str( nValue ); SetGETParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }
	void SetGETParamUInt32( const char *pchPostParamName, uint32 unValue ) { CNumStr str( unValue ); SetGETParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }
	void SetGETParamInt64( const char *pchPostParamName, int64 nValue ) { CNumStr str( nValue ); SetGETParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }
	void SetGETParamUInt64( const char *pchPostParamName, uint64 unValue ) { CNumStr str( unValue ); SetGETParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }
	void SetGETParamFloat( const char *pchPostParamName, float fValue ) { CNumStr str( fValue ); SetGETParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }

	// Add a POST param to the request given a string for the name and value
	void SetPOSTParamString( const char *pchPostParamName, const char *pString ) { SetPOSTParamRaw( pchPostParamName, (uint8*)pString, Q_strlen(pString) ); }
	void SetPOSTParamBool( const char *pchPostParamName, bool bValue ) { SetPOSTParamRaw( pchPostParamName, (uint8*)(bValue ? "1" : "0"), 1 ); }
	void SetPOSTParamInt32( const char *pchPostParamName, int32 nValue ) { CNumStr str( nValue ); SetPOSTParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }
	void SetPOSTParamUInt32( const char *pchPostParamName, uint32 unValue ) { CNumStr str( unValue ); SetPOSTParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }
	void SetPOSTParamInt64( const char *pchPostParamName, int64 nValue ) { CNumStr str( nValue ); SetPOSTParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }
	void SetPOSTParamUInt64( const char *pchPostParamName, uint64 unValue ) { CNumStr str( unValue ); SetPOSTParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }
	void SetPOSTParamFloat( const char *pchPostParamName, float fValue ) { CNumStr str( fValue ); SetPOSTParamRaw( pchPostParamName, (uint8*)str.String(), Q_strlen( str ) ); }

	// Adds a POST param containing raw data to the request. If you are using the Web API, you probably do not want this function
	void SetPOSTParamRaw( const char *pchPostParamName, uint8 *pData, uint32 cubDataLen );

	// Raw iteration support for GET and POST parameters
	uint32 GetPOSTParamCount() const					{ return m_pProto->post_params_size(); }
	const char* GetPOSTParamName( uint32 i ) const		{ return m_pProto->post_params( i ).name().c_str(); }
	const char* GetPOSTParamValue( uint32 i ) const		{ return m_pProto->post_params( i ).value().c_str(); }
	uint32 GetGETParamCount() const						{ return m_pProto->get_params_size(); }
	const char* GetGETParamName( uint32 i ) const		{ return m_pProto->get_params( i ).name().c_str(); }
	const char* GetGETParamValue( uint32 i ) const		{ return m_pProto->get_params( i ).value().c_str(); }

	// Fetch a request header by header name and convert it to a time value
	RTime32 GetRequestHeaderTimeValue( const char *pchRequestHeaderName, RTime32 rtDefault = 0 ) const;

	// Fetch a request headers value by header name
	const char *GetRequestHeaderValue( const char *pchRequestHeaderName, const char *pchDefault = NULL ) const;

	// Set a header field for the request
	void SetRequestHeaderValue( const char *pchHeaderName, const char *pchHeaderString );

	// Set the method for the request object
	void SetEHTTPMethod( EHTTPMethod eMethod ) { m_pProto->set_request_method( eMethod ); }

	// Set the relative URL for the request
	void SetURL( const char *pchURL ) 
	{ 
		AssertMsg( pchURL && pchURL[0] == '/', "URLs must start with the slash (/) character. Param: %s", pchURL );
		m_pProto->set_url( pchURL );
	}

	void SetURLDirect( const char *pchURL, size_t size ) 
	{ 
		AssertMsg( pchURL && pchURL[0] == '/', "URLs must start with the slash (/) character. Param: %s", pchURL );
		m_pProto->set_url( pchURL, size );
	}

	// Set body data
	void SetBodyData( const void *pubData, uint32 cubData );
	bool BHasBodyData()									{ return m_pProto->has_body(); }
	uint GetBodyDataSize() const							{ return (uint)m_pProto->body().size(); }
	const char* GetBodyData() const						{ return m_pProto->body().c_str(); }

	// Set hostname for request to target (or host it was received on)
	void SetHostname( const char *pchHost ) { m_pProto->set_hostname( pchHost ); }
	void SetHostnameDirect( const char *pchHost, uint32 unLength ) { m_pProto->set_hostname( pchHost, unLength ); }
	const char *GetHostname() const { return m_pProto->hostname().c_str(); }

	// Set the overall timeout in seconds for this request
	void SetAbsoluteTimeoutSeconds( uint32 unSeconds ) { m_pProto->set_absolute_timeout( unSeconds ); }

	// Get the total absolute timeout value for the request
	uint32 GetAbsoluteTimeoutSeconds() { return m_pProto->absolute_timeout(); }

	//accesses the HTTP message
	const CMsgHttpRequest& GetProtoObj() const		{ return *m_pProto; }

	static void RetrieveURLEncodedData( const char *pchQueryString, int nQueryStrLen, CUtlVector<CMsgHttpRequest_QueryParam> &vecParams );

protected:

	// Adds a GET param containing raw data to the request. If you are using the Web API, you probably do not want this function
	void SetGETParamRaw( const char *pchGetParamName, uint8 *pData, uint32 cubDataLen );

	// Common initialization code
	void Init( CMsgHttpRequest* pProto );

	//the protobuf object that stores all of our contents
	CMsgHttpRequest*	m_pProto;
	//whether or not we own this proto and should free it when the object is destroyed
	bool				m_bOwnProto;
};


//-----------------------------------------------------------------------------
// Purpose: A wrapper to CHTTPRequest for Steam WebAPIs. Host, mode, and API key 
//	are set automatically
//-----------------------------------------------------------------------------
class CSteamAPIRequest : public CHTTPRequest
{
public:
	CSteamAPIRequest( EHTTPMethod eMethod, const char *pchInterface, const char *pchMethod, int nVersion );
};


class CHTTPResponse
{
public:
	CHTTPResponse();
	virtual ~CHTTPResponse();

	// Get a specific headers data 
	const char *GetResponseHeaderValue( const char *pchName, const char *pchDefault = NULL ) const { return m_pkvResponseHeaders->GetString( pchName, pchDefault ); }

	// Set a specific headers data, will clobber any existing value for that header
	virtual void SetResponseHeaderValue( const char *pchName, const char *pchValue ) { m_pkvResponseHeaders->SetString( pchName, pchValue ); }

	// Set status code for response
	virtual void SetStatusCode( EHTTPStatusCode eStatusCode ) { m_eStatusCode = eStatusCode; }

	// Set the expiration header based on a time delta from now
	void SetExpirationHeaderDeltaFromNow( int32 nSecondsFromNow );

	// Set the expiration header based on a time delta from now
	void SetHeaderTimeValue( const char *pchHeaderName, RTime32 rtTimestamp );

	// Get the entire headers KV (in case you want to iterate them all or such)
	KeyValues *GetResponseHeadersKV() const { return m_pkvResponseHeaders; }

	// Accessors to the body data in the response
	const uint8 *GetPubBody() const			{ return (uint8*)m_pbufBody->Base(); }
	uint32 GetCubBody() const				{ return m_pbufBody->TellPut(); }
	const CUtlBuffer *GetBodyBuffer() const { return m_pbufBody; }
	CUtlBuffer *GetBodyBuffer()				{ return m_pbufBody; }

	// Accessor
	EHTTPStatusCode GetStatusCode() const { return m_eStatusCode; }

	// writes the response into a protobuf for use in messages
	void SerializeIntoProtoBuf( CMsgHttpResponse & response ) const;

	// reads the response out of a protobuf from a message
	void DeserializeFromProtoBuf( const CMsgHttpResponse & response );

protected:
	static CBufferPool &GetBufferPool();

	EHTTPStatusCode m_eStatusCode;
	CUtlBuffer *m_pbufBody;
	KeyValues *m_pkvResponseHeaders;
};

}
#include "tier0/memdbgoff.h"

#endif // HTTP_H