| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <math.h> // ceil | 5 #include <math.h> // ceil |
| 6 #include "base/compiler_specific.h" | 6 #include "base/compiler_specific.h" |
| 7 #include "base/platform_test.h" | 7 #include "base/platform_test.h" |
| 8 #include "net/base/client_socket_factory.h" | 8 #include "net/base/client_socket_factory.h" |
| 9 #include "net/base/test_completion_callback.h" | 9 #include "net/base/test_completion_callback.h" |
| 10 #include "net/base/upload_data.h" | 10 #include "net/base/upload_data.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 bool async; | 25 bool async; |
| 26 int result; | 26 int result; |
| 27 }; | 27 }; |
| 28 | 28 |
| 29 struct MockRead { | 29 struct MockRead { |
| 30 // Read failure (no data). | 30 // Read failure (no data). |
| 31 MockRead(bool async, int result) : async(async) , result(result), data(NULL), | 31 MockRead(bool async, int result) : async(async) , result(result), data(NULL), |
| 32 data_len(0) { } | 32 data_len(0) { } |
| 33 | 33 |
| 34 // Asynchronous read success (inferred data length). | 34 // Asynchronous read success (inferred data length). |
| 35 MockRead(const char* data) : async(true), result(0), data(data), | 35 explicit MockRead(const char* data) : async(true), result(0), data(data), |
| 36 data_len(strlen(data)) { } | 36 data_len(strlen(data)) { } |
| 37 | 37 |
| 38 // Read success (inferred data length). | 38 // Read success (inferred data length). |
| 39 MockRead(bool async, const char* data) : async(async), result(0), data(data), | 39 MockRead(bool async, const char* data) : async(async), result(0), data(data), |
| 40 data_len(strlen(data)) { } | 40 data_len(strlen(data)) { } |
| 41 | 41 |
| 42 // Read success. | 42 // Read success. |
| 43 MockRead(bool async, const char* data, int data_len) : async(async), | 43 MockRead(bool async, const char* data, int data_len) : async(async), |
| 44 result(0), data(data), data_len(data_len) { } | 44 result(0), data(data), data_len(data_len) { } |
| 45 | 45 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 69 // Tests should assign the first N entries of mock_sockets to point to valid | 69 // Tests should assign the first N entries of mock_sockets to point to valid |
| 70 // MockSocket objects. The first unused entry should be NULL'd. | 70 // MockSocket objects. The first unused entry should be NULL'd. |
| 71 // | 71 // |
| 72 MockSocket* mock_sockets[10]; | 72 MockSocket* mock_sockets[10]; |
| 73 | 73 |
| 74 // Index of the next mock_sockets element to use. | 74 // Index of the next mock_sockets element to use. |
| 75 int mock_sockets_index; | 75 int mock_sockets_index; |
| 76 | 76 |
| 77 class MockTCPClientSocket : public net::ClientSocket { | 77 class MockTCPClientSocket : public net::ClientSocket { |
| 78 public: | 78 public: |
| 79 MockTCPClientSocket(const net::AddressList& addresses) | 79 explicit MockTCPClientSocket(const net::AddressList& addresses) |
| 80 : data_(mock_sockets[mock_sockets_index++]), | 80 : data_(mock_sockets[mock_sockets_index++]), |
| 81 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 81 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
| 82 callback_(NULL), | 82 callback_(NULL), |
| 83 read_index_(0), | 83 read_index_(0), |
| 84 read_offset_(0), | 84 read_offset_(0), |
| 85 write_index_(0), | 85 write_index_(0), |
| 86 connected_(false) { | 86 connected_(false) { |
| 87 DCHECK(data_) << "overran mock_sockets array"; | 87 DCHECK(data_) << "overran mock_sockets array"; |
| 88 } | 88 } |
| 89 // ClientSocket methods: | 89 // ClientSocket methods: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 } | 128 } |
| 129 } | 129 } |
| 130 if (r.async) { | 130 if (r.async) { |
| 131 RunCallbackAsync(callback, result); | 131 RunCallbackAsync(callback, result); |
| 132 return net::ERR_IO_PENDING; | 132 return net::ERR_IO_PENDING; |
| 133 } | 133 } |
| 134 return result; | 134 return result; |
| 135 } | 135 } |
| 136 virtual int Write(const char* buf, int buf_len, | 136 virtual int Write(const char* buf, int buf_len, |
| 137 net::CompletionCallback* callback) { | 137 net::CompletionCallback* callback) { |
| 138 DCHECK(buf); |
| 139 DCHECK(buf_len > 0); |
| 138 DCHECK(!callback_); | 140 DCHECK(!callback_); |
| 139 // Not using mock writes; succeed synchronously. | 141 // Not using mock writes; succeed synchronously. |
| 140 if (!data_->writes) | 142 if (!data_->writes) |
| 141 return buf_len; | 143 return buf_len; |
| 142 | 144 |
| 143 // Check that what we are writing matches the expectation. | 145 // Check that what we are writing matches the expectation. |
| 144 // Then give the mocked return value. | 146 // Then give the mocked return value. |
| 145 MockWrite& w = data_->writes[write_index_]; | 147 MockWrite& w = data_->writes[write_index_++]; |
| 146 int result = w.result; | 148 int result = w.result; |
| 147 if (w.data) { | 149 if (w.data) { |
| 148 std::string expected_data(w.data, w.data_len); | 150 std::string expected_data(w.data, w.data_len); |
| 149 std::string actual_data(buf, buf_len); | 151 std::string actual_data(buf, buf_len); |
| 150 EXPECT_EQ(expected_data, actual_data); | 152 EXPECT_EQ(expected_data, actual_data); |
| 151 if (expected_data != actual_data) | 153 if (expected_data != actual_data) |
| 152 return net::ERR_UNEXPECTED; | 154 return net::ERR_UNEXPECTED; |
| 153 if (result == net::OK) | 155 if (result == net::OK) |
| 154 result = w.data_len; | 156 result = w.data_len; |
| 155 } | 157 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 // Fill |str| with a long header list that consumes >= |size| bytes. | 274 // Fill |str| with a long header list that consumes >= |size| bytes. |
| 273 void FillLargeHeadersString(std::string* str, int size) { | 275 void FillLargeHeadersString(std::string* str, int size) { |
| 274 const char* row = | 276 const char* row = |
| 275 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"; | 277 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n"; |
| 276 const int sizeof_row = strlen(row); | 278 const int sizeof_row = strlen(row); |
| 277 const int num_rows = static_cast<int>( | 279 const int num_rows = static_cast<int>( |
| 278 ceil(static_cast<float>(size) / sizeof_row)); | 280 ceil(static_cast<float>(size) / sizeof_row)); |
| 279 const int sizeof_data = num_rows * sizeof_row; | 281 const int sizeof_data = num_rows * sizeof_row; |
| 280 DCHECK(sizeof_data >= size); | 282 DCHECK(sizeof_data >= size); |
| 281 str->reserve(sizeof_data); | 283 str->reserve(sizeof_data); |
| 282 | 284 |
| 283 for (int i = 0; i < num_rows; ++i) | 285 for (int i = 0; i < num_rows; ++i) |
| 284 str->append(row, sizeof_row); | 286 str->append(row, sizeof_row); |
| 285 } | 287 } |
| 286 | 288 |
| 287 //----------------------------------------------------------------------------- | 289 //----------------------------------------------------------------------------- |
| 288 | 290 |
| 289 TEST_F(HttpNetworkTransactionTest, Basic) { | 291 TEST_F(HttpNetworkTransactionTest, Basic) { |
| 290 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( | 292 scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction( |
| 291 CreateSession(), &mock_socket_factory)); | 293 CreateSession(), &mock_socket_factory)); |
| 292 } | 294 } |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 rv = ReadTransaction(trans.get(), &response_data); | 921 rv = ReadTransaction(trans.get(), &response_data); |
| 920 EXPECT_STREQ("0123456789", response_data.c_str()); | 922 EXPECT_STREQ("0123456789", response_data.c_str()); |
| 921 | 923 |
| 922 // We now check to make sure the TCPClientSocket was not added back to | 924 // We now check to make sure the TCPClientSocket was not added back to |
| 923 // the pool. | 925 // the pool. |
| 924 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); | 926 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); |
| 925 trans.reset(); | 927 trans.reset(); |
| 926 // Make sure that the socket didn't get recycled after calling the destructor. | 928 // Make sure that the socket didn't get recycled after calling the destructor. |
| 927 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); | 929 EXPECT_EQ(0, session->connection_pool()->idle_socket_count()); |
| 928 } | 930 } |
| 931 |
| 932 TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) { |
| 933 net::HttpRequestInfo request[2]; |
| 934 // Transaction 1: a GET request that succeeds. The socket is recycled |
| 935 // after use. |
| 936 request[0].method = "GET"; |
| 937 request[0].url = GURL("http://www.google.com/"); |
| 938 request[0].load_flags = 0; |
| 939 // Transaction 2: a POST request. Reuses the socket kept alive from |
| 940 // transaction 1. The first attempts fails when writing the POST data. |
| 941 // This causes the transaction to retry with a new socket. The second |
| 942 // attempt succeeds. |
| 943 request[1].method = "POST"; |
| 944 request[1].url = GURL("http://www.google.com/login.cgi"); |
| 945 request[1].upload_data = new net::UploadData; |
| 946 request[1].upload_data->AppendBytes("foo", 3); |
| 947 request[1].load_flags = 0; |
| 948 |
| 949 scoped_refptr<net::HttpNetworkSession> session = CreateSession(); |
| 950 |
| 951 // The first socket is used for transaction 1 and the first attempt of |
| 952 // transaction 2. |
| 953 |
| 954 // The response of transaction 1. |
| 955 MockRead data_reads1[] = { |
| 956 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"), |
| 957 MockRead("hello world"), |
| 958 MockRead(false, net::OK), |
| 959 }; |
| 960 // The mock write results of transaction 1 and the first attempt of |
| 961 // transaction 2. |
| 962 MockWrite data_writes1[] = { |
| 963 MockWrite(false, 64), // GET |
| 964 MockWrite(false, 93), // POST |
| 965 MockWrite(false, net::ERR_CONNECTION_ABORTED), // POST data |
| 966 }; |
| 967 MockSocket data1; |
| 968 data1.reads = data_reads1; |
| 969 data1.writes = data_writes1; |
| 970 |
| 971 // The second socket is used for the second attempt of transaction 2. |
| 972 |
| 973 // The response of transaction 2. |
| 974 MockRead data_reads2[] = { |
| 975 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"), |
| 976 MockRead("welcome"), |
| 977 MockRead(false, net::OK), |
| 978 }; |
| 979 // The mock write results of the second attempt of transaction 2. |
| 980 MockWrite data_writes2[] = { |
| 981 MockWrite(false, 93), // POST |
| 982 MockWrite(false, 3), // POST data |
| 983 }; |
| 984 MockSocket data2; |
| 985 data2.reads = data_reads2; |
| 986 data2.writes = data_writes2; |
| 987 |
| 988 mock_sockets[0] = &data1; |
| 989 mock_sockets[1] = &data2; |
| 990 mock_sockets[2] = NULL; |
| 991 |
| 992 const char* kExpectedResponseData[] = { |
| 993 "hello world", "welcome" |
| 994 }; |
| 995 |
| 996 for (int i = 0; i < 2; ++i) { |
| 997 scoped_ptr<net::HttpTransaction> trans( |
| 998 new net::HttpNetworkTransaction(session, &mock_socket_factory)); |
| 999 |
| 1000 TestCompletionCallback callback; |
| 1001 |
| 1002 int rv = trans->Start(&request[i], &callback); |
| 1003 EXPECT_EQ(net::ERR_IO_PENDING, rv); |
| 1004 |
| 1005 rv = callback.WaitForResult(); |
| 1006 EXPECT_EQ(net::OK, rv); |
| 1007 |
| 1008 const net::HttpResponseInfo* response = trans->GetResponseInfo(); |
| 1009 EXPECT_TRUE(response != NULL); |
| 1010 |
| 1011 EXPECT_TRUE(response->headers != NULL); |
| 1012 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
| 1013 |
| 1014 std::string response_data; |
| 1015 rv = ReadTransaction(trans.get(), &response_data); |
| 1016 EXPECT_EQ(net::OK, rv); |
| 1017 EXPECT_EQ(kExpectedResponseData[i], response_data); |
| 1018 } |
| 1019 } |
| OLD | NEW |