[vlc-devel] [PATCH] demux/adaptive: handle redirections in HTTPConnection
Zhao Zhili
wantlamy at gmail.com
Wed Jul 5 12:28:40 CEST 2017
---
modules/demux/adaptive/http/HTTPConnection.cpp | 66
+++++++++++++++++---------
modules/demux/adaptive/http/HTTPConnection.hpp | 16 +++++--
2 files changed, 55 insertions(+), 27 deletions(-)
diff --git a/modules/demux/adaptive/http/HTTPConnection.cpp
b/modules/demux/adaptive/http/HTTPConnection.cpp
index a250d87..0b2f7f8 100644
--- a/modules/demux/adaptive/http/HTTPConnection.cpp
+++ b/modules/demux/adaptive/http/HTTPConnection.cpp
@@ -65,7 +65,6 @@ HTTPConnection::HTTPConnection(vlc_object_t *p_object_,
Socket *socket_, bool pe
socket = socket_;
psz_useragent = var_InheritString(p_object_, "http-user-agent");
queryOk = false;
- retries = 0;
connectionClose = !persistent;
chunked = false;
chunked_eof = false;
@@ -108,27 +107,24 @@ void HTTPConnection::disconnect()
socket->disconnect();
}
-int HTTPConnection::request(const std::string &path, const BytesRange
&range)
+HTTPConnection::HTTPErrorType HTTPConnection::doRequest(const BytesRange
&range)
{
queryOk = false;
chunked = false;
chunked_eof = false;
chunkLength = 0;
- /* Set new path for this query */
- params.setPath(path);
-
msg_Dbg(p_object, "Retrieving %s @%zu", params.getUrl().c_str(),
range.isValid() ? range.getStartByte() : 0);
if(!connected() && ( params.getHostname().empty() || !connect() ))
- return VLC_EGENERIC;
+ return HTTPGenericError;
bytesRange = range;
if(range.isValid() && range.getEndByte() > 0)
contentLength = range.getEndByte() - range.getStartByte() + 1;
- std::string header = buildRequestHeader(path);
+ std::string header = buildRequestHeader();
if(connectionClose)
header.append("Connection: close\r\n");
header.append("\r\n");
@@ -140,17 +136,20 @@ int HTTPConnection::request(const std::string &path,
const BytesRange &range)
{
/* server closed connection pipeline after last req. need new
*/
connectionClose = true;
- return request(path, range);
+ return doRequest(range);
+ }
+ else
+ {
+ return HTTPGenericError;
}
- return VLC_EGENERIC;
}
- int i_ret = parseReply();
- if(i_ret == VLC_SUCCESS)
+ HTTPConnection::HTTPErrorType i_ret = parseReply();
+ if(i_ret == HTTPSuccess)
{
queryOk = true;
}
- else if(i_ret == VLC_ETIMEOUT) /* redir */
+ else if(i_ret == HTTPRedirect) /* redir */
{
socket->disconnect();
if(locationparams.getScheme().empty())
@@ -159,19 +158,40 @@ int HTTPConnection::request(const std::string &path,
const BytesRange &range)
params = locationparams;
locationparams = ConnectionParams();
}
- else if(i_ret == VLC_EGENERIC)
+ else if(i_ret == HTTPGenericError)
{
socket->disconnect();
if(!connectionClose)
{
connectionClose = true;
- return request(path, range);
+ return doRequest(range);
}
}
return i_ret;
}
+int HTTPConnection::request(const std::string &path, const BytesRange
&range)
+{
+ /* Set new path for this query */
+ params.setPath(path);
+
+ for(int retries = 0; retries < maxRedirectCount; retries++)
+ {
+ HTTPConnection::HTTPErrorType ret = doRequest(range);
+ if (ret == HTTPSuccess)
+ return VLC_SUCCESS;
+ else if (ret == HTTPGenericError)
+ return VLC_EGENERIC;
+ else if (ret == HTTPRedirect)
+ continue;
+ else
+ break;
+ }
+
+ return VLC_EGENERIC;
+}
+
ssize_t HTTPConnection::read(void *p_buffer, size_t len)
{
if( !connected() ||
@@ -215,17 +235,17 @@ bool HTTPConnection::send(const void *buf, size_t
size)
return socket->send(p_object, buf, size);
}
-int HTTPConnection::parseReply()
+HTTPConnection::HTTPErrorType HTTPConnection::parseReply()
{
std::string line = readLine();
if(line.empty())
- return VLC_EGENERIC;
+ return HTTPGenericError;
if (line.compare(0, 9, "HTTP/1.1 ")!=0)
{
if(line.compare(0, 9, "HTTP/1.0 ")!=0)
- return VLC_ENOOBJ;
+ return HTTPGenericError;
else
connectionClose = true;
}
@@ -254,15 +274,15 @@ int HTTPConnection::parseReply()
!locationparams.getUrl().empty())
{
msg_Info(p_object, "%d redirection to %s", replycode,
locationparams.getUrl().c_str());
- return VLC_ETIMEOUT;
+ return HTTPRedirect;
}
else if (replycode != 200 && replycode != 206)
{
- msg_Err(p_object, "Failed reading %s: %s",
params.getUrl().c_str(), line.c_str());
- return VLC_ENOOBJ;
+ msg_Err(p_object, "%d Failed reading %s: %s", replycode,
params.getUrl().c_str(), line.c_str());
+ return HTTPGenericError;
}
- return VLC_SUCCESS;
+ return HTTPSuccess;
}
ssize_t HTTPConnection::readChunk(void *p_buffer, size_t len)
@@ -360,10 +380,10 @@ void HTTPConnection::onHeader(const std::string &key,
}
}
-std::string HTTPConnection::buildRequestHeader(const std::string &path)
const
+std::string HTTPConnection::buildRequestHeader() const
{
std::stringstream req;
- req << "GET " << path << " HTTP/1.1\r\n" <<
+ req << "GET " << params.getPath() << " HTTP/1.1\r\n" <<
"Host: " << params.getHostname() << "\r\n" <<
"Cache-Control: no-cache" << "\r\n" <<
"User-Agent: " << std::string(psz_useragent) << "\r\n";
diff --git a/modules/demux/adaptive/http/HTTPConnection.hpp
b/modules/demux/adaptive/http/HTTPConnection.hpp
index 85ca53b..707e604 100644
--- a/modules/demux/adaptive/http/HTTPConnection.hpp
+++ b/modules/demux/adaptive/http/HTTPConnection.hpp
@@ -73,6 +73,15 @@ namespace adaptive
void setUsed( bool );
protected:
+ enum HTTPErrorType
+ {
+ HTTPSuccess = 0,
+ HTTPGenericError,
+ HTTPRedirect,
+ };
+
+ virtual HTTPConnection::HTTPErrorType doRequest(const
BytesRange &range);
+
virtual bool connected () const;
virtual bool connect ();
virtual void disconnect ();
@@ -82,10 +91,10 @@ namespace adaptive
virtual void onHeader (const std::string &line,
const std::string &value);
virtual std::string extraRequestHeaders() const;
- virtual std::string buildRequestHeader(const std::string
&path) const;
+ virtual std::string buildRequestHeader() const;
ssize_t readChunk (void *p_buffer, size_t len);
- int parseReply();
+ HTTPConnection::HTTPErrorType parseReply();
std::string readLine();
char * psz_useragent;
@@ -95,8 +104,7 @@ namespace adaptive
bool chunked_eof;
size_t chunkLength;
bool queryOk;
- int retries;
- static const int retryCount = 5;
+ static const int maxRedirectCount = 5;
private:
Socket *socket;
--
2.7.4
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20170705/a9e32251/attachment.html>
More information about the vlc-devel
mailing list