1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/renderer/media/flash_embed_rewrite.h"
6 
7 #include "base/metrics/histogram_macros.h"
8 #include "url/gurl.h"
9 
RewriteFlashEmbedURL(const GURL & url)10 GURL FlashEmbedRewrite::RewriteFlashEmbedURL(const GURL& url) {
11   DCHECK(url.is_valid());
12 
13   if (url.DomainIs("youtube.com") || url.DomainIs("youtube-nocookie.com"))
14     return RewriteYouTubeFlashEmbedURL(url);
15 
16   if (url.DomainIs("dailymotion.com"))
17     return RewriteDailymotionFlashEmbedURL(url);
18 
19   return GURL();
20 }
21 
RewriteYouTubeFlashEmbedURL(const GURL & url)22 GURL FlashEmbedRewrite::RewriteYouTubeFlashEmbedURL(const GURL& url) {
23   // YouTube URLs are of the form of youtube.com/v/VIDEO_ID. So, we check to see
24   // if the given URL does follow that format.
25   if (url.path().find("/v/") != 0)
26     return GURL();
27 
28   std::string url_str = url.spec();
29 
30   // If the website is using an invalid YouTube URL, we will try and
31   // fix the URL by ensuring that if there are multiple parameters,
32   // the parameter string begins with a "?" and then follows with a "&"
33   // for each subsequent parameter. We do this because the Flash video player
34   // has some URL correction capabilities so we don't want this move to HTML5
35   // to break webpages that used to work.
36   size_t index = url_str.find_first_of("&?");
37   bool invalid_url = index != std::string::npos && url_str.at(index) == '&';
38 
39   if (invalid_url) {
40     // ? should appear first before all parameters.
41     url_str.replace(index, 1, "?");
42 
43     // Replace all instances of ? (after the first) with &.
44     for (size_t pos = index + 1;
45          (pos = url_str.find("?", pos)) != std::string::npos; pos += 1) {
46       url_str.replace(pos, 1, "&");
47     }
48   }
49 
50   GURL corrected_url = GURL(url_str);
51 
52   // Change the path to use the YouTube HTML5 API.
53   std::string path = corrected_url.path();
54   path.replace(path.find("/v/"), 3, "/embed/");
55 
56   url::Replacements<char> r;
57   r.SetPath(path.c_str(), url::Component(0, path.length()));
58 
59   return corrected_url.ReplaceComponents(r);
60 }
61 
RewriteDailymotionFlashEmbedURL(const GURL & url)62 GURL FlashEmbedRewrite::RewriteDailymotionFlashEmbedURL(const GURL& url) {
63   // Dailymotion flash embeds are of the form of either:
64   //  - /swf/
65   //  - /swf/video/
66   if (url.path().find("/swf/") != 0)
67     return GURL();
68 
69   std::string path = url.path();
70   int replace_length = path.find("/swf/video/") == 0 ? 11 : 5;
71   path.replace(0, replace_length, "/embed/video/");
72 
73   url::Replacements<char> r;
74   r.SetPath(path.c_str(), url::Component(0, path.length()));
75 
76   return url.ReplaceComponents(r);
77 }
78