<commit_before># -*- coding: iso8859-1 -*-
#
# Copyright (C) 2005 Edgewall Software
# Copyright (C) 2005 <NAME> <<EMAIL>>
#
# Trac is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Trac is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: <NAME> <<EMAIL>>

import mimetypes
import os
import os.path

from trac.core import *
from trac.perm import PermissionCache, PermissionError
from trac.util import escape, http_date, TRUE
from trac.web.href import Href
from trac.web.session import Session


class RequestDone(Exception):
    """
    Marker exception that indicates whether request processing has completed
    and a response was sent.
    """


class Request(object):
    """
    This class is used to abstract the interface between different frontends.

    Trac modules must use this interface. It is not allowed to have
    frontend (cgi, tracd, mod_python) specific code in the modules.
    """

    method = None
    scheme = None
    server_name = None
    server_port = None
    remote_addr = None
    remote_user = None

    args = None
    hdf = None
    authname = None
    perm = None
    session = None
    _headers = None # additional headers to send

    def __init__(self):
        import Cookie
        self.incookie = Cookie.SimpleCookie()
        self.outcookie = Cookie.SimpleCookie()
        self._headers = []

    def get_header(self, name):
        """
        Return the value of the specified HTTP header, or `None` if there's no
        such header in the request.
        """
        raise NotImplementedError

    def send_response(self, code):
        """
        Set the status code of the response.
        """
        raise NotImplementedError

    def send_header(self, name, value):
        """
        Send the response header with the specified name and value.
        """
        raise NotImplementedError

    def end_headers(self):
        """
        Must be called after all headers have been sent and before the actual
        content is written.
        """
        raise NotImplementedError

    def check_modified(self, timesecs, extra=''):
        """
        Check the request "If-None-Match" header against an entity tag generated
        from the specified last modified time in seconds (`timesecs`),
        optionally appending an `extra` string to indicate variants of the
        requested resource.

        If the generated tag matches the "If-None-Match" header of the request,
        this method sends a "304 Not Modified" response to the client.
        Otherwise, it adds the entity tag as as "ETag" header to the response so
        that consequetive requests can be cached.
        """
        etag = 'W"%s/%d/%s"' % (self.authname, timesecs, extra)
        inm = self.get_header('If-None-Match')
        if (not inm or inm != etag):
            self._headers.append(('ETag', etag))
        else:
            self.send_response(304)
            self.end_headers()
            raise RequestDone()

    def redirect(self, url):
        """
        Send a redirect to the client, forwarding to the specified URL. The
        `url` may be relative or absolute, relative URLs will be translated
        appropriately.
        """
        if self.session:
            self.session.save() # has to be done before the redirect is sent
        self.send_response(302)
        if not url.startswith('http://') and not url.startswith('https://'):
            # Make sure the URL is absolute
            url = absolute_url(self, url)
        self.send_header('Location', url)
        self.send_header('Content-Type', 'text/plain')
        self.send_header('Pragma', 'no-cache')
        self.send_header('Cache-control', 'no-cache')
        self.send_header('Expires', 'Fri, 01 Jan 1999 00:00:00 GMT')
        cookies = self.outcookie.output(header='')
        for cookie in cookies.splitlines():
            self.send_header('Set-Cookie', cookie.strip())
        self.end_headers()
        self.write('Redirecting...')
        raise RequestDone()

    def display(self, template, content_type='text/html', response=200):
        """
        Render the response using the ClearSilver template given by the
        `template` parameter, which can be either the name of the template file,
        or an already parsed `neo_cs.CS` object.
        """
        assert self.hdf, 'HDF dataset not available'
        if self.args.has_key('hdfdump'):
            # FIXME: the administrator should probably be able to disable HDF
            #        dumps
            content_type = 'text/plain'
            data = str(self.hdf)
        else:
            data = self.hdf.render(template)

        self.send_response(response)
        self.send_header('Cache-control', 'must-revalidate')
        self.send_header('Expires', 'Fri, 01 Jan 1999 00:00:00 GMT')
        self.send_header('Content-Type', content_type + ';charset=utf-8')
        self.send_header('Content-Length', len(data))
        for name, value in self._headers:
            self.send_header(name, value)
        cookies = self.outcookie.output(header='')
        for cookie in cookies.splitlines():
            self.send_header('Set-Cookie', cookie.strip())
        self.end_headers()

        if self.method != 'HEAD':
            self.write(data)

        raise RequestDone

    def send_file(self, path, mimetype=None):
        """
        Send a local file to the browser. This method includes the
        "Last-Modified", "Content-Type" and "Content-Length" headers in the
        response, corresponding to the file attributes. It also checks the last
        modification time of the local file against the "If-Modified-Since"
        provided by the user agent, and sends a "304 Not Modified" response if
        it matches.
        """
        if not os.path.isfile(path):
            raise TracError, "File %s not found" % path

        stat = os.stat(path)
        last_modified = http_date(stat.st_mtime)
        if last_modified == self.get_header('If-Modified-Since'):
            self.send_response(304)
            raise RequestDone

        self.send_response(200)
        if not mimetype:
            mimetype = mimetypes.guess_type(path)[0]
        self.send_header('Content-Type', mimetype)
        self.send_header('Content-Length', stat.st_size)
        self.send_header('Last-Modified', last_modified)
        self.end_headers()

        if self.method != 'HEAD':
            try:<commit_msg>A call req.send_response() always has to be followed by a call to req.end_headers().<commit_after># -*- coding: iso8859-1 -*-
