view mercurial/hgweb/request.py @ 2466:e10665147d26

push over http: server side authorization support. new hgrc entries allow_push, deny_push, push_ssl control push over http. allow_push list controls push. if empty or not set, no user can push. if "*", any user (incl. unauthenticated user) can push. if list of user names, only authenticated users in list can push. deny_push list examined before allow_push. if "*", no user can push. if list of user names, no unauthenticated user can push, and no users in list can push. push_ssl requires https connection for push. default is true, so password sniffing can not be done.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Tue, 20 Jun 2006 15:23:01 -0700
parents 09b1c9ef317c
children d0db3462d568
line wrap: on
line source

# hgweb/request.py - An http request from either CGI or the standalone server.
#
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
# Copyright 2005 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

from mercurial.demandload import demandload
demandload(globals(), "socket sys cgi os errno")
from mercurial.i18n import gettext as _

class hgrequest(object):
    def __init__(self, inp=None, out=None, env=None):
        self.inp = inp or sys.stdin
        self.out = out or sys.stdout
        self.env = env or os.environ
        self.form = cgi.parse(self.inp, self.env, keep_blank_values=1)
        self.will_close = True

    def read(self, count=-1):
        return self.inp.read(count)

    def write(self, *things):
        for thing in things:
            if hasattr(thing, "__iter__"):
                for part in thing:
                    self.write(part)
            else:
                try:
                    self.out.write(str(thing))
                except socket.error, inst:
                    if inst[0] != errno.ECONNRESET:
                        raise

    def done(self):
        if self.will_close:
            self.inp.close()
            self.out.close()
        else:
            self.out.flush()

    def header(self, headers=[('Content-type','text/html')]):
        for header in headers:
            self.out.write("%s: %s\r\n" % header)
        self.out.write("\r\n")

    def httphdr(self, type, filename=None, length=0, headers={}):
        headers = headers.items()
        headers.append(('Content-type', type))
        if filename:
            headers.append(('Content-disposition', 'attachment; filename=%s' %
                            filename))
        # we do not yet support http 1.1 chunked transfer, so we have
        # to force connection to close if content-length not known
        if length:
            headers.append(('Content-length', str(length)))
            self.will_close = False
        else:
            headers.append(('Connection', 'close'))
            self.will_close = True
        self.header(headers)