Repository: rasterio/rasterio

Issue:
Rasterio ignores AWS_NO_SIGN_REQUEST=YES environment variable
## Expected behavior and actual behavior.

GDAL supports `AWS_NO_SIGN_REQUEST=YES` option, if set, GDAL assumes that all S3 access can be made without any credentials.

Accessing files from public buckets with `AWS_NO_SIGN_REQUEST=YES` is extremely slow as every `.open` call causes an attempt to obtain STS tokens from IAM service that eventually silently fails. Work around is to configure `botocore` with fake credentials either via files or environment variables.

## Steps to reproduce the problem.


```python
import os
os.environ['AWS_NO_SIGN_REQUEST'] = 'YES'
import logging
logger = logging.getLogger('botocore')
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler()) # Writes to console

import rasterio
from rasterio.session import AWSSession

sess = AWSSession()
```
Inspect logs and see something like:

```
Looking for credentials via: env
Looking for credentials via: env
Looking for credentials via: assume-role
Looking for credentials via: assume-role
Looking for credentials via: assume-role-with-web-identity
Looking for credentials via: assume-role-with-web-identity
Looking for credentials via: shared-credentials-file
Looking for credentials via: shared-credentials-file
Looking for credentials via: custom-process
Looking for credentials via: custom-process
Looking for credentials via: config-file
Looking for credentials via: config-file
Looking for credentials via: ec2-credentials-file
Looking for credentials via: ec2-credentials-file
Looking for credentials via: boto-config
Looking for credentials via: boto-config
Looking for credentials via: container-role
Looking for credentials via: container-role
Looking for credentials via: iam-role
Looking for credentials via: iam-role
```

These are triggered from here:

https://github.com/mapbox/rasterio/blob/d8f342e4e6d2a89dd17b488ec912d1e51a8f13f3/rasterio/session.py#L281

via 
https://github.com/mapbox/rasterio/blob/d8f342e4e6d2a89dd17b488ec912d1e51a8f13f3/rasterio/env.py#L395

decorator.

I think following changes would be ideal:

1. `AWSSession` should not default `aws_unsigned=False`, but instead should inspect content of `AWS_NO_SIGN_REQUEST` environment variable if that is set.
2. Should not attempt to obtain credentials if `aws_unsigned=True`, currently it happens regardless of user settings since `self._session` is never `None`, see previously reported and fixed #1637 seems to have re-surfaced.

## Operating system

Linux, Ubuntu 18.04

## Rasterio version and provenance
1.1.5




Discussion:

Resolving patch:
diff --git a/rasterio/session.py b/rasterio/session.py
--- a/rasterio/session.py
+++ b/rasterio/session.py
@@ -1,6 +1,7 @@
 """Abstraction for sessions in various clouds."""
 
 import logging
+import os
 
 from rasterio.path import parse_path, UnparsedPath
 
@@ -276,9 +277,13 @@ def __init__(
                 profile_name=profile_name)
 
         self.requester_pays = requester_pays
-        self.unsigned = aws_unsigned
+        self.unsigned = bool(os.getenv("AWS_NO_SIGN_REQUEST", aws_unsigned))
         self.endpoint_url = endpoint_url
-        self._creds = self._session._session.get_credentials() if self._session else None
+        self._creds = (
+            self._session._session.get_credentials()
+            if not self.unsigned and self._session
+            else None
+        )
 
     @classmethod
     def hascreds(cls, config):


Test patch:
diff --git a/tests/test_session.py b/tests/test_session.py
--- a/tests/test_session.py
+++ b/tests/test_session.py
@@ -224,3 +224,15 @@ def test_session_aws_or_dummy_dummy(monkeypatch):
     with monkeypatch.context() as mpctx:
         mpctx.setattr("rasterio.session.boto3", None)
         assert isinstance(Session.aws_or_dummy(), DummySession)
+
+
+def test_no_sign_request(monkeypatch):
+    """If AWS_NO_SIGN_REQUEST is set do not default to aws_unsigned=False"""
+    monkeypatch.setenv("AWS_NO_SIGN_REQUEST", "YES")
+    assert AWSSession().unsigned
+
+
+def test_no_credentialization_if_unsigned(monkeypatch):
+    """Don't get credentials if we're not signing, see #1984"""
+    sesh = AWSSession(aws_unsigned=True)
+    assert sesh._creds is None