diff --git a/.travis.yml b/.travis.yml
index 7037c57..895d219 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,7 +12,7 @@ matrix:
           env: TOXENV=py34
         - python: 3.5
           env: TOXENV=py35
-        - python: 3.6-dev
+        - python: 3.6
           env: TOXENV=py36
         - python: nightly
           env: TOXENV=py37
@@ -21,7 +21,6 @@ matrix:
         - python: 3.5
           env: TOXENV=py2-cover,py3-cover,coverage
     allow_failures:
-        - env: TOXENV=py36
         - env: TOXENV=py37
 
 install:
diff --git a/CHANGES.txt b/CHANGES.txt
index 393cd8d..2105fe8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,13 @@
 Unreleased
 ----------
 
+Bugfix
+~~~~~~
 
+- ``Response.__init__`` would discard ``app_iter`` when a ``Response`` had no
+  body, this would cause issues when ``app_iter`` was an object that was tied
+  to the life-cycle of a web application and had to be properly closed.
+  ``app_iter`` is more advanced API for ``Response`` and thus even if it
+  contains a body and is thus against the HTTP RFC's, we should let the users
+  shoot themselves by returning a body. See
+  https://github.com/Pylons/webob/issues/305
diff --git a/setup.py b/setup.py
index a1418c5..d74f25e 100644
--- a/setup.py
+++ b/setup.py
@@ -38,6 +38,7 @@ setup(
         "Programming Language :: Python :: 3.3",
         "Programming Language :: Python :: 3.4",
         "Programming Language :: Python :: 3.5",
+        "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python :: Implementation :: PyPy",
     ],
diff --git a/webob/response.py b/webob/response.py
index 899fc99..cd376b9 100644
--- a/webob/response.py
+++ b/webob/response.py
@@ -320,7 +320,7 @@ class Response(object):
                     if k.lower() != 'content-length'
                 ]
             self._headerlist.append(('Content-Length', str(len(body))))
-        elif app_iter is None or not code_has_body:
+        elif app_iter is None and not code_has_body:
             app_iter = [b'']
 
         self._app_iter = app_iter

diff --git a/tests/test_response.py b/tests/test_response.py
index 1d272c6..8e9b3ae 100644
--- a/tests/test_response.py
+++ b/tests/test_response.py
@@ -1316,7 +1316,9 @@ def test_204_has_no_body():
 
 def test_204_app_iter_set():
     res = Response(status='204', app_iter=[b'test'])
-    assert res.body == b''
+
+    # You are on your own in this case... you set app_iter you bought it
+    assert res.body == b'test'
     assert res.content_length is None
     assert res.headerlist == []
 
@@ -1353,3 +1355,13 @@ def test_content_type_has_charset():
     assert res.content_type == 'application/foo'
     assert res.charset == 'UTF-8'
     assert res.headers['Content-Type'] == 'application/foo; charset=UTF-8'
+
+def test_app_iter_is_same():
+    class app_iter(object):
+        pass
+
+    my_app_iter = app_iter()
+
+    res = Response(status=204, app_iter=my_app_iter)
+    assert res.app_iter == my_app_iter
+    assert isinstance(res.app_iter, app_iter)

Seems WebOb 1.7 has some glitches with WebTest when a 204 is responded
The recent WebOb 1.7 changes to initialisation function seem to had introduced a side effect when WebTest is used, as webtest will recreate a new `Response` object from the application response.

A simple testcase can be created to showcase the issue:

```
from webob import Response

def wsgi_app(environ, start_response):
    resp = Response(status='204 No Content', body=b'')
    resp.content_type = None
    return resp(environ, start_response)
```

The snippet is meant to work on both 1.6 and 1.7, so it adds some unnecessary values like `body` and `content_type` which are already provided in 1.7 (those values are in fact a nop on 1.7) while they are required on 1.6 to generate a response without content.

The response is as expected both on 1.6 and 1.7

```
Response: 204 No Content


```

Creating a plain webtest `TestApp` from the previous example:

```
from webtest import TestApp

app = TestApp(wsgi_app)
app.get('/')
```

will issue a validation error on WebOb 1.7:

```
Iterator garbage collected without being closedException AssertionError: AssertionError('Iterator garbage collected without being closed',) in <bound method IteratorWrapper.__del__ of <webtest.lint.IteratorWrapper object at 0x100ed0850>> ignored
```

while it will work without the error with WebOb 1.6.

