Fresh returns true when the response is still “fresh” in the client's cache, otherwise false is returned to indicate that the client cache is now stale and the full response should be sent. When a client sends the Cache-Control: no-cache request header to indicate an end-to-end reload request, this
()
| 402 | // reload request, this module will return false to make handling these requests transparent. |
| 403 | // https://github.com/jshttp/fresh/blob/master/index.js#L33 |
| 404 | func (r *DefaultReq) Fresh() bool { |
| 405 | header := &r.c.fasthttp.Request.Header |
| 406 | |
| 407 | // fields |
| 408 | modifiedSince := header.Peek(HeaderIfModifiedSince) |
| 409 | noneMatch := header.Peek(HeaderIfNoneMatch) |
| 410 | |
| 411 | // unconditional request |
| 412 | if len(modifiedSince) == 0 && len(noneMatch) == 0 { |
| 413 | return false |
| 414 | } |
| 415 | |
| 416 | // Always return stale when Cache-Control: no-cache |
| 417 | // to support end-to-end reload requests |
| 418 | // https://www.rfc-editor.org/rfc/rfc9111#section-5.2.1.4 |
| 419 | cacheControl := header.Peek(HeaderCacheControl) |
| 420 | if len(cacheControl) > 0 && isNoCache(utils.UnsafeString(cacheControl)) { |
| 421 | return false |
| 422 | } |
| 423 | |
| 424 | // if-none-match takes precedence over if-modified-since (RFC 9110) |
| 425 | if len(noneMatch) > 0 { |
| 426 | if len(noneMatch) == 1 && noneMatch[0] == '*' { |
| 427 | return true |
| 428 | } |
| 429 | app := r.c.app |
| 430 | response := &r.c.fasthttp.Response |
| 431 | etag := app.toString(response.Header.Peek(HeaderETag)) |
| 432 | if etag == "" { |
| 433 | return false |
| 434 | } |
| 435 | if app.isEtagStale(etag, noneMatch) { |
| 436 | return false |
| 437 | } |
| 438 | return true |
| 439 | } |
| 440 | |
| 441 | // if-modified-since (only reached when if-none-match is absent) |
| 442 | if len(modifiedSince) > 0 { |
| 443 | response := &r.c.fasthttp.Response |
| 444 | lastModified := response.Header.Peek(HeaderLastModified) |
| 445 | if len(lastModified) == 0 { |
| 446 | return false |
| 447 | } |
| 448 | lastModifiedTime, err := fasthttp.ParseHTTPDate(lastModified) |
| 449 | if err != nil { |
| 450 | return false |
| 451 | } |
| 452 | // Common conditional request: the client echoes back the exact |
| 453 | // Last-Modified it was given. Identical, already-validated dates are |
| 454 | // equal, so skip the second parse and comparison. |
| 455 | if !bytes.Equal(lastModified, modifiedSince) { |
| 456 | modifiedSinceTime, err := fasthttp.ParseHTTPDate(modifiedSince) |
| 457 | if err != nil { |
| 458 | return false |
| 459 | } |
| 460 | if lastModifiedTime.Compare(modifiedSinceTime) == 1 { |
| 461 | return false |
no test coverage detected