28#include <SFML/Network/Http.hpp>
40 std::string ToLower(
const std::string& Str)
42 std::string Ret = Str;
43 for (std::string::iterator i = Ret.begin(); i != Ret.end(); ++i)
44 *i =
static_cast<char>(tolower(*i));
70 myFields[ToLower(Field)] = Value;
80 myMethod = RequestMethod;
93 if (myURI.empty() || (myURI[0] !=
'/'))
104 myMajorVersion = Major;
105 myMinorVersion = Minor;
123std::string Http::Request::ToString()
const
125 std::ostringstream Out;
128 std::string RequestMethod;
132 case Get : RequestMethod =
"GET";
break;
133 case Post : RequestMethod =
"POST";
break;
134 case Head : RequestMethod =
"HEAD";
break;
138 Out << RequestMethod <<
" " << myURI <<
" ";
139 Out <<
"HTTP/" << myMajorVersion <<
"." << myMinorVersion <<
"\r\n";
142 for (FieldTable::const_iterator i = myFields.begin(); i != myFields.end(); ++i)
144 Out << i->first <<
": " << i->second <<
"\r\n";
160bool Http::Request::HasField(
const std::string& Field)
const
162 return myFields.find(Field) != myFields.end();
183 FieldTable::const_iterator It = myFields.find(ToLower(Field));
184 if (It != myFields.end())
190 static const std::string Empty =
"";
210 return myMajorVersion;
219 return myMinorVersion;
239void Http::Response::FromString(
const std::string& Data)
241 std::istringstream In(Data);
247 if ((Version.size() >= 8) && (Version[6] ==
'.') &&
248 (ToLower(Version.substr(0, 5)) ==
"http/") &&
249 isdigit(Version[5]) && isdigit(Version[7]))
251 myMajorVersion = Version[5] -
'0';
252 myMinorVersion = Version[7] -
'0';
257 myStatus = InvalidResponse;
264 if (In >> StatusCode)
266 myStatus =
static_cast<Status
>(StatusCode);
271 myStatus = InvalidResponse;
276 In.ignore(10000,
'\n');
280 while (std::getline(In, Line) && (Line.size() > 2))
282 std::string::size_type Pos = Line.find(
": ");
283 if (Pos != std::string::npos)
286 std::string Field = Line.substr(0, Pos);
287 std::string Value = Line.substr(Pos + 2);
290 if (!Value.empty() && (*Value.rbegin() ==
'\r'))
291 Value.erase(Value.size() - 1);
294 myFields[ToLower(Field)] = Value;
300 std::copy(std::istreambuf_iterator<char>(In), std::istreambuf_iterator<char>(), std::back_inserter(myBody));
330 std::string Protocol = ToLower(Host.substr(0, 8));
331 if (Protocol.substr(0, 7) ==
"http://")
334 myHostName = Host.substr(7);
335 myPort = (Port != 0 ? Port : 80);
337 else if (Protocol ==
"https://")
340 myHostName = Host.substr(8);
341 myPort = (Port != 0 ? Port : 443);
347 myPort = (Port != 0 ? Port : 80);
351 if (!myHostName.empty() && (*myHostName.rbegin() ==
'/'))
352 myHostName.erase(myHostName.size() - 1);
370 if (!ToSend.HasField(
"From"))
372 ToSend.
SetField(
"From",
"user@sfml-dev.org");
374 if (!ToSend.HasField(
"User-Agent"))
376 ToSend.
SetField(
"User-Agent",
"libsfml-network/1.x");
378 if (!ToSend.HasField(
"Host"))
380 ToSend.
SetField(
"Host", myHostName);
382 if (!ToSend.HasField(
"Content-Length"))
384 std::ostringstream Out;
385 Out << ToSend.myBody.size();
386 ToSend.
SetField(
"Content-Length", Out.str());
388 if ((ToSend.myMethod ==
Request::Post) && !ToSend.HasField(
"Content-Type"))
390 ToSend.
SetField(
"Content-Type",
"application/x-www-form-urlencoded");
392 if ((ToSend.myMajorVersion * 10 + ToSend.myMinorVersion >= 11) && !ToSend.HasField(
"Connection"))
394 ToSend.
SetField(
"Connection",
"close");
401 if (myConnection.Connect(myPort, myHost, Timeout) == Socket::Done)
404 std::string RequestStr = ToSend.ToString();
406 if (!RequestStr.empty())
409 if (myConnection.Send(RequestStr.c_str(), RequestStr.size()) == sf::Socket::Done)
412 std::string ReceivedStr;
413 std::size_t Size = 0;
415 while (myConnection.Receive(Buffer,
sizeof(Buffer), Size) == sf::Socket::Done)
417 ReceivedStr.append(Buffer, Buffer + Size);
421 Received.FromString(ReceivedStr);
426 myConnection.Close();
This class wraps an HTTP request, which is basically :
void SetField(const std::string &Field, const std::string &Value)
Set the value of a field; the field is added if it doesn't exist.
void SetBody(const std::string &Body)
Set the body of the request.
void SetMethod(Method RequestMethod)
Set the request method.
void SetURI(const std::string &URI)
Set the target URI of the request.
Method
Enumerate the available HTTP methods for a request.
@ Post
Request in post mode, usually to send data to a page.
Request(Method RequestMethod=Get, const std::string &URI="/", const std::string &Body="")
Default constructor.
void SetHttpVersion(unsigned int Major, unsigned int Minor)
Set the HTTP version of the request.
This class wraps an HTTP response, which is basically :
Response()
Default constructor.
const std::string & GetField(const std::string &Field) const
Get the value of a field.
Status GetStatus() const
Get the header's status code.
Status
Enumerate all the valid status codes returned in a HTTP response.
@ ConnectionFailed
Connection with server failed.
const std::string & GetBody() const
Get the body of the response.
unsigned int GetMinorHttpVersion() const
Get the major HTTP version number of the response.
unsigned int GetMajorHttpVersion() const
Get the major HTTP version number of the response.
void SetHost(const std::string &Host, unsigned short Port=0)
Set the target host.
Response SendRequest(const Request &Req, float Timeout=0.f)
Send a HTTP request and return the server's response.
Http()
Default constructor.
IPAddress provides easy manipulation of IP v4 addresses.