iOS Safari incorrectly reports "AppleCoreMedia" as UA string
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 27 Jun 2020 19:31:17 +0000 (19:31 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 27 Jun 2020 19:31:17 +0000 (19:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=213245
<rdar://problem/64471582>

Reviewed by Youenn Fablet.

Source/WebCore:

Tests: TestWebKitAPI.MediaLoading.UserAgentStringCRABS
       TestWebKitAPI.MediaLoading.UserAgentStringHLS

* platform/network/cocoa/WebCoreNSURLSession.mm:
(-[WebCoreNSURLSessionDataTask initWithSession:identifier:request:]):

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/MediaLoading.mm: Added.
(TestWebKitAPI::parseUserAgent):
(TestWebKitAPI::TEST):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263627 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaLoading.mm [new file with mode: 0644]

index 46f727e..3c3e2f8 100644 (file)
@@ -1,3 +1,17 @@
+2020-06-27  Jer Noble  <jer.noble@apple.com>
+
+        iOS Safari incorrectly reports "AppleCoreMedia" as UA string
+        https://bugs.webkit.org/show_bug.cgi?id=213245
+        <rdar://problem/64471582>
+
+        Reviewed by Youenn Fablet.
+
+        Tests: TestWebKitAPI.MediaLoading.UserAgentStringCRABS
+               TestWebKitAPI.MediaLoading.UserAgentStringHLS
+
+        * platform/network/cocoa/WebCoreNSURLSession.mm:
+        (-[WebCoreNSURLSessionDataTask initWithSession:identifier:request:]):
+
 2020-06-27  Rob Buis  <rbuis@igalia.com>
 
         Require <form> to be connected
index dd00daf..38511c8 100644 (file)
@@ -657,6 +657,14 @@ void WebCoreNSURLSessionDataTaskClient::loadFinished(PlatformMediaResource& reso
     self.session = session;
     self.state = NSURLSessionTaskStateSuspended;
     self.priority = NSURLSessionTaskPriorityDefault;
+
+    // CoreMedia will explicitly add a user agent header. Remove if present.
+    if (auto* userAgentValue = [request valueForHTTPHeaderField:@"User-Agent"]) {
+        NSMutableURLRequest* mutableRequest = [request mutableCopyWithZone:nil];
+        [mutableRequest setValue:nil forHTTPHeaderField:@"User-Agent"];
+        request = [mutableRequest autorelease];
+    }
+
     self.originalRequest = self.currentRequest = request;
 
     return self;
index a32d4d3..a120543 100644 (file)
@@ -1,3 +1,16 @@
+2020-06-27  Jer Noble  <jer.noble@apple.com>
+
+        iOS Safari incorrectly reports "AppleCoreMedia" as UA string
+        https://bugs.webkit.org/show_bug.cgi?id=213245
+        <rdar://problem/64471582>
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/MediaLoading.mm: Added.
+        (TestWebKitAPI::parseUserAgent):
+        (TestWebKitAPI::TEST):
+
 2020-06-27  Philippe Normand  <pnormand@igalia.com>
 
         Migrate run-minibrowser to webkitpy
index 08d8e54..d641130 100644 (file)
                CAB0FF5222332407006CA5B0 /* IndexedDBFileName-1.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CAB0FF51223323F6006CA5B0 /* IndexedDBFileName-1.html */; };
                CAB0FF5322332407006CA5B0 /* IndexedDBFileName-2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CAB0FF50223323F6006CA5B0 /* IndexedDBFileName-2.html */; };
                CAB0FF5522332C57006CA5B0 /* IndexedDBFileName.mm in Sources */ = {isa = PBXBuildFile; fileRef = CAB0FF5422332C3A006CA5B0 /* IndexedDBFileName.mm */; };
+               CD0370E324A44D9600BA3CAE /* MediaLoading.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD0370E224A44B7A00BA3CAE /* MediaLoading.mm */; };
                CD0BD0A61F79924D001AB2CF /* ContextMenuImgWithVideo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD0BD0A51F799220001AB2CF /* ContextMenuImgWithVideo.mm */; };
                CD0BD0A81F79982D001AB2CF /* ContextMenuImgWithVideo.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD0BD0A71F7997C2001AB2CF /* ContextMenuImgWithVideo.html */; };
                CD227E44211A4D5D00D285AF /* PreferredAudioBufferSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD227E43211A4D5D00D285AF /* PreferredAudioBufferSize.mm */; };
                CAB0FF50223323F6006CA5B0 /* IndexedDBFileName-2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "IndexedDBFileName-2.html"; sourceTree = "<group>"; };
                CAB0FF51223323F6006CA5B0 /* IndexedDBFileName-1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "IndexedDBFileName-1.html"; sourceTree = "<group>"; };
                CAB0FF5422332C3A006CA5B0 /* IndexedDBFileName.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IndexedDBFileName.mm; sourceTree = "<group>"; };
+               CD0370E224A44B7A00BA3CAE /* MediaLoading.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaLoading.mm; sourceTree = "<group>"; };
                CD0BD0A51F799220001AB2CF /* ContextMenuImgWithVideo.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuImgWithVideo.mm; sourceTree = "<group>"; };
                CD0BD0A71F7997C2001AB2CF /* ContextMenuImgWithVideo.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = ContextMenuImgWithVideo.html; sourceTree = "<group>"; };
                CD225C071C45A69200140761 /* ParsedContentRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParsedContentRange.cpp; sourceTree = "<group>"; };
                                8C10AF96206467770018FD90 /* LocalStoragePersistence.mm */,
                                7A6A2C6F1DCCF87B00C0D085 /* LocalStorageQuirkTest.mm */,
                                07CC7DFD2266330800E39181 /* MediaBufferingPolicy.mm */,
