@@ -1224,14 +1224,16 @@ HttpTransactCache::CalcVariability(const OverridableHttpConfigParams *http_confi
12241224 HTTP_STATUS_PRECONDITION_FAILED is returned if one fails; otherwise,
12251225 the response's status code is returned.
12261226
1227- If the request is a RANGE request with If-range,
1228- HTTP_STATUS_RANGE_NOT_SATISFIABLE is returned if the If-range condition
1229- is not satisfied (or fails); that means the document is changed and
1230- the whole document should be returned with 200 status code. Otherwise,
1231- the response's status code is returned.
1227+ If the request is a RANGE request with If-range, the response's
1228+ status code is returned. This is because in the case of If-range
1229+ headers, it's not so useful to perform checks on it at the same time
1230+ as other conditional headers. Upon encountering an invalid If-range
1231+ header, the server must ignore the RANGE and If-range headers
1232+ entirely. As such, it's more appropriate to validate If-range
1233+ headers when processing RANGE headers. On other occasions, it's
1234+ easier to treat If-range requests as plain non-conditional ones.
12321235
1233- @return status code: HTTP_STATUS_NOT_MODIFIED,
1234- HTTP_STATUS_PRECONDITION_FAILED, or HTTP_STATUS_RANGE_NOT_SATISFIABLE.
1236+ @return status code: HTTP_STATUS_NOT_MODIFIED or HTTP_STATUS_PRECONDITION_FAILED
12351237
12361238*/
12371239HTTPStatus
@@ -1244,7 +1246,7 @@ HttpTransactCache::match_response_to_request_conditionals(HTTPHdr *request, HTTP
12441246 ink_assert (response->status_get () != HTTP_STATUS_RANGE_NOT_SATISFIABLE);
12451247
12461248 if (!(request->presence (MIME_PRESENCE_IF_MODIFIED_SINCE | MIME_PRESENCE_IF_NONE_MATCH | MIME_PRESENCE_IF_UNMODIFIED_SINCE |
1247- MIME_PRESENCE_IF_MATCH | MIME_PRESENCE_RANGE ))) {
1249+ MIME_PRESENCE_IF_MATCH))) {
12481250 return response->status_get ();
12491251 }
12501252
@@ -1357,47 +1359,50 @@ HttpTransactCache::match_response_to_request_conditionals(HTTPHdr *request, HTTP
13571359 return response_code;
13581360 }
13591361
1360- // Handling If-Range header:
1361- // As Range && If-Range don't occur often, we want to put the
1362- // If-Range code in the end
1363- if (request->presence (MIME_PRESENCE_RANGE) && request->presence (MIME_PRESENCE_IF_RANGE)) {
1364- int raw_len, comma_sep_list_len;
1362+ return response->status_get ();
1363+ }
13651364
1366- const char *if_value = request->value_get (MIME_FIELD_IF_RANGE, MIME_LEN_IF_RANGE, &comma_sep_list_len);
1365+ /* *
1366+ Validates the contents of If-range headers in client requests. The presence of Range
1367+ headers needs to be checked before calling this method.
13671368
1368- // this is an ETag, similar to If-Match
1369- if (!if_value || if_value[0 ] == ' "' || (comma_sep_list_len > 1 && if_value[1 ] == ' /' )) {
1370- if (!if_value) {
1371- if_value = " " ;
1372- comma_sep_list_len = 0 ;
1373- }
1369+ @return Whether the condition specified by If-range is met, if there is any.
1370+ If there's no If-range header, then true.
13741371
1375- const char *raw_etags = response->value_get (MIME_FIELD_ETAG, MIME_LEN_ETAG, &raw_len);
1372+ */
1373+ bool
1374+ HttpTransactCache::validate_ifrange_header_if_any (HTTPHdr *request, HTTPHdr *response)
1375+ {
1376+ if (!request->presence (MIME_PRESENCE_IF_RANGE)) {
1377+ return true ;
1378+ }
13761379
1377- if (!raw_etags) {
1378- raw_etags = " " ;
1379- raw_len = 0 ;
1380- }
1380+ int raw_len, comma_sep_list_len;
13811381
1382- if (do_strings_match_strongly (raw_etags, raw_len, if_value, comma_sep_list_len)) {
1383- return response->status_get ();
1384- } else {
1385- return HTTP_STATUS_RANGE_NOT_SATISFIABLE;
1386- }
1382+ const char *if_value = request->value_get (MIME_FIELD_IF_RANGE, MIME_LEN_IF_RANGE, &comma_sep_list_len);
1383+
1384+ // this is an ETag, similar to If-Match
1385+ if (!if_value || if_value[0 ] == ' "' || (comma_sep_list_len > 1 && if_value[1 ] == ' /' )) {
1386+ if (!if_value) {
1387+ if_value = " " ;
1388+ comma_sep_list_len = 0 ;
13871389 }
1388- // this a Date, similar to If-Unmodified-Since but must be an exact match
1389- else {
1390- // lm_value is zero if Last-modified not exists
1391- ink_time_t lm_value = response->get_last_modified ();
13921390
1393- // condition fails if Last-modified not exists
1394- if ((request->get_if_range_date () != lm_value) || (lm_value == 0 )) {
1395- return HTTP_STATUS_RANGE_NOT_SATISFIABLE;
1396- } else {
1397- return response->status_get ();
1398- }
1391+ const char *raw_etags = response->value_get (MIME_FIELD_ETAG, MIME_LEN_ETAG, &raw_len);
1392+
1393+ if (!raw_etags) {
1394+ raw_etags = " " ;
1395+ raw_len = 0 ;
13991396 }
1397+
1398+ return do_strings_match_strongly (raw_etags, raw_len, if_value, comma_sep_list_len);
14001399 }
14011400
1402- return response->status_get ();
1401+ // this a Date, similar to If-Unmodified-Since but must be an exact match
1402+
1403+ // lm_value is zero if Last-modified not exists
1404+ ink_time_t lm_value = response->get_last_modified ();
1405+
1406+ // condition fails if Last-modified not exists
1407+ return (request->get_if_range_date () == lm_value) && (lm_value != 0 );
14031408}
0 commit comments