1
0
mirror of https://github.com/httpie/cli.git synced 2025-01-07 23:01:53 +02:00

Don't fail if config dir not writeable (close #738)

This commit is contained in:
Jakub Roztocil 2019-08-29 14:05:00 +02:00
parent d998013655
commit 9bd8b4e8f7
5 changed files with 25 additions and 42 deletions

View File

@ -14,11 +14,12 @@ This project adheres to `Semantic Versioning <http://semver.org/>`_.
* Added ``--max-headers`` to allow setting the max header limit.
* Added ``--compress``.
* Added ``https`` alias command with ``https://`` as the default scheme.
* Fixed an exception when ``stdin`` was a closed fd.
* Fixed an error when ``stdin`` was a closed fd.
* Fixed an error when the config directory was not writeable.
`1.0.3`_ (2019-08-26)
-------------------------
---------------------
* Fixed CVE-2019-10751 — the way the output filename is generated for
``--download`` requests without ``--output`` resulting in a redirect has

View File

@ -55,7 +55,7 @@ class BaseConfigDict(dict):
if e.errno != errno.ENOENT:
raise
def save(self):
def save(self, fail_silently=False):
self['__meta__'] = {
'httpie': __version__
}
@ -65,9 +65,13 @@ class BaseConfigDict(dict):
if self.about:
self['__meta__']['about'] = self.about
with open(self.path, 'w') as f:
json.dump(self, f, indent=4, sort_keys=True, ensure_ascii=True)
f.write('\n')
try:
with open(self.path, 'w') as f:
json.dump(self, f, indent=4, sort_keys=True, ensure_ascii=True)
f.write('\n')
except IOError:
if not fail_silently:
raise
def delete(self):
try:
@ -92,21 +96,5 @@ class Config(BaseConfigDict):
self.update(self.DEFAULTS)
self.directory = directory
def load(self):
super(Config, self).load()
self._migrate_implicit_content_type()
def _get_path(self):
return os.path.join(self.directory, self.name + '.json')
def _migrate_implicit_content_type(self):
"""Migrate the removed implicit_content_type config option"""
try:
implicit_content_type = self.pop('implicit_content_type')
except KeyError:
self.save()
else:
if implicit_content_type == 'form':
self['default_options'].insert(0, '--form')
self.save()
self.load()

View File

@ -82,7 +82,7 @@ class Environment(object):
if not hasattr(self, '_config'):
self._config = Config(directory=self.config_dir)
if self._config.is_new():
self._config.save()
self._config.save(fail_silently=True)
else:
self._config.load()
return self._config

View File

@ -1,5 +1,5 @@
from httpie import __version__
from utils import MockEnvironment, http
from utils import MockEnvironment, http, HTTP_OK
from httpie.context import Environment
@ -11,6 +11,14 @@ def test_default_options(httpbin):
assert r.json['form'] == {"foo": "bar"}
def test_config_dir_not_writeable(httpbin):
r = http(httpbin + '/get', env=MockEnvironment(
config_dir='/',
create_temp_config_dir=False,
))
assert HTTP_OK in r
def test_default_options_overwrite(httpbin):
env = MockEnvironment()
env.config['default_options'] = ['--form']
@ -19,22 +27,6 @@ def test_default_options_overwrite(httpbin):
assert r.json['json'] == {"foo": "bar"}
def test_migrate_implicit_content_type():
config = MockEnvironment().config
config['implicit_content_type'] = 'json'
config.save()
config.load()
assert 'implicit_content_type' not in config
assert not config['default_options']
config['implicit_content_type'] = 'form'
config.save()
config.load()
assert 'implicit_content_type' not in config
assert config['default_options'] == ['--form']
def test_current_version():
version = Environment().config['__meta__']['httpie']
assert version == __version__

View File

@ -39,7 +39,8 @@ class MockEnvironment(Environment):
stdout_isatty = True
is_windows = False
def __init__(self, **kwargs):
def __init__(self, create_temp_config_dir=True, **kwargs):
self.create_temp_config_dir = create_temp_config_dir
if 'stdout' not in kwargs:
kwargs['stdout'] = tempfile.TemporaryFile(
mode='w+b',
@ -55,7 +56,8 @@ class MockEnvironment(Environment):
@property
def config(self):
if not self.config_dir.startswith(tempfile.gettempdir()):
if (self.create_temp_config_dir
and not self.config_dir.startswith(tempfile.gettempdir())):
self.config_dir = mk_config_dir()
self._delete_config_dir = True
return super(MockEnvironment, self).config