Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: third_party/WebKit/Source/core/page/EventSource.cpp

Issue 1264453002: Split the constructor of ThreadableLoader into two methods (ctor and start()) (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009, 2012 Ericsson AB. All rights reserved. 2 * Copyright (C) 2009, 2012 Ericsson AB. All rights reserved.
3 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Copyright (C) 2011, Code Aurora Forum. All rights reserved. 4 * Copyright (C) 2011, Code Aurora Forum. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 const unsigned long long EventSource::defaultReconnectDelay = 3000; 62 const unsigned long long EventSource::defaultReconnectDelay = 3000;
63 63
64 inline EventSource::EventSource(ExecutionContext* context, const KURL& url, cons t EventSourceInit& eventSourceInit) 64 inline EventSource::EventSource(ExecutionContext* context, const KURL& url, cons t EventSourceInit& eventSourceInit)
65 : ActiveDOMObject(context) 65 : ActiveDOMObject(context)
66 , m_url(url) 66 , m_url(url)
67 , m_withCredentials(eventSourceInit.withCredentials()) 67 , m_withCredentials(eventSourceInit.withCredentials())
68 , m_state(CONNECTING) 68 , m_state(CONNECTING)
69 , m_decoder(TextResourceDecoder::create("text/plain", "UTF-8")) 69 , m_decoder(TextResourceDecoder::create("text/plain", "UTF-8"))
70 , m_connectTimer(this, &EventSource::connectTimerFired) 70 , m_connectTimer(this, &EventSource::connectTimerFired)
71 , m_discardTrailingNewline(false) 71 , m_discardTrailingNewline(false)
72 , m_requestInFlight(false)
73 , m_reconnectDelay(defaultReconnectDelay) 72 , m_reconnectDelay(defaultReconnectDelay)
74 { 73 {
75 } 74 }
76 75
77 EventSource* EventSource::create(ExecutionContext* context, const String& url, c onst EventSourceInit& eventSourceInit, ExceptionState& exceptionState) 76 EventSource* EventSource::create(ExecutionContext* context, const String& url, c onst EventSourceInit& eventSourceInit, ExceptionState& exceptionState)
78 { 77 {
79 if (url.isEmpty()) { 78 if (url.isEmpty()) {
80 exceptionState.throwDOMException(SyntaxError, "Cannot open an EventSourc e to an empty URL."); 79 exceptionState.throwDOMException(SyntaxError, "Cannot open an EventSourc e to an empty URL.");
81 return nullptr; 80 return nullptr;
82 } 81 }
(...skipping 14 matching lines...) Expand all
97 EventSource* source = new EventSource(context, fullURL, eventSourceInit); 96 EventSource* source = new EventSource(context, fullURL, eventSourceInit);
98 97
99 source->scheduleInitialConnect(); 98 source->scheduleInitialConnect();
100 source->suspendIfNeeded(); 99 source->suspendIfNeeded();
101 return source; 100 return source;
102 } 101 }
103 102
104 EventSource::~EventSource() 103 EventSource::~EventSource()
105 { 104 {
106 ASSERT(m_state == CLOSED); 105 ASSERT(m_state == CLOSED);
107 ASSERT(!m_requestInFlight); 106 ASSERT(!m_loader);
108 } 107 }
109 108
110 void EventSource::scheduleInitialConnect() 109 void EventSource::scheduleInitialConnect()
111 { 110 {
112 ASSERT(m_state == CONNECTING); 111 ASSERT(m_state == CONNECTING);
113 ASSERT(!m_requestInFlight); 112 ASSERT(!m_loader);
114 113
115 m_connectTimer.startOneShot(0, BLINK_FROM_HERE); 114 m_connectTimer.startOneShot(0, BLINK_FROM_HERE);
116 } 115 }
117 116
118 void EventSource::connect() 117 void EventSource::connect()
119 { 118 {
120 ASSERT(m_state == CONNECTING); 119 ASSERT(m_state == CONNECTING);
121 ASSERT(!m_requestInFlight); 120 ASSERT(!m_loader);
122 ASSERT(executionContext()); 121 ASSERT(executionContext());
123 122
124 ExecutionContext& executionContext = *this->executionContext(); 123 ExecutionContext& executionContext = *this->executionContext();
125 ResourceRequest request(m_url); 124 ResourceRequest request(m_url);
126 request.setHTTPMethod(HTTPNames::GET); 125 request.setHTTPMethod(HTTPNames::GET);
127 request.setHTTPHeaderField(HTTPNames::Accept, "text/event-stream"); 126 request.setHTTPHeaderField(HTTPNames::Accept, "text/event-stream");
128 request.setHTTPHeaderField(HTTPNames::Cache_Control, "no-cache"); 127 request.setHTTPHeaderField(HTTPNames::Cache_Control, "no-cache");
129 request.setRequestContext(WebURLRequest::RequestContextEventSource); 128 request.setRequestContext(WebURLRequest::RequestContextEventSource);
130 if (!m_lastEventId.isEmpty()) { 129 if (!m_lastEventId.isEmpty()) {
131 // HTTP headers are Latin-1 byte strings, but the Last-Event-ID header i s encoded as UTF-8. 130 // HTTP headers are Latin-1 byte strings, but the Last-Event-ID header i s encoded as UTF-8.
(...skipping 10 matching lines...) Expand all
142 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa ssMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConn ectSrcDirective; 141 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa ssMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConn ectSrcDirective;
143 142
144 ResourceLoaderOptions resourceLoaderOptions; 143 ResourceLoaderOptions resourceLoaderOptions;
145 resourceLoaderOptions.allowCredentials = (origin->canRequestNoSuborigin(m_ur l) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials; 144 resourceLoaderOptions.allowCredentials = (origin->canRequestNoSuborigin(m_ur l) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
146 resourceLoaderOptions.credentialsRequested = m_withCredentials ? ClientReque stedCredentials : ClientDidNotRequestCredentials; 145 resourceLoaderOptions.credentialsRequested = m_withCredentials ? ClientReque stedCredentials : ClientDidNotRequestCredentials;
147 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData; 146 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
148 resourceLoaderOptions.securityOrigin = origin; 147 resourceLoaderOptions.securityOrigin = origin;
149 148
150 InspectorInstrumentation::willSendEventSourceRequest(&executionContext, this ); 149 InspectorInstrumentation::willSendEventSourceRequest(&executionContext, this );
151 // InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient will be called synchronously. 150 // InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient will be called synchronously.
152 m_loader = ThreadableLoader::create(executionContext, this, request, options , resourceLoaderOptions); 151 m_loader = ThreadableLoader::create(executionContext, this, options, resourc eLoaderOptions);
153 152 m_loader->start(request);
154 if (m_loader)
155 m_requestInFlight = true;
156 } 153 }
157 154
158 void EventSource::networkRequestEnded() 155 void EventSource::networkRequestEnded()
159 { 156 {
160 if (!m_requestInFlight)
161 return;
162
163 InspectorInstrumentation::didFinishEventSourceRequest(executionContext(), th is); 157 InspectorInstrumentation::didFinishEventSourceRequest(executionContext(), th is);
164 158
165 m_requestInFlight = false; 159 m_loader = nullptr;
166 160
167 if (m_state != CLOSED) 161 if (m_state != CLOSED)
168 scheduleReconnect(); 162 scheduleReconnect();
169 } 163 }
170 164
171 void EventSource::scheduleReconnect() 165 void EventSource::scheduleReconnect()
172 { 166 {
173 m_state = CONNECTING; 167 m_state = CONNECTING;
174 m_connectTimer.startOneShot(m_reconnectDelay / 1000.0, BLINK_FROM_HERE); 168 m_connectTimer.startOneShot(m_reconnectDelay / 1000.0, BLINK_FROM_HERE);
175 dispatchEvent(Event::create(EventTypeNames::error)); 169 dispatchEvent(Event::create(EventTypeNames::error));
(...skipping 15 matching lines...) Expand all
191 } 185 }
192 186
193 EventSource::State EventSource::readyState() const 187 EventSource::State EventSource::readyState() const
194 { 188 {
195 return m_state; 189 return m_state;
196 } 190 }
197 191
198 void EventSource::close() 192 void EventSource::close()
199 { 193 {
200 if (m_state == CLOSED) { 194 if (m_state == CLOSED) {
201 ASSERT(!m_requestInFlight); 195 ASSERT(!m_loader);
202 return; 196 return;
203 } 197 }
204 198
205 // Stop trying to reconnect if EventSource was explicitly closed or if Activ eDOMObject::stop() was called. 199 // Stop trying to reconnect if EventSource was explicitly closed or if Activ eDOMObject::stop() was called.
206 if (m_connectTimer.isActive()) { 200 if (m_connectTimer.isActive()) {
207 m_connectTimer.stop(); 201 m_connectTimer.stop();
208 } 202 }
209 203
210 if (m_requestInFlight) 204 if (m_loader) {
211 m_loader->cancel(); 205 m_loader->cancel();
206 m_loader = nullptr;
207 }
212 208
213 m_state = CLOSED; 209 m_state = CLOSED;
214 } 210 }
215 211
216 const AtomicString& EventSource::interfaceName() const 212 const AtomicString& EventSource::interfaceName() const
217 { 213 {
218 return EventTargetNames::EventSource; 214 return EventTargetNames::EventSource;
219 } 215 }
220 216
221 ExecutionContext* EventSource::executionContext() const 217 ExecutionContext* EventSource::executionContext() const
222 { 218 {
223 return ActiveDOMObject::executionContext(); 219 return ActiveDOMObject::executionContext();
224 } 220 }
225 221
226 void EventSource::didReceiveResponse(unsigned long, const ResourceResponse& resp onse, PassOwnPtr<WebDataConsumerHandle> handle) 222 void EventSource::didReceiveResponse(unsigned long, const ResourceResponse& resp onse, PassOwnPtr<WebDataConsumerHandle> handle)
227 { 223 {
228 ASSERT_UNUSED(handle, !handle); 224 ASSERT_UNUSED(handle, !handle);
229 ASSERT(m_state == CONNECTING); 225 ASSERT(m_state == CONNECTING);
230 ASSERT(m_requestInFlight); 226 ASSERT(m_loader);
231 227
232 m_eventStreamOrigin = SecurityOrigin::create(response.url())->toString(); 228 m_eventStreamOrigin = SecurityOrigin::create(response.url())->toString();
233 int statusCode = response.httpStatusCode(); 229 int statusCode = response.httpStatusCode();
234 bool mimeTypeIsValid = response.mimeType() == "text/event-stream"; 230 bool mimeTypeIsValid = response.mimeType() == "text/event-stream";
235 bool responseIsValid = statusCode == 200 && mimeTypeIsValid; 231 bool responseIsValid = statusCode == 200 && mimeTypeIsValid;
236 if (responseIsValid) { 232 if (responseIsValid) {
237 const String& charset = response.textEncodingName(); 233 const String& charset = response.textEncodingName();
238 // If we have a charset, the only allowed value is UTF-8 (case-insensiti ve). 234 // If we have a charset, the only allowed value is UTF-8 (case-insensiti ve).
239 responseIsValid = charset.isEmpty() || equalIgnoringCase(charset, "UTF-8 "); 235 responseIsValid = charset.isEmpty() || equalIgnoringCase(charset, "UTF-8 ");
240 if (!responseIsValid) { 236 if (!responseIsValid) {
(...skipping 21 matching lines...) Expand all
262 dispatchEvent(Event::create(EventTypeNames::open)); 258 dispatchEvent(Event::create(EventTypeNames::open));
263 } else { 259 } else {
264 m_loader->cancel(); 260 m_loader->cancel();
265 dispatchEvent(Event::create(EventTypeNames::error)); 261 dispatchEvent(Event::create(EventTypeNames::error));
266 } 262 }
267 } 263 }
268 264
269 void EventSource::didReceiveData(const char* data, unsigned length) 265 void EventSource::didReceiveData(const char* data, unsigned length)
270 { 266 {
271 ASSERT(m_state == OPEN); 267 ASSERT(m_state == OPEN);
272 ASSERT(m_requestInFlight); 268 ASSERT(m_loader);
273 269
274 append(m_receiveBuf, m_decoder->decode(data, length)); 270 append(m_receiveBuf, m_decoder->decode(data, length));
275 parseEventStream(); 271 parseEventStream();
276 } 272 }
277 273
278 void EventSource::didFinishLoading(unsigned long, double) 274 void EventSource::didFinishLoading(unsigned long, double)
279 { 275 {
280 ASSERT(m_state == OPEN); 276 ASSERT(m_state == OPEN);
281 ASSERT(m_requestInFlight); 277 ASSERT(m_loader);
282 278
283 if (m_receiveBuf.size() > 0 || m_data.size() > 0) { 279 if (m_receiveBuf.size() > 0 || m_data.size() > 0) {
284 parseEventStream(); 280 parseEventStream();
285 281
286 // Discard everything that has not been dispatched by now. 282 // Discard everything that has not been dispatched by now.
287 m_receiveBuf.clear(); 283 m_receiveBuf.clear();
288 m_data.clear(); 284 m_data.clear();
289 m_eventName = emptyAtom; 285 m_eventName = emptyAtom;
290 m_currentlyParsedEventId = nullAtom; 286 m_currentlyParsedEventId = nullAtom;
291 } 287 }
292 networkRequestEnded(); 288 networkRequestEnded();
293 } 289 }
294 290
295 void EventSource::didFail(const ResourceError& error) 291 void EventSource::didFail(const ResourceError& error)
296 { 292 {
297 ASSERT(m_state != CLOSED); 293 ASSERT(m_state != CLOSED);
298 ASSERT(m_requestInFlight); 294 ASSERT(m_loader);
299 295
300 if (error.isCancellation()) 296 if (error.isCancellation())
301 m_state = CLOSED; 297 m_state = CLOSED;
302 networkRequestEnded(); 298 networkRequestEnded();
303 } 299 }
304 300
305 void EventSource::didFailAccessControlCheck(const ResourceError& error) 301 void EventSource::didFailAccessControlCheck(const ResourceError& error)
306 { 302 {
303 ASSERT(m_loader);
304
307 String message = "EventSource cannot load " + error.failingURL() + ". " + er ror.localizedDescription(); 305 String message = "EventSource cannot load " + error.failingURL() + ". " + er ror.localizedDescription();
308 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSource , ErrorMessageLevel, message)); 306 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSource , ErrorMessageLevel, message));
309 307
310 abortConnectionAttempt(); 308 abortConnectionAttempt();
311 } 309 }
312 310
313 void EventSource::didFailRedirectCheck() 311 void EventSource::didFailRedirectCheck()
314 { 312 {
313 ASSERT(m_loader);
314
315 abortConnectionAttempt(); 315 abortConnectionAttempt();
316 } 316 }
317 317
318 void EventSource::abortConnectionAttempt() 318 void EventSource::abortConnectionAttempt()
319 { 319 {
320 ASSERT(m_state == CONNECTING); 320 ASSERT(m_state == CONNECTING);
321 321
322 m_loader = nullptr; 322 m_loader = nullptr;
323 m_state = CLOSED; 323 m_state = CLOSED;
324 networkRequestEnded(); 324 networkRequestEnded();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 if (ok) 417 if (ok)
418 m_reconnectDelay = retry; 418 m_reconnectDelay = retry;
419 } 419 }
420 } 420 }
421 } 421 }
422 } 422 }
423 423
424 void EventSource::stop() 424 void EventSource::stop()
425 { 425 {
426 close(); 426 close();
427
428 // (Non)Oilpan: In order to make Worker shutdowns clean,
429 // deref the loader. This will in turn deref its
430 // RefPtr<WorkerGlobalScope>.
431 //
432 // Worth doing regardless, it is no longer of use.
433 m_loader = nullptr;
hiroshige 2016/01/26 08:44:50 Why do we remove |m_loader = nullptr;|? Is it safe
tyoshino (SeeGerritForStatus) 2016/01/29 12:36:52 I've added this code to close().
434 } 427 }
435 428
436 bool EventSource::hasPendingActivity() const 429 bool EventSource::hasPendingActivity() const
437 { 430 {
438 return m_state != CLOSED; 431 return m_state != CLOSED;
439 } 432 }
440 433
441 PassRefPtrWillBeRawPtr<MessageEvent> EventSource::createMessageEvent() 434 PassRefPtrWillBeRawPtr<MessageEvent> EventSource::createMessageEvent()
442 { 435 {
443 RefPtrWillBeRawPtr<MessageEvent> event = MessageEvent::create(); 436 RefPtrWillBeRawPtr<MessageEvent> event = MessageEvent::create();
444 event->initMessageEvent(m_eventName.isEmpty() ? EventTypeNames::message : m_ eventName, false, false, SerializedScriptValueFactory::instance().create(String( m_data)), m_eventStreamOrigin, m_lastEventId, 0, nullptr); 437 event->initMessageEvent(m_eventName.isEmpty() ? EventTypeNames::message : m_ eventName, false, false, SerializedScriptValueFactory::instance().create(String( m_data)), m_eventStreamOrigin, m_lastEventId, 0, nullptr);
445 m_data.clear(); 438 m_data.clear();
446 return event.release(); 439 return event.release();
447 } 440 }
448 441
449 DEFINE_TRACE(EventSource) 442 DEFINE_TRACE(EventSource)
450 { 443 {
451 RefCountedGarbageCollectedEventTargetWithInlineData::trace(visitor); 444 RefCountedGarbageCollectedEventTargetWithInlineData::trace(visitor);
452 ActiveDOMObject::trace(visitor); 445 ActiveDOMObject::trace(visitor);
453 } 446 }
454 447
455 } // namespace blink 448 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698