---
# get with mismatch https
# get with mismatch https and ignore validation

- name: get request without return_content
  win_uri:
    url: https://{{httpbin_host}}/get
    return_content: no
  register: get_request_without_content

- name: assert get request without return_content
  assert:
    that:
    - not get_request_without_content.changed
    - get_request_without_content.content is not defined
    - get_request_without_content.json is not defined
    - get_request_without_content.status_code == 200

- name: get request with xml content
  win_uri:
    url: https://{{httpbin_host}}/xml
    return_content: yes
  register: get_request_with_xml_content

- name: assert get request with xml content
  assert:
    that:
    - not get_request_with_xml_content.changed
    - get_request_with_xml_content.content is defined
    - get_request_with_xml_content.json is not defined
    - get_request_with_xml_content.status_code == 200

- name: get request with binary content
  win_uri:
    url: https://{{httpbin_host}}/image/png
    return_content: yes
  register: get_request_with_binary_content

- name: assert get request with binary content
  assert:
    that:
    - not get_request_with_binary_content.changed
    - get_request_with_binary_content.content is defined
    - get_request_with_binary_content.json is not defined
    - get_request_with_xml_content.status_code == 200

- name: get request with return_content and dest (check mode)
  win_uri:
    url: https://{{httpbin_host}}/get
    return_content: yes
    dest: '{{ remote_tmp_dir }}\get.json'
  register: get_request_with_dest_check
  check_mode: yes

- name: get stat of downloaded file (check mode)
  win_stat:
    path: '{{ remote_tmp_dir }}\get.json'
  register: get_request_with_dest_actual_check

- name: assert get request with return_content and dest (check mode)
  assert:
    that:
    - get_request_with_dest_check.changed
    - get_request_with_dest_check.content is defined
    - get_request_with_dest_check.json is defined
    - get_request_with_dest_actual_check.stat.exists == False

- name: get request with return_content and dest
  win_uri:
    url: https://{{httpbin_host}}/base64/{{ '{"key":"value"}' | b64encode }}
    return_content: yes
    dest: '{{ remote_tmp_dir }}\get.json'
  register: get_request_with_dest

- name: get stat of downloaded file
  win_stat:
    path: '{{ remote_tmp_dir }}\get.json'
    checksum_algorithm: sha1
    get_checksum: yes
  register: get_request_with_dest_actual

- name: assert get request with return_content and dest
  assert:
    that:
    - get_request_with_dest.changed
    - get_request_with_dest.content is defined
    - get_request_with_dest.json is defined
    - get_request_with_dest_actual.stat.exists == True
    - get_request_with_dest_actual.stat.checksum == get_request_with_dest.content|hash('sha1')

- name: get request with return_content and dest (idempotent)
  win_uri:
    url: https://{{httpbin_host}}/base64/{{ '{"key":"value"}' | b64encode }}
    return_content: yes
    dest: '{{ remote_tmp_dir }}\get.json'
  register: get_request_with_dest_again

- name: assert get request with return_content and dest (idempotent)
  assert:
    that:
    - not get_request_with_dest_again.changed

- name: test request with creates option should skip
  win_uri:
    url: https://{{httpbin_host}}/get
    creates: '{{ remote_tmp_dir }}\get.json'
  register: request_with_creates_skipped

- name: assert test request with creates option should skip
  assert:
    that:
    - not request_with_creates_skipped.changed
    - request_with_creates_skipped.skipped

- name: test request with creates option should not skip
  win_uri:
    url: https://{{httpbin_host}}/get
    creates: '{{ remote_tmp_dir }}\fake.json'
  register: request_with_creates_not_skipped

- name: assert test request with creates option should not skip
  assert:
    that:
    - not request_with_creates_not_skipped.changed
    - request_with_creates_not_skipped.skipped is not defined

- name: post request with return_content, dest and different content
  win_uri:
    url: https://{{httpbin_host}}/post
    method: POST
    content_type: application/json
    body: '{"foo": "bar"}'
    return_content: yes
    dest: '{{ remote_tmp_dir }}\get.json'
  register: post_request_with_different_content

- name: get stat of downloaded file
  win_stat:
    path: '{{ remote_tmp_dir }}\get.json'
    checksum_algorithm: sha1
    get_checksum: yes
  register: post_request_with_different_content_actual

- name: assert post request with return_content, dest and different content
  assert:
    that:
    - post_request_with_different_content.changed
    - post_request_with_different_content_actual.stat.exists == True
    - post_request_with_different_content_actual.stat.checksum == post_request_with_different_content.content|hash('sha1')

- name: test safe redirection of get
  win_uri:
    url: https://{{httpbin_host}}/redirect/2
  register: redirect_safe

- name: assert safe redirection of get
  assert:
    that:
    - redirect_safe.status_code == 200
    - redirect_safe.response_uri == 'https://' + httpbin_host + '/get'

- name: test safe redirection of head
  win_uri:
    url: https://{{httpbin_host}}/redirect/2
    method: HEAD
  register: redirect_safe_head

