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 "core/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(SecurityOrigin* securityOrigin, const KURL& url)
     86 {
     87     String consoleMessage("Text track from origin '" + SecurityOrigin::create(url)->toString() + "' has been blocked from loading: Not at same origin as the document, and parent of track element does not have a 'crossorigin' attribute. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.");
     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     if (m_state != Failed)
     96         m_state = resource->errorOccurred() ? Failed : Finished;
     97 
     98     if (m_state == Finished && m_cueParser)
     99         m_cueParser->flush();
    100 
    101     if (!m_cueLoadTimer.isActive())
    102         m_cueLoadTimer.startOneShot(0, FROM_HERE);
    103 
    104     cancelLoad();
    105 }
    106 
    107 bool TextTrackLoader::load(const KURL& url, const AtomicString& crossOriginMode)
    108 {
    109     cancelLoad();
    110 
    111     FetchRequest cueRequest(ResourceRequest(m_document.completeURL(url)), FetchInitiatorTypeNames::texttrack);
    112 
    113     if (!crossOriginMode.isNull()) {
    114         cueRequest.setCrossOriginAccessControl(m_document.securityOrigin(), crossOriginMode);
    115     } else if (!m_document.securityOrigin()->canRequest(url)) {
    116         // Text track elements without 'crossorigin' set on the parent are "No CORS"; report error if not same-origin.
    117         corsPolicyPreventedLoad(m_document.securityOrigin(), url);
    118         return false;
    119     }
    120 
    121     ResourceFetcher* fetcher = m_document.fetcher();
    122     setResource(fetcher->fetchTextTrack(cueRequest));
    123     return resource();
    124 }
    125 
    126 void TextTrackLoader::newCuesParsed()
    127 {
    128     if (m_cueLoadTimer.isActive())
    129         return;
    130 
    131     m_newCuesAvailable = true;
    132     m_cueLoadTimer.startOneShot(0, FROM_HERE);
    133 }
    134 
    135 void TextTrackLoader::newRegionsParsed()
    136 {
    137     m_client.newRegionsAvailable(this);
    138 }
    139 
    140 void TextTrackLoader::fileFailedToParse()
    141 {
    142     WTF_LOG(Media, "TextTrackLoader::fileFailedToParse");
    143 
    144     m_state = Failed;
    145 
    146     if (!m_cueLoadTimer.isActive())
    147         m_cueLoadTimer.startOneShot(0, FROM_HERE);
    148 
    149     cancelLoad();
    150 }
    151 
    152 void TextTrackLoader::getNewCues(WillBeHeapVector<RefPtrWillBeMember<VTTCue> >& outputCues)
    153 {
    154     ASSERT(m_cueParser);
    155     if (m_cueParser)
    156         m_cueParser->getNewCues(outputCues);
    157 }
    158 
    159 void TextTrackLoader::getNewRegions(WillBeHeapVector<RefPtrWillBeMember<VTTRegion> >& outputRegions)
    160 {
    161     ASSERT(m_cueParser);
    162     if (m_cueParser)
    163         m_cueParser->getNewRegions(outputRegions);
    164 }
    165 
    166 void TextTrackLoader::trace(Visitor* visitor)
    167 {
    168     visitor->trace(m_cueParser);
    169 }
    170 
    171 }
    172