Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions httpie/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def collect_messages(
base_headers=httpie_session_headers,
request_body_read_callback=request_body_read_callback
)
send_kwargs = make_send_kwargs(args)
send_kwargs = make_send_kwargs(args, env)
send_kwargs_mergeable_from_env = make_send_kwargs_mergeable_from_env(args)
requests_session = build_requests_session(
ssl_version=args.ssl_version,
Expand Down Expand Up @@ -278,9 +278,12 @@ def make_default_headers(args: argparse.Namespace) -> HTTPHeadersDict:
return default_headers


def make_send_kwargs(args: argparse.Namespace) -> dict:
def make_send_kwargs(args: argparse.Namespace, env: Environment = None) -> dict:
timeout = args.timeout or None
if timeout is None and env is not None and env.config.default_timeout:
timeout = env.config.default_timeout
return {
'timeout': args.timeout or None,
'timeout': timeout,
'allow_redirects': False,
}

Expand Down Expand Up @@ -343,6 +346,9 @@ def make_request_kwargs(
headers = make_default_headers(args)
if base_headers:
headers.update(base_headers)
# Apply default headers from config (can be overridden by user)
if env.config.default_headers:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: safely guard the env reference to prevent NoneType attribute errors

While env is safely guarded up in make_send_kwargs, it is missing a guard here in make_request_kwargs on line 350:

if env and env.config.default_headers:

headers.update(env.config.default_headers)
headers.update(args.headers)
if args.offline and args.chunked and 'Transfer-Encoding' not in headers:
# When online, we let requests set the header instead to be able more
Expand Down
12 changes: 11 additions & 1 deletion httpie/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ def version(self):
class Config(BaseConfigDict):
FILENAME = 'config.json'
DEFAULTS = {
'default_options': []
'default_options': [],
'default_headers': {},
'default_timeout': None
}

def __init__(self, directory: Union[str, Path] = DEFAULT_CONFIG_DIR):
Expand All @@ -149,6 +151,14 @@ def __init__(self, directory: Union[str, Path] = DEFAULT_CONFIG_DIR):
def default_options(self) -> list:
return self['default_options']

@property
def default_headers(self) -> dict:
return self['default_headers']

@property
def default_timeout(self):
return self['default_timeout']

def _configured_path(self, config_option: str, default: str) -> None:
return Path(
self.get(config_option, self.directory / default)
Expand Down
33 changes: 33 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,36 @@ def test_custom_config_dir(monkeypatch: MonkeyPatch, tmp_path: Path):
def test_windows_config_dir(monkeypatch: MonkeyPatch):
monkeypatch.delenv(ENV_HTTPIE_CONFIG_DIR, raising=False)
assert get_default_config_dir() == DEFAULT_WINDOWS_CONFIG_DIR


def test_default_headers(httpbin):
env = MockEnvironment()
env.config['default_headers'] = {'X-Custom-Header': 'test-value'}
env.config.save()
r = http(httpbin + '/headers', env=env)
assert HTTP_OK in r
assert r.json['headers']['X-Custom-Header'] == 'test-value'


def test_default_headers_overridable(httpbin):
env = MockEnvironment()
env.config['default_headers'] = {'X-Custom-Header': 'default-value'}
env.config.save()
r = http(httpbin + '/headers', 'X-Custom-Header:override-value', env=env)
assert HTTP_OK in r
assert r.json['headers']['X-Custom-Header'] == 'override-value'


def test_default_timeout(httpbin):
env = MockEnvironment()
env.config['default_timeout'] = 30
env.config.save()
assert env.config.default_timeout == 30


def test_default_timeout_overridable(httpbin):
env = MockEnvironment()
env.config['default_timeout'] = 30
env.config.save()
r = http('--timeout=60', httpbin + '/get', env=env)
assert HTTP_OK in r
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: add a specific assertion to verify the timeout override value

While checking for HTTP_OK confirms the request succeeded, the test doesn't explicitly verify that the --timeout=60 argument successfully overrode the default_timeout setting of 30 during execution.

Adding an assertion for checking would make this test block significantly stronger.

Loading