| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/appcache/appcache_response.h" | 5 #include "webkit/appcache/appcache_response.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/pickle.h" | 10 #include "base/pickle.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "net/base/completion_callback.h" |
| 12 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 13 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
| 14 #include "webkit/appcache/appcache_service.h" | 15 #include "webkit/appcache/appcache_service.h" |
| 15 | 16 |
| 16 namespace appcache { | 17 namespace appcache { |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 // Disk cache entry data indices. | 21 // Disk cache entry data indices. |
| 21 enum { | 22 enum { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 | 68 |
| 68 HttpResponseInfoIOBuffer::HttpResponseInfoIOBuffer(net::HttpResponseInfo* info) | 69 HttpResponseInfoIOBuffer::HttpResponseInfoIOBuffer(net::HttpResponseInfo* info) |
| 69 : http_info(info), response_data_size(kUnkownResponseDataSize) {} | 70 : http_info(info), response_data_size(kUnkownResponseDataSize) {} |
| 70 | 71 |
| 71 HttpResponseInfoIOBuffer::~HttpResponseInfoIOBuffer() {} | 72 HttpResponseInfoIOBuffer::~HttpResponseInfoIOBuffer() {} |
| 72 | 73 |
| 73 // AppCacheResponseIO ---------------------------------------------- | 74 // AppCacheResponseIO ---------------------------------------------- |
| 74 | 75 |
| 75 AppCacheResponseIO::AppCacheResponseIO( | 76 AppCacheResponseIO::AppCacheResponseIO( |
| 76 int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) | 77 int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) |
| 77 : response_id_(response_id), group_id_(group_id), disk_cache_(disk_cache), | 78 : response_id_(response_id), |
| 78 entry_(NULL), buffer_len_(0), user_callback_(NULL), | 79 group_id_(group_id), |
| 80 disk_cache_(disk_cache), |
| 81 entry_(NULL), |
| 82 buffer_len_(0), |
| 79 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 83 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 80 } | 84 } |
| 81 | 85 |
| 82 AppCacheResponseIO::~AppCacheResponseIO() { | 86 AppCacheResponseIO::~AppCacheResponseIO() { |
| 83 if (entry_) | 87 if (entry_) |
| 84 entry_->Close(); | 88 entry_->Close(); |
| 85 } | 89 } |
| 86 | 90 |
| 87 void AppCacheResponseIO::ScheduleIOOldCompletionCallback(int result) { | 91 void AppCacheResponseIO::ScheduleIOOldCompletionCallback(int result) { |
| 88 MessageLoop::current()->PostTask( | 92 MessageLoop::current()->PostTask( |
| 89 FROM_HERE, base::Bind(&AppCacheResponseIO::OnIOComplete, | 93 FROM_HERE, base::Bind(&AppCacheResponseIO::OnIOComplete, |
| 90 weak_factory_.GetWeakPtr(), result)); | 94 weak_factory_.GetWeakPtr(), result)); |
| 91 } | 95 } |
| 92 | 96 |
| 93 void AppCacheResponseIO::InvokeUserOldCompletionCallback(int result) { | 97 void AppCacheResponseIO::InvokeUserOldCompletionCallback(int result) { |
| 94 // Clear the user callback and buffers prior to invoking the callback | 98 // Clear the user callback and buffers prior to invoking the callback |
| 95 // so the caller can schedule additional operations in the callback. | 99 // so the caller can schedule additional operations in the callback. |
| 96 buffer_ = NULL; | 100 buffer_ = NULL; |
| 97 info_buffer_ = NULL; | 101 info_buffer_ = NULL; |
| 98 net::OldCompletionCallback* temp_user_callback = user_callback_; | 102 net::CompletionCallback cb = callback_; |
| 99 user_callback_ = NULL; | 103 callback_.Reset(); |
| 100 temp_user_callback->Run(result); | 104 cb.Run(result); |
| 101 } | 105 } |
| 102 | 106 |
| 103 void AppCacheResponseIO::ReadRaw(int index, int offset, | 107 void AppCacheResponseIO::ReadRaw(int index, int offset, |
| 104 net::IOBuffer* buf, int buf_len) { | 108 net::IOBuffer* buf, int buf_len) { |
| 105 DCHECK(entry_); | 109 DCHECK(entry_); |
| 106 int rv = entry_->Read( | 110 int rv = entry_->Read( |
| 107 index, offset, buf, buf_len, | 111 index, offset, buf, buf_len, |
| 108 base::Bind(&AppCacheResponseIO::OnRawIOComplete, | 112 base::Bind(&AppCacheResponseIO::OnRawIOComplete, |
| 109 weak_factory_.GetWeakPtr())); | 113 weak_factory_.GetWeakPtr())); |
| 110 if (rv != net::ERR_IO_PENDING) | 114 if (rv != net::ERR_IO_PENDING) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 136 range_offset_(0), range_length_(kint32max), | 140 range_offset_(0), range_length_(kint32max), |
| 137 read_position_(0) { | 141 read_position_(0) { |
| 138 } | 142 } |
| 139 | 143 |
| 140 AppCacheResponseReader::~AppCacheResponseReader() { | 144 AppCacheResponseReader::~AppCacheResponseReader() { |
| 141 if (open_callback_) | 145 if (open_callback_) |
| 142 open_callback_.release()->Cancel(); | 146 open_callback_.release()->Cancel(); |
| 143 } | 147 } |
| 144 | 148 |
| 145 void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf, | 149 void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf, |
| 146 net::OldCompletionCallback* callback) { | 150 const net::CompletionCallback& callback) { |
| 147 DCHECK(callback && !IsReadPending()); | 151 DCHECK(!callback.is_null()); |
| 148 DCHECK(info_buf && !info_buf->http_info.get()); | 152 DCHECK(!IsReadPending()); |
| 149 DCHECK(!buffer_.get() && !info_buffer_.get()); | 153 DCHECK(info_buf); |
| 154 DCHECK(!info_buf->http_info.get()); |
| 155 DCHECK(!buffer_.get()); |
| 156 DCHECK(!info_buffer_.get()); |
| 150 | 157 |
| 151 info_buffer_ = info_buf; | 158 info_buffer_ = info_buf; |
| 152 user_callback_ = callback; // cleared on completion | 159 callback_ = callback; // cleared on completion |
| 153 OpenEntryIfNeededAndContinue(); | 160 OpenEntryIfNeededAndContinue(); |
| 154 } | 161 } |
| 155 | 162 |
| 156 void AppCacheResponseReader::ContinueReadInfo() { | 163 void AppCacheResponseReader::ContinueReadInfo() { |
| 157 if (!entry_) { | 164 if (!entry_) { |
| 158 ScheduleIOOldCompletionCallback(net::ERR_CACHE_MISS); | 165 ScheduleIOOldCompletionCallback(net::ERR_CACHE_MISS); |
| 159 return; | 166 return; |
| 160 } | 167 } |
| 161 | 168 |
| 162 int size = entry_->GetSize(kResponseInfoIndex); | 169 int size = entry_->GetSize(kResponseInfoIndex); |
| 163 if (size <= 0) { | 170 if (size <= 0) { |
| 164 ScheduleIOOldCompletionCallback(net::ERR_CACHE_MISS); | 171 ScheduleIOOldCompletionCallback(net::ERR_CACHE_MISS); |
| 165 return; | 172 return; |
| 166 } | 173 } |
| 167 | 174 |
| 168 buffer_ = new net::IOBuffer(size); | 175 buffer_ = new net::IOBuffer(size); |
| 169 ReadRaw(kResponseInfoIndex, 0, buffer_.get(), size); | 176 ReadRaw(kResponseInfoIndex, 0, buffer_.get(), size); |
| 170 } | 177 } |
| 171 | 178 |
| 172 void AppCacheResponseReader::ReadData(net::IOBuffer* buf, int buf_len, | 179 void AppCacheResponseReader::ReadData(net::IOBuffer* buf, int buf_len, |
| 173 net::OldCompletionCallback* callback) { | 180 const net::CompletionCallback& callback) { |
| 174 DCHECK(callback && !IsReadPending()); | 181 DCHECK(!callback.is_null()); |
| 175 DCHECK(buf && (buf_len >= 0)); | 182 DCHECK(!IsReadPending()); |
| 176 DCHECK(!buffer_.get() && !info_buffer_.get()); | 183 DCHECK(buf); |
| 184 DCHECK(buf_len >= 0); |
| 185 DCHECK(!buffer_.get()); |
| 186 DCHECK(!info_buffer_.get()); |
| 177 | 187 |
| 178 buffer_ = buf; | 188 buffer_ = buf; |
| 179 buffer_len_ = buf_len; | 189 buffer_len_ = buf_len; |
| 180 user_callback_ = callback; // cleared on completion | 190 callback_ = callback; // cleared on completion |
| 181 OpenEntryIfNeededAndContinue(); | 191 OpenEntryIfNeededAndContinue(); |
| 182 } | 192 } |
| 183 | 193 |
| 184 void AppCacheResponseReader::ContinueReadData() { | 194 void AppCacheResponseReader::ContinueReadData() { |
| 185 if (!entry_) { | 195 if (!entry_) { |
| 186 ScheduleIOOldCompletionCallback(net::ERR_CACHE_MISS); | 196 ScheduleIOOldCompletionCallback(net::ERR_CACHE_MISS); |
| 187 return; | 197 return; |
| 188 } | 198 } |
| 189 | 199 |
| 190 if (read_position_ + buffer_len_ > range_length_) { | 200 if (read_position_ + buffer_len_ > range_length_) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 | 240 |
| 231 void AppCacheResponseReader::OpenEntryIfNeededAndContinue() { | 241 void AppCacheResponseReader::OpenEntryIfNeededAndContinue() { |
| 232 int rv; | 242 int rv; |
| 233 if (entry_) { | 243 if (entry_) { |
| 234 rv = net::OK; | 244 rv = net::OK; |
| 235 } else if (!disk_cache_) { | 245 } else if (!disk_cache_) { |
| 236 rv = net::ERR_FAILED; | 246 rv = net::ERR_FAILED; |
| 237 } else { | 247 } else { |
| 238 open_callback_ = new EntryCallback<AppCacheResponseReader>( | 248 open_callback_ = new EntryCallback<AppCacheResponseReader>( |
| 239 this, &AppCacheResponseReader::OnOpenEntryComplete); | 249 this, &AppCacheResponseReader::OnOpenEntryComplete); |
| 240 rv = disk_cache_->OpenEntry(response_id_, &open_callback_->entry_ptr_, | 250 rv = disk_cache_->OpenEntry( |
| 241 open_callback_.get()); | 251 response_id_, &open_callback_->entry_ptr_, |
| 252 base::Bind(&net::OldCompletionCallbackAdapter, open_callback_)); |
| 242 } | 253 } |
| 243 | 254 |
| 244 if (rv != net::ERR_IO_PENDING) | 255 if (rv != net::ERR_IO_PENDING) |
| 245 OnOpenEntryComplete(rv); | 256 OnOpenEntryComplete(rv); |
| 246 } | 257 } |
| 247 | 258 |
| 248 void AppCacheResponseReader::OnOpenEntryComplete(int rv) { | 259 void AppCacheResponseReader::OnOpenEntryComplete(int rv) { |
| 249 DCHECK(info_buffer_.get() || buffer_.get()); | 260 DCHECK(info_buffer_.get() || buffer_.get()); |
| 250 | 261 |
| 251 if (open_callback_) { | 262 if (open_callback_) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 269 : AppCacheResponseIO(response_id, group_id, disk_cache), | 280 : AppCacheResponseIO(response_id, group_id, disk_cache), |
| 270 info_size_(0), write_position_(0), write_amount_(0), | 281 info_size_(0), write_position_(0), write_amount_(0), |
| 271 creation_phase_(INITIAL_ATTEMPT) { | 282 creation_phase_(INITIAL_ATTEMPT) { |
| 272 } | 283 } |
| 273 | 284 |
| 274 AppCacheResponseWriter::~AppCacheResponseWriter() { | 285 AppCacheResponseWriter::~AppCacheResponseWriter() { |
| 275 if (create_callback_) | 286 if (create_callback_) |
| 276 create_callback_.release()->Cancel(); | 287 create_callback_.release()->Cancel(); |
| 277 } | 288 } |
| 278 | 289 |
| 279 void AppCacheResponseWriter::WriteInfo(HttpResponseInfoIOBuffer* info_buf, | 290 void AppCacheResponseWriter::WriteInfo( |
| 280 net::OldCompletionCallback* callback) { | 291 HttpResponseInfoIOBuffer* info_buf, |
| 281 DCHECK(callback && !IsWritePending()); | 292 const net::CompletionCallback& callback) { |
| 282 DCHECK(info_buf && info_buf->http_info.get()); | 293 DCHECK(!callback.is_null()); |
| 283 DCHECK(!buffer_.get() && !info_buffer_.get()); | 294 DCHECK(!IsWritePending()); |
| 295 DCHECK(info_buf); |
| 296 DCHECK(info_buf->http_info.get()); |
| 297 DCHECK(!buffer_.get()); |
| 298 DCHECK(!info_buffer_.get()); |
| 284 DCHECK(info_buf->http_info->headers); | 299 DCHECK(info_buf->http_info->headers); |
| 285 | 300 |
| 286 info_buffer_ = info_buf; | 301 info_buffer_ = info_buf; |
| 287 user_callback_ = callback; // cleared on completion | 302 callback_ = callback; // cleared on completion |
| 288 CreateEntryIfNeededAndContinue(); | 303 CreateEntryIfNeededAndContinue(); |
| 289 } | 304 } |
| 290 | 305 |
| 291 void AppCacheResponseWriter::ContinueWriteInfo() { | 306 void AppCacheResponseWriter::ContinueWriteInfo() { |
| 292 if (!entry_) { | 307 if (!entry_) { |
| 293 ScheduleIOOldCompletionCallback(net::ERR_FAILED); | 308 ScheduleIOOldCompletionCallback(net::ERR_FAILED); |
| 294 return; | 309 return; |
| 295 } | 310 } |
| 296 | 311 |
| 297 const bool kSkipTransientHeaders = true; | 312 const bool kSkipTransientHeaders = true; |
| 298 const bool kTruncated = false; | 313 const bool kTruncated = false; |
| 299 Pickle* pickle = new Pickle; | 314 Pickle* pickle = new Pickle; |
| 300 info_buffer_->http_info->Persist(pickle, kSkipTransientHeaders, kTruncated); | 315 info_buffer_->http_info->Persist(pickle, kSkipTransientHeaders, kTruncated); |
| 301 write_amount_ = static_cast<int>(pickle->size()); | 316 write_amount_ = static_cast<int>(pickle->size()); |
| 302 buffer_ = new WrappedPickleIOBuffer(pickle); // takes ownership of pickle | 317 buffer_ = new WrappedPickleIOBuffer(pickle); // takes ownership of pickle |
| 303 WriteRaw(kResponseInfoIndex, 0, buffer_, write_amount_); | 318 WriteRaw(kResponseInfoIndex, 0, buffer_, write_amount_); |
| 304 } | 319 } |
| 305 | 320 |
| 306 void AppCacheResponseWriter::WriteData(net::IOBuffer* buf, int buf_len, | 321 void AppCacheResponseWriter::WriteData( |
| 307 net::OldCompletionCallback* callback) { | 322 net::IOBuffer* buf, int buf_len, const net::CompletionCallback& callback) { |
| 308 DCHECK(callback && !IsWritePending()); | 323 DCHECK(!callback.is_null()); |
| 309 DCHECK(buf && (buf_len >= 0)); | 324 DCHECK(!IsWritePending()); |
| 310 DCHECK(!buffer_.get() && !info_buffer_.get()); | 325 DCHECK(buf); |
| 326 DCHECK(buf_len >= 0); |
| 327 DCHECK(!buffer_.get()); |
| 328 DCHECK(!info_buffer_.get()); |
| 311 | 329 |
| 312 buffer_ = buf; | 330 buffer_ = buf; |
| 313 write_amount_ = buf_len; | 331 write_amount_ = buf_len; |
| 314 user_callback_ = callback; // cleared on completion | 332 callback_ = callback; // cleared on completion |
| 315 CreateEntryIfNeededAndContinue(); | 333 CreateEntryIfNeededAndContinue(); |
| 316 } | 334 } |
| 317 | 335 |
| 318 void AppCacheResponseWriter::ContinueWriteData() { | 336 void AppCacheResponseWriter::ContinueWriteData() { |
| 319 if (!entry_) { | 337 if (!entry_) { |
| 320 ScheduleIOOldCompletionCallback(net::ERR_FAILED); | 338 ScheduleIOOldCompletionCallback(net::ERR_FAILED); |
| 321 return; | 339 return; |
| 322 } | 340 } |
| 323 WriteRaw(kResponseContentIndex, write_position_, buffer_, write_amount_); | 341 WriteRaw(kResponseContentIndex, write_position_, buffer_, write_amount_); |
| 324 } | 342 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 339 if (entry_) { | 357 if (entry_) { |
| 340 creation_phase_ = NO_ATTEMPT; | 358 creation_phase_ = NO_ATTEMPT; |
| 341 rv = net::OK; | 359 rv = net::OK; |
| 342 } else if (!disk_cache_) { | 360 } else if (!disk_cache_) { |
| 343 creation_phase_ = NO_ATTEMPT; | 361 creation_phase_ = NO_ATTEMPT; |
| 344 rv = net::ERR_FAILED; | 362 rv = net::ERR_FAILED; |
| 345 } else { | 363 } else { |
| 346 creation_phase_ = INITIAL_ATTEMPT; | 364 creation_phase_ = INITIAL_ATTEMPT; |
| 347 create_callback_ = new EntryCallback<AppCacheResponseWriter>( | 365 create_callback_ = new EntryCallback<AppCacheResponseWriter>( |
| 348 this, &AppCacheResponseWriter::OnCreateEntryComplete); | 366 this, &AppCacheResponseWriter::OnCreateEntryComplete); |
| 349 rv = disk_cache_->CreateEntry(response_id_, &create_callback_->entry_ptr_, | 367 rv = disk_cache_->CreateEntry( |
| 350 create_callback_.get()); | 368 response_id_, &create_callback_->entry_ptr_, |
| 369 base::Bind(&net::OldCompletionCallbackAdapter, create_callback_)); |
| 351 } | 370 } |
| 352 if (rv != net::ERR_IO_PENDING) | 371 if (rv != net::ERR_IO_PENDING) |
| 353 OnCreateEntryComplete(rv); | 372 OnCreateEntryComplete(rv); |
| 354 } | 373 } |
| 355 | 374 |
| 356 void AppCacheResponseWriter::OnCreateEntryComplete(int rv) { | 375 void AppCacheResponseWriter::OnCreateEntryComplete(int rv) { |
| 357 DCHECK(info_buffer_.get() || buffer_.get()); | 376 DCHECK(info_buffer_.get() || buffer_.get()); |
| 358 | 377 |
| 359 if (creation_phase_ == INITIAL_ATTEMPT) { | 378 if (creation_phase_ == INITIAL_ATTEMPT) { |
| 360 if (rv != net::OK) { | 379 if (rv != net::OK) { |
| 361 // We may try to overwrite existing entries. | 380 // We may try to overwrite existing entries. |
| 362 creation_phase_ = DOOM_EXISTING; | 381 creation_phase_ = DOOM_EXISTING; |
| 363 rv = disk_cache_->DoomEntry(response_id_, create_callback_.get()); | 382 rv = disk_cache_->DoomEntry( |
| 383 response_id_, base::Bind(&net::OldCompletionCallbackAdapter, |
| 384 create_callback_)); |
| 364 if (rv != net::ERR_IO_PENDING) | 385 if (rv != net::ERR_IO_PENDING) |
| 365 OnCreateEntryComplete(rv); | 386 OnCreateEntryComplete(rv); |
| 366 return; | 387 return; |
| 367 } | 388 } |
| 368 } else if (creation_phase_ == DOOM_EXISTING) { | 389 } else if (creation_phase_ == DOOM_EXISTING) { |
| 369 creation_phase_ = SECOND_ATTEMPT; | 390 creation_phase_ = SECOND_ATTEMPT; |
| 370 rv = disk_cache_->CreateEntry(response_id_, &create_callback_->entry_ptr_, | 391 rv = disk_cache_->CreateEntry( |
| 371 create_callback_.get()); | 392 response_id_, &create_callback_->entry_ptr_, |
| 393 base::Bind(&net::OldCompletionCallbackAdapter, create_callback_)); |
| 372 if (rv != net::ERR_IO_PENDING) | 394 if (rv != net::ERR_IO_PENDING) |
| 373 OnCreateEntryComplete(rv); | 395 OnCreateEntryComplete(rv); |
| 374 return; | 396 return; |
| 375 } | 397 } |
| 376 | 398 |
| 377 if (create_callback_) { | 399 if (create_callback_) { |
| 378 if (rv == net::OK) { | 400 if (rv == net::OK) { |
| 379 entry_ = create_callback_->entry_ptr_; | 401 entry_ = create_callback_->entry_ptr_; |
| 380 create_callback_->entry_ptr_ = NULL; | 402 create_callback_->entry_ptr_ = NULL; |
| 381 } | 403 } |
| 382 create_callback_ = NULL; | 404 create_callback_ = NULL; |
| 383 } | 405 } |
| 384 | 406 |
| 385 if (info_buffer_) | 407 if (info_buffer_) |
| 386 ContinueWriteInfo(); | 408 ContinueWriteInfo(); |
| 387 else | 409 else |
| 388 ContinueWriteData(); | 410 ContinueWriteData(); |
| 389 } | 411 } |
| 390 | 412 |
| 391 } // namespace appcache | 413 } // namespace appcache |
| 392 | |
| OLD | NEW |