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

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

Powered by Google App Engine
This is Rietveld 408576698