mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 12:51:05 +08:00
Added support for chunked http transfers
sf::Http now understands transfers that are sent using Chunked Transfer Encoding (RFC 2616; section 3.6.1).
This commit is contained in:
parent
08b49cc15c
commit
306b77bfc5
@ -316,6 +316,18 @@ public :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void parse(const std::string& data);
|
void parse(const std::string& data);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Read values passed in the answer header
|
||||||
|
///
|
||||||
|
/// This function is used by Http to extract values passed
|
||||||
|
/// in the response.
|
||||||
|
///
|
||||||
|
/// \param in String stream containing the header values
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void parseFields(std::istream &in);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Types
|
// Types
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -231,9 +232,48 @@ void Http::Response::parse(const std::string& data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ignore the end of the first line
|
// Ignore the end of the first line
|
||||||
in.ignore(10000, '\n');
|
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||||
|
|
||||||
// Parse the other lines, which contain fields, one by one
|
// Parse the other lines, which contain fields, one by one
|
||||||
|
parseFields(in);
|
||||||
|
|
||||||
|
m_body.clear();
|
||||||
|
|
||||||
|
// Determine whether the transfer is chunked
|
||||||
|
if (toLower(getField("transfer-encoding")) != "chunked")
|
||||||
|
{
|
||||||
|
// Not chunked - just read everything at once
|
||||||
|
std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::back_inserter(m_body));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Chunked - have to read chunk by chunk
|
||||||
|
std::size_t length;
|
||||||
|
|
||||||
|
// Read all chunks, identified by a chunk-size not being 0
|
||||||
|
while (in >> std::hex >> length)
|
||||||
|
{
|
||||||
|
// Drop the rest of the line (chunk-extension)
|
||||||
|
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||||
|
|
||||||
|
// Copy the actual content data
|
||||||
|
std::istreambuf_iterator<char> it(in);
|
||||||
|
for (std::size_t i = 0; i < length; i++)
|
||||||
|
m_body.push_back(*it++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop the rest of the line (chunk-extension)
|
||||||
|
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||||
|
|
||||||
|
// Read all trailers (if present)
|
||||||
|
parseFields(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void Http::Response::parseFields(std::istream &in)
|
||||||
|
{
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(in, line) && (line.size() > 2))
|
while (std::getline(in, line) && (line.size() > 2))
|
||||||
{
|
{
|
||||||
@ -252,10 +292,6 @@ void Http::Response::parse(const std::string& data)
|
|||||||
m_fields[toLower(field)] = value;
|
m_fields[toLower(field)] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally extract the body
|
|
||||||
m_body.clear();
|
|
||||||
std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::back_inserter(m_body));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user