#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

#
# This replay file assumes that caching is enabled and
# proxy.config.http.cache.ignore_client_cc_max_age is set to 0 so that we can
# test max-age in the client requests.
#

meta:
  version: "1.0"

  blocks:
  - request_for_positive_max_age: &request_for_positive_max_age
      client-request:
        method: "GET"
        version: "1.1"
        scheme: "http"
        url: /path/200_positive_max_age
        headers:
          fields:
          - [ Host, example.com ]

        # Add a delay so ATS has time to finish any caching IO for the previous
        # transaction.
        delay: 100ms

  - request_for_zero_max_age: &request_for_zero_max_age
      client-request:
        method: "GET"
        version: "1.1"
        scheme: "http"
        url: /path/200_zero_max_age
        headers:
          fields:
          - [ Host, example.com ]

        # Add a delay so ATS has time to finish any caching IO for the previous
        # transaction.
        delay: 100ms

  - request_for_negative_max_age: &request_for_negative_max_age
      client-request:
        method: "GET"
        version: "1.1"
        scheme: "http"
        url: /path/200_negative_max_age
        headers:
          fields:
          - [ Host, example.com ]

        # Add a delay so ATS has time to finish any caching IO for the previous
        # transaction.
        delay: 100ms

  - request_for_non_number_max_age: &request_for_non_number_max_age
      client-request:
        method: "GET"
        version: "1.1"
        scheme: "http"
        url: /path/200_non_number_max_age
        headers:
          fields:
          - [ Host, example.com ]

        # Add a delay so ATS has time to finish any caching IO for the previous
        # transaction.
        delay: 100ms

  - 200_ok_response: &200_ok_response
      server-response:
        status: 200
        reason: OK
        headers:
          fields:
          - [ Content-Length, 16 ]
          - [ Cache-Control, max-age=300 ]

