[repoapi] fold ClientConnection into Connection
Connection replaces ClientConnection everywhere.
Some notes:
* testlib: .client_cnx and .repo_cnx become aliases of .cnx (we might
not want to tell people to update their tests again for just no real
benefit, so we'll live with these aliases for a while)
* entity.as_rset must not be cached because we risk caching result
sets having a Connection object as .req (helps unittest_breadcrumbs)
* entity._cw_dont_cache_attributes loses its repo/request special
paths and only keeps its storage/bfss user (this helps
unittest_wfobjs)
* moreover, entity.cw_instantiate and .cw_set stop overriding the
attributes cache *after* the before_*_entity hooks have run, because
there is no need to (it is now actually harmful to do it and
unittest_hooks.test_html_tidy* tests remain green because of this)
* rset._build_entity sticks its .req onto the entity just fetched from
the cache, because otherwise it might carry a _cw that is a
Connection object where a Request is expected (helps
unittest_views_actions)
* we get overall better cache usages (entity caches were split over
Request + ClientConnection and Connection), hence the changes
unittest_entity and unittest_wfobjs
* void the ecache when providing the cnx to a request object
Having the entity cache pre-filled when we bind it to the request
object hurts because these entities are bound to Connection objects,
that lack e.g. `.form` or `.add_js` and crash the views subsystem.
Thus, the unittest_testlib.test_error_raised test will are kept
green.
Closes #3837233
"""twisted server for CubicWeb web instances
:organization: Logilab
:copyright: 2001-2011 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
class HTTPResponse(object):
"""An object representing an HTTP Response to be sent to the client.
"""
def __init__(self, twisted_request, code=None, headers=None, stream=None):
self._headers_out = headers
self._twreq = twisted_request
self._stream = stream
self._code = code
self._init_headers()
self._finalize()
def _init_headers(self):
if self._headers_out is None:
return
# initialize headers
for k, values in self._headers_out.getAllRawHeaders():
self._twreq.responseHeaders.setRawHeaders(k, values)
# add content-length if not present
if (self._headers_out.getHeader('content-length') is None
and self._stream is not None):
self._twreq.setHeader('content-length', len(self._stream))
def _finalize(self):
# we must set code before writing anything, else it's too late
if self._code is not None:
self._twreq.setResponseCode(self._code)
if self._stream is not None:
self._twreq.write(str(self._stream))
self._twreq.finish()
def __repr__(self):
return "<%s.%s code=%d>" % (self.__module__, self.__class__.__name__, self._code)