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

Side by Side Diff: net/http/http_stream_parser_unittest.cc

Issue 1314783007: Added and implemented HttpStream::GetTotalSentBytes for basic streams. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "net/http/http_stream_parser.h" 5 #include "net/http/http_stream_parser.h"
6 6
7 #include <stdint.h>
8
7 #include <algorithm> 9 #include <algorithm>
8 #include <string> 10 #include <string>
9 #include <vector> 11 #include <vector>
10 12
11 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
12 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h" 15 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/ref_counted.h" 16 #include "base/memory/ref_counted.h"
15 #include "base/run_loop.h" 17 #include "base/run_loop.h"
16 #include "base/strings/string_piece.h" 18 #include "base/strings/string_piece.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 data->set_socket(socket.get()); 54 data->set_socket(socket.get());
53 55
54 TestCompletionCallback callback; 56 TestCompletionCallback callback;
55 EXPECT_EQ(OK, socket->Connect(callback.callback())); 57 EXPECT_EQ(OK, socket->Connect(callback.callback()));
56 58
57 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle); 59 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle);
58 socket_handle->SetSocket(socket.Pass()); 60 socket_handle->SetSocket(socket.Pass());
59 return socket_handle.Pass(); 61 return socket_handle.Pass();
60 } 62 }
61 63
64 // Helper method to get the total data size of the MockWrites in |writes|.
65 int64_t WritesSize(const MockWrite writes[], size_t length) {
mmenke 2015/08/31 22:23:13 Suggest calling this CountWriteBytes. WriteBytes
mmenke 2015/08/31 22:23:13 Maybe make this part of SequencedSocketData instea
sclittle 2015/09/01 01:21:48 OK, I've created CountReadBytes and CountWriteByte
mmenke 2015/09/01 17:39:43 I actually disagree here - seems like a utility fu
sclittle 2015/09/01 20:03:00 Often the length is necessary - a single SocketDat
66 int64_t total = 0;
67 for (const MockWrite* write = writes; write != writes + length; ++write) {
68 total += write->data_len;
69 }
70 return total;
71 }
72
62 // The empty payload is how the last chunk is encoded. 73 // The empty payload is how the last chunk is encoded.
63 TEST(HttpStreamParser, EncodeChunk_EmptyPayload) { 74 TEST(HttpStreamParser, EncodeChunk_EmptyPayload) {
64 char output[kOutputSize]; 75 char output[kOutputSize];
65 76
66 const base::StringPiece kPayload = ""; 77 const base::StringPiece kPayload = "";
67 const base::StringPiece kExpected = "0\r\n\r\n"; 78 const base::StringPiece kExpected = "0\r\n\r\n";
68 const int num_bytes_written = 79 const int num_bytes_written =
69 HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output)); 80 HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output));
70 ASSERT_EQ(kExpected.size(), static_cast<size_t>(num_bytes_written)); 81 ASSERT_EQ(kExpected.size(), static_cast<size_t>(num_bytes_written));
71 EXPECT_EQ(kExpected, base::StringPiece(output, num_bytes_written)); 82 EXPECT_EQ(kExpected, base::StringPiece(output, num_bytes_written));
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 get_runner.ReadHeaders(); 1009 get_runner.ReadHeaders();
999 EXPECT_EQ(200, get_runner.response_info()->headers->response_code()); 1010 EXPECT_EQ(200, get_runner.response_info()->headers->response_code());
1000 EXPECT_EQ(headers_size, get_runner.parser()->received_bytes()); 1011 EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
1001 int64 response_size = headers_size + body.size(); 1012 int64 response_size = headers_size + body.size();
1002 int body_size = body.size(); 1013 int body_size = body.size();
1003 int read_lengths[] = {body_size, 0}; 1014 int read_lengths[] = {body_size, 0};
1004 get_runner.ReadBody(body_size, read_lengths); 1015 get_runner.ReadBody(body_size, read_lengths);
1005 EXPECT_EQ(response_size, get_runner.parser()->received_bytes()); 1016 EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
1006 } 1017 }
1007 1018
1019 TEST(HttpStreamParser, SentBytesNoHeaders) {
1020 MockWrite writes[] = {
1021 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"),
1022 };
1023
1024 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
1025 scoped_ptr<ClientSocketHandle> socket_handle =
1026 CreateConnectedSocketHandle(&data);
1027
1028 HttpRequestInfo request;
1029 request.method = "GET";
1030 request.url = GURL("http://localhost");
1031
1032 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
1033 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
1034 BoundNetLog());
1035
1036 HttpResponseInfo response;
1037 TestCompletionCallback callback;
1038 ASSERT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", HttpRequestHeaders(),
mmenke 2015/08/31 22:23:13 These should probably just be EXPECTs - at least t
sclittle 2015/09/01 01:21:48 Done.
1039 &response, callback.callback()));
1040
1041 EXPECT_EQ(WritesSize(writes, arraysize(writes)), parser.sent_bytes());
1042 }
1043
1044 TEST(HttpStreamParser, SentBytesWithHeaders) {
1045 MockWrite writes[] = {
1046 MockWrite(SYNCHRONOUS, 0,
1047 "GET / HTTP/1.1\r\n"
1048 "Host: localhost\r\n"
1049 "Connection: Keep-Alive\r\n\r\n"),
1050 };
1051
1052 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
1053 scoped_ptr<ClientSocketHandle> socket_handle =
1054 CreateConnectedSocketHandle(&data);
1055
1056 HttpRequestInfo request;
1057 request.method = "GET";
1058 request.url = GURL("http://localhost");
1059
1060 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
1061 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
1062 BoundNetLog());
1063
1064 HttpRequestHeaders headers;
1065 headers.SetHeader("Host", "localhost");
1066 headers.SetHeader("Connection", "Keep-Alive");
1067
1068 HttpResponseInfo response;
1069 TestCompletionCallback callback;
1070 ASSERT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
1071 callback.callback()));
1072
1073 EXPECT_EQ(WritesSize(writes, arraysize(writes)), parser.sent_bytes());
1074 }
1075
1076 TEST(HttpStreamParser, SentBytesWithHeadersMultiWrite) {
1077 MockWrite writes[] = {
1078 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
1079 MockWrite(SYNCHRONOUS, 1, "Host: localhost\r\n"),
1080 MockWrite(SYNCHRONOUS, 2, "Connection: Keep-Alive\r\n\r\n"),
1081 };
1082
1083 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
1084 scoped_ptr<ClientSocketHandle> socket_handle =
1085 CreateConnectedSocketHandle(&data);
1086
1087 HttpRequestInfo request;
1088 request.method = "GET";
1089 request.url = GURL("http://localhost");
1090
1091 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
1092 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
1093 BoundNetLog());
1094
1095 HttpRequestHeaders headers;
1096 headers.SetHeader("Host", "localhost");
1097 headers.SetHeader("Connection", "Keep-Alive");
1098
1099 HttpResponseInfo response;
1100 TestCompletionCallback callback;
1101
1102 int rv = parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
1103 callback.callback());
1104 ASSERT_EQ(OK, rv);
1105
1106 EXPECT_EQ(WritesSize(writes, arraysize(writes)), parser.sent_bytes());
1107 }
1108
1109 TEST(HttpStreamParser, SentBytesWithErrorWritingHeaders) {
1110 MockWrite writes[] = {
1111 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
1112 MockWrite(SYNCHRONOUS, 1, "Host: localhost\r\n"),
1113 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 2),
1114 };
1115
1116 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
1117 scoped_ptr<ClientSocketHandle> socket_handle =
1118 CreateConnectedSocketHandle(&data);
1119
1120 HttpRequestInfo request;
1121 request.method = "GET";
1122 request.url = GURL("http://localhost");
1123
1124 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
1125 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
1126 BoundNetLog());
1127
1128 HttpRequestHeaders headers;
1129 headers.SetHeader("Host", "localhost");
1130 headers.SetHeader("Connection", "Keep-Alive");
1131
1132 HttpResponseInfo response;
1133 TestCompletionCallback callback;
1134 ASSERT_EQ(ERR_CONNECTION_RESET,
1135 parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
1136 callback.callback()));
1137
1138 EXPECT_EQ(WritesSize(writes, arraysize(writes)), parser.sent_bytes());
1139 }
1140
1141 TEST(HttpStreamParser, SentBytesPost) {
1142 MockWrite writes[] = {
1143 MockWrite(SYNCHRONOUS, 0, "POST / HTTP/1.1\r\n"),
1144 MockWrite(SYNCHRONOUS, 1, "Content-Length: 12\r\n\r\n"),
1145 MockWrite(SYNCHRONOUS, 2, "hello world!"),
1146 };
1147
1148 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
1149 scoped_ptr<ClientSocketHandle> socket_handle =
1150 CreateConnectedSocketHandle(&data);
1151
1152 ScopedVector<UploadElementReader> element_readers;
1153 element_readers.push_back(new UploadBytesElementReader("hello world!", 12));
1154 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
1155 ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
1156
1157 HttpRequestInfo request;
1158 request.method = "POST";
1159 request.url = GURL("http://localhost");
1160 request.upload_data_stream = &upload_data_stream;
1161
1162 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
1163 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
1164 BoundNetLog());
1165
1166 HttpRequestHeaders headers;
1167 headers.SetHeader("Content-Length", "12");
1168
1169 HttpResponseInfo response;
1170 TestCompletionCallback callback;
1171 ASSERT_EQ(OK, parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response,
1172 callback.callback()));
1173
1174 EXPECT_EQ(WritesSize(writes, arraysize(writes)), parser.sent_bytes());
1175 }
1176
1177 TEST(HttpStreamParser, SentBytesChunkedPost) {
mmenke 2015/08/31 22:23:13 Rather than duplicate some of these larger tests,
sclittle 2015/09/01 01:21:47 Done.
1178 static const char kChunk1[] = "Chunk 1";
1179 static const char kChunk2[] = "Chunky 2";
1180 static const char kChunk3[] = "Test 3";
1181
1182 MockWrite writes[] = {
1183 MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"),
1184 MockWrite(ASYNC, 1, "Transfer-Encoding: chunked\r\n\r\n"),
1185 MockWrite(ASYNC, 2, "7\r\nChunk 1\r\n"),
1186 MockWrite(ASYNC, 3, "8\r\nChunky 2\r\n"),
1187 MockWrite(ASYNC, 4, "6\r\nTest 3\r\n"),
1188 MockWrite(ASYNC, 5, "0\r\n\r\n"),
1189 };
1190
1191 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
1192 scoped_ptr<ClientSocketHandle> socket_handle =
1193 CreateConnectedSocketHandle(&data);
1194
1195 ChunkedUploadDataStream upload_data_stream(0);
1196 ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
1197
1198 HttpRequestInfo request;
1199 request.method = "POST";
1200 request.url = GURL("http://localhost");
1201 request.upload_data_stream = &upload_data_stream;
1202
1203 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
1204 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
1205 BoundNetLog());
1206
1207 HttpRequestHeaders headers;
1208 headers.SetHeader("Transfer-Encoding", "chunked");
1209
1210 HttpResponseInfo response;
1211 TestCompletionCallback callback;
1212 ASSERT_EQ(ERR_IO_PENDING, parser.SendRequest("POST / HTTP/1.1\r\n", headers,
1213 &response, callback.callback()));
1214
1215 base::RunLoop().RunUntilIdle();
1216 upload_data_stream.AppendData(kChunk1, arraysize(kChunk1) - 1, false);
1217
1218 base::RunLoop().RunUntilIdle();
1219 upload_data_stream.AppendData(kChunk2, arraysize(kChunk2) - 1, false);
1220
1221 base::RunLoop().RunUntilIdle();
1222 upload_data_stream.AppendData(kChunk3, arraysize(kChunk3) - 1, true);
1223
1224 ASSERT_EQ(OK, callback.WaitForResult());
1225
1226 EXPECT_EQ(WritesSize(writes, arraysize(writes)), parser.sent_bytes());
1227 }
1228
1229 TEST(HttpStreamParser, SentBytesChunkedPostError) {
1230 static const char kChunk[] = "Chunk 1";
1231
1232 MockWrite writes[] = {
1233 MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"),
1234 MockWrite(ASYNC, 1, "Transfer-Encoding: chunked\r\n\r\n"),
1235 MockWrite(ASYNC, 2, "7\r\nChunk 1\r\n"),
1236 MockWrite(SYNCHRONOUS, ERR_FAILED, 3),
1237 };
1238
1239 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
1240 scoped_ptr<ClientSocketHandle> socket_handle =
1241 CreateConnectedSocketHandle(&data);
1242
1243 ChunkedUploadDataStream upload_data_stream(0);
1244 ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
1245
1246 HttpRequestInfo request;
1247 request.method = "POST";
1248 request.url = GURL("http://localhost");
1249 request.upload_data_stream = &upload_data_stream;
1250
1251 scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
1252 HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
1253 BoundNetLog());
1254
1255 HttpRequestHeaders headers;
1256 headers.SetHeader("Transfer-Encoding", "chunked");
1257
1258 HttpResponseInfo response;
1259 TestCompletionCallback callback;
1260 ASSERT_EQ(ERR_IO_PENDING, parser.SendRequest("POST / HTTP/1.1\r\n", headers,
1261 &response, callback.callback()));
1262
1263 base::RunLoop().RunUntilIdle();
1264 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false);
1265
1266 base::RunLoop().RunUntilIdle();
1267 // This write should fail.
1268 upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false);
1269 ASSERT_EQ(ERR_FAILED, callback.WaitForResult());
1270
1271 EXPECT_EQ(WritesSize(writes, arraysize(writes)), parser.sent_bytes());
1272 }
1273
1008 // Test that an HttpStreamParser can be read from after it's received headers 1274 // Test that an HttpStreamParser can be read from after it's received headers
1009 // and data structures owned by its owner have been deleted. This happens 1275 // and data structures owned by its owner have been deleted. This happens
1010 // when a ResponseBodyDrainer is used. 1276 // when a ResponseBodyDrainer is used.
1011 TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) { 1277 TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) {
1012 MockWrite writes[] = { 1278 MockWrite writes[] = {
1013 MockWrite(SYNCHRONOUS, 0, 1279 MockWrite(SYNCHRONOUS, 0,
1014 "GET /foo.html HTTP/1.1\r\n\r\n"), 1280 "GET /foo.html HTTP/1.1\r\n\r\n"),
1015 }; 1281 };
1016 1282
1017 const int kBodySize = 1; 1283 const int kBodySize = 1;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 response_info.reset(); 1315 response_info.reset();
1050 1316
1051 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize)); 1317 scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
1052 ASSERT_EQ(kBodySize, parser.ReadResponseBody( 1318 ASSERT_EQ(kBodySize, parser.ReadResponseBody(
1053 body_buffer.get(), kBodySize, callback.callback())); 1319 body_buffer.get(), kBodySize, callback.callback()));
1054 } 1320 }
1055 1321
1056 } // namespace 1322 } // namespace
1057 1323
1058 } // namespace net 1324 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698