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;
123 std::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";
160 bool Http::Request::HasField(
const std::string& Field)
const 162 return myFields.find(Field) != myFields.end();
170 myStatus (ConnectionFailed),
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;
239 void 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();
void SetHost(const std::string &Host, unsigned short Port=0)
Set the target host.
void SetBody(const std::string &Body)
Set the body of the request.
Request(Method RequestMethod=Get, const std::string &URI="/", const std::string &Body="")
Default constructor.
This class wraps an HTTP response, 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 SetMethod(Method RequestMethod)
Set the request method.
Request in post mode, usually to send data to a page.
Status
Enumerate all the valid status codes returned in a HTTP response.
Method
Enumerate the available HTTP methods for a request.
void SetURI(const std::string &URI)
Set the target URI of the request.
Socket::Status Receive(char *Data, std::size_t MaxSize, std::size_t &SizeReceived)
Receive an array of bytes from the host (must be connected first).
const std::string & GetField(const std::string &Field) const
Get the value of a field.
Socket::Status Send(const char *Data, std::size_t Size)
Send an array of bytes to the host (must be connected first)
unsigned int GetMinorHttpVersion() const
Get the major HTTP version number of the response.
Socket::Status Connect(unsigned short Port, const IPAddress &HostAddress, float Timeout=0.f)
Connect to another computer on a specified port.
unsigned int GetMajorHttpVersion() const
Get the major HTTP version number of the response.
Status GetStatus() const
Get the header's status code.
Http()
Default constructor.
IPAddress provides easy manipulation of IP v4 addresses.
const std::string & GetBody() const
Get the body of the response.
This class wraps an HTTP request, which is basically :
bool Close()
Close the socket.
Response()
Default constructor.
Response SendRequest(const Request &Req, float Timeout=0.f)
Send a HTTP request and return the server's response.
void SetHttpVersion(unsigned int Major, unsigned int Minor)
Set the HTTP version of the request.