checkIfHeaders function
Check if the conditions specified in the optional If headers are
satisfied, such as If-Modified-Since
and If-None-Match
headers.
If false is returned, the caller shall stop from generating further content.
lastModified
- when it was last modified. Ignored if null.etag
- the ETag. Ignored if null.
Implementation
bool checkIfHeaders(HttpConnect connect, DateTime? lastModified, String? etag) {
final HttpResponse response = connect.response;
if (response.statusCode >= 300)
return true; //Ignore If, since caused by forward-by-error (see also Issue 59)
final HttpRequest request = connect.request;
//Check If-Match
final ifMatch = connect.headerValue(HttpHeaders.ifMatchHeader);
if (ifMatch != null && ifMatch != "*"
&& (etag == null || !_matchETag(ifMatch, etag))) { //not match
response.statusCode = HttpStatus.preconditionFailed;
return false;
}
//Check If-None-Match
//Note: it shall be checked before If-Modified-Since
final ifNoneMatch = connect.headerValue(HttpHeaders.ifNoneMatchHeader);
if (ifNoneMatch != null) {
if (ifNoneMatch == "*"
|| (etag != null && _matchETag(ifNoneMatch, etag))) { //match
final String method = request.method;
if (method == "GET" || method == "HEAD") {
response.statusCode = HttpStatus.notModified;
if (etag != null)
response.headers.set(HttpHeaders.etagHeader, etag);
return false;
}
response.statusCode = HttpStatus.preconditionFailed;
return false;
}
}
if (lastModified != null) {
//Check If-Modified-Since
//Ignored it if If-None-Match specified (since ETag differs)
final ifModifiedSince = request.headers.ifModifiedSince;
if (ifModifiedSince != null && ifNoneMatch == null
&& lastModified.isBefore(ifModifiedSince.add(_oneSecond))) {
response.statusCode = HttpStatus.notModified;
if (etag != null)
response.headers.set(HttpHeaders.etagHeader, etag);
return false;
}
//Check If-Unmodified-Since
final value = connect.headerValue(HttpHeaders.ifUnmodifiedSinceHeader);
if (value != null) {
try {
final DateTime ifUnmodifiedSince = HttpDate.parse(value);
if (lastModified.isAfter(ifUnmodifiedSince.add(_oneSecond))) {
response.statusCode = HttpStatus.preconditionFailed;
return false;
}
} catch (e) { //ignore it silently
}
}
}
return true;
}