cubicweb/etwist/http.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Fri, 01 Dec 2017 11:19:19 +0100
changeset 12244 6a71cb23f827
parent 11877 32a3860c799d
permissions -rw-r--r--
Disable pytest's logs reporting CubicWeb already prints captured logs in stderr upon test failure, so we get them twice. Until we fix our logging management, disabling pytest capture and restore brings the output level back to sanity.

"""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
"""




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):
        # cw_failed is set on errors such as "connection aborted by client". In
        # such cases, req.finish() was already called and calling it a twice
        # would crash
        if getattr(self._twreq, 'cw_failed', False):
            return
        # 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)