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

Side by Side Diff: content/browser/download/mhtml_generation_manager.cc

Issue 2683493002: Get signals working in the EXTRA_DATA section of MHTML (Closed)
Patch Set: FIx tests, add unit test Created 3 years, 9 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 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/download/mhtml_generation_manager.h" 5 #include "content/browser/download/mhtml_generation_manager.h"
6 6
7 #include <map> 7 #include <map>
8 #include <queue> 8 #include <queue>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 14 matching lines...) Expand all
25 #include "content/browser/frame_host/render_frame_host_impl.h" 25 #include "content/browser/frame_host/render_frame_host_impl.h"
26 #include "content/common/frame_messages.h" 26 #include "content/common/frame_messages.h"
27 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/render_frame_host.h" 28 #include "content/public/browser/render_frame_host.h"
29 #include "content/public/browser/render_process_host.h" 29 #include "content/public/browser/render_process_host.h"
30 #include "content/public/browser/render_process_host_observer.h" 30 #include "content/public/browser/render_process_host_observer.h"
31 #include "content/public/browser/web_contents.h" 31 #include "content/public/browser/web_contents.h"
32 #include "content/public/common/mhtml_generation_params.h" 32 #include "content/public/common/mhtml_generation_params.h"
33 #include "net/base/mime_util.h" 33 #include "net/base/mime_util.h"
34 34
35 namespace {
36 const char kApplicationJson[] = "application/json";
37 } // namespace
38
35 namespace content { 39 namespace content {
36 40
37 // The class and all of its members live on the UI thread. Only static methods 41 // The class and all of its members live on the UI thread. Only static methods
38 // are executed on other threads. 42 // are executed on other threads.
39 class MHTMLGenerationManager::Job : public RenderProcessHostObserver { 43 class MHTMLGenerationManager::Job : public RenderProcessHostObserver {
40 public: 44 public:
41 Job(int job_id, 45 Job(int job_id,
42 WebContents* web_contents, 46 WebContents* web_contents,
43 const MHTMLGenerationParams& params, 47 const MHTMLGenerationParams& params,
44 const GenerateMHTMLCallback& callback); 48 const GenerateMHTMLCallback& callback);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 98
95 private: 99 private:
96 // Writes the MHTML footer to the file and closes it. 100 // Writes the MHTML footer to the file and closes it.
97 // 101 //
98 // Note: The same |boundary| marker must be used for all "boundaries" -- in 102 // Note: The same |boundary| marker must be used for all "boundaries" -- in
99 // the header, parts and footer -- that belong to the same MHTML document (see 103 // the header, parts and footer -- that belong to the same MHTML document (see
100 // also rfc1341, section 7.2.1, "boundary" description). 104 // also rfc1341, section 7.2.1, "boundary" description).
101 static std::tuple<MhtmlSaveStatus, int64_t> CloseFileOnFileThread( 105 static std::tuple<MhtmlSaveStatus, int64_t> CloseFileOnFileThread(
102 MhtmlSaveStatus save_status, 106 MhtmlSaveStatus save_status,
103 const std::string& boundary, 107 const std::string& boundary,
104 base::File file); 108 base::File file,
109 const std::string& extra_data);
105 void AddFrame(RenderFrameHost* render_frame_host); 110 void AddFrame(RenderFrameHost* render_frame_host);
106 111
112 // If we have any extra data sections to write out, write them into the file
113 // while on the file thread. Returns true for success.
114 static bool WriteExtraDataSectionOnFileThread(const std::string& boundary,
115 base::File& file,
116 const std::string& extra_data);
117
107 // Creates a new map with values (content ids) the same as in 118 // Creates a new map with values (content ids) the same as in
108 // |frame_tree_node_to_content_id_| map, but with the keys translated from 119 // |frame_tree_node_to_content_id_| map, but with the keys translated from
109 // frame_tree_node_id into a |site_instance|-specific routing_id. 120 // frame_tree_node_id into a |site_instance|-specific routing_id.
110 std::map<int, std::string> CreateFrameRoutingIdToContentId( 121 std::map<int, std::string> CreateFrameRoutingIdToContentId(
111 SiteInstance* site_instance); 122 SiteInstance* site_instance);
112 123
113 // Id used to map renderer responses to jobs. 124 // Id used to map renderer responses to jobs.
114 // See also MHTMLGenerationManager::id_to_job_ map. 125 // See also MHTMLGenerationManager::id_to_job_ map.
115 const int job_id_; 126 const int job_id_;
116 127
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 return; 359 return;
349 } 360 }
350 361
351 // If no previous error occurred the boundary should be sent. 362 // If no previous error occurred the boundary should be sent.
352 BrowserThread::PostTaskAndReplyWithResult( 363 BrowserThread::PostTaskAndReplyWithResult(
353 BrowserThread::FILE, FROM_HERE, 364 BrowserThread::FILE, FROM_HERE,
354 base::Bind( 365 base::Bind(
355 &MHTMLGenerationManager::Job::CloseFileOnFileThread, save_status, 366 &MHTMLGenerationManager::Job::CloseFileOnFileThread, save_status,
356 (save_status == MhtmlSaveStatus::SUCCESS ? mhtml_boundary_marker_ 367 (save_status == MhtmlSaveStatus::SUCCESS ? mhtml_boundary_marker_
357 : std::string()), 368 : std::string()),
358 base::Passed(&browser_file_)), 369 base::Passed(&browser_file_), params_.extra_data),
359 callback); 370 callback);
360 } 371 }
361 372
362 bool MHTMLGenerationManager::Job::IsMessageFromFrameExpected( 373 bool MHTMLGenerationManager::Job::IsMessageFromFrameExpected(
363 RenderFrameHostImpl* sender) { 374 RenderFrameHostImpl* sender) {
364 int sender_id = sender->frame_tree_node()->frame_tree_node_id(); 375 int sender_id = sender->frame_tree_node()->frame_tree_node_id();
365 if (sender_id != frame_tree_node_id_of_busy_frame_) 376 if (sender_id != frame_tree_node_id_of_busy_frame_)
366 return false; 377 return false;
367 378
368 // We only expect one message per frame - let's make sure subsequent messages 379 // We only expect one message per frame - let's make sure subsequent messages
(...skipping 25 matching lines...) Expand all
394 405
395 // Report success if all frames have been processed. 406 // Report success if all frames have been processed.
396 if (pending_frame_tree_node_ids_.empty()) 407 if (pending_frame_tree_node_ids_.empty())
397 return MhtmlSaveStatus::SUCCESS; 408 return MhtmlSaveStatus::SUCCESS;
398 409
399 return SendToNextRenderFrame(); 410 return SendToNextRenderFrame();
400 } 411 }
401 412
402 // static 413 // static
403 std::tuple<MhtmlSaveStatus, int64_t> 414 std::tuple<MhtmlSaveStatus, int64_t>
404 MHTMLGenerationManager::Job::CloseFileOnFileThread(MhtmlSaveStatus save_status, 415 MHTMLGenerationManager::Job::CloseFileOnFileThread(
405 const std::string& boundary, 416 MhtmlSaveStatus save_status,
406 base::File file) { 417 const std::string& boundary,
418 base::File file,
419 const std::string& extra_data) {
407 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 420 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
408 421
409 // If no previous error occurred the boundary should have been provided. 422 // If no previous error occurred the boundary should have been provided.
410 if (save_status == MhtmlSaveStatus::SUCCESS) { 423 if (save_status == MhtmlSaveStatus::SUCCESS) {
411 TRACE_EVENT0("page-serialization", 424 TRACE_EVENT0("page-serialization",
412 "MHTMLGenerationManager::Job MHTML footer writing"); 425 "MHTMLGenerationManager::Job MHTML footer writing");
413 DCHECK(!boundary.empty()); 426 DCHECK(!boundary.empty());
427
428 // Write the extra data into a section of its own, if we have any.
429 if (!WriteExtraDataSectionOnFileThread(boundary, file, extra_data))
430 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR;
431
414 std::string footer = base::StringPrintf("--%s--\r\n", boundary.c_str()); 432 std::string footer = base::StringPrintf("--%s--\r\n", boundary.c_str());
415 DCHECK(base::IsStringASCII(footer)); 433 DCHECK(base::IsStringASCII(footer));
416 if (file.WriteAtCurrentPos(footer.data(), footer.size()) < 0) 434 if (file.WriteAtCurrentPos(footer.data(), footer.size()) < 0)
417 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR; 435 save_status = MhtmlSaveStatus::FILE_WRITTING_ERROR;
418 } 436 }
419 437
420 // If the file is still valid try to close it. Only update the status if that 438 // If the file is still valid try to close it. Only update the status if that
421 // won't hide an earlier error. 439 // won't hide an earlier error.
422 int64_t file_size = -1; 440 int64_t file_size = -1;
423 if (file.IsValid()) { 441 if (file.IsValid()) {
424 file_size = file.GetLength(); 442 file_size = file.GetLength();
425 file.Close(); 443 file.Close();
426 } else if (save_status == MhtmlSaveStatus::SUCCESS) { 444 } else if (save_status == MhtmlSaveStatus::SUCCESS) {
427 save_status = MhtmlSaveStatus::FILE_CLOSING_ERROR; 445 save_status = MhtmlSaveStatus::FILE_CLOSING_ERROR;
428 } 446 }
429 447
430 return std::make_tuple(save_status, file_size); 448 return std::make_tuple(save_status, file_size);
431 } 449 }
432 450
451 // static
452 bool MHTMLGenerationManager::Job::WriteExtraDataSectionOnFileThread(
453 const std::string& boundary,
454 base::File& file,
455 const std::string& extra_data) {
456 // Write a newline, then a boundary, then the mime type, another newline,
457 // the extra data string, and end with a newline.
458 std::string extra_data_section =
459 base::StringPrintf("--%s--\r\n%s\r\n%s\r\n", boundary.c_str(),
Dmitry Titov 2017/03/14 01:16:02 It looks like you are trying to form a 'legit' MHT
romax 2017/03/14 19:08:05 is it possible to have some kind of signs that thi
Pete Williamson 2017/03/15 22:38:22 I explicitly kept this section as extra data. Sig
Pete Williamson 2017/03/15 22:38:22 I moved the Content-Type to where I build the data
460 kApplicationJson, extra_data.c_str());
461 // Now actually write the string into the file.
462 DCHECK(base::IsStringASCII(extra_data_section));
463 if (file.WriteAtCurrentPos(extra_data_section.data(),
464 extra_data_section.size()) < 0)
465 return false;
466
467 return true;
468 }
469
433 MHTMLGenerationManager* MHTMLGenerationManager::GetInstance() { 470 MHTMLGenerationManager* MHTMLGenerationManager::GetInstance() {
434 return base::Singleton<MHTMLGenerationManager>::get(); 471 return base::Singleton<MHTMLGenerationManager>::get();
435 } 472 }
436 473
437 MHTMLGenerationManager::MHTMLGenerationManager() : next_job_id_(0) {} 474 MHTMLGenerationManager::MHTMLGenerationManager() : next_job_id_(0) {}
438 475
439 MHTMLGenerationManager::~MHTMLGenerationManager() { 476 MHTMLGenerationManager::~MHTMLGenerationManager() {
440 } 477 }
441 478
442 void MHTMLGenerationManager::SaveMHTML(WebContents* web_contents, 479 void MHTMLGenerationManager::SaveMHTML(WebContents* web_contents,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 return iter->second.get(); 629 return iter->second.get();
593 } 630 }
594 631
595 void MHTMLGenerationManager::RenderProcessExited(Job* job) { 632 void MHTMLGenerationManager::RenderProcessExited(Job* job) {
596 DCHECK_CURRENTLY_ON(BrowserThread::UI); 633 DCHECK_CURRENTLY_ON(BrowserThread::UI);
597 DCHECK(job); 634 DCHECK(job);
598 JobFinished(job, MhtmlSaveStatus::RENDER_PROCESS_EXITED); 635 JobFinished(job, MhtmlSaveStatus::RENDER_PROCESS_EXITED);
599 } 636 }
600 637
601 } // namespace content 638 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698