Support the specification of additional HTTP headers in the creation of a DataSource.
related-to-bug: 2393577
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/List.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/threads.h>
|
||||
@@ -35,7 +36,9 @@ public:
|
||||
kWantsPrefetching = 1,
|
||||
};
|
||||
|
||||
static sp<DataSource> CreateFromURI(const char *uri);
|
||||
static sp<DataSource> CreateFromURI(
|
||||
const char *uri,
|
||||
const KeyedVector<String8, String8> *headers = NULL);
|
||||
|
||||
DataSource() {}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define HTTP_DATASOURCE_H_
|
||||
|
||||
#include <media/stagefright/DataSource.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
@@ -26,8 +27,13 @@ class HTTPStream;
|
||||
|
||||
class HTTPDataSource : public DataSource {
|
||||
public:
|
||||
HTTPDataSource(const char *host, int port, const char *path);
|
||||
HTTPDataSource(const char *uri);
|
||||
HTTPDataSource(
|
||||
const char *host, int port, const char *path,
|
||||
const KeyedVector<String8, String8> *headers = NULL);
|
||||
|
||||
HTTPDataSource(
|
||||
const char *uri,
|
||||
const KeyedVector<String8, String8> *headers = NULL);
|
||||
|
||||
virtual status_t initCheck() const;
|
||||
|
||||
@@ -45,6 +51,8 @@ private:
|
||||
kBufferSize = 64 * 1024
|
||||
};
|
||||
|
||||
String8 mHeaders;
|
||||
|
||||
HTTPStream *mHttp;
|
||||
char *mHost;
|
||||
int mPort;
|
||||
@@ -58,6 +66,7 @@ private:
|
||||
status_t mInitCheck;
|
||||
|
||||
ssize_t sendRangeRequest(size_t offset);
|
||||
void initHeaders(const KeyedVector<String8, String8> *overrides);
|
||||
|
||||
HTTPDataSource(const HTTPDataSource &);
|
||||
HTTPDataSource &operator=(const HTTPDataSource &);
|
||||
|
||||
@@ -31,9 +31,6 @@ public:
|
||||
static sp<MediaExtractor> Create(
|
||||
const sp<DataSource> &source, const char *mime = NULL);
|
||||
|
||||
static sp<MediaExtractor> CreateFromURI(
|
||||
const char *uri, const char *mime = NULL);
|
||||
|
||||
virtual size_t countTracks() = 0;
|
||||
virtual sp<MediaSource> getTrack(size_t index) = 0;
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ status_t StagefrightPlayer::initCheck() {
|
||||
}
|
||||
|
||||
status_t StagefrightPlayer::setDataSource(
|
||||
const char *url, const KeyedVector<String8, String8> *) {
|
||||
const char *url, const KeyedVector<String8, String8> *headers) {
|
||||
LOGI("setDataSource('%s')", url);
|
||||
return mPlayer->setDataSource(url);
|
||||
return mPlayer->setDataSource(url, headers);
|
||||
}
|
||||
|
||||
// Warning: The filedescriptor passed into this method will only be valid until
|
||||
|
||||
@@ -152,12 +152,13 @@ void AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
status_t AwesomePlayer::setDataSource(const char *uri) {
|
||||
status_t AwesomePlayer::setDataSource(
|
||||
const char *uri, const KeyedVector<String8, String8> *headers) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
reset_l();
|
||||
|
||||
sp<DataSource> dataSource = DataSource::CreateFromURI(uri);
|
||||
sp<DataSource> dataSource = DataSource::CreateFromURI(uri, headers);
|
||||
|
||||
if (dataSource == NULL) {
|
||||
return UNKNOWN_ERROR;
|
||||
|
||||
@@ -95,12 +95,13 @@ void DataSource::RegisterDefaultSniffers() {
|
||||
}
|
||||
|
||||
// static
|
||||
sp<DataSource> DataSource::CreateFromURI(const char *uri) {
|
||||
sp<DataSource> DataSource::CreateFromURI(
|
||||
const char *uri, const KeyedVector<String8, String8> *headers) {
|
||||
sp<DataSource> source;
|
||||
if (!strncasecmp("file://", uri, 7)) {
|
||||
source = new FileSource(uri + 7);
|
||||
} else if (!strncasecmp("http://", uri, 7)) {
|
||||
source = new HTTPDataSource(uri);
|
||||
source = new HTTPDataSource(uri, headers);
|
||||
source = new CachingDataSource(source, 64 * 1024, 10);
|
||||
} else {
|
||||
// Assume it's a filename.
|
||||
|
||||
@@ -31,14 +31,13 @@ static const char *kUserAgent = "stagefright-http";
|
||||
// accordingly and return true, otherwise return false and leave the stream
|
||||
// connected.
|
||||
static bool PerformRedirectIfNecessary(
|
||||
HTTPStream *http, string *host, string *path, int *port) {
|
||||
HTTPStream *http, const String8 &headers,
|
||||
string *host, string *path, int *port) {
|
||||
String8 request;
|
||||
request.append("HEAD ");
|
||||
request.append(path->c_str());
|
||||
request.append(" HTTP/1.1\r\n");
|
||||
request.append("User-Agent: ");
|
||||
request.append(kUserAgent);
|
||||
request.append("\r\n");
|
||||
request.append(headers);
|
||||
request.append("Host: ");
|
||||
request.append(host->c_str());
|
||||
request.append("\r\n\r\n");
|
||||
@@ -94,7 +93,8 @@ static bool PerformRedirectIfNecessary(
|
||||
return true;
|
||||
}
|
||||
|
||||
HTTPDataSource::HTTPDataSource(const char *uri)
|
||||
HTTPDataSource::HTTPDataSource(
|
||||
const char *uri, const KeyedVector<String8, String8> *headers)
|
||||
: mHttp(new HTTPStream),
|
||||
mHost(NULL),
|
||||
mPort(0),
|
||||
@@ -105,6 +105,8 @@ HTTPDataSource::HTTPDataSource(const char *uri)
|
||||
mFirstRequest(true) {
|
||||
CHECK(!strncasecmp("http://", uri, 7));
|
||||
|
||||
initHeaders(headers);
|
||||
|
||||
string host;
|
||||
string path;
|
||||
int port;
|
||||
@@ -140,14 +142,16 @@ HTTPDataSource::HTTPDataSource(const char *uri)
|
||||
if (mInitCheck != OK) {
|
||||
return;
|
||||
}
|
||||
} while (PerformRedirectIfNecessary(mHttp, &host, &path, &port));
|
||||
} while (PerformRedirectIfNecessary(mHttp, mHeaders, &host, &path, &port));
|
||||
|
||||
mHost = strdup(host.c_str());
|
||||
mPort = port;
|
||||
mPath = strdup(path.c_str());
|
||||
}
|
||||
|
||||
HTTPDataSource::HTTPDataSource(const char *_host, int port, const char *_path)
|
||||
HTTPDataSource::HTTPDataSource(
|
||||
const char *_host, int port, const char *_path,
|
||||
const KeyedVector<String8, String8> *headers)
|
||||
: mHttp(new HTTPStream),
|
||||
mHost(NULL),
|
||||
mPort(0),
|
||||
@@ -156,6 +160,8 @@ HTTPDataSource::HTTPDataSource(const char *_host, int port, const char *_path)
|
||||
mBufferLength(0),
|
||||
mBufferOffset(0),
|
||||
mFirstRequest(true) {
|
||||
initHeaders(headers);
|
||||
|
||||
string host = _host;
|
||||
string path = _path;
|
||||
|
||||
@@ -168,7 +174,7 @@ HTTPDataSource::HTTPDataSource(const char *_host, int port, const char *_path)
|
||||
if (mInitCheck != OK) {
|
||||
return;
|
||||
}
|
||||
} while (PerformRedirectIfNecessary(mHttp, &host, &path, &port));
|
||||
} while (PerformRedirectIfNecessary(mHttp, mHeaders, &host, &path, &port));
|
||||
|
||||
mHost = strdup(host.c_str());
|
||||
mPort = port;
|
||||
@@ -200,9 +206,6 @@ HTTPDataSource::~HTTPDataSource() {
|
||||
}
|
||||
|
||||
ssize_t HTTPDataSource::sendRangeRequest(size_t offset) {
|
||||
char agent[128];
|
||||
sprintf(agent, "User-Agent: %s\r\n", kUserAgent);
|
||||
|
||||
char host[128];
|
||||
sprintf(host, "Host: %s\r\n", mHost);
|
||||
|
||||
@@ -221,7 +224,7 @@ ssize_t HTTPDataSource::sendRangeRequest(size_t offset) {
|
||||
if ((err = mHttp->send("GET ")) != OK
|
||||
|| (err = mHttp->send(mPath)) != OK
|
||||
|| (err = mHttp->send(" HTTP/1.1\r\n")) != OK
|
||||
|| (err = mHttp->send(agent)) != OK
|
||||
|| (err = mHttp->send(mHeaders.string())) != OK
|
||||
|| (err = mHttp->send(host)) != OK
|
||||
|| (err = mHttp->send(range)) != OK
|
||||
|| (err = mHttp->send("\r\n")) != OK
|
||||
@@ -304,5 +307,28 @@ ssize_t HTTPDataSource::readAt(off_t offset, void *data, size_t size) {
|
||||
return copy;
|
||||
}
|
||||
|
||||
void HTTPDataSource::initHeaders(
|
||||
const KeyedVector<String8, String8> *overrides) {
|
||||
mHeaders = String8();
|
||||
|
||||
mHeaders.append("User-Agent: ");
|
||||
mHeaders.append(kUserAgent);
|
||||
mHeaders.append("\r\n");
|
||||
|
||||
if (overrides == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < overrides->size(); ++i) {
|
||||
String8 line;
|
||||
line.append(overrides->keyAt(i));
|
||||
line.append(": ");
|
||||
line.append(overrides->valueAt(i));
|
||||
line.append("\r\n");
|
||||
|
||||
mHeaders.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
|
||||
@@ -67,16 +67,4 @@ sp<MediaExtractor> MediaExtractor::Create(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
sp<MediaExtractor> MediaExtractor::CreateFromURI(
|
||||
const char *uri, const char *mime) {
|
||||
sp<DataSource> source = DataSource::CreateFromURI(uri);
|
||||
|
||||
if (source == NULL || source->initCheck() != OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Create(source, mime);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -49,7 +49,10 @@ struct AwesomePlayer {
|
||||
|
||||
void setListener(const wp<MediaPlayerBase> &listener);
|
||||
|
||||
status_t setDataSource(const char *uri);
|
||||
status_t setDataSource(
|
||||
const char *uri,
|
||||
const KeyedVector<String8, String8> *headers = NULL);
|
||||
|
||||
status_t setDataSource(int fd, int64_t offset, int64_t length);
|
||||
|
||||
void reset();
|
||||
|
||||
@@ -245,10 +245,20 @@ private:
|
||||
NodeReaper &operator=(const NodeReaper &);
|
||||
};
|
||||
|
||||
static sp<MediaExtractor> CreateExtractorFromURI(const char *uri) {
|
||||
sp<DataSource> source = DataSource::CreateFromURI(uri);
|
||||
|
||||
if (source == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return MediaExtractor::Create(source);
|
||||
}
|
||||
|
||||
static sp<MediaSource> MakeSource(
|
||||
const char *uri,
|
||||
const char *mimeType) {
|
||||
sp<MediaExtractor> extractor = MediaExtractor::CreateFromURI(uri);
|
||||
sp<MediaExtractor> extractor = CreateExtractorFromURI(uri);
|
||||
|
||||
if (extractor == NULL) {
|
||||
return NULL;
|
||||
@@ -500,7 +510,7 @@ static sp<MediaSource> CreateSourceForMime(const char *mime) {
|
||||
const char *url = GetURLForMime(mime);
|
||||
CHECK(url != NULL);
|
||||
|
||||
sp<MediaExtractor> extractor = MediaExtractor::CreateFromURI(url);
|
||||
sp<MediaExtractor> extractor = CreateExtractorFromURI(url);
|
||||
|
||||
CHECK(extractor != NULL);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user