1 /*
2 * Copyright (C) 2009 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2009, 2011 Google Inc. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27
28 #include "config.h"
29
30 #if ENABLE(WORKERS)
31
32 #include "WorkerScriptLoader.h"
33
34 #include "CrossThreadTask.h"
35 #include "ResourceRequest.h"
36 #include "ScriptExecutionContext.h"
37 #include "SecurityOrigin.h"
38 #include "WorkerContext.h"
39 #include "WorkerScriptLoaderClient.h"
40 #include "WorkerThreadableLoader.h"
41 #include <wtf/OwnPtr.h>
42 #include <wtf/UnusedParam.h>
43
44 namespace WebCore {
45
WorkerScriptLoader(ResourceRequestBase::TargetType targetType)46 WorkerScriptLoader::WorkerScriptLoader(ResourceRequestBase::TargetType targetType)
47 : m_client(0)
48 , m_failed(false)
49 , m_identifier(0)
50 , m_targetType(targetType)
51 {
52 }
53
loadSynchronously(ScriptExecutionContext * scriptExecutionContext,const KURL & url,CrossOriginRequestPolicy crossOriginRequestPolicy)54 void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecutionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy)
55 {
56 m_url = url;
57
58 OwnPtr<ResourceRequest> request(createResourceRequest());
59 if (!request)
60 return;
61
62 ASSERT(scriptExecutionContext->isWorkerContext());
63
64 ThreadableLoaderOptions options;
65 options.allowCredentials = true;
66 options.crossOriginRequestPolicy = crossOriginRequestPolicy;
67 options.sendLoadCallbacks = true;
68
69 WorkerThreadableLoader::loadResourceSynchronously(static_cast<WorkerContext*>(scriptExecutionContext), *request, *this, options);
70 }
71
loadAsynchronously(ScriptExecutionContext * scriptExecutionContext,const KURL & url,CrossOriginRequestPolicy crossOriginRequestPolicy,WorkerScriptLoaderClient * client)72 void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext* scriptExecutionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy, WorkerScriptLoaderClient* client)
73 {
74 ASSERT(client);
75 m_client = client;
76 m_url = url;
77
78 OwnPtr<ResourceRequest> request(createResourceRequest());
79 if (!request)
80 return;
81
82 ThreadableLoaderOptions options;
83 options.allowCredentials = true;
84 options.crossOriginRequestPolicy = crossOriginRequestPolicy;
85 options.sendLoadCallbacks = true;
86
87 m_threadableLoader = ThreadableLoader::create(scriptExecutionContext, this, *request, options);
88 }
89
responseURL() const90 const KURL& WorkerScriptLoader::responseURL() const
91 {
92 ASSERT(!failed());
93 return m_responseURL;
94 }
95
createResourceRequest()96 PassOwnPtr<ResourceRequest> WorkerScriptLoader::createResourceRequest()
97 {
98 OwnPtr<ResourceRequest> request(new ResourceRequest(m_url));
99 request->setHTTPMethod("GET");
100 request->setTargetType(m_targetType);
101 return request.release();
102 }
103
didReceiveResponse(const ResourceResponse & response)104 void WorkerScriptLoader::didReceiveResponse(const ResourceResponse& response)
105 {
106 if (response.httpStatusCode() / 100 != 2 && response.httpStatusCode()) {
107 m_failed = true;
108 return;
109 }
110 m_responseURL = response.url();
111 m_responseEncoding = response.textEncodingName();
112 if (m_client)
113 m_client->didReceiveResponse(response);
114 }
115
didReceiveData(const char * data,int len)116 void WorkerScriptLoader::didReceiveData(const char* data, int len)
117 {
118 if (m_failed)
119 return;
120
121 if (!m_decoder) {
122 if (!m_responseEncoding.isEmpty())
123 m_decoder = TextResourceDecoder::create("text/javascript", m_responseEncoding);
124 else
125 m_decoder = TextResourceDecoder::create("text/javascript", "UTF-8");
126 }
127
128 if (!len)
129 return;
130
131 if (len == -1)
132 len = strlen(data);
133
134 m_script += m_decoder->decode(data, len);
135 }
136
didFinishLoading(unsigned long identifier,double)137 void WorkerScriptLoader::didFinishLoading(unsigned long identifier, double)
138 {
139 if (m_failed)
140 return;
141
142 if (m_decoder)
143 m_script += m_decoder->flush();
144
145 m_identifier = identifier;
146 notifyFinished();
147 }
148
didFail(const ResourceError &)149 void WorkerScriptLoader::didFail(const ResourceError&)
150 {
151 notifyError();
152 }
153
didFailRedirectCheck()154 void WorkerScriptLoader::didFailRedirectCheck()
155 {
156 notifyError();
157 }
158
didReceiveAuthenticationCancellation(const ResourceResponse &)159 void WorkerScriptLoader::didReceiveAuthenticationCancellation(const ResourceResponse&)
160 {
161 notifyError();
162 }
163
notifyError()164 void WorkerScriptLoader::notifyError()
165 {
166 m_failed = true;
167 notifyFinished();
168 }
169
notifyFinished()170 void WorkerScriptLoader::notifyFinished()
171 {
172 if (m_client)
173 m_client->notifyFinished();
174 }
175
176 } // namespace WebCore
177
178 #endif // ENABLE(WORKERS)
179