Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp (216490 => 216491)
--- releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp 2017-05-09 09:58:32 UTC (rev 216490)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp 2017-05-09 09:58:40 UTC (rev 216491)
@@ -49,75 +49,76 @@
using namespace WebCore;
class StreamingClient {
- public:
- StreamingClient(WebKitWebSrc*);
- virtual ~StreamingClient();
+public:
+ StreamingClient(WebKitWebSrc*, ResourceRequest&&);
+ virtual ~StreamingClient();
- protected:
- char* createReadBuffer(size_t requestedSize, size_t& actualSize);
- void handleResponseReceived(const ResourceResponse&);
- void handleDataReceived(const char*, int);
- void handleNotifyFinished();
+protected:
+ char* createReadBuffer(size_t requestedSize, size_t& actualSize);
+ void handleResponseReceived(const ResourceResponse&);
+ void handleDataReceived(const char*, int);
+ void handleNotifyFinished();
- GstElement* m_src;
+ GRefPtr<GstElement> m_src;
+ ResourceRequest m_request;
};
class CachedResourceStreamingClient final : public PlatformMediaResourceClient, public StreamingClient {
WTF_MAKE_NONCOPYABLE(CachedResourceStreamingClient);
- public:
- CachedResourceStreamingClient(WebKitWebSrc*);
- virtual ~CachedResourceStreamingClient();
+public:
+ CachedResourceStreamingClient(WebKitWebSrc*, ResourceRequest&&);
+ virtual ~CachedResourceStreamingClient();
- private:
- // PlatformMediaResourceClient virtual methods.
+private:
+ // PlatformMediaResourceClient virtual methods.
#if USE(SOUP)
- char* getOrCreateReadBuffer(PlatformMediaResource&, size_t requestedSize, size_t& actualSize) override;
+ char* getOrCreateReadBuffer(PlatformMediaResource&, size_t requestedSize, size_t& actualSize) override;
#endif
- void responseReceived(PlatformMediaResource&, const ResourceResponse&) override;
- void dataReceived(PlatformMediaResource&, const char*, int) override;
- void accessControlCheckFailed(PlatformMediaResource&, const ResourceError&) override;
- void loadFailed(PlatformMediaResource&, const ResourceError&) override;
- void loadFinished(PlatformMediaResource&) override;
+ void responseReceived(PlatformMediaResource&, const ResourceResponse&) override;
+ void dataReceived(PlatformMediaResource&, const char*, int) override;
+ void accessControlCheckFailed(PlatformMediaResource&, const ResourceError&) override;
+ void loadFailed(PlatformMediaResource&, const ResourceError&) override;
+ void loadFinished(PlatformMediaResource&) override;
};
class ResourceHandleStreamingClient : public ThreadSafeRefCounted<ResourceHandleStreamingClient>, public ResourceHandleClient, public StreamingClient {
- public:
- static Ref<ResourceHandleStreamingClient> create(WebKitWebSrc* src, ResourceRequest&& request)
- {
- return adoptRef(*new ResourceHandleStreamingClient(src, WTFMove(request)));
- }
- virtual ~ResourceHandleStreamingClient();
+public:
+ static Ref<ResourceHandleStreamingClient> create(WebKitWebSrc* src, ResourceRequest&& request)
+ {
+ return adoptRef(*new ResourceHandleStreamingClient(src, WTFMove(request)));
+ }
+ virtual ~ResourceHandleStreamingClient();
- void invalidate();
+ void invalidate();
- // StreamingClient virtual methods.
- bool loadFailed() const;
- void setDefersLoading(bool);
+ // StreamingClient virtual methods.
+ bool loadFailed() const;
+ void setDefersLoading(bool);
- private:
- ResourceHandleStreamingClient(WebKitWebSrc*, ResourceRequest&&);
- void cleanupAndStopRunLoop();
+private:
+ ResourceHandleStreamingClient(WebKitWebSrc*, ResourceRequest&&);
+ void cleanupAndStopRunLoop();
- // ResourceHandleClient virtual methods.
+ // ResourceHandleClient virtual methods.
#if USE(SOUP)
- char* getOrCreateReadBuffer(size_t requestedSize, size_t& actualSize) override;
+ char* getOrCreateReadBuffer(size_t requestedSize, size_t& actualSize) override;
#endif
- ResourceRequest willSendRequest(ResourceHandle*, ResourceRequest&&, ResourceResponse&&) override;
- void didReceiveResponse(ResourceHandle*, ResourceResponse&&) override;
- void didReceiveData(ResourceHandle*, const char*, unsigned, int) override;
- void didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&&, int encodedLength) override;
- void didFinishLoading(ResourceHandle*, double /*finishTime*/) override;
- void didFail(ResourceHandle*, const ResourceError&) override;
- void wasBlocked(ResourceHandle*) override;
- void cannotShowURL(ResourceHandle*) override;
+ ResourceRequest willSendRequest(ResourceHandle*, ResourceRequest&&, ResourceResponse&&) override;
+ void didReceiveResponse(ResourceHandle*, ResourceResponse&&) override;
+ void didReceiveData(ResourceHandle*, const char*, unsigned, int) override;
+ void didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&&, int encodedLength) override;
+ void didFinishLoading(ResourceHandle*, double) override;
+ void didFail(ResourceHandle*, const ResourceError&) override;
+ void wasBlocked(ResourceHandle*) override;
+ void cannotShowURL(ResourceHandle*) override;
- ThreadIdentifier m_thread { 0 };
- Lock m_initializeRunLoopConditionMutex;
- Condition m_initializeRunLoopCondition;
- RunLoop* m_runLoop { nullptr };
- Lock m_terminateRunLoopConditionMutex;
- Condition m_terminateRunLoopCondition;
- RefPtr<ResourceHandle> m_resource;
+ ThreadIdentifier m_thread { 0 };
+ Lock m_initializeRunLoopConditionMutex;
+ Condition m_initializeRunLoopCondition;
+ RunLoop* m_runLoop { nullptr };
+ Lock m_terminateRunLoopConditionMutex;
+ Condition m_terminateRunLoopCondition;
+ RefPtr<ResourceHandle> m_resource;
};
enum MainThreadSourceNotification {
@@ -133,7 +134,7 @@
GstAppSrc* appsrc;
GstPad* srcpad;
CString originalURI;
- CString resolvedURI;
+ CString redirectedURI;
bool keepAlive;
GUniquePtr<GstStructure> extraHeaders;
bool compress;
@@ -310,6 +311,8 @@
// This might need tweaking for ports not using libsoup.
g_object_set(priv->appsrc, "min-percent", 20, NULL);
+ gst_base_src_set_automatic_eos(GST_BASE_SRC(priv->appsrc), FALSE);
+
gst_app_src_set_caps(priv->appsrc, 0);
gst_app_src_set_size(priv->appsrc, -1);
}
@@ -372,7 +375,7 @@
g_value_set_string(value, priv->originalURI.data());
break;
case PROP_RESOLVED_LOCATION:
- g_value_set_string(value, priv->resolvedURI.data());
+ g_value_set_string(value, priv->redirectedURI.isNull() ? priv->originalURI.data() : priv->redirectedURI.data());
break;
case PROP_KEEP_ALIVE:
g_value_set_boolean(value, priv->keepAlive);
@@ -594,7 +597,7 @@
loadOptions |= PlatformMediaResourceLoader::LoadOption::BufferData;
priv->resource = priv->loader->requestResource(request, loadOptions);
if (priv->resource) {
- priv->resource->setClient(std::make_unique<CachedResourceStreamingClient>(protector.get()));
+ priv->resource->setClient(std::make_unique<CachedResourceStreamingClient>(protector.get(), ResourceRequest(request)));
GST_DEBUG_OBJECT(protector.get(), "Started request");
} else {
GST_ERROR_OBJECT(protector.get(), "Failed to setup streaming client");
@@ -672,6 +675,8 @@
case GST_QUERY_URI: {
WTF::GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
gst_query_set_uri(query, src->priv->originalURI.data());
+ if (!src->priv->redirectedURI.isNull())
+ gst_query_set_uri_redirection(query, src->priv->redirectedURI.data());
result = TRUE;
break;
}
@@ -739,6 +744,7 @@
WTF::GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
+ priv->redirectedURI = CString();
priv->originalURI = CString();
if (!uri)
return TRUE;
@@ -857,19 +863,19 @@
return src->priv->didPassAccessControlCheck;
}
-StreamingClient::StreamingClient(WebKitWebSrc* src)
- : m_src(static_cast<GstElement*>(gst_object_ref(src)))
+StreamingClient::StreamingClient(WebKitWebSrc* src, ResourceRequest&& request)
+ : m_src(GST_ELEMENT(src))
+ , m_request(WTFMove(request))
{
}
StreamingClient::~StreamingClient()
{
- gst_object_unref(m_src);
}
char* StreamingClient::createReadBuffer(size_t requestedSize, size_t& actualSize)
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
WebKitWebSrcPrivate* priv = src->priv;
ASSERT(!priv->buffer);
@@ -888,12 +894,14 @@
void StreamingClient::handleResponseReceived(const ResourceResponse& response)
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
WebKitWebSrcPrivate* priv = src->priv;
GST_DEBUG_OBJECT(src, "Received response: %d", response.httpStatusCode());
- priv->resolvedURI = response.url().string().utf8();
+ auto responseURI = response.url().string().utf8();
+ if (priv->originalURI != responseURI)
+ priv->redirectedURI = WTFMove(responseURI);
if (response.httpStatusCode() >= 400) {
GST_ELEMENT_ERROR(src, RESOURCE, READ, ("Received %d HTTP error code", response.httpStatusCode()), (nullptr));
@@ -940,11 +948,26 @@
gst_app_src_set_size(priv->appsrc, -1);
gst_app_src_set_caps(priv->appsrc, 0);
+
+ // Emit a GST_EVENT_CUSTOM_DOWNSTREAM_STICKY event to let GStreamer know about the HTTP headers sent and received.
+ GstStructure* httpHeaders = gst_structure_new_empty("http-headers");
+ gst_structure_set(httpHeaders, "uri", G_TYPE_STRING, priv->originalURI.data(), nullptr);
+ if (!priv->redirectedURI.isNull())
+ gst_structure_set(httpHeaders, "redirection-uri", G_TYPE_STRING, priv->redirectedURI.data(), nullptr);
+ GUniquePtr<GstStructure> headers(gst_structure_new_empty("request-headers"));
+ for (const auto& header : m_request.httpHeaderFields())
+ gst_structure_set(headers.get(), header.key.utf8().data(), G_TYPE_STRING, header.value.utf8().data(), nullptr);
+ gst_structure_set(httpHeaders, "request-headers", GST_TYPE_STRUCTURE, headers.get(), nullptr);
+ headers.reset(gst_structure_new_empty("response-headers"));
+ for (const auto& header : response.httpHeaderFields())
+ gst_structure_set(headers.get(), header.key.utf8().data(), G_TYPE_STRING, header.value.utf8().data(), nullptr);
+ gst_structure_set(httpHeaders, "response-headers", GST_TYPE_STRUCTURE, headers.get(), nullptr);
+ gst_pad_push_event(GST_BASE_SRC_PAD(priv->appsrc), gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, httpHeaders));
}
void StreamingClient::handleDataReceived(const char* data, int length)
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
WebKitWebSrcPrivate* priv = src->priv;
WTF::GMutexLocker<GMutex> locker(*GST_OBJECT_GET_LOCK(src));
@@ -1011,7 +1034,7 @@
void StreamingClient::handleNotifyFinished()
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
WebKitWebSrcPrivate* priv = src->priv;
GST_DEBUG_OBJECT(src, "Have EOS");
@@ -1023,8 +1046,8 @@
}
}
-CachedResourceStreamingClient::CachedResourceStreamingClient(WebKitWebSrc* src)
- : StreamingClient(src)
+CachedResourceStreamingClient::CachedResourceStreamingClient(WebKitWebSrc* src, ResourceRequest&& request)
+ : StreamingClient(src, WTFMove(request))
{
}
@@ -1041,7 +1064,7 @@
void CachedResourceStreamingClient::responseReceived(PlatformMediaResource&, const ResourceResponse& response)
{
- WebKitWebSrcPrivate* priv = WEBKIT_WEB_SRC(m_src)->priv;
+ WebKitWebSrcPrivate* priv = WEBKIT_WEB_SRC(m_src.get())->priv;
priv->didPassAccessControlCheck = priv->resource->didPassAccessControlCheck();
handleResponseReceived(response);
}
@@ -1053,7 +1076,7 @@
void CachedResourceStreamingClient::accessControlCheckFailed(PlatformMediaResource&, const ResourceError& error)
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
GST_ELEMENT_ERROR(src, RESOURCE, READ, ("%s", error.localizedDescription().utf8().data()), (nullptr));
gst_app_src_end_of_stream(src->priv->appsrc);
webKitWebSrcStop(src);
@@ -1061,7 +1084,7 @@
void CachedResourceStreamingClient::loadFailed(PlatformMediaResource&, const ResourceError& error)
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
if (!error.isCancellation()) {
GST_ERROR_OBJECT(src, "Have failure: %s", error.localizedDescription().utf8().data());
@@ -1077,14 +1100,14 @@
}
ResourceHandleStreamingClient::ResourceHandleStreamingClient(WebKitWebSrc* src, ResourceRequest&& request)
- : StreamingClient(src)
+ : StreamingClient(src, WTFMove(request))
{
LockHolder locker(m_initializeRunLoopConditionMutex);
- m_thread = createThread("ResourceHandleStreamingClient", [this, request = WTFMove(request)] {
+ m_thread = createThread("ResourceHandleStreamingClient", [this] {
{
LockHolder locker(m_initializeRunLoopConditionMutex);
m_runLoop = &RunLoop::current();
- m_resource = ResourceHandle::create(nullptr /*context*/, request, this, true, false);
+ m_resource = ResourceHandle::create(nullptr /*context*/, m_request, this, true, false);
m_initializeRunLoopCondition.notifyOne();
}
if (!m_resource)
@@ -1186,7 +1209,7 @@
void ResourceHandleStreamingClient::didFail(ResourceHandle*, const ResourceError& error)
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
GST_ERROR_OBJECT(src, "Have failure: %s", error.localizedDescription().utf8().data());
GST_ELEMENT_ERROR(src, RESOURCE, FAILED, ("%s", error.localizedDescription().utf8().data()), (0));
@@ -1195,7 +1218,7 @@
void ResourceHandleStreamingClient::wasBlocked(ResourceHandle*)
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
GUniquePtr<gchar> uri;
GST_ERROR_OBJECT(src, "Request was blocked");
@@ -1209,7 +1232,7 @@
void ResourceHandleStreamingClient::cannotShowURL(ResourceHandle*)
{
- WebKitWebSrc* src = ""
+ WebKitWebSrc* src = ""
GUniquePtr<gchar> uri;
GST_ERROR_OBJECT(src, "Cannot show URL");