23#include "uriencoder.h"
31using namespace NSROOT;
33WSRequest::WSRequest(
const std::string& server,
unsigned port)
38, m_service_method(WS_METHOD_Get)
39, m_charset(REQUEST_STD_CHARSET)
41, m_contentType(WS_CTYPE_Form)
48 RequestAcceptEncoding(
true);
51WSRequest::WSRequest(
const std::string& server,
unsigned port,
bool secureURI)
54, m_secure_uri(secureURI)
56, m_service_method(WS_METHOD_Get)
57, m_charset(REQUEST_STD_CHARSET)
59, m_contentType(WS_CTYPE_Form)
64 RequestAcceptEncoding(
true);
67WSRequest::WSRequest(
const URIParser& uri, WS_METHOD method)
70, m_service_method(method)
71, m_charset(REQUEST_STD_CHARSET)
73, m_contentType(WS_CTYPE_Form)
78 m_server.assign(uri.Host());
79 if (uri.Scheme() && strncmp(uri.Scheme(),
"https", 5) == 0)
82 m_port = uri.Port() ? uri.Port() : 443;
85 m_port = uri.Port() ? uri.Port() : 80;
89 m_service_url.append(uri.Path());
92 m_service_url.append(
"#").append(uri.Fragment());
95 m_contentData.append(uri.Params());
98 RequestAcceptEncoding(
true);
101WSRequest::~WSRequest()
105WSRequest::WSRequest(
const WSRequest& o,
const URIParser& redirection)
106: m_server(o.m_server)
108, m_secure_uri(o.m_secure_uri)
109, m_service_method(o.m_service_method)
110, m_charset(o.m_charset)
111, m_accept(o.m_accept)
112, m_contentType(o.m_contentType)
113, m_contentTypeStr(o.m_contentTypeStr)
114, m_contentData(o.m_contentData)
115, m_headers(o.m_headers)
116, m_userAgent(o.m_userAgent)
122 if (redirection.Host())
123 m_server.assign(redirection.Host());
125 if (redirection.Scheme())
127 if (strncmp(redirection.Scheme(),
"https", 5) == 0)
130 m_port = redirection.Port() ? redirection.Port() : 443;
134 m_secure_uri = false;
135 m_port = redirection.Port() ? redirection.Port() : 80;
141 if (redirection.Path())
142 m_service_url.append(redirection.Path());
150 if (redirection.Fragment())
151 m_service_url.append(
"#").append(redirection.Fragment());
152 else if (o_uri.Fragment())
153 m_service_url.append(
"#").append(o_uri.Fragment());
160void WSRequest::RequestService(
const std::string& url, WS_METHOD method)
163 m_service_method = method;
166void WSRequest::RequestAccept(
const std::string& contentType)
168 m_accept = contentType;
171void WSRequest::RequestAcceptEncoding(
bool yesno)
175 SetHeader(ws_header_to_str(WS_HEADER_Accept_Encoding),
"gzip, deflate");
177 SetHeader(ws_header_to_str(WS_HEADER_Accept_Encoding),
"");
180 SetHeader(ws_header_to_str(WS_HEADER_Accept_Encoding),
"");
184void WSRequest::SetUserAgent(
const std::string& value)
189void WSRequest::SetHeader(
const std::string& field,
const std::string& value)
191 std::string _key(field);
192 std::transform(_key.cbegin(), _key.cend(), _key.begin(), ::toupper);
193 m_headers[_key] = std::make_pair(field, value);
196void WSRequest::ClearHeader(
const std::string& field)
198 std::string _key(field);
199 std::transform(_key.cbegin(), _key.cend(), _key.begin(), ::toupper);
200 std::map<std::string, header_t>::const_iterator it = m_headers.find(_key);
201 if (it != m_headers.end())
205void WSRequest::SetContentParam(
const std::string& param,
const std::string& value)
207 if (m_contentType != WS_CTYPE_Form)
209 if (!m_contentData.empty())
210 m_contentData.append(
"&");
211 m_contentData.append(param).append(
"=").append(urlencode(value));
214void WSRequest::SetContentCustom(
const std::string& contentType,
const char *content)
216 m_contentType = WS_CTYPE_UNKNOWN;
217 m_contentTypeStr = contentType;
218 m_contentData = content;
221void WSRequest::ClearContent()
223 m_contentData.clear();
224 m_contentType = WS_CTYPE_Form;
225 m_contentTypeStr.clear();
228bool WSRequest::WriteMessage(WSRequestStreamSink& sink)
const
230 switch (m_service_method)
233 return WriteMessageGET(sink,
"GET");
235 return WriteMessagePOST(sink,
"POST");
237 return WriteMessageGET(sink,
"HEAD");
238 case WS_METHOD_Subscribe:
239 return WriteMessageGET(sink,
"SUBSCRIBE");
240 case WS_METHOD_Unsubscribe:
241 return WriteMessageGET(sink,
"UNSUBSCRIBE");
242 case WS_METHOD_Notify:
243 return WriteMessagePOST(sink,
"NOTIFY");
245 return WriteMessagePOST(sink,
"PUT");
246 case WS_METHOD_Delete:
247 return WriteMessageGET(sink,
"DELETE");
248 case WS_METHOD_Options:
249 return WriteMessageGET(sink,
"OPTIONS");
255bool WSRequest::WriteCommonHeading(WSRequestStreamSink& sink)
const
262 msg.append(ws_header_to_str(WS_HEADER_Host)).append(
": ");
263 if (m_server.find(
':') == std::string::npos)
264 msg.append(m_server);
266 msg.append(
"[").append(m_server).append(
"]");
267 unsigned len = uint_to_strdec(m_port, buf.data, 12, 0);
268 msg.append(
":").append(buf.data, len).append(WS_CRLF);
271 if (m_userAgent.empty())
272 msg.append(ws_header_to_str(WS_HEADER_User_Agent)).append(
": " REQUEST_USER_AGENT WS_CRLF);
274 msg.append(ws_header_to_str(WS_HEADER_User_Agent)).append(
": ").append(m_userAgent).append(WS_CRLF);
277 msg.append(ws_header_to_str(WS_HEADER_Connection)).append(
": " REQUEST_CONNECTION WS_CRLF);
280 if (!m_accept.empty())
281 msg.append(ws_header_to_str(WS_HEADER_Accept)).append(
": ").append(m_accept).append(WS_CRLF);
284 msg.append(ws_header_to_str(WS_HEADER_Accept_Charset)).append(
": ").append(m_charset).append(WS_CRLF);
286 if (!sink.WriteRequestStream(msg.c_str(), msg.size()))
290 for (std::map<std::string, header_t>::const_iterator it = m_headers.begin(); it != m_headers.end(); ++it)
292 msg.assign(it->second.first).append(
": ").append(it->second.second).append(WS_CRLF);
293 if (!sink.WriteRequestStream(msg.c_str(), msg.size()))
300bool WSRequest::WriteMessageGET(WSRequestStreamSink& sink,
const char* method)
const
306 msg.append(method).append(
" ").append(m_service_url);
307 if (!m_contentData.empty() && m_contentType == WS_CTYPE_Form)
308 msg.append(
"?").append(m_contentData);
309 msg.append(
" " REQUEST_PROTOCOL WS_CRLF);
311 DBG(DBG_PROTO,
"%s: %s", __FUNCTION__, msg.c_str());
312 if (!sink.WriteRequestStream(msg.c_str(), msg.size()))
314 if (!WriteCommonHeading(sink))
317 if (!sink.WriteRequestStream(WS_CRLF, WS_CRLF_LEN))
320 return sink.FlushRequestStream();
323bool WSRequest::WriteMessagePOST(WSRequestStreamSink& sink,
const char* method)
const
329 msg.append(method).append(
" ").append(m_service_url).append(
" " REQUEST_PROTOCOL WS_CRLF);
331 DBG(DBG_PROTO,
"%s: %s", __FUNCTION__, msg.c_str());
332 if (!sink.WriteRequestStream(msg.c_str(), msg.size()))
334 if (!WriteCommonHeading(sink))
337 if (!m_contentData.empty() && m_contentType != WS_CTYPE_None)
340 unsigned bl = uint_to_strdec(m_contentData.size(), buf.data, 12, 0);
342 if (m_contentType == WS_CTYPE_UNKNOWN)
343 msg.append(ws_header_to_str(WS_HEADER_Content_Type)).append(
": ").append(m_contentTypeStr);
345 msg.append(ws_header_to_str(WS_HEADER_Content_Type)).append(
": ").append(ws_ctype_to_str(m_contentType));
346 msg.append(
"; charset=" REQUEST_STD_CHARSET WS_CRLF);
347 msg.append(ws_header_to_str(WS_HEADER_Content_Length)).append(
": ").append(buf.data, bl).append(WS_CRLF);
350 if (!sink.WriteRequestStream(msg.c_str(), msg.size()))
353 if (!sink.WriteRequestStream(m_contentData.c_str(), m_contentData.size()))
359 if (!sink.WriteRequestStream(WS_CRLF, WS_CRLF_LEN))
363 return sink.FlushRequestStream();