Home | History | Annotate | Download | only in loader
      1 /*
      2  * Copyright (C) 2011 Google Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #include "core/loader/TextTrackLoader.h"
     29 
     30 #include "FetchInitiatorTypeNames.h"
     31 #include "core/dom/Document.h"
     32 #include "core/fetch/CrossOriginAccessControl.h"
     33 #include "core/fetch/FetchRequest.h"
     34 #include "core/fetch/ResourceFetcher.h"
     35 #include "platform/Logging.h"
     36 #include "platform/SharedBuffer.h"
     37 #include "platform/weborigin/SecurityOrigin.h"
     38 
     39 namespace WebCore {
     40 
     41 TextTrackLoader::TextTrackLoader(TextTrackLoaderClient& client, Document& document)
     42     : m_client(client)
     43     , m_document(document)
     44     , m_cueLoadTimer(this, &TextTrackLoader::cueLoadTimerFired)
     45     , m_state(Idle)
     46     , m_newCuesAvailable(false)
     47 {
     48 }
     49 
     50 TextTrackLoader::~TextTrackLoader()
     51 {
     52 }
     53 
     54 void TextTrackLoader::cueLoadTimerFired(Timer<TextTrackLoader>* timer)
     55 {
     56     ASSERT_UNUSED(timer, timer == &m_cueLoadTimer);
     57 
     58     if (m_newCuesAvailable) {
     59         m_newCuesAvailable = false;
     60         m_client.newCuesAvailable(this);
     61     }
     62 
     63     if (m_state >= Finished)
     64         m_client.cueLoadingCompleted(this, m_state == Failed);
     65 }
     66 
     67 void TextTrackLoader::cancelLoad()
     68 {
     69     clearResource();
     70 }
     71 
     72 void TextTrackLoader::dataReceived(Resource* resource, const char* data, int length)
     73 {
     74     ASSERT(this->resource() == resource);
     75 
     76     if (m_state == Failed)
     77         return;
     78 
     79     if (!m_cueParser)
     80         m_cueParser = VTTParser::create(this, m_document);
     81 
     82     m_cueParser->parseBytes(data, length);
     83 }
     84 
     85 void TextTrackLoader::corsPolicyPreventedLoad()
     86 {
     87     DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin text track load denied by Cross-Origin Resource Sharing policy."));
     88     m_document.addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage);
     89     m_state = Failed;
     90 }
     91 
     92 void TextTrackLoader::notifyFinished(Resource* resource)
     93 {
     94     ASSERT(this->resource() == resource);
     95 
     96     if (!m_crossOriginMode.isNull()
     97         && !m_document.securityOrigin()->canRequest(resource->response().url())
     98         && !resource->passesAccessControlCheck(m_document.securityOrigin())) {
     99 
    100         corsPolicyPreventedLoad();
    101     }
    102 
    103     if (m_state != Failed)
    104         m_state = resource->errorOccurred() ? Failed : Finished;
    105 
    106     if (m_state == Finished && m_cueParser)
    107         m_cueParser->flush();
    108 
    109     if (!m_cueLoadTimer.isActive())
    110         m_cueLoadTimer.startOneShot(0);
    111 
    112     cancelLoad();
    113 }
    114 
    115 bool TextTrackLoader::load(const KURL& url, const String& crossOriginMode)
    116 {
    117     cancelLoad();
    118 
    119     FetchRequest cueRequest(ResourceRequest(m_document.completeURL(url)), FetchInitiatorTypeNames::texttrack);
    120 
    121     if (!crossOriginMode.isNull()) {
    122         m_crossOriginMode = crossOriginMode;
    123         StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
    124         updateRequestForAccessControl(cueRequest.mutableResourceRequest(), m_document.securityOrigin(), allowCredentials);
    125     } else {
    126         // Cross-origin resources that are not suitably CORS-enabled may not load.
    127         if (!m_document.securityOrigin()->canRequest(url)) {
    128             corsPolicyPreventedLoad();
    129             return false;
    130         }
    131     }
    132 
    133     ResourceFetcher* fetcher = m_document.fetcher();
    134     setResource(fetcher->fetchRawResource(cueRequest));
    135     return resource();
    136 }
    137 
    138 void TextTrackLoader::newCuesParsed()
    139 {
    140     if (m_cueLoadTimer.isActive())
    141         return;
    142 
    143     m_newCuesAvailable = true;
    144     m_cueLoadTimer.startOneShot(0);
    145 }
    146 
    147 void TextTrackLoader::newRegionsParsed()
    148 {
    149     m_client.newRegionsAvailable(this);
    150 }
    151 
    152 void TextTrackLoader::fileFailedToParse()
    153 {
    154     WTF_LOG(Media, "TextTrackLoader::fileFailedToParse");
    155 
    156     m_state = Failed;
    157 
    158     if (!m_cueLoadTimer.isActive())
    159         m_cueLoadTimer.startOneShot(0);
    160 
    161     cancelLoad();
    162 }
    163 
    164 void TextTrackLoader::getNewCues(Vector<RefPtr<VTTCue> >& outputCues)
    165 {
    166     ASSERT(m_cueParser);
    167     if (m_cueParser)
    168         m_cueParser->getNewCues(outputCues);
    169 }
    170 
    171 void TextTrackLoader::getNewRegions(Vector<RefPtr<VTTRegion> >& outputRegions)
    172 {
    173     ASSERT(m_cueParser);
    174     if (m_cueParser)
    175         m_cueParser->getNewRegions(outputRegions);
    176 }
    177 
    178 }
    179