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

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

Issue 2545213002: Refactor Content-Range response header parsing into http_util (Closed)
Patch Set: Addressed mmenke comment Created 4 years 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
« no previous file with comments | « no previous file | net/http/http_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // The rules for header parsing were borrowed from Firefox: 5 // The rules for header parsing were borrowed from Firefox:
6 // http://lxr.mozilla.org/seamonkey/source/netwerk/protocol/http/src/nsHttpRespo nseHead.cpp 6 // http://lxr.mozilla.org/seamonkey/source/netwerk/protocol/http/src/nsHttpRespo nseHead.cpp
7 // The rules for parsing content-types were also borrowed from Firefox: 7 // The rules for parsing content-types were also borrowed from Firefox:
8 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 8 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834
9 9
10 #include "net/http/http_response_headers.h" 10 #include "net/http/http_response_headers.h"
(...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 return -1; 1296 return -1;
1297 1297
1298 int64_t result; 1298 int64_t result;
1299 bool ok = base::StringToInt64(content_length_val, &result); 1299 bool ok = base::StringToInt64(content_length_val, &result);
1300 if (!ok || result < 0) 1300 if (!ok || result < 0)
1301 return -1; 1301 return -1;
1302 1302
1303 return result; 1303 return result;
1304 } 1304 }
1305 1305
1306 // From RFC 2616 14.16:
1307 // content-range-spec =
1308 // bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" )
1309 // byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*"
1310 // instance-length = 1*DIGIT
1311 // bytes-unit = "bytes"
1312 bool HttpResponseHeaders::GetContentRange(int64_t* first_byte_position, 1306 bool HttpResponseHeaders::GetContentRange(int64_t* first_byte_position,
1313 int64_t* last_byte_position, 1307 int64_t* last_byte_position,
1314 int64_t* instance_length) const { 1308 int64_t* instance_length) const {
1315 size_t iter = 0; 1309 size_t iter = 0;
1316 std::string content_range_spec; 1310 std::string content_range_spec;
1317 *first_byte_position = *last_byte_position = *instance_length = -1; 1311 if (!EnumerateHeader(&iter, kContentRange, &content_range_spec)) {
1318 if (!EnumerateHeader(&iter, kContentRange, &content_range_spec)) 1312 *first_byte_position = *last_byte_position = *instance_length = -1;
1319 return false;
1320
1321 // If the header value is empty, we have an invalid header.
1322 if (content_range_spec.empty())
1323 return false;
1324
1325 size_t space_position = content_range_spec.find(' ');
1326 if (space_position == std::string::npos)
1327 return false;
1328
1329 // Invalid header if it doesn't contain "bytes-unit".
1330 std::string::const_iterator content_range_spec_begin =
1331 content_range_spec.begin();
1332 std::string::const_iterator content_range_spec_end =
1333 content_range_spec.begin() + space_position;
1334 HttpUtil::TrimLWS(&content_range_spec_begin, &content_range_spec_end);
1335 if (!base::LowerCaseEqualsASCII(
1336 base::StringPiece(content_range_spec_begin, content_range_spec_end),
1337 "bytes")) {
1338 return false; 1313 return false;
1339 } 1314 }
1340 1315
1341 size_t slash_position = content_range_spec.find('/', space_position + 1); 1316 return HttpUtil::ParseContentRangeHeader(content_range_spec,
1342 if (slash_position == std::string::npos) 1317 first_byte_position,
1343 return false; 1318 last_byte_position, instance_length);
1344
1345 // Obtain the part behind the space and before slash.
1346 std::string::const_iterator byte_range_resp_spec_begin =
1347 content_range_spec.begin() + space_position + 1;
1348 std::string::const_iterator byte_range_resp_spec_end =
1349 content_range_spec.begin() + slash_position;
1350 HttpUtil::TrimLWS(&byte_range_resp_spec_begin, &byte_range_resp_spec_end);
1351
1352 // Parse the byte-range-resp-spec part.
1353 std::string byte_range_resp_spec(byte_range_resp_spec_begin,
1354 byte_range_resp_spec_end);
1355 // If byte-range-resp-spec != "*".
1356 if (!base::LowerCaseEqualsASCII(byte_range_resp_spec, "*")) {
1357 size_t minus_position = byte_range_resp_spec.find('-');
1358 if (minus_position != std::string::npos) {
1359 // Obtain first-byte-pos.
1360 std::string::const_iterator first_byte_pos_begin =
1361 byte_range_resp_spec.begin();
1362 std::string::const_iterator first_byte_pos_end =
1363 byte_range_resp_spec.begin() + minus_position;
1364 HttpUtil::TrimLWS(&first_byte_pos_begin, &first_byte_pos_end);
1365
1366 bool ok = base::StringToInt64(StringPiece(first_byte_pos_begin,
1367 first_byte_pos_end),
1368 first_byte_position);
1369
1370 // Obtain last-byte-pos.
1371 std::string::const_iterator last_byte_pos_begin =
1372 byte_range_resp_spec.begin() + minus_position + 1;
1373 std::string::const_iterator last_byte_pos_end =
1374 byte_range_resp_spec.end();
1375 HttpUtil::TrimLWS(&last_byte_pos_begin, &last_byte_pos_end);
1376
1377 ok &= base::StringToInt64(StringPiece(last_byte_pos_begin,
1378 last_byte_pos_end),
1379 last_byte_position);
1380 if (!ok) {
1381 *first_byte_position = *last_byte_position = -1;
1382 return false;
1383 }
1384 if (*first_byte_position < 0 || *last_byte_position < 0 ||
1385 *first_byte_position > *last_byte_position)
1386 return false;
1387 } else {
1388 return false;
1389 }
1390 }
1391
1392 // Parse the instance-length part.
1393 // If instance-length == "*".
1394 std::string::const_iterator instance_length_begin =
1395 content_range_spec.begin() + slash_position + 1;
1396 std::string::const_iterator instance_length_end =
1397 content_range_spec.end();
1398 HttpUtil::TrimLWS(&instance_length_begin, &instance_length_end);
1399
1400 if (base::StartsWith(
1401 base::StringPiece(instance_length_begin, instance_length_end), "*",
1402 base::CompareCase::SENSITIVE)) {
1403 return false;
1404 } else if (!base::StringToInt64(StringPiece(instance_length_begin,
1405 instance_length_end),
1406 instance_length)) {
1407 *instance_length = -1;
1408 return false;
1409 }
1410
1411 // We have all the values; let's verify that they make sense for a 206
1412 // response.
1413 if (*first_byte_position < 0 || *last_byte_position < 0 ||
1414 *instance_length < 0 || *instance_length - 1 < *last_byte_position)
1415 return false;
1416
1417 return true;
1418 } 1319 }
1419 1320
1420 std::unique_ptr<base::Value> HttpResponseHeaders::NetLogCallback( 1321 std::unique_ptr<base::Value> HttpResponseHeaders::NetLogCallback(
1421 NetLogCaptureMode capture_mode) const { 1322 NetLogCaptureMode capture_mode) const {
1422 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 1323 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
1423 base::ListValue* headers = new base::ListValue(); 1324 base::ListValue* headers = new base::ListValue();
1424 headers->AppendString(EscapeNonASCII(GetStatusLine())); 1325 headers->AppendString(EscapeNonASCII(GetStatusLine()));
1425 size_t iterator = 0; 1326 size_t iterator = 0;
1426 std::string name; 1327 std::string name;
1427 std::string value; 1328 std::string value;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 return true; 1369 return true;
1469 } 1370 }
1470 1371
1471 bool HttpResponseHeaders::IsChunkEncoded() const { 1372 bool HttpResponseHeaders::IsChunkEncoded() const {
1472 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. 1373 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies.
1473 return GetHttpVersion() >= HttpVersion(1, 1) && 1374 return GetHttpVersion() >= HttpVersion(1, 1) &&
1474 HasHeaderValue("Transfer-Encoding", "chunked"); 1375 HasHeaderValue("Transfer-Encoding", "chunked");
1475 } 1376 }
1476 1377
1477 } // namespace net 1378 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/http/http_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698