mirror of
https://github.com/ansible/ansible.git
synced 2026-02-03 20:40:24 -05:00
Merge 977c697c8f into 7f17759bfe
This commit is contained in:
commit
1d3af46e3b
5 changed files with 70 additions and 14 deletions
3
changelogs/fragments/uri_cookies.yml
Normal file
3
changelogs/fragments/uri_cookies.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
bugfixes:
|
||||
- uri - return cookies and cookies_string even if follow_redirects is set to None (https://github.com/ansible/ansible/issues/85780).
|
||||
|
|
@ -1163,6 +1163,25 @@ def url_redirect_argument_spec():
|
|||
)
|
||||
|
||||
|
||||
def _process_cookies(cookies: cookiejar.CookieJar) -> tuple[dict[str, str], str]:
|
||||
"""
|
||||
Parse the cookies into a nice dictionary and string representation of the cookies
|
||||
:arg cookies: a CookieJar object
|
||||
:return: a dictionary of cookies and a string representation of the cookies
|
||||
"""
|
||||
cookie_list = []
|
||||
cookie_dict = {}
|
||||
# Python sorts cookies in order of most specific (ie. longest) path first. See ``CookieJar._cookie_attrs``
|
||||
# Cookies with the same path are reversed from response order.
|
||||
# This code makes no assumptions about that, and accepts the order given by python
|
||||
for cookie in cookies:
|
||||
cookie_dict[cookie.name] = cookie.value
|
||||
cookie_list.append((cookie.name, cookie.value))
|
||||
cookies_string = '; '.join('%s=%s' % c for c in cookie_list)
|
||||
|
||||
return cookie_dict, cookies_string
|
||||
|
||||
|
||||
def fetch_url(module, url, data=None, headers=None, method=None,
|
||||
use_proxy=None, force=False, last_mod_time=None, timeout=10,
|
||||
use_gssapi=False, unix_socket=None, ca_path=None, cookies=None, unredirected_headers=None,
|
||||
|
|
@ -1258,19 +1277,7 @@ def fetch_url(module, url, data=None, headers=None, method=None,
|
|||
else:
|
||||
temp_headers[name] = value
|
||||
info.update(temp_headers)
|
||||
|
||||
# parse the cookies into a nice dictionary
|
||||
cookie_list = []
|
||||
cookie_dict = {}
|
||||
# Python sorts cookies in order of most specific (ie. longest) path first. See ``CookieJar._cookie_attrs``
|
||||
# Cookies with the same path are reversed from response order.
|
||||
# This code makes no assumptions about that, and accepts the order given by python
|
||||
for cookie in cookies:
|
||||
cookie_dict[cookie.name] = cookie.value
|
||||
cookie_list.append((cookie.name, cookie.value))
|
||||
info['cookies_string'] = '; '.join('%s=%s' % c for c in cookie_list)
|
||||
|
||||
info['cookies'] = cookie_dict
|
||||
info['cookies'], info['cookies_string'] = _process_cookies(cookies)
|
||||
# finally update the result with a message about the fetch
|
||||
info.update(dict(msg="OK (%s bytes)" % r.headers.get('Content-Length', 'unknown'), url=r.geturl(), status=r.code))
|
||||
except (ConnectionError, ValueError) as e:
|
||||
|
|
@ -1295,6 +1302,7 @@ def fetch_url(module, url, data=None, headers=None, method=None,
|
|||
try:
|
||||
# Lowercase keys, to conform to py2 behavior, so that py3 and py2 are predictable
|
||||
info.update({k.lower(): v for k, v in e.info().items()})
|
||||
info['cookies'], info['cookies_string'] = _process_cookies(cookies)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,37 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import http.cookies
|
||||
import http.server
|
||||
import socketserver
|
||||
import sys
|
||||
import urllib.parse
|
||||
|
||||
if __name__ == '__main__':
|
||||
PORT = int(sys.argv[1])
|
||||
content_type_json = "application/json"
|
||||
|
||||
class Handler(http.server.SimpleHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
if self.path == '/login':
|
||||
# For testcase - follow_redirects is None and Cookies are set
|
||||
# https://github.com/ansible/ansible/issues/85780
|
||||
content_length = int(self.headers['Content-Length'])
|
||||
post_data_bytes = self.rfile.read(content_length)
|
||||
post_data_str = post_data_bytes.decode('utf-8')
|
||||
parsed_data = urllib.parse.parse_qs(post_data_str)
|
||||
username = parsed_data.get('username', [None])[0]
|
||||
password = parsed_data.get('password', [None])[0]
|
||||
if username == "user" and password == "pass":
|
||||
# Set a cookie
|
||||
cookie = http.cookies.SimpleCookie()
|
||||
cookie['session_id'] = 'secure_session_token_123'
|
||||
self.send_response(302)
|
||||
self.send_header('Location', '/success.html')
|
||||
self.send_header('Set-Cookie', cookie.output(header=''))
|
||||
self.end_headers()
|
||||
else:
|
||||
self.send_error(404)
|
||||
|
||||
def do_GET(self):
|
||||
if self.path == '/chunked':
|
||||
self.request.sendall(
|
||||
|
|
|
|||
|
|
@ -774,3 +774,24 @@
|
|||
assert:
|
||||
that:
|
||||
- uri_check.msg == "This action (uri) does not support check mode."
|
||||
|
||||
# https://github.com/ansible/ansible/issues/85780
|
||||
- name: Test if cookies are returned when follow_redirects is none
|
||||
ansible.builtin.uri:
|
||||
method: POST
|
||||
url: "http://localhost:{{ http_port }}/login"
|
||||
follow_redirects: none
|
||||
body_format: form-urlencoded
|
||||
body:
|
||||
username: user
|
||||
password: pass
|
||||
status_code: [302]
|
||||
register: cookies_return
|
||||
|
||||
- name: Check if cookies are returned if follow_redirects is None
|
||||
assert:
|
||||
that:
|
||||
- cookies_return.cookies_string is defined
|
||||
- cookies_return.cookies is defined
|
||||
- cookies_return.cookies_string != ''
|
||||
- cookies_return['cookies']['session_id'] == 'secure_session_token_123'
|
||||
|
|
|
|||
|
|
@ -170,7 +170,8 @@ def test_fetch_url_httperror(open_url_mock, fake_ansible_module):
|
|||
r, info = fetch_url(fake_ansible_module, BASE_URL)
|
||||
|
||||
assert info == {'msg': 'HTTP Error 500: Internal Server Error', 'body': 'TESTS',
|
||||
'status': 500, 'url': BASE_URL, 'content-type': 'application/json'}
|
||||
'status': 500, 'url': BASE_URL, 'content-type': 'application/json',
|
||||
'cookies': {}, 'cookies_string': ''}
|
||||
|
||||
|
||||
def test_fetch_url_urlerror(open_url_mock, fake_ansible_module):
|
||||
|
|
|
|||
Loading…
Reference in a new issue