| OLD | NEW |
| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 ASSERT(m_state == CONNECTING); | 106 ASSERT(m_state == CONNECTING); |
| 107 ASSERT(!m_loader); | 107 ASSERT(!m_loader); |
| 108 | 108 |
| 109 m_connectTimer.startOneShot(0, BLINK_FROM_HERE); | 109 m_connectTimer.startOneShot(0, BLINK_FROM_HERE); |
| 110 } | 110 } |
| 111 | 111 |
| 112 void EventSource::connect() | 112 void EventSource::connect() |
| 113 { | 113 { |
| 114 ASSERT(m_state == CONNECTING); | 114 ASSERT(m_state == CONNECTING); |
| 115 ASSERT(!m_loader); | 115 ASSERT(!m_loader); |
| 116 ASSERT(executionContext()); | 116 ASSERT(getExecutionContext()); |
| 117 | 117 |
| 118 ExecutionContext& executionContext = *this->executionContext(); | 118 ExecutionContext& executionContext = *this->getExecutionContext(); |
| 119 ResourceRequest request(m_url); | 119 ResourceRequest request(m_url); |
| 120 request.setHTTPMethod(HTTPNames::GET); | 120 request.setHTTPMethod(HTTPNames::GET); |
| 121 request.setHTTPHeaderField(HTTPNames::Accept, "text/event-stream"); | 121 request.setHTTPHeaderField(HTTPNames::Accept, "text/event-stream"); |
| 122 request.setHTTPHeaderField(HTTPNames::Cache_Control, "no-cache"); | 122 request.setHTTPHeaderField(HTTPNames::Cache_Control, "no-cache"); |
| 123 request.setRequestContext(WebURLRequest::RequestContextEventSource); | 123 request.setRequestContext(WebURLRequest::RequestContextEventSource); |
| 124 request.setExternalRequestStateFromRequestorAddressSpace(executionContext.se
curityContext().addressSpace()); | 124 request.setExternalRequestStateFromRequestorAddressSpace(executionContext.se
curityContext().addressSpace()); |
| 125 if (m_parser && !m_parser->lastEventId().isEmpty()) { | 125 if (m_parser && !m_parser->lastEventId().isEmpty()) { |
| 126 // HTTP headers are Latin-1 byte strings, but the Last-Event-ID header i
s encoded as UTF-8. | 126 // HTTP headers are Latin-1 byte strings, but the Last-Event-ID header i
s encoded as UTF-8. |
| 127 // TODO(davidben): This should be captured in the type of setHTTPHeaderF
ield's arguments. | 127 // TODO(davidben): This should be captured in the type of setHTTPHeaderF
ield's arguments. |
| 128 CString lastEventIdUtf8 = m_parser->lastEventId().utf8(); | 128 CString lastEventIdUtf8 = m_parser->lastEventId().utf8(); |
| 129 request.setHTTPHeaderField(HTTPNames::Last_Event_ID, AtomicString(reinte
rpret_cast<const LChar*>(lastEventIdUtf8.data()), lastEventIdUtf8.length())); | 129 request.setHTTPHeaderField(HTTPNames::Last_Event_ID, AtomicString(reinte
rpret_cast<const LChar*>(lastEventIdUtf8.data()), lastEventIdUtf8.length())); |
| 130 } | 130 } |
| 131 | 131 |
| 132 SecurityOrigin* origin = executionContext.securityOrigin(); | 132 SecurityOrigin* origin = executionContext.getSecurityOrigin(); |
| 133 | 133 |
| 134 ThreadableLoaderOptions options; | 134 ThreadableLoaderOptions options; |
| 135 options.preflightPolicy = PreventPreflight; | 135 options.preflightPolicy = PreventPreflight; |
| 136 options.crossOriginRequestPolicy = UseAccessControl; | 136 options.crossOriginRequestPolicy = UseAccessControl; |
| 137 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa
ssMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceCont
entSecurityPolicy; | 137 options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypa
ssMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceCont
entSecurityPolicy; |
| 138 | 138 |
| 139 ResourceLoaderOptions resourceLoaderOptions; | 139 ResourceLoaderOptions resourceLoaderOptions; |
| 140 resourceLoaderOptions.allowCredentials = (origin->canRequestNoSuborigin(m_ur
l) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials; | 140 resourceLoaderOptions.allowCredentials = (origin->canRequestNoSuborigin(m_ur
l) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials; |
| 141 resourceLoaderOptions.credentialsRequested = m_withCredentials ? ClientReque
stedCredentials : ClientDidNotRequestCredentials; | 141 resourceLoaderOptions.credentialsRequested = m_withCredentials ? ClientReque
stedCredentials : ClientDidNotRequestCredentials; |
| 142 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData; | 142 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData; |
| 143 resourceLoaderOptions.securityOrigin = origin; | 143 resourceLoaderOptions.securityOrigin = origin; |
| 144 | 144 |
| 145 InspectorInstrumentation::willSendEventSourceRequest(&executionContext, this
); | 145 InspectorInstrumentation::willSendEventSourceRequest(&executionContext, this
); |
| 146 // InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient
will be called synchronously. | 146 // InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient
will be called synchronously. |
| 147 m_loader = ThreadableLoader::create(executionContext, this, options, resourc
eLoaderOptions); | 147 m_loader = ThreadableLoader::create(executionContext, this, options, resourc
eLoaderOptions); |
| 148 m_loader->start(request); | 148 m_loader->start(request); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void EventSource::networkRequestEnded() | 151 void EventSource::networkRequestEnded() |
| 152 { | 152 { |
| 153 InspectorInstrumentation::didFinishEventSourceRequest(executionContext(), th
is); | 153 InspectorInstrumentation::didFinishEventSourceRequest(getExecutionContext(),
this); |
| 154 | 154 |
| 155 m_loader = nullptr; | 155 m_loader = nullptr; |
| 156 | 156 |
| 157 if (m_state != CLOSED) | 157 if (m_state != CLOSED) |
| 158 scheduleReconnect(); | 158 scheduleReconnect(); |
| 159 } | 159 } |
| 160 | 160 |
| 161 void EventSource::scheduleReconnect() | 161 void EventSource::scheduleReconnect() |
| 162 { | 162 { |
| 163 m_state = CONNECTING; | 163 m_state = CONNECTING; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 } | 206 } |
| 207 | 207 |
| 208 m_state = CLOSED; | 208 m_state = CLOSED; |
| 209 } | 209 } |
| 210 | 210 |
| 211 const AtomicString& EventSource::interfaceName() const | 211 const AtomicString& EventSource::interfaceName() const |
| 212 { | 212 { |
| 213 return EventTargetNames::EventSource; | 213 return EventTargetNames::EventSource; |
| 214 } | 214 } |
| 215 | 215 |
| 216 ExecutionContext* EventSource::executionContext() const | 216 ExecutionContext* EventSource::getExecutionContext() const |
| 217 { | 217 { |
| 218 return ContextLifecycleObserver::executionContext(); | 218 return ContextLifecycleObserver::getExecutionContext(); |
| 219 } | 219 } |
| 220 | 220 |
| 221 void EventSource::didReceiveResponse(unsigned long, const ResourceResponse& resp
onse, PassOwnPtr<WebDataConsumerHandle> handle) | 221 void EventSource::didReceiveResponse(unsigned long, const ResourceResponse& resp
onse, PassOwnPtr<WebDataConsumerHandle> handle) |
| 222 { | 222 { |
| 223 ASSERT_UNUSED(handle, !handle); | 223 ASSERT_UNUSED(handle, !handle); |
| 224 ASSERT(m_state == CONNECTING); | 224 ASSERT(m_state == CONNECTING); |
| 225 ASSERT(m_loader); | 225 ASSERT(m_loader); |
| 226 | 226 |
| 227 m_eventStreamOrigin = SecurityOrigin::create(response.url())->toString(); | 227 m_eventStreamOrigin = SecurityOrigin::create(response.url())->toString(); |
| 228 int statusCode = response.httpStatusCode(); | 228 int statusCode = response.httpStatusCode(); |
| 229 bool mimeTypeIsValid = response.mimeType() == "text/event-stream"; | 229 bool mimeTypeIsValid = response.mimeType() == "text/event-stream"; |
| 230 bool responseIsValid = statusCode == 200 && mimeTypeIsValid; | 230 bool responseIsValid = statusCode == 200 && mimeTypeIsValid; |
| 231 if (responseIsValid) { | 231 if (responseIsValid) { |
| 232 const String& charset = response.textEncodingName(); | 232 const String& charset = response.textEncodingName(); |
| 233 // If we have a charset, the only allowed value is UTF-8 (case-insensiti
ve). | 233 // If we have a charset, the only allowed value is UTF-8 (case-insensiti
ve). |
| 234 responseIsValid = charset.isEmpty() || equalIgnoringCase(charset, "UTF-8
"); | 234 responseIsValid = charset.isEmpty() || equalIgnoringCase(charset, "UTF-8
"); |
| 235 if (!responseIsValid) { | 235 if (!responseIsValid) { |
| 236 StringBuilder message; | 236 StringBuilder message; |
| 237 message.appendLiteral("EventSource's response has a charset (\""); | 237 message.appendLiteral("EventSource's response has a charset (\""); |
| 238 message.append(charset); | 238 message.append(charset); |
| 239 message.appendLiteral("\") that is not UTF-8. Aborting the connectio
n."); | 239 message.appendLiteral("\") that is not UTF-8. Aborting the connectio
n."); |
| 240 // FIXME: We are missing the source line. | 240 // FIXME: We are missing the source line. |
| 241 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessa
geSource, ErrorMessageLevel, message.toString())); | 241 getExecutionContext()->addConsoleMessage(ConsoleMessage::create(JSMe
ssageSource, ErrorMessageLevel, message.toString())); |
| 242 } | 242 } |
| 243 } else { | 243 } else { |
| 244 // To keep the signal-to-noise ratio low, we only log 200-response with
an invalid MIME type. | 244 // To keep the signal-to-noise ratio low, we only log 200-response with
an invalid MIME type. |
| 245 if (statusCode == 200 && !mimeTypeIsValid) { | 245 if (statusCode == 200 && !mimeTypeIsValid) { |
| 246 StringBuilder message; | 246 StringBuilder message; |
| 247 message.appendLiteral("EventSource's response has a MIME type (\""); | 247 message.appendLiteral("EventSource's response has a MIME type (\""); |
| 248 message.append(response.mimeType()); | 248 message.append(response.mimeType()); |
| 249 message.appendLiteral("\") that is not \"text/event-stream\". Aborti
ng the connection."); | 249 message.appendLiteral("\") that is not \"text/event-stream\". Aborti
ng the connection."); |
| 250 // FIXME: We are missing the source line. | 250 // FIXME: We are missing the source line. |
| 251 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessa
geSource, ErrorMessageLevel, message.toString())); | 251 getExecutionContext()->addConsoleMessage(ConsoleMessage::create(JSMe
ssageSource, ErrorMessageLevel, message.toString())); |
| 252 } | 252 } |
| 253 } | 253 } |
| 254 | 254 |
| 255 if (responseIsValid) { | 255 if (responseIsValid) { |
| 256 m_state = OPEN; | 256 m_state = OPEN; |
| 257 AtomicString lastEventId; | 257 AtomicString lastEventId; |
| 258 if (m_parser) { | 258 if (m_parser) { |
| 259 // The new parser takes over the event ID. | 259 // The new parser takes over the event ID. |
| 260 lastEventId = m_parser->lastEventId(); | 260 lastEventId = m_parser->lastEventId(); |
| 261 } | 261 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 292 if (error.isCancellation()) | 292 if (error.isCancellation()) |
| 293 m_state = CLOSED; | 293 m_state = CLOSED; |
| 294 networkRequestEnded(); | 294 networkRequestEnded(); |
| 295 } | 295 } |
| 296 | 296 |
| 297 void EventSource::didFailAccessControlCheck(const ResourceError& error) | 297 void EventSource::didFailAccessControlCheck(const ResourceError& error) |
| 298 { | 298 { |
| 299 ASSERT(m_loader); | 299 ASSERT(m_loader); |
| 300 | 300 |
| 301 String message = "EventSource cannot load " + error.failingURL() + ". " + er
ror.localizedDescription(); | 301 String message = "EventSource cannot load " + error.failingURL() + ". " + er
ror.localizedDescription(); |
| 302 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSource
, ErrorMessageLevel, message)); | 302 getExecutionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSou
rce, ErrorMessageLevel, message)); |
| 303 | 303 |
| 304 abortConnectionAttempt(); | 304 abortConnectionAttempt(); |
| 305 } | 305 } |
| 306 | 306 |
| 307 void EventSource::didFailRedirectCheck() | 307 void EventSource::didFailRedirectCheck() |
| 308 { | 308 { |
| 309 ASSERT(m_loader); | 309 ASSERT(m_loader); |
| 310 | 310 |
| 311 abortConnectionAttempt(); | 311 abortConnectionAttempt(); |
| 312 } | 312 } |
| 313 | 313 |
| 314 void EventSource::onMessageEvent(const AtomicString& eventType, const String& da
ta, const AtomicString& lastEventId) | 314 void EventSource::onMessageEvent(const AtomicString& eventType, const String& da
ta, const AtomicString& lastEventId) |
| 315 { | 315 { |
| 316 RefPtrWillBeRawPtr<MessageEvent> e = MessageEvent::create(); | 316 RefPtrWillBeRawPtr<MessageEvent> e = MessageEvent::create(); |
| 317 e->initMessageEvent(eventType, false, false, SerializedScriptValueFactory::i
nstance().create(data), m_eventStreamOrigin, lastEventId, 0, nullptr); | 317 e->initMessageEvent(eventType, false, false, SerializedScriptValueFactory::i
nstance().create(data), m_eventStreamOrigin, lastEventId, 0, nullptr); |
| 318 | 318 |
| 319 InspectorInstrumentation::willDispatchEventSourceEvent(executionContext(), t
his, eventType, lastEventId, data); | 319 InspectorInstrumentation::willDispatchEventSourceEvent(getExecutionContext()
, this, eventType, lastEventId, data); |
| 320 dispatchEvent(e); | 320 dispatchEvent(e); |
| 321 } | 321 } |
| 322 | 322 |
| 323 void EventSource::onReconnectionTimeSet(unsigned long long reconnectionTime) | 323 void EventSource::onReconnectionTimeSet(unsigned long long reconnectionTime) |
| 324 { | 324 { |
| 325 m_reconnectDelay = reconnectionTime; | 325 m_reconnectDelay = reconnectionTime; |
| 326 } | 326 } |
| 327 | 327 |
| 328 void EventSource::abortConnectionAttempt() | 328 void EventSource::abortConnectionAttempt() |
| 329 { | 329 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 348 | 348 |
| 349 DEFINE_TRACE(EventSource) | 349 DEFINE_TRACE(EventSource) |
| 350 { | 350 { |
| 351 visitor->trace(m_parser); | 351 visitor->trace(m_parser); |
| 352 RefCountedGarbageCollectedEventTargetWithInlineData::trace(visitor); | 352 RefCountedGarbageCollectedEventTargetWithInlineData::trace(visitor); |
| 353 ContextLifecycleObserver::trace(visitor); | 353 ContextLifecycleObserver::trace(visitor); |
| 354 EventSourceParser::Client::trace(visitor); | 354 EventSourceParser::Client::trace(visitor); |
| 355 } | 355 } |
| 356 | 356 |
| 357 } // namespace blink | 357 } // namespace blink |
| OLD | NEW |