OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 , m_target(target) | 69 , m_target(target) |
70 , m_resumeTimer(this, &EventQueue::resumeTimerFired) { } | 70 , m_resumeTimer(this, &EventQueue::resumeTimerFired) { } |
71 | 71 |
72 DOMWebSocket::EventQueue::~EventQueue() { stop(); } | 72 DOMWebSocket::EventQueue::~EventQueue() { stop(); } |
73 | 73 |
74 void DOMWebSocket::EventQueue::dispatch(PassRefPtrWillBeRawPtr<Event> event) | 74 void DOMWebSocket::EventQueue::dispatch(PassRefPtrWillBeRawPtr<Event> event) |
75 { | 75 { |
76 switch (m_state) { | 76 switch (m_state) { |
77 case Active: | 77 case Active: |
78 ASSERT(m_events.isEmpty()); | 78 ASSERT(m_events.isEmpty()); |
79 ASSERT(m_target->executionContext()); | 79 ASSERT(m_target->getExecutionContext()); |
80 m_target->dispatchEvent(event); | 80 m_target->dispatchEvent(event); |
81 break; | 81 break; |
82 case Suspended: | 82 case Suspended: |
83 m_events.append(event); | 83 m_events.append(event); |
84 break; | 84 break; |
85 case Stopped: | 85 case Stopped: |
86 ASSERT(m_events.isEmpty()); | 86 ASSERT(m_events.isEmpty()); |
87 // Do nothing. | 87 // Do nothing. |
88 break; | 88 break; |
89 } | 89 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 { | 125 { |
126 if (m_state != Active) | 126 if (m_state != Active) |
127 return; | 127 return; |
128 | 128 |
129 WillBeHeapDeque<RefPtrWillBeMember<Event>> events; | 129 WillBeHeapDeque<RefPtrWillBeMember<Event>> events; |
130 events.swap(m_events); | 130 events.swap(m_events); |
131 while (!events.isEmpty()) { | 131 while (!events.isEmpty()) { |
132 if (m_state == Stopped || m_state == Suspended) | 132 if (m_state == Stopped || m_state == Suspended) |
133 break; | 133 break; |
134 ASSERT(m_state == Active); | 134 ASSERT(m_state == Active); |
135 ASSERT(m_target->executionContext()); | 135 ASSERT(m_target->getExecutionContext()); |
136 m_target->dispatchEvent(events.takeFirst()); | 136 m_target->dispatchEvent(events.takeFirst()); |
137 // |this| can be stopped here. | 137 // |this| can be stopped here. |
138 } | 138 } |
139 if (m_state == Suspended) { | 139 if (m_state == Suspended) { |
140 while (!m_events.isEmpty()) | 140 while (!m_events.isEmpty()) |
141 events.append(m_events.takeFirst()); | 141 events.append(m_events.takeFirst()); |
142 events.swap(m_events); | 142 events.swap(m_events); |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 { | 231 { |
232 } | 232 } |
233 | 233 |
234 DOMWebSocket::~DOMWebSocket() | 234 DOMWebSocket::~DOMWebSocket() |
235 { | 235 { |
236 ASSERT(!m_channel); | 236 ASSERT(!m_channel); |
237 } | 237 } |
238 | 238 |
239 void DOMWebSocket::logError(const String& message) | 239 void DOMWebSocket::logError(const String& message) |
240 { | 240 { |
241 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSource
, ErrorMessageLevel, message)); | 241 getExecutionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSou
rce, ErrorMessageLevel, message)); |
242 } | 242 } |
243 | 243 |
244 DOMWebSocket* DOMWebSocket::create(ExecutionContext* context, const String& url,
ExceptionState& exceptionState) | 244 DOMWebSocket* DOMWebSocket::create(ExecutionContext* context, const String& url,
ExceptionState& exceptionState) |
245 { | 245 { |
246 StringOrStringSequence protocols; | 246 StringOrStringSequence protocols; |
247 return create(context, url, protocols, exceptionState); | 247 return create(context, url, protocols, exceptionState); |
248 } | 248 } |
249 | 249 |
250 DOMWebSocket* DOMWebSocket::create(ExecutionContext* context, const String& url,
const StringOrStringSequence& protocols, ExceptionState& exceptionState) | 250 DOMWebSocket* DOMWebSocket::create(ExecutionContext* context, const String& url,
const StringOrStringSequence& protocols, ExceptionState& exceptionState) |
251 { | 251 { |
(...skipping 18 matching lines...) Expand all Loading... |
270 } | 270 } |
271 | 271 |
272 if (exceptionState.hadException()) | 272 if (exceptionState.hadException()) |
273 return nullptr; | 273 return nullptr; |
274 | 274 |
275 return webSocket; | 275 return webSocket; |
276 } | 276 } |
277 | 277 |
278 void DOMWebSocket::connect(const String& url, const Vector<String>& protocols, E
xceptionState& exceptionState) | 278 void DOMWebSocket::connect(const String& url, const Vector<String>& protocols, E
xceptionState& exceptionState) |
279 { | 279 { |
280 UseCounter::count(executionContext(), UseCounter::WebSocket); | 280 UseCounter::count(getExecutionContext(), UseCounter::WebSocket); |
281 | 281 |
282 WTF_LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data())
; | 282 WTF_LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data())
; |
283 m_url = KURL(KURL(), url); | 283 m_url = KURL(KURL(), url); |
284 | 284 |
285 if (executionContext()->securityContext().getInsecureRequestsPolicy() == Sec
urityContext::InsecureRequestsUpgrade && m_url.protocol() == "ws") { | 285 if (getExecutionContext()->securityContext().getInsecureRequestsPolicy() ==
SecurityContext::InsecureRequestsUpgrade && m_url.protocol() == "ws") { |
286 UseCounter::count(executionContext(), UseCounter::UpgradeInsecureRequest
sUpgradedRequest); | 286 UseCounter::count(getExecutionContext(), UseCounter::UpgradeInsecureRequ
estsUpgradedRequest); |
287 m_url.setProtocol("wss"); | 287 m_url.setProtocol("wss"); |
288 if (m_url.port() == 80) | 288 if (m_url.port() == 80) |
289 m_url.setPort(443); | 289 m_url.setPort(443); |
290 } | 290 } |
291 | 291 |
292 if (!m_url.isValid()) { | 292 if (!m_url.isValid()) { |
293 m_state = CLOSED; | 293 m_state = CLOSED; |
294 exceptionState.throwDOMException(SyntaxError, "The URL '" + url + "' is
invalid."); | 294 exceptionState.throwDOMException(SyntaxError, "The URL '" + url + "' is
invalid."); |
295 return; | 295 return; |
296 } | 296 } |
297 if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { | 297 if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { |
298 m_state = CLOSED; | 298 m_state = CLOSED; |
299 exceptionState.throwDOMException(SyntaxError, "The URL's scheme must be
either 'ws' or 'wss'. '" + m_url.protocol() + "' is not allowed."); | 299 exceptionState.throwDOMException(SyntaxError, "The URL's scheme must be
either 'ws' or 'wss'. '" + m_url.protocol() + "' is not allowed."); |
300 return; | 300 return; |
301 } | 301 } |
302 | 302 |
303 if (m_url.hasFragmentIdentifier()) { | 303 if (m_url.hasFragmentIdentifier()) { |
304 m_state = CLOSED; | 304 m_state = CLOSED; |
305 exceptionState.throwDOMException(SyntaxError, "The URL contains a fragme
nt identifier ('" + m_url.fragmentIdentifier() + "'). Fragment identifiers are n
ot allowed in WebSocket URLs."); | 305 exceptionState.throwDOMException(SyntaxError, "The URL contains a fragme
nt identifier ('" + m_url.fragmentIdentifier() + "'). Fragment identifiers are n
ot allowed in WebSocket URLs."); |
306 return; | 306 return; |
307 } | 307 } |
308 | 308 |
309 if (!Platform::current()->portAllowed(m_url)) { | 309 if (!Platform::current()->portAllowed(m_url)) { |
310 m_state = CLOSED; | 310 m_state = CLOSED; |
311 exceptionState.throwSecurityError("The port " + String::number(m_url.por
t()) + " is not allowed."); | 311 exceptionState.throwSecurityError("The port " + String::number(m_url.por
t()) + " is not allowed."); |
312 return; | 312 return; |
313 } | 313 } |
314 | 314 |
315 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. | 315 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. |
316 if (!ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) && !ex
ecutionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { | 316 if (!ContentSecurityPolicy::shouldBypassMainWorld(getExecutionContext()) &&
!getExecutionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { |
317 m_state = CLOSED; | 317 m_state = CLOSED; |
318 // The URL is safe to expose to JavaScript, as this check happens synchr
onously before redirection. | 318 // The URL is safe to expose to JavaScript, as this check happens synchr
onously before redirection. |
319 exceptionState.throwSecurityError("Refused to connect to '" + m_url.elid
edString() + "' because it violates the document's Content Security Policy."); | 319 exceptionState.throwSecurityError("Refused to connect to '" + m_url.elid
edString() + "' because it violates the document's Content Security Policy."); |
320 return; | 320 return; |
321 } | 321 } |
322 | 322 |
323 // Fail if not all elements in |protocols| are valid. | 323 // Fail if not all elements in |protocols| are valid. |
324 for (size_t i = 0; i < protocols.size(); ++i) { | 324 for (size_t i = 0; i < protocols.size(); ++i) { |
325 if (!isValidSubprotocolString(protocols[i])) { | 325 if (!isValidSubprotocolString(protocols[i])) { |
326 m_state = CLOSED; | 326 m_state = CLOSED; |
327 exceptionState.throwDOMException(SyntaxError, "The subprotocol '" +
encodeSubprotocolString(protocols[i]) + "' is invalid."); | 327 exceptionState.throwDOMException(SyntaxError, "The subprotocol '" +
encodeSubprotocolString(protocols[i]) + "' is invalid."); |
328 return; | 328 return; |
329 } | 329 } |
330 } | 330 } |
331 | 331 |
332 // Fail if there're duplicated elements in |protocols|. | 332 // Fail if there're duplicated elements in |protocols|. |
333 HashSet<String> visited; | 333 HashSet<String> visited; |
334 for (size_t i = 0; i < protocols.size(); ++i) { | 334 for (size_t i = 0; i < protocols.size(); ++i) { |
335 if (!visited.add(protocols[i]).isNewEntry) { | 335 if (!visited.add(protocols[i]).isNewEntry) { |
336 m_state = CLOSED; | 336 m_state = CLOSED; |
337 exceptionState.throwDOMException(SyntaxError, "The subprotocol '" +
encodeSubprotocolString(protocols[i]) + "' is duplicated."); | 337 exceptionState.throwDOMException(SyntaxError, "The subprotocol '" +
encodeSubprotocolString(protocols[i]) + "' is duplicated."); |
338 return; | 338 return; |
339 } | 339 } |
340 } | 340 } |
341 | 341 |
342 String protocolString; | 342 String protocolString; |
343 if (!protocols.isEmpty()) | 343 if (!protocols.isEmpty()) |
344 protocolString = joinStrings(protocols, subprotocolSeperator()); | 344 protocolString = joinStrings(protocols, subprotocolSeperator()); |
345 | 345 |
346 m_channel = createChannel(executionContext(), this); | 346 m_channel = createChannel(getExecutionContext(), this); |
347 | 347 |
348 if (!m_channel->connect(m_url, protocolString)) { | 348 if (!m_channel->connect(m_url, protocolString)) { |
349 m_state = CLOSED; | 349 m_state = CLOSED; |
350 exceptionState.throwSecurityError("An insecure WebSocket connection may
not be initiated from a page loaded over HTTPS."); | 350 exceptionState.throwSecurityError("An insecure WebSocket connection may
not be initiated from a page loaded over HTTPS."); |
351 releaseChannel(); | 351 releaseChannel(); |
352 return; | 352 return; |
353 } | 353 } |
354 } | 354 } |
355 | 355 |
356 void DOMWebSocket::updateBufferedAmountAfterClose(uint64_t payloadSize) | 356 void DOMWebSocket::updateBufferedAmountAfterClose(uint64_t payloadSize) |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 return; | 569 return; |
570 } | 570 } |
571 ASSERT_NOT_REACHED(); | 571 ASSERT_NOT_REACHED(); |
572 } | 572 } |
573 | 573 |
574 const AtomicString& DOMWebSocket::interfaceName() const | 574 const AtomicString& DOMWebSocket::interfaceName() const |
575 { | 575 { |
576 return EventTargetNames::DOMWebSocket; | 576 return EventTargetNames::DOMWebSocket; |
577 } | 577 } |
578 | 578 |
579 ExecutionContext* DOMWebSocket::executionContext() const | 579 ExecutionContext* DOMWebSocket::getExecutionContext() const |
580 { | 580 { |
581 return ActiveDOMObject::executionContext(); | 581 return ActiveDOMObject::getExecutionContext(); |
582 } | 582 } |
583 | 583 |
584 void DOMWebSocket::contextDestroyed() | 584 void DOMWebSocket::contextDestroyed() |
585 { | 585 { |
586 WTF_LOG(Network, "WebSocket %p contextDestroyed()", this); | 586 WTF_LOG(Network, "WebSocket %p contextDestroyed()", this); |
587 ASSERT(!m_channel); | 587 ASSERT(!m_channel); |
588 ASSERT(m_state == CLOSED); | 588 ASSERT(m_state == CLOSED); |
589 ActiveDOMObject::contextDestroyed(); | 589 ActiveDOMObject::contextDestroyed(); |
590 } | 590 } |
591 | 591 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 DEFINE_TRACE(DOMWebSocket) | 713 DEFINE_TRACE(DOMWebSocket) |
714 { | 714 { |
715 visitor->trace(m_channel); | 715 visitor->trace(m_channel); |
716 visitor->trace(m_eventQueue); | 716 visitor->trace(m_eventQueue); |
717 WebSocketChannelClient::trace(visitor); | 717 WebSocketChannelClient::trace(visitor); |
718 RefCountedGarbageCollectedEventTargetWithInlineData<DOMWebSocket>::trace(vis
itor); | 718 RefCountedGarbageCollectedEventTargetWithInlineData<DOMWebSocket>::trace(vis
itor); |
719 ActiveDOMObject::trace(visitor); | 719 ActiveDOMObject::trace(visitor); |
720 } | 720 } |
721 | 721 |
722 } // namespace blink | 722 } // namespace blink |
OLD | NEW |