[vlc-commits] demux: adaptive: add chunked transfert support
Francois Cartegnie
git at videolan.org
Wed Nov 2 19:16:16 CET 2016
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Nov 2 19:14:31 2016 +0100| [b99bc394843b4967e1f54904608027154e683896] | committer: Francois Cartegnie
demux: adaptive: add chunked transfert support
refs #17551
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b99bc394843b4967e1f54904608027154e683896
---
modules/demux/adaptive/http/HTTPConnection.cpp | 64 +++++++++++++++++++++++++-
modules/demux/adaptive/http/HTTPConnection.hpp | 4 ++
2 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/modules/demux/adaptive/http/HTTPConnection.cpp b/modules/demux/adaptive/http/HTTPConnection.cpp
index 7c6d07b..824fe4c 100644
--- a/modules/demux/adaptive/http/HTTPConnection.cpp
+++ b/modules/demux/adaptive/http/HTTPConnection.cpp
@@ -66,6 +66,9 @@ HTTPConnection::HTTPConnection(vlc_object_t *p_object_, Socket *socket_, bool pe
queryOk = false;
retries = 0;
connectionClose = !persistent;
+ chunked = false;
+ chunked_eof = false;
+ chunkLength = 0;
}
HTTPConnection::~HTTPConnection()
@@ -98,6 +101,8 @@ void HTTPConnection::disconnect()
queryOk = false;
bytesRead = 0;
contentLength = 0;
+ chunked = false;
+ chunkLength = 0;
bytesRange = BytesRange();
socket->disconnect();
}
@@ -105,6 +110,9 @@ void HTTPConnection::disconnect()
int HTTPConnection::request(const std::string &path, const BytesRange &range)
{
queryOk = false;
+ chunked = false;
+ chunked_eof = false;
+ chunkLength = 0;
/* Set new path for this query */
params.setPath(path);
@@ -172,7 +180,8 @@ ssize_t HTTPConnection::read(void *p_buffer, size_t len)
if(len > toRead)
len = toRead;
- ssize_t ret = socket->read(p_object, p_buffer, len);
+ ssize_t ret = ( chunked ) ? readChunk(p_buffer, len)
+ : socket->read(p_object, p_buffer, len);
if(ret >= 0)
bytesRead += ret;
@@ -235,6 +244,54 @@ int HTTPConnection::parseReply()
return VLC_SUCCESS;
}
+ssize_t HTTPConnection::readChunk(void *p_buffer, size_t len)
+{
+ size_t copied = 0;
+
+ for( ; copied < len && !chunked_eof; )
+ {
+ /* adapted from access/http/chunked.c */
+ if(chunkLength == 0)
+ {
+ std::string line = readLine();
+ int end;
+ if (std::sscanf(line.c_str(), "%zx%n", &chunkLength, &end) < 1
+ || (line[end] != '\0' && line[end] != ';' /* ignore extension(s) */))
+ return -1;
+ }
+
+ if(chunkLength > 0)
+ {
+ size_t toread = len - copied;
+ if(toread > chunkLength)
+ toread = chunkLength;
+
+ ssize_t in = socket->read(p_object, &((uint8_t*)p_buffer)[copied], toread);
+ if(in < 0)
+ {
+ return (copied == 0) ? in : copied;
+ }
+ else if((size_t)in < toread)
+ {
+ return copied + in;
+ }
+ copied += in;
+ chunkLength -= in;
+ }
+ else chunked_eof = true;
+
+ if(chunkLength == 0)
+ {
+ char crlf[2];
+ ssize_t in = socket->read(p_object, &crlf, 2);
+ if(in < 2 || memcmp(crlf, "\r\n", 2))
+ return (copied == 0) ? -1 : copied;
+ }
+ }
+
+ return copied;
+}
+
std::string HTTPConnection::readLine()
{
return socket->readline(p_object);
@@ -272,6 +329,10 @@ void HTTPConnection::onHeader(const std::string &key,
{
connectionClose = true;
}
+ else if (key == "Transfer-Encoding" && value == "chunked")
+ {
+ chunked = true;
+ }
}
std::string HTTPConnection::buildRequestHeader(const std::string &path) const
@@ -280,7 +341,6 @@ std::string HTTPConnection::buildRequestHeader(const std::string &path) const
req << "GET " << path << " HTTP/1.1\r\n" <<
"Host: " << params.getHostname() << "\r\n" <<
"Cache-Control: no-cache" << "\r\n" <<
- "Accept-Encoding: identity" << "\r\n" <<
"User-Agent: " << std::string(psz_useragent) << "\r\n";
req << extraRequestHeaders();
return req.str();
diff --git a/modules/demux/adaptive/http/HTTPConnection.hpp b/modules/demux/adaptive/http/HTTPConnection.hpp
index c9ee3bb..1a1a955 100644
--- a/modules/demux/adaptive/http/HTTPConnection.hpp
+++ b/modules/demux/adaptive/http/HTTPConnection.hpp
@@ -84,11 +84,15 @@ namespace adaptive
virtual std::string extraRequestHeaders() const;
virtual std::string buildRequestHeader(const std::string &path) const;
+ ssize_t readChunk (void *p_buffer, size_t len);
int parseReply();
std::string readLine();
char * psz_useragent;
bool connectionClose;
+ bool chunked;
+ bool chunked_eof;
+ size_t chunkLength;
bool queryOk;
int retries;
static const int retryCount = 5;
More information about the vlc-commits
mailing list