This seems to be related to https://github.com/Pylons/webob/commit/35fd5854b4b706adafa4caab43b6bcdcf3e6a934 as https://github.com/Pylons/webob/blob/master/webob/response.py#L323 throws away the webtest `IteratorWrapper` injected by WebTest replacing it with `[b'']` as `code_has_body` is False and thus breaking `WebTest`

I wouldn't take for granted that if there is an `app_iter` it will be wrong and needs to be discarded as response has no content. It's probably a right assumption in the case of `body`, but discarding `app_iter` might in fact break some application by discarding an iterator which returns an empty response too but has other side effects.
tests/test_response.py::test_204_app_iter_set tests/test_response.py::test_app_iter_is_same
tests/test_response.py::test_response tests/test_response.py::test_set_response_status_binary tests/test_response.py::test_set_response_status_str_no_reason tests/test_response.py::test_set_response_status_str_generic_reason tests/test_response.py::test_set_response_status_code tests/test_response.py::test_set_response_status_bad tests/test_response.py::test_set_response_status_code_generic_reason tests/test_response.py::test_content_type tests/test_response.py::test_init_content_type_w_charset tests/test_response.py::test_init_adds_default_charset_when_not_json tests/test_response.py::test_init_no_charset_when_json tests/test_response.py::test_init_keeps_specified_charset_when_json tests/test_response.py::test_init_doesnt_add_default_content_type_with_bodyless_status tests/test_response.py::test_cookies tests/test_response.py::test_unicode_cookies_error_raised tests/test_response.py::test_unicode_cookies_warning_issued tests/test_response.py::test_cookies_raises_typeerror tests/test_response.py::test_http_only_cookie tests/test_response.py::test_headers tests/test_response.py::test_response_copy tests/test_response.py::test_response_copy_content_md5 tests/test_response.py::test_HEAD_closes tests/test_response.py::test_HEAD_conditional_response_returns_empty_response tests/test_response.py::test_HEAD_conditional_response_range_empty_response tests/test_response.py::test_conditional_response_if_none_match_false tests/test_response.py::test_conditional_response_if_none_match_true tests/test_response.py::test_conditional_response_if_none_match_weak tests/test_response.py::test_conditional_response_if_modified_since_false tests/test_response.py::test_conditional_response_if_modified_since_true tests/test_response.py::test_conditional_response_range_not_satisfiable_response tests/test_response.py::test_HEAD_conditional_response_range_not_satisfiable_response tests/test_response.py::test_md5_etag tests/test_response.py::test_md5_etag_set_content_md5 tests/test_response.py::test_decode_content_defaults_to_identity tests/test_response.py::test_decode_content_with_deflate tests/test_response.py::test_content_length tests/test_response.py::test_app_iter_range tests/test_response.py::test_app_iter_range_inner_method tests/test_response.py::test_has_body tests/test_response.py::test_str_crlf tests/test_response.py::test_from_file tests/test_response.py::test_from_file2 tests/test_response.py::test_from_text_file tests/test_response.py::test_from_file_w_leading_space_in_header tests/test_response.py::test_file_bad_header tests/test_response.py::test_from_file_not_unicode_headers tests/test_response.py::test_file_with_http_version tests/test_response.py::test_file_with_http_version_more_status tests/test_response.py::test_set_status tests/test_response.py::test_set_headerlist tests/test_response.py::test_request_uri_no_script_name tests/test_response.py::test_request_uri_https tests/test_response.py::test_app_iter_range_starts_after_iter_end tests/test_response.py::test_resp_write_app_iter_non_list tests/test_response.py::test_response_file_body_writelines tests/test_response.py::test_response_file_body_tell_text tests/test_response.py::test_response_write_non_str tests/test_response.py::test_response_file_body_write_empty_app_iter tests/test_response.py::test_response_file_body_write_empty_body tests/test_response.py::test_response_file_body_close_not_implemented tests/test_response.py::test_response_file_body_repr tests/test_response.py::test_body_get_is_none tests/test_response.py::test_body_get_is_unicode_notverylong tests/test_response.py::test_body_get_is_unicode tests/test_response.py::test_body_set_not_unicode_or_str tests/test_response.py::test_body_set_unicode tests/test_response.py::test_body_set_under_body_doesnt_exist tests/test_response.py::test_body_del tests/test_response.py::test_text_get_no_charset tests/test_response.py::test_text_get_no_default_body_encoding tests/test_response.py::test_unicode_body tests/test_response.py::test_text_get_decode tests/test_response.py::test_text_set_no_charset tests/test_response.py::test_text_set_no_default_body_encoding tests/test_response.py::test_text_set_not_unicode tests/test_response.py::test_text_del tests/test_response.py::test_body_file_del tests/test_response.py::test_write_unicode tests/test_response.py::test_write_unicode_no_charset tests/test_response.py::test_write_text tests/test_response.py::test_app_iter_del tests/test_response.py::test_charset_set_no_content_type_header tests/test_response.py::test_charset_del_no_content_type_header tests/test_response.py::test_content_type_params_get_no_semicolon_in_content_type_header tests/test_response.py::test_content_type_params_get_semicolon_in_content_type_header tests/test_response.py::test_content_type_params_set_value_dict_empty tests/test_response.py::test_content_type_params_set_ok_param_quoting tests/test_response.py::test_charset_delete tests/test_response.py::test_set_cookie_overwrite tests/test_response.py::test_set_cookie_value_is_None tests/test_response.py::test_set_cookie_expires_is_None_and_max_age_is_int tests/test_response.py::test_set_cookie_expires_is_None_and_max_age_is_timedelta tests/test_response.py::test_set_cookie_expires_is_datetime_and_max_age_is_None tests/test_response.py::test_set_cookie_expires_is_timedelta_and_max_age_is_None tests/test_response.py::test_set_cookie_expires_is_datetime_tz_and_max_age_is_None tests/test_response.py::test_delete_cookie tests/test_response.py::test_delete_cookie_with_path tests/test_response.py::test_delete_cookie_with_domain tests/test_response.py::test_unset_cookie_not_existing_and_not_strict tests/test_response.py::test_unset_cookie_not_existing_and_strict tests/test_response.py::test_unset_cookie_key_in_cookies tests/test_response.py::test_merge_cookies_no_set_cookie tests/test_response.py::test_merge_cookies_resp_is_Response tests/test_response.py::test_merge_cookies_resp_is_wsgi_callable tests/test_response.py::test_body_get_body_is_None_len_app_iter_is_zero tests/test_response.py::test_cache_control_get tests/test_response.py::test_location tests/test_response.py::test_location_unicode tests/test_response.py::test_request_uri_http tests/test_response.py::test_request_uri_no_script_name2 tests/test_response.py::test_cache_control_object_max_age_ten tests/test_response.py::test_cache_control_set_object_error tests/test_response.py::test_cache_expires_set tests/test_response.py::test_status_code_set tests/test_response.py::test_cache_control_set_dict tests/test_response.py::test_cache_control_set_None tests/test_response.py::test_cache_control_set_unicode tests/test_response.py::test_cache_control_set_control_obj_is_not_None tests/test_response.py::test_cache_control_del tests/test_response.py::test_body_file_get tests/test_response.py::test_body_file_write_no_charset tests/test_response.py::test_body_file_write_unicode_encodes tests/test_response.py::test_repr tests/test_response.py::test_cache_expires_set_timedelta tests/test_response.py::test_cache_expires_set_int tests/test_response.py::test_cache_expires_set_None tests/test_response.py::test_cache_expires_set_zero tests/test_response.py::test_encode_content_unknown tests/test_response.py::test_encode_content_identity tests/test_response.py::test_encode_content_gzip_already_gzipped tests/test_response.py::test_encode_content_gzip_notyet_gzipped tests/test_response.py::test_encode_content_gzip_notyet_gzipped_lazy tests/test_response.py::test_encode_content_gzip_buffer_coverage tests/test_response.py::test_decode_content_identity tests/test_response.py::test_decode_content_weird tests/test_response.py::test_decode_content_gzip tests/test_response.py::test__make_location_absolute_has_scheme_only tests/test_response.py::test__make_location_absolute_path tests/test_response.py::test__make_location_absolute_already_absolute tests/test_response.py::test_response_set_body_file1 tests/test_response.py::test_response_set_body_file2 tests/test_response.py::test_response_json_body tests/test_response.py::test_cache_expires_set_zero_then_nonzero tests/test_response.py::test_default_content_type tests/test_response.py::test_default_charset tests/test_response.py::test_header_list_no_defaults tests/test_response.py::test_204_has_no_body tests/test_response.py::test_explicit_charset tests/test_response.py::test_set_content_type tests/test_response.py::test_raises_no_charset tests/test_response.py::test_raises_none_charset tests/test_response.py::test_doesnt_raise_with_charset_content_type_has_no_charset tests/test_response.py::test_content_type_has_charset