summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-02-17 13:35:08 -0800
committerAndreas Huber <andih@google.com>2011-02-17 14:30:05 -0800
commit8cb0c4168bf4b678e4a6edfcf409247016be20d5 (patch)
treed3a274bc9913bacca91d58456697823b31bbaf93 /media/libstagefright
parentf71eb135c28dd7b305b7030776ef0d44fac732c4 (diff)
downloadframeworks_av-8cb0c4168bf4b678e4a6edfcf409247016be20d5.zip
frameworks_av-8cb0c4168bf4b678e4a6edfcf409247016be20d5.tar.gz
frameworks_av-8cb0c4168bf4b678e4a6edfcf409247016be20d5.tar.bz2
Experimental support for https transfers in stagefright.
Change-Id: If1bd0f265dda136c7c34b53317f64383023b53a3
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/Android.mk6
-rw-r--r--media/libstagefright/AwesomePlayer.cpp3
-rw-r--r--media/libstagefright/DataSource.cpp3
-rw-r--r--media/libstagefright/HTTPStream.cpp99
-rw-r--r--media/libstagefright/NuHTTPDataSource.cpp34
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp3
-rw-r--r--media/libstagefright/include/HTTPStream.h5
-rw-r--r--media/libstagefright/include/NuHTTPDataSource.h2
8 files changed, 133 insertions, 22 deletions
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 53435f8..80eb59f 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -58,7 +58,8 @@ LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/base/include/media/stagefright/openmax \
$(TOP)/external/flac/include \
$(TOP)/external/tremolo \
- $(TOP)/frameworks/base/media/libstagefright/rtsp
+ $(TOP)/frameworks/base/media/libstagefright/rtsp \
+ $(TOP)/external/openssl/include \
LOCAL_SHARED_LIBRARIES := \
libbinder \
@@ -72,7 +73,8 @@ LOCAL_SHARED_LIBRARIES := \
libstagefright_yuv \
libcamera_client \
libdrmframework \
- libcrypto
+ libcrypto \
+ libssl
LOCAL_STATIC_LIBRARIES := \
libstagefright_color_conversion \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 8866750..b1d3630 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1481,7 +1481,8 @@ status_t AwesomePlayer::prepareAsync_l() {
status_t AwesomePlayer::finishSetDataSource_l() {
sp<DataSource> dataSource;
- if (!strncasecmp("http://", mUri.string(), 7)) {
+ if (!strncasecmp("http://", mUri.string(), 7)
+ || !strncasecmp("https://", mUri.string(), 8)) {
mConnectingDataSource = new NuHTTPDataSource;
mLock.unlock();
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 8f9c150..3b38208 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -125,7 +125,8 @@ sp<DataSource> DataSource::CreateFromURI(
sp<DataSource> source;
if (!strncasecmp("file://", uri, 7)) {
source = new FileSource(uri + 7);
- } else if (!strncasecmp("http://", uri, 7)) {
+ } else if (!strncasecmp("http://", uri, 7)
+ || !strncasecmp("https://", uri, 8)) {
sp<NuHTTPDataSource> httpSource = new NuHTTPDataSource;
if (httpSource->connect(uri, headers) != OK) {
return NULL;
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 77a61a5..498c7b8 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -34,6 +34,8 @@
#include <media/stagefright/foundation/ADebug.h>
+#include <openssl/ssl.h>
+
namespace android {
// static
@@ -41,11 +43,18 @@ const char *HTTPStream::kStatusKey = ":status:"; // MUST be lowercase.
HTTPStream::HTTPStream()
: mState(READY),
- mSocket(-1) {
+ mSocket(-1),
+ mSSLContext(NULL),
+ mSSL(NULL) {
}
HTTPStream::~HTTPStream() {
disconnect();
+
+ if (mSSLContext != NULL) {
+ SSL_CTX_free((SSL_CTX *)mSSLContext);
+ mSSLContext = NULL;
+ }
}
static bool MakeSocketBlocking(int s, bool blocking) {
@@ -198,7 +207,11 @@ static ssize_t MyReceive(int s, void *data, size_t size, int flags) {
return MySendReceive(s, data, size, flags, false /* sendData */);
}
-status_t HTTPStream::connect(const char *server, int port) {
+status_t HTTPStream::connect(const char *server, int port, bool https) {
+ if (port < 0) {
+ port = https ? 443 : 80;
+ }
+
Mutex::Autolock autoLock(mLock);
status_t err = OK;
@@ -249,6 +262,47 @@ status_t HTTPStream::connect(const char *server, int port) {
return res;
}
+ if (https) {
+ CHECK(mSSL == NULL);
+
+ if (mSSLContext == NULL) {
+ SSL_library_init();
+
+ mSSLContext = SSL_CTX_new(TLSv1_client_method());
+
+ if (mSSLContext == NULL) {
+ LOGE("failed to create SSL context");
+ mState = READY;
+ return ERROR_IO;
+ }
+ }
+
+ mSSL = SSL_new((SSL_CTX *)mSSLContext);
+
+ if (mSSL == NULL) {
+ LOGE("failed to create SSL session");
+
+ mState = READY;
+ return ERROR_IO;
+ }
+
+ int res = SSL_set_fd((SSL *)mSSL, mSocket);
+
+ if (res == 1) {
+ res = SSL_connect((SSL *)mSSL);
+ }
+
+ if (res != 1) {
+ SSL_free((SSL *)mSSL);
+ mSSL = NULL;
+
+ LOGE("failed to connect over SSL");
+ mState = READY;
+
+ return ERROR_IO;
+ }
+ }
+
mState = CONNECTED;
return OK;
@@ -261,6 +315,13 @@ status_t HTTPStream::disconnect() {
return ERROR_NOT_CONNECTED;
}
+ if (mSSL != NULL) {
+ SSL_shutdown((SSL *)mSSL);
+
+ SSL_free((SSL *)mSSL);
+ mSSL = NULL;
+ }
+
CHECK(mSocket >= 0);
close(mSocket);
mSocket = -1;
@@ -276,7 +337,16 @@ status_t HTTPStream::send(const char *data, size_t size) {
}
while (size > 0) {
- ssize_t n = MySend(mSocket, data, size, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_write((SSL *)mSSL, data, size);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MySend(mSocket, data, size, 0);
+ }
if (n < 0) {
disconnect();
@@ -317,7 +387,17 @@ status_t HTTPStream::receive_line(char *line, size_t size) {
for (;;) {
char c;
- ssize_t n = MyReceive(mSocket, &c, 1, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_read((SSL *)mSSL, &c, 1);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MyReceive(mSocket, &c, 1, 0);
+ }
+
if (n < 0) {
disconnect();
@@ -437,7 +517,16 @@ status_t HTTPStream::receive_header(int *http_status) {
ssize_t HTTPStream::receive(void *data, size_t size) {
size_t total = 0;
while (total < size) {
- ssize_t n = MyReceive(mSocket, (char *)data + total, size - total, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_read((SSL *)mSSL, (char *)data + total, size - total);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MyReceive(mSocket, (char *)data + total, size - total, 0);
+ }
if (n < 0) {
LOGE("recv failed, errno = %d (%s)", (int)n, strerror(-n));
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index 0376e1c..e39fab3 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -24,22 +24,30 @@ static bool ParseSingleUnsignedLong(
}
static bool ParseURL(
- const char *url, String8 *host, unsigned *port, String8 *path) {
+ const char *url, String8 *host, unsigned *port,
+ String8 *path, bool *https) {
host->setTo("");
*port = 0;
path->setTo("");
- if (strncasecmp("http://", url, 7)) {
+ size_t hostStart;
+ if (!strncasecmp("http://", url, 7)) {
+ hostStart = 7;
+ *https = false;
+ } else if (!strncasecmp("https://", url, 8)) {
+ hostStart = 8;
+ *https = true;
+ } else {
return false;
}
- const char *slashPos = strchr(&url[7], '/');
+ const char *slashPos = strchr(&url[hostStart], '/');
if (slashPos == NULL) {
- host->setTo(&url[7]);
+ host->setTo(&url[hostStart]);
path->setTo("/");
} else {
- host->setTo(&url[7], slashPos - &url[7]);
+ host->setTo(&url[hostStart], slashPos - &url[hostStart]);
path->setTo(slashPos);
}
@@ -57,7 +65,7 @@ static bool ParseURL(
String8 tmp(host->string(), colonOffset);
*host = tmp;
} else {
- *port = 80;
+ *port = (*https) ? 443 : 80;
}
return true;
@@ -66,6 +74,7 @@ static bool ParseURL(
NuHTTPDataSource::NuHTTPDataSource()
: mState(DISCONNECTED),
mPort(0),
+ mHTTPS(false),
mOffset(0),
mContentLength(0),
mContentLengthValid(false),
@@ -111,11 +120,12 @@ status_t NuHTTPDataSource::connect(
mUri = uri;
- if (!ParseURL(uri, &host, &port, &path)) {
+ bool https;
+ if (!ParseURL(uri, &host, &port, &path, &https)) {
return ERROR_MALFORMED;
}
- return connect(host, port, path, headers, offset);
+ return connect(host, port, path, https, headers, offset);
}
static bool IsRedirectStatusCode(int httpStatus) {
@@ -125,6 +135,7 @@ static bool IsRedirectStatusCode(int httpStatus) {
status_t NuHTTPDataSource::connect(
const char *host, unsigned port, const char *path,
+ bool https,
const String8 &headers,
off64_t offset) {
LOGI("connect to %s:%u%s @%lld", host, port, path, offset);
@@ -132,7 +143,7 @@ status_t NuHTTPDataSource::connect(
bool needsToReconnect = true;
if (mState == CONNECTED && host == mHost && port == mPort
- && offset == mOffset) {
+ && https == mHTTPS && offset == mOffset) {
if (mContentLengthValid && mOffset == mContentLength) {
LOGI("Didn't have to reconnect, old one's still good.");
needsToReconnect = false;
@@ -142,6 +153,7 @@ status_t NuHTTPDataSource::connect(
mHost = host;
mPort = port;
mPath = path;
+ mHTTPS = https;
mHeaders = headers;
status_t err = OK;
@@ -150,7 +162,7 @@ status_t NuHTTPDataSource::connect(
if (needsToReconnect) {
mHTTP.disconnect();
- err = mHTTP.connect(host, port);
+ err = mHTTP.connect(host, port, https);
}
if (err != OK) {
@@ -353,7 +365,7 @@ ssize_t NuHTTPDataSource::readAt(off64_t offset, void *data, size_t size) {
String8 host = mHost;
String8 path = mPath;
String8 headers = mHeaders;
- status_t err = connect(host, mPort, path, headers, offset);
+ status_t err = connect(host, mPort, path, mHTTPS, headers, offset);
if (err != OK) {
return err;
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index f7a9085..ee845a3 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -189,7 +189,8 @@ status_t LiveSession::fetchFile(const char *url, sp<ABuffer> *out) {
if (!strncasecmp(url, "file://", 7)) {
source = new FileSource(url + 7);
- } else if (strncasecmp(url, "http://", 7)) {
+ } else if (strncasecmp(url, "http://", 7)
+ && strncasecmp(url, "https://", 8)) {
return ERROR_UNSUPPORTED;
} else {
{
diff --git a/media/libstagefright/include/HTTPStream.h b/media/libstagefright/include/HTTPStream.h
index 545cd0c..09e6a5f 100644
--- a/media/libstagefright/include/HTTPStream.h
+++ b/media/libstagefright/include/HTTPStream.h
@@ -32,7 +32,7 @@ public:
HTTPStream();
~HTTPStream();
- status_t connect(const char *server, int port = 80);
+ status_t connect(const char *server, int port = -1, bool https = false);
status_t disconnect();
status_t send(const char *data, size_t size);
@@ -71,6 +71,9 @@ private:
KeyedVector<AString, AString> mHeaders;
+ void *mSSLContext;
+ void *mSSL;
+
HTTPStream(const HTTPStream &);
HTTPStream &operator=(const HTTPStream &);
};
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index a99e84a..3918434 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -57,6 +57,7 @@ private:
String8 mHost;
unsigned mPort;
String8 mPath;
+ bool mHTTPS;
String8 mHeaders;
String8 mUri;
@@ -83,6 +84,7 @@ private:
status_t connect(
const char *host, unsigned port, const char *path,
+ bool https,
const String8 &headers,
off64_t offset);