- name: assert safe redirection of head
  assert:
    that:
    - redirect_safe_head.status_code == 200
    - redirect_safe_head.response_uri == 'https://' + httpbin_host + '/get'

- name: test safe redirection of put
  win_uri:
    url: https://{{httpbin_host}}/redirect-to?url=https://{{httpbin_host}}/put
    body: data
    status_code: 302
    method: PUT
  register: redirect_safe_put

- name: assert safe redirection of put
  assert:
    that:
    - redirect_safe_put.status_code == 302
    - redirect_safe_put.response_uri == 'https://' + httpbin_host + '/redirect-to?url=https://' + httpbin_host + '/put'

- name: test none redirection of get
  win_uri:
    url: https://{{httpbin_host}}/redirect/2
    status_code: 302
    follow_redirects: none
  register: redirect_none

- name: assert none redirection of get
  assert:
    that:
    - redirect_none.status_code == 302
    - redirect_none.response_uri == 'https://' + httpbin_host + '/redirect/2'

- name: test none redirection of put
  win_uri:
    url: https://{{httpbin_host}}/redirect-to?url=https://{{httpbin_host}}/put
    body: data
    status_code: 302
    method: PUT
    follow_redirects: none
  register: redirect_none_put

- name: assert none redirection of put
  assert:
    that:
    - redirect_none_put.status_code == 302
    - redirect_none_put.response_uri == 'https://' + httpbin_host + '/redirect-to?url=https://' + httpbin_host + '/put'

- name: test all redirection of get
  win_uri:
    url: https://{{httpbin_host}}/redirect/2
    follow_redirects: all
  register: redirect_all

- name: assert all redirection of get
  assert:
    that:
    - redirect_all.status_code == 200
    - redirect_all.response_uri == 'https://' + httpbin_host + '/get'

- name: test all redirection of put
  win_uri:
    url: https://{{httpbin_host}}/redirect-to?url=https://{{httpbin_host}}/put
    body: data
    method: PUT
    follow_redirects: all
  register: redirect_all_put

- name: assert all redirection of put
  assert:
    that:
    - redirect_all_put.status_code == 200
    - redirect_all_put.response_uri == 'https://' + httpbin_host + '/put'

- name: test exceeded maximum redirection
  win_uri:
    url: https://{{httpbin_host}}/redirect/5
    maximum_redirection: 4
    status_code: 302
  register: maximum_redirection

- name: assert exceeded maximum redirection
  assert:
    that:
    - maximum_redirection.status_code == 302
    - maximum_redirection.response_uri == 'https://' + httpbin_host + '/relative-redirect/1'

- name: test basic auth
  win_uri:
    url: https://{{httpbin_host}}/basic-auth/user/passwd
    user: user
    password: passwd
  register: basic_auth

- name: assert test basic auth
  assert:
    that:
    - not basic_auth.changed
    - basic_auth.status_code == 200

- name: test basic auth with force auth
  win_uri:
    url: https://{{httpbin_host}}/hidden-basic-auth/user/passwd
    user: user
    password: passwd
    force_basic_auth: yes
  register: basic_auth_forced

- name: assert test basic auth with forced auth
  assert:
    that:
    - not basic_auth_forced.changed
    - basic_auth_forced.status_code == 200

- name: test PUT
  win_uri:
    url: https://{{httpbin_host}}/put
    method: PUT
    body: foo=bar
    return_content: yes
  register: put_request

- name: assert test PUT
  assert:
    that:
    - not put_request.changed
    - put_request.status_code == 200
    - put_request.json.data == 'foo=bar'

- name: test OPTIONS
  win_uri:
    url: https://{{httpbin_host}}/
    method: OPTIONS
  register: option_request

- name: assert test OPTIONS
  assert:
    that:
    - not option_request.changed
    - option_request.status_code == 200
    - 'option_request.allow.split(", ")|sort == ["GET", "HEAD", "OPTIONS"]'

# SNI Tests

- name: validate status_codes are correct
  win_uri:
    url: https://{{httpbin_host}}/status/202
    status_code:
    - 202
    - 418
    method: POST
    body: foo
  register: status_code_check

- name: assert validate status_codes are correct
  assert:
    that:
    - not status_code_check.changed
    - status_code_check.status_code == 202

- name: send JSON body with dict type
  win_uri:
    url: https://{{httpbin_host}}/post
    method: POST
    body:
      foo: bar
      list:
      - 1
      - 2
      dict:
        foo: bar
    headers:
      'Content-Type': 'text/json'
    return_content: yes
  register: json_as_dict

- name: set fact of expected json dict
  set_fact:
    json_as_dict_value:
      foo: bar
      list:
      - 1
      - 2
      dict:
        foo: bar

- name: assert send JSON body with dict type
  assert:
    that:
    - not json_as_dict.changed
    - json_as_dict.json.json == json_as_dict_value
    - json_as_dict.status_code == 200

- name: send JSON body with 1 item in list
  win_uri:
    url: https://{{httpbin_host}}/post
    method: POST
    body:
      - foo: bar
    headers:
      'Content-Type': 'text/json'
    return_content: yes
  register: json_as_oneitemlist

