1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "game_share/http_client.h"
20 using namespace NLMISC
;
21 using namespace NLNET
;
25 // ***************************************************************************
26 bool CHttpClient::connect(std::string server
)
30 // Convert an URL to a host if needed
31 if (server
.substr(0, 7) == "http://")
32 server
= server
.substr(7);
33 server
= server
.substr(0, server
.find( "/" ));
35 // Add the default port if no port in the cfg, and check if not already connected
36 if(server
.find(':') == string::npos
)
38 CInetAddress addr
= CInetAddress(server
);
39 if (_Sock
.connected())
41 if (addr
== _Sock
.remoteAddr())
49 if(!_Sock
.connected())
51 nlwarning("Can't connect to web server '%s'", server
.c_str());
56 nldebug("Connected to web server '%s'", server
.c_str());
59 catch(const Exception
&e
)
61 nlwarning("Can't connect to web server '%s': %s", server
.c_str(), e
.what());
75 // ***************************************************************************
76 bool CHttpClient::send(const std::string
& buffer
, bool verbose
)
78 nlassert(_Sock
.connected());
82 nldebug("Sending '%s' to '%s'", trim(buffer
).c_str(), _Sock
.remoteAddr().asString().c_str());
85 uint32 size
= (uint32
)buffer
.size();
89 if(_Sock
.send((uint8
*)buffer
.c_str(), size
, false) != CSock::Ok
)
91 nlwarning ("Can't send data to the server");
98 // ***************************************************************************
99 bool CHttpClient::sendRequest(const std::string
& methodWB
, const std::string
&url
, const std::string
&cookieName
, const std::string
&cookieValue
, const std::string
& postParams
, bool verbose
)
101 std::string path
, host
;
103 // Remove the protocol from the URL
104 if (url
.substr(0, 7) == "http://")
105 path
= url
.substr(7);
109 std::string::size_type pos
= path
.find("/");
111 // Remove the host from the URL
112 if (pos
!= std::string::npos
)
114 host
= path
.substr(0, pos
);
115 path
= path
.substr(pos
);
123 // build HTTP request
125 request
+= methodWB
+ " " + path
+ " HTTP/1.1\r\n";
126 request
+= "Host: " + host
+ "\r\n";
127 request
+= "Connection: close\r\n";
130 if (cookieName
.empty() && postParams
.empty())
134 return send(request
, verbose
);
138 if (!cookieName
.empty())
139 request
+= "Cookie: " + cookieName
+ "=" + cookieValue
+ "\r\n";
141 if (!postParams
.empty())
143 request
+= "Content-Type: application/x-www-form-urlencoded\r\n";
144 request
+= "Content-Length: " + toString(postParams
.size()) + "\r\n";
146 request
+= postParams
;
151 return send(request
, verbose
);
155 // ***************************************************************************
156 bool CHttpClient::sendGet(const string
&url
, const string
& params
, bool verbose
)
158 return sendRequest("GET", url
+ (params
.empty() ? "" : ("?" + params
)), string(), string(), string(), verbose
);
161 // ***************************************************************************
162 bool CHttpClient::sendGetWithCookie(const string
&url
, const string
&name
, const string
&value
, const string
& params
, bool verbose
)
164 return sendRequest("GET", url
+ (params
.empty() ? "" : ("?" + params
)), name
, value
, string(), verbose
);
167 // ***************************************************************************
168 bool CHttpClient::sendPost(const string
&url
, const string
& params
, bool verbose
)
170 return sendRequest("POST", url
, string(), string(), params
, verbose
);
173 // ***************************************************************************
174 bool CHttpClient::sendPostWithCookie(const string
&url
, const string
&name
, const string
&value
, const string
& params
, bool verbose
)
176 return sendRequest("POST", url
, name
, value
, params
, verbose
);
179 // ***************************************************************************
180 bool CHttpClient::receive(string
&res
, bool verbose
)
182 nlassert(_Sock
.connected());
189 if(verbose
) nlinfo("Receiving");
195 if (_Sock
.receive((uint8
*)buf
, size
, false) == CSock::Ok
)
197 if (verbose
) nlinfo("Received OK %u bytes", size
);
200 //nlinfo("block received '%s'", buf);
204 if (verbose
) nlinfo("Received CLOSE %u bytes", size
);
207 //nlwarning ("server connection closed");
212 //nlinfo("all received '%s'", res.c_str());
214 // only keep content (delimited by two \r\n) and discard server headers
215 std::string::size_type pos
= res
.find("\r\n\r\n");
217 if (pos
!= std::string::npos
)
219 res
= res
.substr(pos
+ 4);
225 // ***************************************************************************
226 void CHttpClient::disconnect()
228 //if(_Sock.connected())
229 // NB Nico : close all the time, to avoid printing into the log after release
230 // in CSock dtor -> causes a crash
235 // ***************************************************************************
236 CHttpPostTask::CHttpPostTask(const std::string
&host
, const std::string
&page
, const std::string
¶ms
)
243 // ***************************************************************************
244 void CHttpPostTask::run(void)
246 CHttpClient httpClient
;
249 if ( ! httpClient
.connect(_Host
))
254 if ( ! httpClient
.sendPost(_Host
+ _Page
, _Params
))
259 httpClient
.receive(ret
);
260 httpClient
.disconnect();