upload_data_stream.cc revision a01ff25d304217e7ef77ad2d83f48aca73be2c9d
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/upload_data_stream.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/file_stream.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/io_buffer.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochUploadDataStream* UploadDataStream::Create(UploadData* data, int* error_code) { 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<UploadDataStream> stream(new UploadDataStream(data)); 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = stream->FillBuf(); 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (error_code) 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *error_code = rv; 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv != OK) 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return stream.release(); 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochUploadDataStream::UploadDataStream(UploadData* data) 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : data_(data), 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf_(new IOBuffer(kBufSize)), 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf_len_(0), 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_element_(data->elements()->begin()), 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_element_offset_(0), 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_element_remaining_(0), 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott total_size_(data->GetContentLength()), 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_position_(0), 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eof_(false) { 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottUploadDataStream::~UploadDataStream() { 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid UploadDataStream::DidConsume(size_t num_bytes) { 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_LE(num_bytes, buf_len_); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!eof_); 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf_len_ -= num_bytes; 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (buf_len_) 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memmove(buf_->data(), buf_->data() + num_bytes, buf_len_); 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FillBuf(); 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott current_position_ += num_bytes; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint UploadDataStream::FillBuf() { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<UploadData::Element>::iterator end = 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_->elements()->end(); 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (buf_len_ < kBufSize && next_element_ != end) { 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool advance_to_next_element = false; 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UploadData::Element& element = *next_element_; 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t size_remaining = kBufSize - buf_len_; 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (element.type() == UploadData::TYPE_BYTES) { 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::vector<char>& d = element.bytes(); 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t count = d.size() - next_element_offset_; 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t bytes_copied = std::min(count, size_remaining); 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(buf_->data() + buf_len_, &d[next_element_offset_], bytes_copied); 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf_len_ += bytes_copied; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (bytes_copied == count) { 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott advance_to_next_element = true; 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_element_offset_ += bytes_copied; 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(element.type() == UploadData::TYPE_FILE); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!next_element_remaining_) { 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the underlying file has been changed, treat it as error. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that the expected modification time from WebKit is based on 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // time_t precision. So we have to convert both to time_t to compare. 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!element.expected_file_modification_time().is_null()) { 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::PlatformFileInfo info; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (file_util::GetFileInfo(element.file_path(), &info) && 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch element.expected_file_modification_time().ToTimeT() != 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch info.last_modified.ToTimeT()) { 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ERR_UPLOAD_FILE_CHANGED; 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_element_remaining_ = element.GetContentLength(); 9469dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#ifdef ANDROID 9569dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen if (element.file_path().value().find("content://") == 0) { 9669dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen next_element_java_stream_.reset( 97a01ff25d304217e7ef77ad2d83f48aca73be2c9dKristian Monsen new android::JavaISWrapper(element.file_path())); 9869dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen } else 9969dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#endif 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_element_stream_.reset(element.NewFileStreamForReading()); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = 0; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int count = 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(std::min(next_element_remaining_, 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<uint64>(size_remaining))); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (count > 0) { 10869dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#ifdef ANDROID 10969dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen if (next_element_java_stream_.get()) 11069dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen rv = next_element_java_stream_->Read(buf_->data() + buf_len_, count); 11169dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen else { 11269dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#endif 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (next_element_stream_.get()) 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = next_element_stream_->Read(buf_->data() + buf_len_, count, NULL); 11569dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#ifdef ANDROID 11669dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen } 11769dbe9fcda26341f31379053f8123d7f611c0be1Kristian Monsen#endif 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv <= 0) { 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If there's less data to read than we initially observed, then 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pad with zero. Otherwise the server will hang waiting for the 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // rest of the data. 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch memset(buf_->data() + buf_len_, 0, count); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = count; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf_len_ += rv; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (static_cast<int>(next_element_remaining_) == rv) { 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott advance_to_next_element = true; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_element_remaining_ -= rv; 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (advance_to_next_element) { 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++next_element_; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_element_offset_ = 0; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_element_remaining_ = 0; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_element_stream_.reset(); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (next_element_ == end && !buf_len_) 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eof_ = true; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return OK; 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 150