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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 else | 59 else |
60 stringBuilder.append('?'); | 60 stringBuilder.append('?'); |
61 } | 61 } |
62 return stringBuilder.toString(); | 62 return stringBuilder.toString(); |
63 } | 63 } |
64 | 64 |
65 MHTMLArchive::MHTMLArchive() {} | 65 MHTMLArchive::MHTMLArchive() {} |
66 | 66 |
67 MHTMLArchive* MHTMLArchive::create(const KURL& url, | 67 MHTMLArchive* MHTMLArchive::create(const KURL& url, |
68 PassRefPtr<const SharedBuffer> data) { | 68 PassRefPtr<const SharedBuffer> data) { |
69 // MHTML pages can only be loaded from local URLs, http/https URLs, and conten
t URLs(Android specific). | 69 // MHTML pages can only be loaded from local URLs, http/https URLs, and |
70 // The latter is now allowed due to full sandboxing enforcement on MHTML pages
. | 70 // content URLs(Android specific). The latter is now allowed due to full |
| 71 // sandboxing enforcement on MHTML pages. |
71 if (!canLoadArchive(url)) | 72 if (!canLoadArchive(url)) |
72 return nullptr; | 73 return nullptr; |
73 | 74 |
74 MHTMLParser parser(std::move(data)); | 75 MHTMLParser parser(std::move(data)); |
75 HeapVector<Member<ArchiveResource>> resources = parser.parseArchive(); | 76 HeapVector<Member<ArchiveResource>> resources = parser.parseArchive(); |
76 if (resources.isEmpty()) | 77 if (resources.isEmpty()) |
77 return nullptr; // Invalid MHTML file. | 78 return nullptr; // Invalid MHTML file. |
78 | 79 |
79 MHTMLArchive* archive = new MHTMLArchive; | 80 MHTMLArchive* archive = new MHTMLArchive; |
80 // The first document suitable resource is the main resource of the top frame. | 81 // The first document suitable resource is the main resource of the top frame. |
81 for (size_t i = 0; i < resources.size(); ++i) { | 82 for (size_t i = 0; i < resources.size(); ++i) { |
82 const AtomicString& mimeType = resources[i]->mimeType(); | 83 const AtomicString& mimeType = resources[i]->mimeType(); |
83 if (archive->mainResource() || | 84 if (archive->mainResource() || |
84 !MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType) || | 85 !MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType) || |
85 MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || | 86 MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || |
86 mimeType == "text/css") | 87 mimeType == "text/css") |
87 archive->addSubresource(resources[i].get()); | 88 archive->addSubresource(resources[i].get()); |
88 else | 89 else |
89 archive->setMainResource(resources[i].get()); | 90 archive->setMainResource(resources[i].get()); |
90 } | 91 } |
91 return archive; | 92 return archive; |
92 } | 93 } |
93 | 94 |
94 bool MHTMLArchive::canLoadArchive(const KURL& url) { | 95 bool MHTMLArchive::canLoadArchive(const KURL& url) { |
95 // MHTML pages can only be loaded from local URLs, http/https URLs, and conten
t URLs(Android specific). | 96 // MHTML pages can only be loaded from local URLs, http/https URLs, and |
96 // The latter is now allowed due to full sandboxing enforcement on MHTML pages
. | 97 // content URLs(Android specific). The latter is now allowed due to full |
| 98 // sandboxing enforcement on MHTML pages. |
97 if (SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol())) | 99 if (SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol())) |
98 return true; | 100 return true; |
99 if (url.protocolIsInHTTPFamily()) | 101 if (url.protocolIsInHTTPFamily()) |
100 return true; | 102 return true; |
101 #if OS(ANDROID) | 103 #if OS(ANDROID) |
102 if (url.protocolIs("content")) | 104 if (url.protocolIs("content")) |
103 return true; | 105 return true; |
104 #endif | 106 #endif |
105 return false; | 107 return false; |
106 } | 108 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 outputBuffer.append(asciiString.data(), asciiString.length()); | 193 outputBuffer.append(asciiString.data(), asciiString.length()); |
192 | 194 |
193 if (!strcmp(contentEncoding, binary)) { | 195 if (!strcmp(contentEncoding, binary)) { |
194 const char* data; | 196 const char* data; |
195 size_t position = 0; | 197 size_t position = 0; |
196 while (size_t length = resource.data->getSomeData(data, position)) { | 198 while (size_t length = resource.data->getSomeData(data, position)) { |
197 outputBuffer.append(data, length); | 199 outputBuffer.append(data, length); |
198 position += length; | 200 position += length; |
199 } | 201 } |
200 } else { | 202 } else { |
201 // FIXME: ideally we would encode the content as a stream without having to
fetch it all. | 203 // FIXME: ideally we would encode the content as a stream without having to |
| 204 // fetch it all. |
202 const char* data = resource.data->data(); | 205 const char* data = resource.data->data(); |
203 size_t dataLength = resource.data->size(); | 206 size_t dataLength = resource.data->size(); |
204 Vector<char> encodedData; | 207 Vector<char> encodedData; |
205 if (!strcmp(contentEncoding, quotedPrintable)) { | 208 if (!strcmp(contentEncoding, quotedPrintable)) { |
206 quotedPrintableEncode(data, dataLength, encodedData); | 209 quotedPrintableEncode(data, dataLength, encodedData); |
207 outputBuffer.append(encodedData.data(), encodedData.size()); | 210 outputBuffer.append(encodedData.data(), encodedData.size()); |
208 outputBuffer.append("\r\n", 2u); | 211 outputBuffer.append("\r\n", 2u); |
209 } else { | 212 } else { |
210 ASSERT(!strcmp(contentEncoding, base64)); | 213 ASSERT(!strcmp(contentEncoding, base64)); |
211 // We are not specifying insertLFs = true below as it would cut the lines
with LFs and MHTML requires CRLFs. | 214 // We are not specifying insertLFs = true below as it would cut the lines |
| 215 // with LFs and MHTML requires CRLFs. |
212 base64Encode(data, dataLength, encodedData); | 216 base64Encode(data, dataLength, encodedData); |
213 const size_t maximumLineLength = 76; | 217 const size_t maximumLineLength = 76; |
214 size_t index = 0; | 218 size_t index = 0; |
215 size_t encodedDataLength = encodedData.size(); | 219 size_t encodedDataLength = encodedData.size(); |
216 do { | 220 do { |
217 size_t lineLength = | 221 size_t lineLength = |
218 std::min(encodedDataLength - index, maximumLineLength); | 222 std::min(encodedDataLength - index, maximumLineLength); |
219 outputBuffer.append(encodedData.data() + index, lineLength); | 223 outputBuffer.append(encodedData.data() + index, lineLength); |
220 outputBuffer.append("\r\n", 2u); | 224 outputBuffer.append("\r\n", 2u); |
221 index += maximumLineLength; | 225 index += maximumLineLength; |
(...skipping 24 matching lines...) Expand all Loading... |
246 ArchiveResource* MHTMLArchive::subresourceForURL(const KURL& url) const { | 250 ArchiveResource* MHTMLArchive::subresourceForURL(const KURL& url) const { |
247 return m_subresources.get(url.getString()); | 251 return m_subresources.get(url.getString()); |
248 } | 252 } |
249 | 253 |
250 DEFINE_TRACE(MHTMLArchive) { | 254 DEFINE_TRACE(MHTMLArchive) { |
251 visitor->trace(m_mainResource); | 255 visitor->trace(m_mainResource); |
252 visitor->trace(m_subresources); | 256 visitor->trace(m_subresources); |
253 } | 257 } |
254 | 258 |
255 } // namespace blink | 259 } // namespace blink |
OLD | NEW |