#
# Copyright (C) 2005 Edgewall Software
# Copyright (C) 2005 <NAME> <<EMAIL>>
#
# Trac is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Trac is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: <NAME> <<EMAIL>>

import mimetypes
import os
import os.path

from trac.core import *
from trac.perm import PermissionCache, PermissionError
from trac.util import escape, http_date, TRUE
from trac.web.href import Href
from trac.web.session import Session


class RequestDone(Exception):
    """
    Marker exception that indicates whether request processing has completed
    and a response was sent.
    """


class Request(object):
    """
    This class is used to abstract the interface between different frontends.

    Trac modules must use this interface. It is not allowed to have
    frontend (cgi, tracd, mod_python) specific code in the modules.
    """

    method = None
    scheme = None
    server_name = None
    server_port = None
    remote_addr = None
    remote_user = None

    args = None
    hdf = None
    authname = None
    perm = None
    session = None
    _headers = None # additional headers to send

    def __init__(self):
        import Cookie
        self.incookie = Cookie.SimpleCookie()
        self.outcookie = Cookie.SimpleCookie()
        self._headers = []

    def get_header(self, name):
        """
        Return the value of the specified HTTP header, or `None` if there's no
        such header in the request.
        """
        raise NotImplementedError

    def send_response(self, code):
        """
        Set the status code of the response.
        """
        raise NotImplementedError

    def send_header(self, name, value):
        """
        Send the response header with the specified name and value.
        """
        raise NotImplementedError

    def end_headers(self):
        """
        Must be called after all headers have been sent and before the actual
        content is written.
        """
        raise NotImplementedError

    def check_modified(self, timesecs, extra=''):
        """
        Check the request "If-None-Match" header against an entity tag generated
        from the specified last modified time in seconds (`timesecs`),
        optionally appending an `extra` string to indicate variants of the
        requested resource.

        If the generated tag matches the "If-None-Match" header of the request,
        this method sends a "304 Not Modified" response to the client.
        Otherwise, it adds the entity tag as as "ETag" header to the response so
        that consequetive requests can be cached.
        """
        etag = 'W"%s/%d/%s"' % (self.authname, timesecs, extra)
        inm = self.get_header('If-None-Match')
        if (not inm or inm != etag):
            self._headers.append(('ETag', etag))
        else:
            self.send_response(304)
            self.end_headers()
            raise RequestDone()

    def redirect(self, url):
        """
        Send a redirect to the client, forwarding to the specified URL. The
        `url` may be relative or absolute, relative URLs will be translated
        appropriately.
        """
        if self.session:
            self.session.save() # has to be done before the redirect is sent
        self.send_response(302)
        if not url.startswith('http://') and not url.startswith('https://'):
            # Make sure the URL is absolute
            url = absolute_url(self, url)
        self.send_header('Location', url)
        self.send_header('Content-Type', 'text/plain')
        self.send_header('Pragma', 'no-cache')
        self.send_header('Cache-control', 'no-cache')
        self.send_header('Expires', 'Fri, 01 Jan 1999 00:00:00 GMT')
        cookies = self.outcookie.output(header='')
        for cookie in cookies.splitlines():
            self.send_header('Set-Cookie', cookie.strip())
        self.end_headers()
        self.write('Redirecting...')
        raise RequestDone()

    def display(self, template, content_type='text/html', response=200):
        """
        Render the response using the ClearSilver template given by the
        `template` parameter, which can be either the name of the template file,
        or an already parsed `neo_cs.CS` object.
        """
        assert self.hdf, 'HDF dataset not available'
        if self.args.has_key('hdfdump'):
            # FIXME: the administrator should probably be able to disable HDF
            #        dumps
            content_type = 'text/plain'
            data = str(self.hdf)
        else:
            data = self.hdf.render(template)

        self.send_response(response)
        self.send_header('Cache-control', 'must-revalidate')
        self.send_header('Expires', 'Fri, 01 Jan 1999 00:00:00 GMT')
        self.send_header('Content-Type', content_type + ';charset=utf-8')
        self.send_header('Content-Length', len(data))
        for name, value in self._headers:
            self.send_header(name, value)
        cookies = self.outcookie.output(header='')
        for cookie in cookies.splitlines():
            self.send_header('Set-Cookie', cookie.strip())
        self.end_headers()

        if self.method != 'HEAD':
            self.write(data)

        raise RequestDone

    def send_file(self, path, mimetype=None):
        """
        Send a local file to the browser. This method includes the
        "Last-Modified", "Content-Type" and "Content-Length" headers in the
        response, corresponding to the file attributes. It also checks the last
        modification time of the local file against the "If-Modified-Since"
        provided by the user agent, and sends a "304 Not Modified" response if
        it matches.
        """
        if not os.path.isfile(path):
            raise TracError, "File %s not found" % path

        stat = os.stat(path)
        last_modified = http_date(stat.st_mtime)
        if last_modified == self.get_header('If-Modified-Since'):
            self.send_response(304)
            self.end_headers()
            raise RequestDone

        self.send_response(200)
        if not mimetype:
            mimetype = mimetypes.guess_type(path)[0]
        self.send_header('Content-Type', mimetype)
        self.send_header('Content-Length', stat.st_size)
        self.send_header('Last-Modified', last_modified)
        self.end_headers()

        if self.method != 'HEAD':
            try:
{'fraction_non_alphanumeric': 0.09220059667566416, 'fraction_numerical': 0.009802528768290951, 'mean_word_length': 2.4238813229571985, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4286549', 'n_tokens_mistral': 3943, 'n_tokens_neox': 3742, 'n_words': 1372}