- name: set fact of expected json 1 item list
  set_fact:
    json_as_oneitemlist_value:
      - foo: bar

- name: assert send JSON body with 1 item in list
  assert:
    that:
    - not json_as_oneitemlist.changed
    - json_as_oneitemlist.json.json == json_as_oneitemlist_value
    - json_as_oneitemlist.status_code == 200

- name: get request with custom headers
  win_uri:
    url: https://{{httpbin_host}}/get
    headers:
      Test-Header: hello
      Another-Header: world
    return_content: yes
  register: get_custom_header

- name: assert request with custom headers
  assert:
    that:
    - not get_custom_header.changed
    - get_custom_header.status_code == 200
    - get_custom_header.json.headers['Test-Header'] == 'hello'
    - get_custom_header.json.headers['Another-Header'] == 'world'

- name: Validate invalid method
  win_uri:
    url: https://{{ httpbin_host }}/anything
    method: UNKNOWN
  register: invalid_method
  ignore_errors: yes

- name: Assert invalid method fails
  assert:
    that:
    - invalid_method is failure
    - invalid_method.status_code == 405
    - invalid_method.status_description == 'METHOD NOT ALLOWED'

# client cert auth tests

- name: get request with timeout
  win_uri:
    url: https://{{httpbin_host}}/delay/10
    timeout: 5
  register: get_with_timeout_fail
  failed_when: '"The operation has timed out" not in get_with_timeout_fail.msg'

- name: connect to fakepath that does not exist
  win_uri:
    url: https://{{httpbin_host}}/fakepath
    status_code: 404
    return_content: yes
  register: invalid_path

# verifies the return values are still set on a non 200 response
- name: assert connect to fakepath that does not exist
  assert:
    that:
    - not invalid_path.changed
    - invalid_path.status_code == 404
    - invalid_path.status_description == 'NOT FOUND'
    - invalid_path.content is defined
    - invalid_path.method == 'GET'
    - invalid_path.connection is defined

- name: post request with custom headers
  win_uri:
    url: https://{{httpbin_host}}/post
    method: POST
    headers:
      Test-Header: hello
      Another-Header: world
    content_type: application/json
    body: '{"foo": "bar"}'
    return_content: yes
  register: post_request_with_custom_headers

- name: assert post with custom headers
  assert:
    that:
    - not post_request_with_custom_headers.changed
    - post_request_with_custom_headers.status_code == 200
    - post_request_with_custom_headers.json.headers['Content-Type'] == "application/json"
    - post_request_with_custom_headers.json.headers['Test-Header'] == 'hello'
    - post_request_with_custom_headers.json.headers['Another-Header'] == 'world'

- name: validate status codes as list of strings
  win_uri:
    url: https://{{httpbin_host}}/status/202
    status_code:
    - '202'
    - '418'
    method: POST
    body: foo
    return_content: yes
  register: request_status_code_string

- name: assert status codes as list of strings
  assert:
    that:
    - not request_status_code_string.changed
    - request_status_code_string.status_code == 202

- name: validate status codes as comma separated list
  win_uri:
    url: https://{{httpbin_host}}/status/202
    status_code: 202, 418
    method: POST
    body: foo
    return_content: yes
  register: request_status_code_comma

- name: assert status codes as comma separated list
  assert:
    that:
    - not request_status_code_comma.changed
    - request_status_code_comma.status_code == 202

# https://github.com/ansible/ansible/issues/55294
- name: get json content that is an array
  win_uri:
    url: https://{{httpbin_host}}/base64/{{ '[{"abc":"def"}]' | b64encode }}
    return_content: yes
  register: content_array

- name: assert content of json array
  assert:
    that:
    - not content_array is changed
    - content_array.content == '[{"abc":"def"}]'
    - content_array.json == [{"abc":"def"}]

- name: send request with explicit http_agent
  win_uri:
    url: https://{{httpbin_host}}/get
    http_agent: test-agent
    return_content: yes
  register: http_agent_option

- name: assert send request with explicit http_agent
  assert:
    that:
    - http_agent_option.json.headers['User-Agent'] == 'test-agent'

- name: send request with explicit User-Agent header
  win_uri:
    url: https://{{httpbin_host}}/get
    headers:
      User-Agent: test-agent
    return_content: yes
  register: http_agent_header

- name: assert send request with explicit User-Agent header
  assert:
    that:
    - http_agent_header.json.headers['User-Agent'] == 'test-agent'

- name: send request with explicit http_agent and header (http_agent wins)
  win_uri:
    url: https://{{httpbin_host}}/get
    http_agent: test-agent-option
    headers:
      User-Agent: test-agent-header
    return_content: yes
  register: http_agent_combo

- name: assert send request with explicit http_agent and header (http_agent wins)
  assert:
    that:
    - http_agent_combo.json.headers['User-Agent'] == 'test-agent-option'
    - http_agent_combo.warnings[0] == "The 'User-Agent' header and the 'http_agent' was set, using the 'http_agent' for web request"