+                               CD0370E224A44B7A00BA3CAE /* MediaLoading.mm */,
                                51BE9E652376089500B4E117 /* MediaType.mm */,
                                5165FE03201EE617009F7EC3 /* MessagePortProviders.mm */,
                                51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */,
                                0711DF52226A95FC003DD2F7 /* AVFoundationSoftLinkTest.mm in Sources */,
                                7CCE7EB51A411A7E00447C4C /* BackForwardList.mm in Sources */,
                                1C7FEB20207C0F2E00D23278 /* BackgroundColor.mm in Sources */,
+                               CD0370E324A44D9600BA3CAE /* MediaLoading.mm in Sources */,
                                C15CBB3023F1FF1A00300CC7 /* BacklightLevelNotification.mm in Sources */,
                                C1692DCA23D10DAE006E88F7 /* Battery.mm in Sources */,
                                374B7A601DF36EEE00ACCB6C /* BundleEditingDelegate.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaLoading.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaLoading.mm
new file mode 100644 (file)
index 0000000..0dd0ed2
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#import "HTTPServer.h"
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import <wtf/text/StringConcatenateNumbers.h>
+
+#if ENABLE(VIDEO) && USE(AVFOUNDATION) && HAVE(NETWORK_FRAMEWORK)
+
+namespace TestWebKitAPI {
+
+static String parseUserAgent(const Vector<char>& request)
+{
+    auto headers = String::fromUTF8(request.data(), request.size()).split("\r\n");
+    auto index = headers.findMatching([] (auto& header) { return header.startsWith("User-Agent:"); });
+    if (index != notFound)
+        return headers[index];
+    return emptyString();
+}
+
+TEST(MediaLoading, UserAgentStringCRABS)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+    webView.get().customUserAgent = @"TestWebKitAPI";
+
+    bool receivedMediaRequest = false;
+
+    HTTPServer server([&](Connection connection) mutable {
+        connection.receiveHTTPRequest([&] (auto&& request) {
+            auto userAgent = parseUserAgent(request);
+            EXPECT_STREQ("User-Agent: TestWebKitAPI", userAgent.utf8().data());
+
+            receivedMediaRequest = true;
+        });
+    });
+
+    [webView loadHTMLString:[NSString stringWithFormat:@"<video src='http://127.0.0.1:%d/video.mp4' autoplay></video>", server.port()] baseURL:nil];
+
+    Util::run(&receivedMediaRequest);
+}
+
+TEST(MediaLoading, UserAgentStringHLS)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+    webView.get().customUserAgent = @"TestWebKitAPI";
+
+    bool receivedManifestRequest = false;
+    bool receivedMediaRequest = false;
+
+    HTTPServer mediaServer([&](Connection connection) mutable {
+        connection.receiveHTTPRequest([connection, &receivedMediaRequest] (Vector<char>&& request) {
+            auto userAgent = parseUserAgent(request);
+            EXPECT_STREQ("User-Agent: TestWebKitAPI", userAgent.utf8().data());
+            receivedMediaRequest = true;
+        });
+    });
+    auto mediaServerPort = mediaServer.port();
+
+    HTTPServer manifestServer([&](Connection connection) mutable {
+        connection.receiveHTTPRequest([connection, mediaServerPort, &receivedManifestRequest] (Vector<char>&& request) {
+            auto userAgent = parseUserAgent(request);
+            EXPECT_STREQ("User-Agent: TestWebKitAPI", userAgent.utf8().data());
+
+            auto payload = makeString(
+                "#EXTM3U\n"
+                "#EXT-X-TARGETDURATION:6\n"
+                "#EXT-X-VERSION:4\n"
+                "#EXT-X-MEDIA-SEQUENCE:0\n"
+                "#EXT-X-PLAYLIST-TYPE:VOD\n"
+                "#EXTINF:6.0272,\n"
+                "http://127.0.0.1:", mediaServerPort, "/main1.ts\n",
+                "#EXT-X-ENDLIST\n"
+            );
+
+            connection.send(makeString("HTTP/1.1 200 OK\r\n",
+                "Content-Length: ", payload.length(), "\r\n",
+                "\r\n",
+                payload
+            ));
+
+            receivedManifestRequest = true;
+        });
+    });
+
+    [webView loadHTMLString:[NSString stringWithFormat:@"<video src='http://127.0.0.1:%d/manifest.m3u8' autoplay></video>", manifestServer.port()] baseURL:nil];
+
+    Util::run(&receivedMediaRequest);
+}
+
+}
+
+#endif