OLD | NEW |
---|---|
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/fileapi/fileapi_message_filter.h" | 5 #include "content/browser/fileapi/fileapi_message_filter.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/platform_file.h" | 13 #include "base/platform_file.h" |
14 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
15 #include "base/strings/string_util.h" | |
15 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
16 #include "base/time/time.h" | 17 #include "base/time/time.h" |
17 #include "content/browser/child_process_security_policy_impl.h" | 18 #include "content/browser/child_process_security_policy_impl.h" |
18 #include "content/browser/fileapi/browser_file_system_helper.h" | 19 #include "content/browser/fileapi/browser_file_system_helper.h" |
19 #include "content/browser/fileapi/chrome_blob_storage_context.h" | 20 #include "content/browser/fileapi/chrome_blob_storage_context.h" |
21 #include "content/browser/streams/stream_registry.h" | |
20 #include "content/common/fileapi/file_system_messages.h" | 22 #include "content/common/fileapi/file_system_messages.h" |
21 #include "content/common/fileapi/webblob_messages.h" | 23 #include "content/common/fileapi/webblob_messages.h" |
22 #include "content/public/browser/user_metrics.h" | 24 #include "content/public/browser/user_metrics.h" |
23 #include "googleurl/src/gurl.h" | 25 #include "googleurl/src/gurl.h" |
24 #include "ipc/ipc_platform_file.h" | 26 #include "ipc/ipc_platform_file.h" |
27 #include "net/base/io_buffer.h" | |
25 #include "net/base/mime_util.h" | 28 #include "net/base/mime_util.h" |
26 #include "net/url_request/url_request_context.h" | 29 #include "net/url_request/url_request_context.h" |
27 #include "net/url_request/url_request_context_getter.h" | 30 #include "net/url_request/url_request_context_getter.h" |
28 #include "webkit/browser/blob/blob_storage_controller.h" | 31 #include "webkit/browser/blob/blob_storage_controller.h" |
29 #include "webkit/browser/fileapi/file_observers.h" | 32 #include "webkit/browser/fileapi/file_observers.h" |
30 #include "webkit/browser/fileapi/file_permission_policy.h" | 33 #include "webkit/browser/fileapi/file_permission_policy.h" |
31 #include "webkit/browser/fileapi/file_system_context.h" | 34 #include "webkit/browser/fileapi/file_system_context.h" |
32 #include "webkit/browser/fileapi/file_system_task_runners.h" | 35 #include "webkit/browser/fileapi/file_system_task_runners.h" |
33 #include "webkit/browser/fileapi/isolated_context.h" | 36 #include "webkit/browser/fileapi/isolated_context.h" |
34 #include "webkit/browser/fileapi/local_file_system_operation.h" | 37 #include "webkit/browser/fileapi/local_file_system_operation.h" |
(...skipping 22 matching lines...) Expand all Loading... | |
57 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( | 60 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( |
58 child_id, path); | 61 child_id, path); |
59 } | 62 } |
60 | 63 |
61 } // namespace | 64 } // namespace |
62 | 65 |
63 FileAPIMessageFilter::FileAPIMessageFilter( | 66 FileAPIMessageFilter::FileAPIMessageFilter( |
64 int process_id, | 67 int process_id, |
65 net::URLRequestContextGetter* request_context_getter, | 68 net::URLRequestContextGetter* request_context_getter, |
66 fileapi::FileSystemContext* file_system_context, | 69 fileapi::FileSystemContext* file_system_context, |
67 ChromeBlobStorageContext* blob_storage_context) | 70 ChromeBlobStorageContext* blob_storage_context, |
71 StreamContext* stream_context) | |
68 : process_id_(process_id), | 72 : process_id_(process_id), |
69 context_(file_system_context), | 73 context_(file_system_context), |
70 request_context_getter_(request_context_getter), | 74 request_context_getter_(request_context_getter), |
71 request_context_(NULL), | 75 request_context_(NULL), |
72 blob_storage_context_(blob_storage_context) { | 76 blob_storage_context_(blob_storage_context), |
77 stream_context_(stream_context) { | |
73 DCHECK(context_); | 78 DCHECK(context_); |
74 DCHECK(request_context_getter_.get()); | 79 DCHECK(request_context_getter_.get()); |
75 DCHECK(blob_storage_context); | 80 DCHECK(blob_storage_context); |
81 DCHECK(stream_context); | |
76 } | 82 } |
77 | 83 |
78 FileAPIMessageFilter::FileAPIMessageFilter( | 84 FileAPIMessageFilter::FileAPIMessageFilter( |
79 int process_id, | 85 int process_id, |
80 net::URLRequestContext* request_context, | 86 net::URLRequestContext* request_context, |
81 fileapi::FileSystemContext* file_system_context, | 87 fileapi::FileSystemContext* file_system_context, |
82 ChromeBlobStorageContext* blob_storage_context) | 88 ChromeBlobStorageContext* blob_storage_context, |
89 StreamContext* stream_context) | |
83 : process_id_(process_id), | 90 : process_id_(process_id), |
84 context_(file_system_context), | 91 context_(file_system_context), |
85 request_context_(request_context), | 92 request_context_(request_context), |
86 blob_storage_context_(blob_storage_context) { | 93 blob_storage_context_(blob_storage_context), |
94 stream_context_(stream_context) { | |
87 DCHECK(context_); | 95 DCHECK(context_); |
88 DCHECK(request_context_); | 96 DCHECK(request_context_); |
89 DCHECK(blob_storage_context); | 97 DCHECK(blob_storage_context); |
98 DCHECK(stream_context); | |
90 } | 99 } |
91 | 100 |
92 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { | 101 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { |
93 BrowserMessageFilter::OnChannelConnected(peer_pid); | 102 BrowserMessageFilter::OnChannelConnected(peer_pid); |
94 | 103 |
95 if (request_context_getter_.get()) { | 104 if (request_context_getter_.get()) { |
96 DCHECK(!request_context_); | 105 DCHECK(!request_context_); |
97 request_context_ = request_context_getter_->GetURLRequestContext(); | 106 request_context_ = request_context_getter_->GetURLRequestContext(); |
98 request_context_getter_ = NULL; | 107 request_context_getter_ = NULL; |
99 DCHECK(request_context_); | 108 DCHECK(request_context_); |
100 } | 109 } |
101 } | 110 } |
102 | 111 |
112 scoped_refptr<Stream> FileAPIMessageFilter::GetStreamForURL(const GURL& url) { | |
113 return stream_context_->registry()->GetStream(url); | |
114 } | |
115 | |
103 void FileAPIMessageFilter::OnChannelClosing() { | 116 void FileAPIMessageFilter::OnChannelClosing() { |
104 BrowserMessageFilter::OnChannelClosing(); | 117 BrowserMessageFilter::OnChannelClosing(); |
105 | 118 |
106 // Unregister all the blob URLs that are previously registered in this | 119 // Unregister all the blob URLs that are previously registered in this |
107 // process. | 120 // process. |
108 for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin(); | 121 for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin(); |
109 iter != blob_urls_.end(); ++iter) { | 122 iter != blob_urls_.end(); ++iter) { |
110 blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); | 123 const GURL url(*iter); |
124 // Intercept stream URLs. | |
125 if (GetStreamForURL(url)) | |
126 stream_context_->registry()->UnregisterStream(url); | |
127 else | |
128 blob_storage_context_->controller()->RemoveBlob(url); | |
111 } | 129 } |
112 | 130 |
113 in_transit_snapshot_files_.clear(); | 131 in_transit_snapshot_files_.clear(); |
114 | 132 |
115 // Close all files that are previously OpenFile()'ed in this process. | 133 // Close all files that are previously OpenFile()'ed in this process. |
116 if (!on_close_callbacks_.IsEmpty()) { | 134 if (!on_close_callbacks_.IsEmpty()) { |
117 DLOG(INFO) | 135 DLOG(INFO) |
118 << "File API: Renderer process shut down before NotifyCloseFile" | 136 << "File API: Renderer process shut down before NotifyCloseFile" |
119 << " for " << on_close_callbacks_.size() << " files opened in PPAPI"; | 137 << " for " << on_close_callbacks_.size() << " files opened in PPAPI"; |
120 } | 138 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) | 176 IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) |
159 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, | 177 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, |
160 OnCreateSnapshotFile) | 178 OnCreateSnapshotFile) |
161 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, | 179 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, |
162 OnDidReceiveSnapshotFile) | 180 OnDidReceiveSnapshotFile) |
163 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) | 181 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) |
164 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) | 182 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) |
165 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, | 183 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, |
166 OnSyncGetPlatformPath) | 184 OnSyncGetPlatformPath) |
167 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) | 185 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) |
186 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingStream, OnStartBuildingStream) | |
kinuko
2013/07/18 06:06:55
Sometimes we interchangeably use the term 'blob' a
tyoshino (SeeGerritForStatus)
2013/07/23 07:27:34
Darin's idea was making Blob a subclass of the Str
kinuko
2013/07/23 08:07:42
This sounds good to me.
(I initially thought we c
tyoshino (SeeGerritForStatus)
2013/07/23 11:54:38
Done
| |
168 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) | 187 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) |
169 IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, | 188 IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, |
170 OnAppendSharedMemory) | 189 OnAppendSharedMemory) |
171 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) | 190 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) |
172 IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) | 191 IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) |
173 IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) | 192 IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) |
174 IPC_MESSAGE_UNHANDLED(handled = false) | 193 IPC_MESSAGE_UNHANDLED(handled = false) |
175 IPC_END_MESSAGE_MAP_EX() | 194 IPC_END_MESSAGE_MAP_EX() |
176 return handled; | 195 return handled; |
177 } | 196 } |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
510 in_transit_snapshot_files_.erase(request_id); | 529 in_transit_snapshot_files_.erase(request_id); |
511 } | 530 } |
512 | 531 |
513 void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) { | 532 void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) { |
514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 533 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
515 blob_storage_context_->controller()->StartBuildingBlob(url); | 534 blob_storage_context_->controller()->StartBuildingBlob(url); |
516 blob_urls_.insert(url.spec()); | 535 blob_urls_.insert(url.spec()); |
517 } | 536 } |
518 | 537 |
538 // Currently |content_type| is ignored inside Chromium. | |
539 // | |
540 // TODO(tyoshino): Set |content_type| to the stream. | |
541 void FileAPIMessageFilter::OnStartBuildingStream( | |
542 const GURL& url, const std::string& content_type) { | |
543 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
544 // Only an internal Blob URL is expected here. See the BlobURL of the Blink. | |
545 DCHECK(StartsWithASCII( | |
546 url.path(), "blobinternal%3A///", true /* case_sensitive*/)); | |
547 // Use an empty security origin for now. Stream accepts a security origin | |
548 // but how it's handled is not fixed yet. | |
549 new Stream(stream_context_->registry(), | |
550 NULL /* write_observer */, | |
551 GURL() /* security_origin */, | |
552 url); | |
553 blob_urls_.insert(url.spec()); | |
554 } | |
555 | |
519 void FileAPIMessageFilter::OnAppendBlobDataItem( | 556 void FileAPIMessageFilter::OnAppendBlobDataItem( |
520 const GURL& url, const BlobData::Item& item) { | 557 const GURL& url, const BlobData::Item& item) { |
521 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 558 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
559 | |
560 scoped_refptr<Stream> stream(GetStreamForURL(url)); | |
561 if (stream.get()) { | |
562 // Data for stream is delivered as TYPE_BYTES item. | |
563 if (item.type() != BlobData::Item::TYPE_BYTES) { | |
564 BadMessageReceived(); | |
565 return; | |
566 } | |
567 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(item.length())); | |
568 memcpy(buffer->data(), item.bytes(), item.length()); | |
569 stream->AddData(buffer, item.length()); | |
570 | |
571 return; | |
572 } | |
573 | |
522 if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) { | 574 if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) { |
523 base::PlatformFileError error; | 575 base::PlatformFileError error; |
524 FileSystemURL filesystem_url(context_->CrackURL(item.url())); | 576 FileSystemURL filesystem_url(context_->CrackURL(item.url())); |
525 if (!HasPermissionsForFile(filesystem_url, | 577 if (!HasPermissionsForFile(filesystem_url, |
526 fileapi::kReadFilePermissions, &error)) { | 578 fileapi::kReadFilePermissions, &error)) { |
527 OnRemoveBlob(url); | 579 OnRemoveBlob(url); |
528 return; | 580 return; |
529 } | 581 } |
530 } | 582 } |
531 if (item.type() == BlobData::Item::TYPE_FILE && | 583 if (item.type() == BlobData::Item::TYPE_FILE && |
(...skipping 19 matching lines...) Expand all Loading... | |
551 #if defined(OS_WIN) | 603 #if defined(OS_WIN) |
552 base::SharedMemory shared_memory(handle, true, peer_handle()); | 604 base::SharedMemory shared_memory(handle, true, peer_handle()); |
553 #else | 605 #else |
554 base::SharedMemory shared_memory(handle, true); | 606 base::SharedMemory shared_memory(handle, true); |
555 #endif | 607 #endif |
556 if (!shared_memory.Map(buffer_size)) { | 608 if (!shared_memory.Map(buffer_size)) { |
557 OnRemoveBlob(url); | 609 OnRemoveBlob(url); |
558 return; | 610 return; |
559 } | 611 } |
560 | 612 |
613 scoped_refptr<Stream> stream(GetStreamForURL(url)); | |
614 if (stream.get()) { | |
615 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(buffer_size)); | |
616 memcpy(buffer->data(), static_cast<char*>(shared_memory.memory()), | |
617 buffer_size); | |
618 stream->AddData(buffer, buffer_size); | |
kinuko
2013/07/18 06:06:55
nit: it might be easier to read if Stream class ju
tyoshino (SeeGerritForStatus)
2013/07/23 11:54:38
Done.
| |
619 return; | |
620 } | |
621 | |
561 BlobData::Item item; | 622 BlobData::Item item; |
562 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), | 623 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), |
563 buffer_size); | 624 buffer_size); |
564 blob_storage_context_->controller()->AppendBlobDataItem(url, item); | 625 blob_storage_context_->controller()->AppendBlobDataItem(url, item); |
565 } | 626 } |
566 | 627 |
567 void FileAPIMessageFilter::OnFinishBuildingBlob( | 628 void FileAPIMessageFilter::OnFinishBuildingBlob( |
568 const GURL& url, const std::string& content_type) { | 629 const GURL& url, const std::string& content_type) { |
569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 630 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
570 blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); | 631 scoped_refptr<Stream> stream(GetStreamForURL(url)); |
632 if (stream.get()) | |
633 stream->Finalize(); | |
634 else | |
635 blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); | |
571 } | 636 } |
572 | 637 |
573 void FileAPIMessageFilter::OnCloneBlob( | 638 void FileAPIMessageFilter::OnCloneBlob( |
574 const GURL& url, const GURL& src_url) { | 639 const GURL& url, const GURL& src_url) { |
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
576 blob_storage_context_->controller()->CloneBlob(url, src_url); | 641 if (GetStreamForURL(src_url)) |
642 stream_context_->registry()->CloneStream(url, src_url); | |
643 else | |
644 blob_storage_context_->controller()->CloneBlob(url, src_url); | |
577 blob_urls_.insert(url.spec()); | 645 blob_urls_.insert(url.spec()); |
578 } | 646 } |
579 | 647 |
580 void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) { | 648 void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) { |
581 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 649 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
582 blob_storage_context_->controller()->RemoveBlob(url); | 650 if (GetStreamForURL(url).get()) |
651 stream_context_->registry()->UnregisterStream(url); | |
652 else | |
653 blob_storage_context_->controller()->RemoveBlob(url); | |
583 blob_urls_.erase(url.spec()); | 654 blob_urls_.erase(url.spec()); |
584 } | 655 } |
585 | 656 |
586 void FileAPIMessageFilter::DidFinish(int request_id, | 657 void FileAPIMessageFilter::DidFinish(int request_id, |
587 base::PlatformFileError result) { | 658 base::PlatformFileError result) { |
588 if (result == base::PLATFORM_FILE_OK) | 659 if (result == base::PLATFORM_FILE_OK) |
589 Send(new FileSystemMsg_DidSucceed(request_id)); | 660 Send(new FileSystemMsg_DidSucceed(request_id)); |
590 else | 661 else |
591 Send(new FileSystemMsg_DidFail(request_id, result)); | 662 Send(new FileSystemMsg_DidFail(request_id, result)); |
592 operations_.erase(request_id); | 663 operations_.erase(request_id); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
740 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { | 811 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { |
741 return CheckFileSystemPermissionsForProcess(context_, process_id_, url, | 812 return CheckFileSystemPermissionsForProcess(context_, process_id_, url, |
742 permissions, error); | 813 permissions, error); |
743 } | 814 } |
744 | 815 |
745 fileapi::FileSystemOperationRunner* FileAPIMessageFilter::operation_runner() { | 816 fileapi::FileSystemOperationRunner* FileAPIMessageFilter::operation_runner() { |
746 return context_->operation_runner(); | 817 return context_->operation_runner(); |
747 } | 818 } |
748 | 819 |
749 } // namespace content | 820 } // namespace content |
OLD | NEW |