OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2011 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 #include "platform/mhtml/ArchiveResource.h" | 65 #include "platform/mhtml/ArchiveResource.h" |
66 #include "platform/mhtml/ArchiveResourceCollection.h" | 66 #include "platform/mhtml/ArchiveResourceCollection.h" |
67 #include "platform/mhtml/MHTMLArchive.h" | 67 #include "platform/mhtml/MHTMLArchive.h" |
68 #include "platform/network/ContentSecurityPolicyResponseHeaders.h" | 68 #include "platform/network/ContentSecurityPolicyResponseHeaders.h" |
69 #include "platform/plugins/PluginData.h" | 69 #include "platform/plugins/PluginData.h" |
70 #include "platform/weborigin/SchemeRegistry.h" | 70 #include "platform/weborigin/SchemeRegistry.h" |
71 #include "platform/weborigin/SecurityPolicy.h" | 71 #include "platform/weborigin/SecurityPolicy.h" |
72 #include "public/platform/Platform.h" | 72 #include "public/platform/Platform.h" |
73 #include "public/platform/WebMimeRegistry.h" | 73 #include "public/platform/WebMimeRegistry.h" |
74 #include "wtf/Assertions.h" | 74 #include "wtf/Assertions.h" |
| 75 #include "wtf/TemporaryChange.h" |
75 #include "wtf/text/WTFString.h" | 76 #include "wtf/text/WTFString.h" |
76 | 77 |
77 namespace blink { | 78 namespace blink { |
78 | 79 |
79 static bool isArchiveMIMEType(const String& mimeType) | 80 static bool isArchiveMIMEType(const String& mimeType) |
80 { | 81 { |
81 return equalIgnoringCase("multipart/related", mimeType); | 82 return equalIgnoringCase("multipart/related", mimeType); |
82 } | 83 } |
83 | 84 |
84 DocumentLoader::DocumentLoader(LocalFrame* frame, const ResourceRequest& req, co
nst SubstituteData& substituteData) | 85 DocumentLoader::DocumentLoader(LocalFrame* frame, const ResourceRequest& req, co
nst SubstituteData& substituteData) |
85 : m_frame(frame) | 86 : m_frame(frame) |
86 , m_fetcher(FrameFetchContext::createContextAndFetcher(this)) | 87 , m_fetcher(FrameFetchContext::createContextAndFetcher(this)) |
87 , m_originalRequest(req) | 88 , m_originalRequest(req) |
88 , m_substituteData(substituteData) | 89 , m_substituteData(substituteData) |
89 , m_request(req) | 90 , m_request(req) |
90 , m_isClientRedirect(false) | 91 , m_isClientRedirect(false) |
91 , m_replacesCurrentHistoryItem(false) | 92 , m_replacesCurrentHistoryItem(false) |
92 , m_navigationType(NavigationTypeOther) | 93 , m_navigationType(NavigationTypeOther) |
93 , m_timeOfLastDataReceived(0.0) | 94 , m_timeOfLastDataReceived(0.0) |
94 , m_applicationCacheHost(ApplicationCacheHost::create(this)) | 95 , m_applicationCacheHost(ApplicationCacheHost::create(this)) |
95 , m_state(NotStarted) | 96 , m_state(NotStarted) |
| 97 , m_inDataReceived(false) |
| 98 , m_dataBuffer(SharedBuffer::create()) |
96 { | 99 { |
97 } | 100 } |
98 | 101 |
99 FrameLoader* DocumentLoader::frameLoader() const | 102 FrameLoader* DocumentLoader::frameLoader() const |
100 { | 103 { |
101 if (!m_frame) | 104 if (!m_frame) |
102 return nullptr; | 105 return nullptr; |
103 return &m_frame->loader(); | 106 return &m_frame->loader(); |
104 } | 107 } |
105 | 108 |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 } | 550 } |
548 | 551 |
549 void DocumentLoader::dataReceived(Resource* resource, const char* data, unsigned
length) | 552 void DocumentLoader::dataReceived(Resource* resource, const char* data, unsigned
length) |
550 { | 553 { |
551 ASSERT(data); | 554 ASSERT(data); |
552 ASSERT(length); | 555 ASSERT(length); |
553 ASSERT_UNUSED(resource, resource == m_mainResource); | 556 ASSERT_UNUSED(resource, resource == m_mainResource); |
554 ASSERT(!m_response.isNull()); | 557 ASSERT(!m_response.isNull()); |
555 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); | 558 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); |
556 | 559 |
| 560 if (m_inDataReceived) { |
| 561 // If this function is reentered, defer processing of the additional |
| 562 // data to the top-level invocation. Reentrant calls can occur because |
| 563 // of web platform (mis-)features that require running a nested message |
| 564 // loop: |
| 565 // - alert(), confirm(), prompt() |
| 566 // - Detach of plugin elements. |
| 567 // - Synchronous XMLHTTPRequest |
| 568 m_dataBuffer->append(data, length); |
| 569 return; |
| 570 } |
| 571 |
557 // Both unloading the old page and parsing the new page may execute JavaScri
pt which destroys the datasource | 572 // Both unloading the old page and parsing the new page may execute JavaScri
pt which destroys the datasource |
558 // by starting a new load, so retain temporarily. | 573 // by starting a new load, so retain temporarily. |
559 RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame.get()); | 574 RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame.get()); |
560 RefPtrWillBeRawPtr<DocumentLoader> protectLoader(this); | 575 RefPtrWillBeRawPtr<DocumentLoader> protectLoader(this); |
561 | 576 |
| 577 TemporaryChange<bool> reentrancyProtector(m_inDataReceived, true); |
| 578 processData(data, length); |
| 579 |
| 580 // Process data received in reentrant invocations. Note that the |
| 581 // invocations of processData() may queue more data in reentrant |
| 582 // invocations, so iterate until it's empty. |
| 583 const char* segment; |
| 584 unsigned pos = 0; |
| 585 while (unsigned length = m_dataBuffer->getSomeData(segment, pos)) { |
| 586 processData(segment, length); |
| 587 pos += length; |
| 588 } |
| 589 // All data has been consumed, so flush the buffer. |
| 590 m_dataBuffer->clear(); |
| 591 } |
| 592 |
| 593 void DocumentLoader::processData(const char* data, unsigned length) |
| 594 { |
562 m_applicationCacheHost->mainResourceDataReceived(data, length); | 595 m_applicationCacheHost->mainResourceDataReceived(data, length); |
563 m_timeOfLastDataReceived = monotonicallyIncreasingTime(); | 596 m_timeOfLastDataReceived = monotonicallyIncreasingTime(); |
564 | 597 |
565 if (isArchiveMIMEType(response().mimeType())) | 598 if (isArchiveMIMEType(response().mimeType())) |
566 return; | 599 return; |
567 commitIfReady(); | 600 commitIfReady(); |
568 if (!frameLoader()) | 601 if (!frameLoader()) |
569 return; | 602 return; |
570 commitData(data, length); | 603 commitData(data, length); |
571 | 604 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 { | 854 { |
822 m_writer = createWriterFor(ownerDocument, init, mimeType(), m_writer ? m_wri
ter->encoding() : emptyAtom, true, ForceSynchronousParsing); | 855 m_writer = createWriterFor(ownerDocument, init, mimeType(), m_writer ? m_wri
ter->encoding() : emptyAtom, true, ForceSynchronousParsing); |
823 if (!source.isNull()) | 856 if (!source.isNull()) |
824 m_writer->appendReplacingData(source); | 857 m_writer->appendReplacingData(source); |
825 endWriting(m_writer.get()); | 858 endWriting(m_writer.get()); |
826 } | 859 } |
827 | 860 |
828 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); | 861 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); |
829 | 862 |
830 } // namespace blink | 863 } // namespace blink |
OLD | NEW |