sessions:
- transactions:

  #
  # Test 1: Verify that a 200 response with a positive max-age is cached.
  #
  - all: { headers: { fields: [[ uuid, 1 ]]}}
    <<: *request_for_positive_max_age

    server-response:
      status: 200
      reason: OK
      headers:
        fields:
        - [ Content-Length, 16 ]
        - [ Cache-Control, max-age=300 ]

    proxy-response:
      status: 200

  - all: { headers: { fields: [[ uuid, 2 ]]}}
    <<: *request_for_positive_max_age

    # This should not go through to the server. Return a non-200 response to
    # verify it is served from cache.
    server-response:
      status: 400
      reason: "Bad Request"
      headers:
        fields:
        - [ Content-Length, 0 ]

    # Expect the cached 200 response.
    proxy-response:
      status: 200

  #
  # Test 2: Verify that a 200 response with a 0 max-age is considered stale.
  #
  - all: { headers: { fields: [[ uuid, 3 ]]}}
    <<: *request_for_zero_max_age

    server-response:
      status: 200
      reason: OK
      headers:
        fields:
        - [ Content-Length, 16 ]
        - [ Cache-Control, max-age=0 ]

    proxy-response:
      status: 200

  - all: { headers: { fields: [[ uuid, 4 ]]}}
    <<: *request_for_zero_max_age

    # This should go through to the server because the response's max-age was 0
    # and therefore object should be considered stale.
    server-response:
      status: 400
      reason: "Bad Request"
      headers:
        fields:
        - [ Content-Length, 0 ]

    # Expect the 400 response from the server because the 200 response should
    # be considered stale.
    proxy-response:
      status: 400

  #
  # Test 3: Verify that a 200 response with a negative max age is not served
  # from the cache. Since it is invalid, the item should be considered stale.
  #
  - all: { headers: { fields: [[ uuid, 5 ]]}}
    <<: *request_for_negative_max_age

    server-response:
      status: 200
      reason: OK
      headers:
        fields:
        - [ Content-Length, 16 ]
        # Notice the negative max-age.
        - [ Cache-Control, max-age=-300 ]

    proxy-response:
      status: 200

  - all: { headers: { fields: [[ uuid, 6 ]]}}
    <<: *request_for_negative_max_age

    # This should go through to the server because the above should not be
    # served from the cache.
    server-response:
      status: 400
      reason: "Bad Request"
      headers:
        fields:
        - [ Content-Length, 0 ]

    # Expect the 400 response from the server because the 200 response should
    # not be served from the cache.
    proxy-response:
      status: 400

  #
  # Test 4: Verify that a 200 response with a non-integer max-age is not served
  # from the cache. Since it is invalid, it should be considered stale.
  #
  - all: { headers: { fields: [[ uuid, 7 ]]}}
    <<: *request_for_non_number_max_age

    server-response:
      status: 200
      reason: OK
      headers:
        fields:
        - [ Content-Length, 16 ]
        # Notice the invalid, non-integer max-age value.
        - [ Cache-Control, max-age=not_a_number ]

    proxy-response:
      status: 200

  - all: { headers: { fields: [[ uuid, 8 ]]}}
    <<: *request_for_non_number_max_age

    # This should go through to the server because the above should not be
    # cached.
    server-response:
      status: 400
      reason: "Bad Request"
      headers:
        fields:
        - [ Content-Length, 0 ]

    # Expect the 400 response from the server because the 200 response should
    # not be cached.
    proxy-response:
      status: 400

  #
  # Test 5: Verify that a request with a positive max-age for the future is
  # replied to out of the cache.
  #
  - all: { headers: { fields: [[ uuid, 9 ]]}}

    # For the first request, simply populate the cache with the object.
    client-request:
      method: "GET"
      version: "1.1"
      scheme: "http"
      url: /path/test_request_with_positive_max_age
      headers:
        fields:
        - [ Host, example.com ]

    <<: *200_ok_response

    proxy-response:
      status: 200

  - all: { headers: { fields: [[ uuid, 10 ]]}}

    # Request the item again, with a max-age specification in the future.
    client-request:
      method: "GET"
      version: "1.1"
      scheme: "http"
      url: /path/test_request_with_positive_max_age
      headers:
        fields:
        - [ Host, example.com ]
        - [ Cache-Control, max-age=300 ]

      # Add a delay so ATS has time to finish any caching IO for the previous
      # transaction.
      delay: 100ms

    # This should be replied to out of the cache, therefore this 400 response
    # should not make it to the client.
    server-response:
      status: 400
      reason: "Bad Request"
      headers:
        fields:
        - [ Content-Length, 0 ]

    # Expect the cached 200 response.
    proxy-response:
      status: 200

  #
  # Test 6: Verify that a request with a 0 max-age results in the object being
  # considered stale.
  #
  - all: { headers: { fields: [[ uuid, 11 ]]}}

    # For the first request, simply populate the cache with the object.
    client-request:
      method: "GET"
      version: "1.1"
      scheme: "http"
      url: /path/test_request_with_zero_max_age
      headers:
        fields:
        - [ Host, example.com ]

    <<: *200_ok_response

    proxy-response:
      status: 200

  - all: { headers: { fields: [[ uuid, 12 ]]}}

    # Request the item again, with a max-age specification in the future.
    client-request:
      method: "GET"
      version: "1.1"
      scheme: "http"
      url: /path/test_request_with_zero_max_age
      headers:
        fields:
        - [ Host, example.com ]
        - [ Cache-Control, max-age=0 ]

      # Add a delay so ATS has time to finish any caching IO for the previous
      # transaction.
      delay: 100ms

    # This should go through to the server because the 0 max-age
    # directive in the request should make ATS consider it stale.
    server-response:
      status: 400
      reason: "Bad Request"
      headers:
        fields:
        - [ Content-Length, 0 ]

    # Expect the 400 response from the server because the 200 response should
    # not be cached.
    proxy-response:
      status: 400

  #
  # Test 7: Verify that a request with a negative max-age directive
  # results in the object being treated as stale.
  #
  - all: { headers: { fields: [[ uuid, 13 ]]}}

    # For the first request, simply populate the cache with the object.
    client-request:
      method: "GET"
      version: "1.1"
      scheme: "http"
      url: /path/test_request_with_negative_max_age
      headers:
        fields:
        - [ Host, example.com ]

    <<: *200_ok_response

    proxy-response:
      status: 200

  - all: { headers: { fields: [[ uuid, 14 ]]}}

    # For the second request, specify a negative max-age value. This is
    # invalid, and thus the freshness should be considered stale.
    client-request:
      method: "GET"
      version: "1.1"
      scheme: "http"
      url: /path/test_request_with_negative_max_age
      headers:
        fields:
        - [ Host, example.com ]
        - [ Cache-Control, max-age=-300 ]

      # Add a delay so ATS has time to finish any caching IO for the previous
      # transaction.
      delay: 100ms

    # This should go through to the server because the negative max-age
    # directive in the request should make ATS consider it stale.
    server-response:
      status: 400
      reason: "Bad Request"
      headers:
        fields:
        - [ Content-Length, 0 ]

    # Expect the 400 response from the server because the 200 response should
    # not be cached.
    proxy-response:
      status: 400
