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

Side by Side Diff: content/browser/loader/temporary_file_manager.cc

Issue 82273002: Fix various issues in RedirectToFileResourceHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments Created 7 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/loader/temporary_file_manager.h"
6
7 #include "base/files/file_util_proxy.h"
8 #include "content/browser/child_process_security_policy_impl.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "net/base/file_stream.h"
11 #include "webkit/common/blob/shareable_file_reference.h"
12
13 using webkit_blob::ShareableFileReference;
14
15 namespace content {
16
17 namespace {
18
19 void RemoveDownloadFileFromChildSecurityPolicy(int child_id,
20 const base::FilePath& path) {
21 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile(
22 child_id, path);
23 }
24
25 } // namespace
26
27 struct TemporaryFileManager::PendingTemporary {
28 int child_id;
29 int request_id;
30 TemporaryFileStreamFactory::Callback callback;
31 bool cancelled;
mmenke 2013/12/04 20:55:48 nit: Methods go before member variables.
davidben 2013/12/04 22:44:04 Done.
32
33 PendingTemporary(int child_id,
34 int request_id,
35 const TemporaryFileStreamFactory::Callback& callback)
36 : child_id(child_id),
37 request_id(request_id),
38 callback(callback),
39 cancelled(false) {
40 }
41 };
42
43 TemporaryFileManager::TemporaryFileManager() : weak_factory_(this) {
44 }
45
46 TemporaryFileManager::~TemporaryFileManager() {
47 }
48
49 void TemporaryFileManager::UnregisterDownloadedTempFile(
50 int child_id, int request_id) {
51 DeletableFilesMap& map = registered_temp_files_[child_id];
52 DeletableFilesMap::iterator found = map.find(request_id);
53 if (found != map.end()) {
54 map.erase(found);
55 }
56
57 // Cancel any pending requests.
58 PendingTemporaryMap::iterator found_pending =
59 pending_temporary_map_.find(GlobalRequestID(child_id, request_id));
60 if (found_pending != pending_temporary_map_.end()) {
61 found_pending->second->cancelled = true;
62 }
63
64 // Note that we don't remove the security bits here. This will be done
65 // when all file refs are deleted (see RegisterDownloadedTempFile).
66 }
67
68 void TemporaryFileManager::UnregisterFilesForChild(int child_id) {
69 registered_temp_files_.erase(child_id);
70
71 // Cancel all pending requests.
72 PendingTemporaryMap::iterator iter =
73 pending_temporary_map_.lower_bound(GlobalRequestID(child_id, -1));
74 PendingTemporaryMap::iterator stop =
75 pending_temporary_map_.lower_bound(GlobalRequestID(child_id + 1, -1));
76 for (; iter != stop; ++iter) {
77 DCHECK_EQ(child_id, iter->first.child_id);
78 iter->second->cancelled = true;
79 }
80 }
81
82 void TemporaryFileManager::CreateTemporary(
83 int child_id,
84 int request_id,
85 const TemporaryFileStreamFactory::Callback& callback) {
86 PendingTemporary* pending =
87 new PendingTemporary(child_id, request_id, callback);
88 pending_temporary_map_[GlobalRequestID(child_id, request_id)] = pending;
89
90 base::FileUtilProxy::CreateTemporary(
91 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
92 base::PLATFORM_FILE_ASYNC,
93 base::Bind(&TemporaryFileManager::DidCreateTemporaryFile, AsWeakPtr(),
94 base::Owned(pending)));
95 }
96
97 void TemporaryFileManager::DidCreateTemporaryFile(
98 TemporaryFileManager::PendingTemporary* pending,
99 base::PlatformFileError error_code,
100 base::PassPlatformFile file_handle,
101 const base::FilePath& file_path) {
102 DCHECK_EQ(pending,
103 pending_temporary_map_[GlobalRequestID(pending->child_id,
104 pending->request_id)]);
105 pending_temporary_map_.erase(GlobalRequestID(pending->child_id,
106 pending->request_id));
107
108 if (error_code != base::PLATFORM_FILE_OK) {
109 if (!pending->cancelled)
110 pending->callback.Run(error_code, scoped_ptr<net::FileStream>(), NULL);
111 return;
112 }
113
114 // Cancelled or not, create the deletable_file so the temporary is cleaned up.
115 scoped_refptr<ShareableFileReference> deletable_file =
116 ShareableFileReference::GetOrCreate(
117 file_path,
118 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
119 BrowserThread::GetMessageLoopProxyForThread(
120 BrowserThread::FILE).get());
121
122 if (pending->cancelled)
123 return;
124
125 scoped_ptr<net::FileStream> file_stream(new net::FileStream(
126 file_handle.ReleaseValue(),
127 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC,
128 NULL));
129
130 RegisterDownloadedTempFile(pending->child_id, pending->request_id,
131 deletable_file.get());
132 pending->callback.Run(error_code, file_stream.Pass(), deletable_file);
133 }
134
135 void TemporaryFileManager::RegisterDownloadedTempFile(
136 int child_id, int request_id, ShareableFileReference* reference) {
137 registered_temp_files_[child_id][request_id] = reference;
138 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
139 child_id, reference->path());
140
141 // When the temp file is deleted, revoke permissions that the renderer has
142 // to that file. This covers an edge case where the file is deleted and then
143 // the same name is re-used for some other purpose, we don't want the old
144 // renderer to still have access to it.
145 //
146 // We do this when the file is deleted because the renderer can take a blob
147 // reference to the temp file that outlives the url loaded that it was
148 // loaded with to keep the file (and permissions) alive.
149 reference->AddFinalReleaseCallback(
150 base::Bind(&RemoveDownloadFileFromChildSecurityPolicy,
151 child_id));
152 }
153
154 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698