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/upload_data_stream_builder.h" 6 7 #include <algorithm> 8 9 #include "base/file_util.h" 10 #include "base/files/file_path.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop_proxy.h" 13 #include "base/time/time.h" 14 #include "net/base/upload_bytes_element_reader.h" 15 #include "net/base/upload_data_stream.h" 16 #include "net/base/upload_file_element_reader.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 #include "url/gurl.h" 19 #include "webkit/browser/blob/blob_storage_controller.h" 20 #include "webkit/common/resource_request_body.h" 21 22 using webkit_blob::BlobData; 23 using webkit_blob::BlobStorageController; 24 using webkit_glue::ResourceRequestBody; 25 26 namespace content { 27 namespace { 28 29 bool AreElementsEqual(const net::UploadElementReader& reader, 30 const ResourceRequestBody::Element& element) { 31 switch(element.type()) { 32 case ResourceRequestBody::Element::TYPE_BYTES: { 33 const net::UploadBytesElementReader* bytes_reader = 34 reader.AsBytesReader(); 35 return bytes_reader && 36 element.length() == bytes_reader->length() && 37 std::equal(element.bytes(), element.bytes() + element.length(), 38 bytes_reader->bytes()); 39 } 40 case ResourceRequestBody::Element::TYPE_FILE: { 41 const net::UploadFileElementReader* file_reader = reader.AsFileReader(); 42 return file_reader && 43 file_reader->path() == element.path() && 44 file_reader->range_offset() == element.offset() && 45 file_reader->range_length() == element.length() && 46 file_reader->expected_modification_time() == 47 element.expected_modification_time(); 48 break; 49 } 50 default: 51 NOTREACHED(); 52 } 53 return false; 54 } 55 56 } // namespace 57 58 TEST(UploadDataStreamBuilderTest, CreateUploadDataStreamWithoutBlob) { 59 base::MessageLoop message_loop; 60 scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; 61 62 const char kData[] = "123"; 63 const base::FilePath::StringType kFilePath = FILE_PATH_LITERAL("abc"); 64 const uint64 kFileOffset = 10U; 65 const uint64 kFileLength = 100U; 66 const base::Time kFileTime = base::Time::FromDoubleT(999); 67 const int64 kIdentifier = 12345; 68 69 request_body->AppendBytes(kData, arraysize(kData) - 1); 70 request_body->AppendFileRange(base::FilePath(kFilePath), 71 kFileOffset, kFileLength, kFileTime); 72 request_body->set_identifier(kIdentifier); 73 74 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( 75 request_body.get(), NULL, NULL, base::MessageLoopProxy::current().get())); 76 77 EXPECT_EQ(kIdentifier, upload->identifier()); 78 ASSERT_EQ(request_body->elements()->size(), upload->element_readers().size()); 79 80 const net::UploadBytesElementReader* r1 = 81 upload->element_readers()[0]->AsBytesReader(); 82 ASSERT_TRUE(r1); 83 EXPECT_EQ(kData, std::string(r1->bytes(), r1->length())); 84 85 const net::UploadFileElementReader* r2 = 86 upload->element_readers()[1]->AsFileReader(); 87 ASSERT_TRUE(r2); 88 EXPECT_EQ(kFilePath, r2->path().value()); 89 EXPECT_EQ(kFileOffset, r2->range_offset()); 90 EXPECT_EQ(kFileLength, r2->range_length()); 91 EXPECT_EQ(kFileTime, r2->expected_modification_time()); 92 } 93 94 TEST(UploadDataStreamBuilderTest, ResolveBlobAndCreateUploadDataStream) { 95 base::MessageLoop message_loop; 96 // Setup blob data for testing. 97 base::Time time1, time2; 98 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); 99 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); 100 101 BlobStorageController blob_storage_controller; 102 scoped_refptr<BlobData> blob_data(new BlobData()); 103 104 GURL blob_url0("blob://url_0"); 105 blob_storage_controller.AddFinishedBlob(blob_url0, blob_data.get()); 106 107 blob_data->AppendData("BlobData"); 108 blob_data->AppendFile( 109 base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1); 110 111 GURL blob_url1("blob://url_1"); 112 blob_storage_controller.AddFinishedBlob(blob_url1, blob_data.get()); 113 114 GURL blob_url2("blob://url_2"); 115 blob_storage_controller.CloneBlob(blob_url2, blob_url1); 116 117 GURL blob_url3("blob://url_3"); 118 blob_storage_controller.CloneBlob(blob_url3, blob_url2); 119 120 // Setup upload data elements for comparison. 121 ResourceRequestBody::Element blob_element1, blob_element2; 122 blob_element1.SetToBytes( 123 blob_data->items().at(0).bytes() + 124 static_cast<int>(blob_data->items().at(0).offset()), 125 static_cast<int>(blob_data->items().at(0).length())); 126 blob_element2.SetToFilePathRange( 127 blob_data->items().at(1).path(), 128 blob_data->items().at(1).offset(), 129 blob_data->items().at(1).length(), 130 blob_data->items().at(1).expected_modification_time()); 131 132 ResourceRequestBody::Element upload_element1, upload_element2; 133 upload_element1.SetToBytes("Hello", 5); 134 upload_element2.SetToFilePathRange( 135 base::FilePath(FILE_PATH_LITERAL("foo1.txt")), 0, 20, time2); 136 137 // Test no blob reference. 138 scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); 139 request_body->AppendBytes(upload_element1.bytes(), upload_element1.length()); 140 request_body->AppendFileRange(upload_element2.path(), 141 upload_element2.offset(), 142 upload_element2.length(), 143 upload_element2.expected_modification_time()); 144 145 scoped_ptr<net::UploadDataStream> upload( 146 UploadDataStreamBuilder::Build(request_body.get(), 147 &blob_storage_controller, 148 NULL, 149 base::MessageLoopProxy::current().get())); 150 151 ASSERT_EQ(2U, upload->element_readers().size()); 152 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1)); 153 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], upload_element2)); 154 155 // Test having only one blob reference that refers to empty blob data. 156 request_body = new ResourceRequestBody(); 157 request_body->AppendBlob(blob_url0); 158 159 upload = 160 UploadDataStreamBuilder::Build(request_body.get(), 161 &blob_storage_controller, 162 NULL, 163 base::MessageLoopProxy::current().get()); 164 ASSERT_EQ(0U, upload->element_readers().size()); 165 166 // Test having only one blob reference. 167 request_body = new ResourceRequestBody(); 168 request_body->AppendBlob(blob_url1); 169 170 upload = 171 UploadDataStreamBuilder::Build(request_body.get(), 172 &blob_storage_controller, 173 NULL, 174 base::MessageLoopProxy::current().get()); 175 ASSERT_EQ(2U, upload->element_readers().size()); 176 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1)); 177 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2)); 178 179 // Test having one blob reference at the beginning. 180 request_body = new ResourceRequestBody(); 181 request_body->AppendBlob(blob_url1); 182 request_body->AppendBytes(upload_element1.bytes(), upload_element1.length()); 183 request_body->AppendFileRange(upload_element2.path(), 184 upload_element2.offset(), 185 upload_element2.length(), 186 upload_element2.expected_modification_time()); 187 188 upload = 189 UploadDataStreamBuilder::Build(request_body.get(), 190 &blob_storage_controller, 191 NULL, 192 base::MessageLoopProxy::current().get()); 193 ASSERT_EQ(4U, upload->element_readers().size()); 194 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1)); 195 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2)); 196 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], upload_element1)); 197 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], upload_element2)); 198 199 // Test having one blob reference at the end. 200 request_body = new ResourceRequestBody(); 201 request_body->AppendBytes(upload_element1.bytes(), upload_element1.length()); 202 request_body->AppendFileRange(upload_element2.path(), 203 upload_element2.offset(), 204 upload_element2.length(), 205 upload_element2.expected_modification_time()); 206 request_body->AppendBlob(blob_url1); 207 208 upload = 209 UploadDataStreamBuilder::Build(request_body.get(), 210 &blob_storage_controller, 211 NULL, 212 base::MessageLoopProxy::current().get()); 213 ASSERT_EQ(4U, upload->element_readers().size()); 214 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1)); 215 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], upload_element2)); 216 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], blob_element1)); 217 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], blob_element2)); 218 219 // Test having one blob reference in the middle. 220 request_body = new ResourceRequestBody(); 221 request_body->AppendBytes(upload_element1.bytes(), upload_element1.length()); 222 request_body->AppendBlob(blob_url1); 223 request_body->AppendFileRange(upload_element2.path(), 224 upload_element2.offset(), 225 upload_element2.length(), 226 upload_element2.expected_modification_time()); 227 228 upload = 229 UploadDataStreamBuilder::Build(request_body.get(), 230 &blob_storage_controller, 231 NULL, 232 base::MessageLoopProxy::current().get()); 233 ASSERT_EQ(4U, upload->element_readers().size()); 234 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1)); 235 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element1)); 236 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], blob_element2)); 237 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], upload_element2)); 238 239 // Test having multiple blob references. 240 request_body = new ResourceRequestBody(); 241 request_body->AppendBlob(blob_url1); 242 request_body->AppendBytes(upload_element1.bytes(), upload_element1.length()); 243 request_body->AppendBlob(blob_url2); 244 request_body->AppendBlob(blob_url3); 245 request_body->AppendFileRange(upload_element2.path(), 246 upload_element2.offset(), 247 upload_element2.length(), 248 upload_element2.expected_modification_time()); 249 250 upload = 251 UploadDataStreamBuilder::Build(request_body.get(), 252 &blob_storage_controller, 253 NULL, 254 base::MessageLoopProxy::current().get()); 255 ASSERT_EQ(8U, upload->element_readers().size()); 256 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1)); 257 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2)); 258 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], upload_element1)); 259 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], blob_element1)); 260 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[4], blob_element2)); 261 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[5], blob_element1)); 262 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[6], blob_element2)); 263 EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[7], upload_element2)); 264 } 265 266 } // namespace content 267