Beispiel #1
0
def main():
	class MyRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):

		def _is_cgi(self):
			path = self.path

			x = '/cgi-bin/htmlhelp.cgi'
			i = len(x)
			if path[:i] == x and (not path[i:] or path[i] == '/'):
				self.cgi_info = '', path[1:i]
				return 1
			return 0
	
	CGIHTTPServer.test(MyRequestHandler)
Beispiel #2
0
 def test_url_collapse_path_split(self):
     test_vectors = {
         "": ("/", ""),
         "..": IndexError,
         "/.//..": IndexError,
         "/": ("/", ""),
         "//": ("/", ""),
         "/\\": ("/", "\\"),
         "/.//": ("/", ""),
         "cgi-bin/file1.py": ("/cgi-bin", "file1.py"),
         "/cgi-bin/file1.py": ("/cgi-bin", "file1.py"),
         "a": ("/", "a"),
         "/a": ("/", "a"),
         "//a": ("/", "a"),
         "./a": ("/", "a"),
         "./C:/": ("/C:", ""),
         "/a/b": ("/a", "b"),
         "/a/b/": ("/a/b", ""),
         "/a/b/c/..": ("/a/b", ""),
         "/a/b/c/../d": ("/a/b", "d"),
         "/a/b/c/../d/e/../f": ("/a/b/d", "f"),
         "/a/b/c/../d/e/../../f": ("/a/b", "f"),
         "/a/b/c/../d/e/.././././..//f": ("/a/b", "f"),
         "../a/b/c/../d/e/.././././..//f": IndexError,
         "/a/b/c/../d/e/../../../f": ("/a", "f"),
         "/a/b/c/../d/e/../../../../f": ("/", "f"),
         "/a/b/c/../d/e/../../../../../f": IndexError,
         "/a/b/c/../d/e/../../../../f/..": ("/", ""),
     }
     for path, expected in test_vectors.iteritems():
         if isinstance(expected, type) and issubclass(expected, Exception):
             self.assertRaises(expected, CGIHTTPServer._url_collapse_path_split, path)
         else:
             actual = CGIHTTPServer._url_collapse_path_split(path)
             self.assertEqual(expected, actual, msg="path = %r\nGot:    %r\nWanted: %r" % (path, actual, expected))
 def is_cgi(self):
     collapsed_path = CGIHTTPServer._url_collapse_path(self.path)
     dir_sep = collapsed_path.find('/', 1)
     head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:]
     if head in self.cgi_directories:
         self.cgi_info = head, tail
         return True
     return False
 def do_POST(self):
     collapsed_path = CGIHTTPServer._url_collapse_path(urllib.unquote(self.path))
     if collapsed_path.endswith("/") and collapsed_path != "/":
         collapsed_path = collapsed_path[:-1]
     if collapsed_path == "/sink/a":
         return self.do_sink_a()
     else:
         self.send_error(404, "No such endpoint (%s)" % collapsed_path)
         return
Beispiel #5
0
 def is_cgi(self):
     path = self.path
     i = path.rfind("?")
     if i >= 0:
         path, query = path[:i], path[i:]
     else:
         query = ""
     root, ext = os.path.splitext(path)
     if self.is_cgi_extension(ext):
         self.cgi_info = CGIHTTPServer._url_collapse_path_split(self.path)
         return True
     return False
Beispiel #6
0
 def is_cgi(self):
     path = self.path
     i = path.rfind('?')
     if i >= 0:
         path, query = path[:i], path[i:]
     else:
         query = ''
     root, ext = os.path.splitext(path)
     if self.is_cgi_extension(ext):
         self.cgi_info = CGIHTTPServer._url_collapse_path_split(self.path)
         return True
     return False
Beispiel #7
0
 def is_cgi(self):
     splitpath = CGIHTTPServer._url_collapse_path_split(self.path)
     script_query = splitpath[1].split("?", 1)
     if script_query[0].endswith(".py"):
         if splitpath[0].startswith("/"):
             # Workaround for some weirdness with how CGIHTTPServer
             # computes the SCRIPT_NAME environment variable.
             splitpath = list(splitpath)
             splitpath[0] = ''
             splitpath = tuple(splitpath)
         self.cgi_info = splitpath
         return True
     return False
Beispiel #8
0
 def test_url_collapse_path(self):
     # verify tail is the last portion and head is the rest on proper urls
     test_vectors = {
         '': '//',
         '..': IndexError,
         '/.//..': IndexError,
         '/': '//',
         '//': '//',
         '/\\': '//\\',
         '/.//': '//',
         'cgi-bin/file1.py': '/cgi-bin/file1.py',
         '/cgi-bin/file1.py': '/cgi-bin/file1.py',
         'a': '//a',
         '/a': '//a',
         '//a': '//a',
         './a': '//a',
         './C:/': '/C:/',
         '/a/b': '/a/b',
         '/a/b/': '/a/b/',
         '/a/b/.': '/a/b/',
         '/a/b/c/..': '/a/b/',
         '/a/b/c/../d': '/a/b/d',
         '/a/b/c/../d/e/../f': '/a/b/d/f',
         '/a/b/c/../d/e/../../f': '/a/b/f',
         '/a/b/c/../d/e/.././././..//f': '/a/b/f',
         '../a/b/c/../d/e/.././././..//f': IndexError,
         '/a/b/c/../d/e/../../../f': '/a/f',
         '/a/b/c/../d/e/../../../../f': '//f',
         '/a/b/c/../d/e/../../../../../f': IndexError,
         '/a/b/c/../d/e/../../../../f/..': '//',
         '/a/b/c/../d/e/../../../../f/../.': '//',
     }
     for path, expected in test_vectors.iteritems():
         if isinstance(expected, type) and issubclass(expected, Exception):
             self.assertRaises(expected, CGIHTTPServer._url_collapse_path,
                               path)
         else:
             actual = CGIHTTPServer._url_collapse_path(path)
             self.assertEqual(expected,
                              actual,
                              msg='path = %r\nGot:    %r\nWanted: %r' %
                              (path, actual, expected))
Beispiel #9
0
    def is_cgi(self):
        #                v added `CGIHTTPServer.`

        collapsed_path = CGIHTTPServer._url_collapse_path(self.path)
        dir_sep = collapsed_path.find('/', 1)
        head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep + 1:]

        if ".class" in tail:
            self.cgi_info = head, tail
            return True

        if head == "/" and tail == "":
            print('head' + head + 'tail' + tail)
            return False
        if head in self.cgi_directories:
            if not tail.endswith('.html'):  # <-- new line
                #if tail.endswith('.py'): # <-- new line
                self.cgi_info = head, tail
                return True
        return False
Beispiel #10
0
 def test_url_collapse_path(self):
     # verify tail is the last portion and head is the rest on proper urls
     test_vectors = {
         '': '//',
         '..': IndexError,
         '/.//..': IndexError,
         '/': '//',
         '//': '//',
         '/\\': '//\\',
         '/.//': '//',
         'cgi-bin/file1.py': '/cgi-bin/file1.py',
         '/cgi-bin/file1.py': '/cgi-bin/file1.py',
         'a': '//a',
         '/a': '//a',
         '//a': '//a',
         './a': '//a',
         './C:/': '/C:/',
         '/a/b': '/a/b',
         '/a/b/': '/a/b/',
         '/a/b/.': '/a/b/',
         '/a/b/c/..': '/a/b/',
         '/a/b/c/../d': '/a/b/d',
         '/a/b/c/../d/e/../f': '/a/b/d/f',
         '/a/b/c/../d/e/../../f': '/a/b/f',
         '/a/b/c/../d/e/.././././..//f': '/a/b/f',
         '../a/b/c/../d/e/.././././..//f': IndexError,
         '/a/b/c/../d/e/../../../f': '/a/f',
         '/a/b/c/../d/e/../../../../f': '//f',
         '/a/b/c/../d/e/../../../../../f': IndexError,
         '/a/b/c/../d/e/../../../../f/..': '//',
         '/a/b/c/../d/e/../../../../f/../.': '//',
     }
     for path, expected in test_vectors.iteritems():
         if isinstance(expected, type) and issubclass(expected, Exception):
             self.assertRaises(expected,
                               CGIHTTPServer._url_collapse_path, path)
         else:
             actual = CGIHTTPServer._url_collapse_path(path)
             self.assertEqual(expected, actual,
                              msg='path = %r\nGot:    %r\nWanted: %r' %
                              (path, actual, expected))
Beispiel #11
0
 def test_url_collapse_path_split(self):
     test_vectors = {
         '': ('/', ''),
         '..': IndexError,
         '/.//..': IndexError,
         '/': ('/', ''),
         '//': ('/', ''),
         '/\\': ('/', '\\'),
         '/.//': ('/', ''),
         'cgi-bin/file1.py': ('/cgi-bin', 'file1.py'),
         '/cgi-bin/file1.py': ('/cgi-bin', 'file1.py'),
         '/cgi-bin/file1.py/PATH-INFO': ('/cgi-bin', 'file1.py/PATH-INFO'),
         'a': ('/', 'a'),
         '/a': ('/', 'a'),
         '//a': ('/', 'a'),
         './a': ('/', 'a'),
         './C:/': ('/C:', ''),
         '/a/b': ('/a', 'b'),
         '/a/b/': ('/a/b', ''),
         '/a/b/c/..': ('/a/b', ''),
         '/a/b/c/../d': ('/a/b', 'd'),
         '/a/b/c/../d/e/../f': ('/a/b/d', 'f'),
         '/a/b/c/../d/e/../../f': ('/a/b', 'f'),
         '/a/b/c/../d/e/.././././..//f': ('/a/b', 'f'),
         '../a/b/c/../d/e/.././././..//f': IndexError,
         '/a/b/c/../d/e/../../../f': ('/a', 'f'),
         '/a/b/c/../d/e/../../../../f': ('/', 'f'),
         '/a/b/c/../d/e/../../../../../f': IndexError,
         '/a/b/c/../d/e/../../../../f/..': ('/', ''),
     }
     for path, expected in test_vectors.iteritems():
         if isinstance(expected, type) and issubclass(expected, Exception):
             self.assertRaises(expected,
                               CGIHTTPServer._url_collapse_path_split, path)
         else:
             actual = CGIHTTPServer._url_collapse_path_split(path)
             self.assertEqual(expected,
                              actual,
                              msg='path = %r\nGot:    %r\nWanted: %r' %
                              (path, actual, expected))
Beispiel #12
0
 def test_url_collapse_path_split(self):
     test_vectors = {
         '': ('/', ''),
         '..': IndexError,
         '/.//..': IndexError,
         '/': ('/', ''),
         '//': ('/', ''),
         '/\\': ('/', '\\'),
         '/.//': ('/', ''),
         'cgi-bin/file1.py': ('/cgi-bin', 'file1.py'),
         '/cgi-bin/file1.py': ('/cgi-bin', 'file1.py'),
         '/cgi-bin/file1.py/PATH-INFO': ('/cgi-bin', 'file1.py/PATH-INFO'),
         'a': ('/', 'a'),
         '/a': ('/', 'a'),
         '//a': ('/', 'a'),
         './a': ('/', 'a'),
         './C:/': ('/C:', ''),
         '/a/b': ('/a', 'b'),
         '/a/b/': ('/a/b', ''),
         '/a/b/c/..': ('/a/b', ''),
         '/a/b/c/../d': ('/a/b', 'd'),
         '/a/b/c/../d/e/../f': ('/a/b/d', 'f'),
         '/a/b/c/../d/e/../../f': ('/a/b', 'f'),
         '/a/b/c/../d/e/.././././..//f': ('/a/b', 'f'),
         '../a/b/c/../d/e/.././././..//f': IndexError,
         '/a/b/c/../d/e/../../../f': ('/a', 'f'),
         '/a/b/c/../d/e/../../../../f': ('/', 'f'),
         '/a/b/c/../d/e/../../../../../f': IndexError,
         '/a/b/c/../d/e/../../../../f/..': ('/', ''),
     }
     for path, expected in test_vectors.iteritems():
         if isinstance(expected, type) and issubclass(expected, Exception):
             self.assertRaises(expected,
                               CGIHTTPServer._url_collapse_path_split, path)
         else:
             actual = CGIHTTPServer._url_collapse_path_split(path)
             self.assertEqual(expected, actual,
                              msg='path = %r\nGot:    %r\nWanted: %r' %
                              (path, actual, expected))
Beispiel #13
0
                break
            head, tail = head[:i], head[i:] + tail
            temp = self.translate_path(head)

        if os.path.isdir(temp):
            for index in self.indices:
                if os.path.exists(os.path.join(temp, index)):
                    head = posixpath.join(head, index)
                    break

        ctype = self.guess_type(head)
        if ctype in self.actions:
            os.environ['REDIRECT_STATUS'] = '200'
            head = self.actions[ctype] + head

        self.path = head + tail + query

    def translate_path(self, path):
        path = posixpath.normpath(urllib.unquote(path))
        n = len(self.aliases)
        for i in range(n):
            url, dir = self.aliases[n - i - 1]
            length = len(url)
            if path[:length] == url:
                return dir + path[length:]
        return ''


if __name__ == '__main__':
    CGIHTTPServer.test(PHPHTTPRequestHandler)
Beispiel #14
0
    def run_cgi(self):
        """Execute a CGI script."""
        path = self.path
        dir, rest = self.cgi_info

        i = path.find('/', len(dir) + 1)
        while i >= 0:
            nextdir = path[:i]
            nextrest = path[i + 1:]

            scriptdir = self.translate_path(nextdir)
            if os.path.isdir(scriptdir):
                dir, rest = nextdir, nextrest
                i = path.find('/', len(dir) + 1)
            else:
                break

        # find an explicit query string, if present.
        i = rest.rfind('?')
        if i >= 0:
            rest, query = rest[:i], rest[i + 1:]
        else:
            query = ''

        # dissect the part after the directory name into a script name &
        # a possible additional path, to be stored in PATH_INFO.
        i = rest.find('/')
        if i >= 0:
            script, rest = rest[:i], rest[i:]
        else:
            script, rest = rest, ''

        scriptname = dir + '/' + script
        scriptfile = self.translate_path(scriptname)
        if not os.path.exists(scriptfile):
            self.send_error(404, "No such CGI script (%r)" % scriptname)
            return
        if not os.path.isfile(scriptfile):
            self.send_error(403,
                            "CGI script is not a plain file (%r)" % scriptname)
            return
        ispy = self.is_python(scriptname)
        if not ispy:
            if not (self.have_fork or self.have_popen2 or self.have_popen3):
                self.send_error(
                    403, "CGI script is not a Python script (%r)" % scriptname)
                return
            if not self.is_executable(scriptfile):
                self.send_error(
                    403, "CGI script is not executable (%r)" % scriptname)
                return

        # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
        # XXX Much of the following could be prepared ahead of time!
        env = {}
        env['SERVER_SOFTWARE'] = self.version_string()
        env['SERVER_NAME'] = self.server.server_name
        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
        env['SERVER_PROTOCOL'] = self.protocol_version
        env['SERVER_PORT'] = str(self.server.server_port)
        env['REQUEST_METHOD'] = self.command
        uqrest = urllib.unquote(rest)
        env['PATH_INFO'] = uqrest
        env['PATH_TRANSLATED'] = self.translate_path(uqrest)
        env['SCRIPT_NAME'] = scriptname
        if query:
            env['QUERY_STRING'] = query
        host = self.address_string()
        if host != self.client_address[0]:
            env['REMOTE_HOST'] = host
        env['REMOTE_ADDR'] = self.client_address[0]
        authorization = self.headers.getheader("authorization")
        if authorization:
            authorization = authorization.split()
            if len(authorization) == 2:
                import base64, binascii
                env['AUTH_TYPE'] = authorization[0]
                if authorization[0].lower() == "basic":
                    try:
                        authorization = base64.decodestring(authorization[1])
                    except binascii.Error:
                        pass
                    else:
                        authorization = authorization.split(':')
                        if len(authorization) == 2:
                            env['REMOTE_USER'] = authorization[0]
        # XXX REMOTE_IDENT
        if self.headers.typeheader is None:
            env['CONTENT_TYPE'] = self.headers.type
        else:
            env['CONTENT_TYPE'] = self.headers.typeheader
        length = self.headers.getheader('content-length')
        if length:
            env['CONTENT_LENGTH'] = length
        referer = self.headers.getheader('referer')
        if referer:
            env['HTTP_REFERER'] = referer
        accept = []
        for line in self.headers.getallmatchingheaders('accept'):
            if line[:1] in "\t\n\r ":
                accept.append(line.strip())
            else:
                accept = accept + line[7:].split(',')
        env['HTTP_ACCEPT'] = ','.join(accept)
        ua = self.headers.getheader('user-agent')
        if ua:
            env['HTTP_USER_AGENT'] = ua
        co = filter(None, self.headers.getheaders('cookie'))
        if co:
            env['HTTP_COOKIE'] = ', '.join(co)
        # XXX Other HTTP_* headers
        # Since we're setting the env in the parent, provide empty
        # values to override previously set values
        for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
                  'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
            env.setdefault(k, "")
        os.environ.update(env)

        self.send_response(200, "Script output follows")

        decoded_query = query.replace('+', ' ')

        if self.have_fork:
            # Unix -- fork as we should
            args = [script]
            if '=' not in decoded_query:
                args.append(decoded_query)
            nobody = CGIHTTPServer.nobody_uid()
            self.wfile.flush()  # Always flush before forking
            pid = os.fork()
            if pid != 0:
                # Parent
                pid, sts = os.waitpid(pid, 0)
                # throw away additional data [see bug #427345]
                while select.select([self.rfile], [], [], 0)[0]:
                    if not self.rfile.read(1):
                        break
                if sts:
                    self.log_error("CGI script exit status %#x", sts)
                return
            # Child
            try:
                try:
                    os.setuid(nobody)
                except os.error:
                    pass
                os.dup2(self.rfile.fileno(), 0)
                os.dup2(self.wfile.fileno(), 1)
                #hack to import python scripts due to permission restrictions
                #regarding launching another interpreter instance
                root, ext = os.path.splitext(scriptfile)
                if ext == '.py':
                    root, script = os.path.split(root)
                    sys.path.append(root)
                    __import__(script)
                    os._exit(0)
                else:
                    os.execve(scriptfile, args, os.environ)
            except:
                self.server.handle_error(self.request, self.client_address)
                os._exit(127)
Beispiel #15
0
    def run_cgi(self):
        """Execute a CGI script."""
        dir, rest = self.cgi_info
        o = urlparse.urlparse(rest)
        # find an explicit query string, if present.
        query = str(o.query)

        # dissect the part after the directory name into a script name &
        # a possible additional path, to be stored in PATH_INFO.
        path = str(o.path)
        i = path.find('/')
        if i >= 0:
            script, rest = path[:i], path[i:]
        else:
            script, rest = path, ''

        scriptname = dir + '/' + script
        scriptfile = self.translate_path(scriptname)
        if not os.path.exists(scriptfile):
            self.send_error(404, "No such CGI script (%r)" % scriptname)
            return
        if not os.path.isfile(scriptfile):
            self.send_error(403, "CGI script is not a plain file (%r)" %
                            scriptname)
            return
        ispy = self.is_python(scriptname)
        if not ispy:
            if not (self.have_fork or self.have_popen2 or self.have_popen3):
                self.send_error(403, "CGI script is not a Python script (%r)" %
                                scriptname)
                return
            if not self.is_executable(scriptfile):
                self.send_error(403, "CGI script is not executable (%r)" %
                                scriptname)
                return

        # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
        # XXX Much of the following could be prepared ahead of time!
        env = copy.deepcopy(os.environ)
        env['SERVER_SOFTWARE'] = self.version_string()
        env['SERVER_NAME'] = self.server.server_name
        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
        env['SERVER_PROTOCOL'] = self.protocol_version
        env['SERVER_PORT'] = str(self.server.server_port)
        env['REQUEST_METHOD'] = self.command
        if query != '':
            if rest != '/captcha':
                rest = script + rest
            else:
                query = query.split('?')[0]
        rest = rest.replace('blog.py/', '')
        uqrest = urllib.unquote(rest)
        env['PATH_INFO'] = '/'+uqrest
        env['PATH_TRANSLATED'] = self.translate_path(uqrest)
        env['SCRIPT_NAME'] = scriptname
        if query:
            env['QUERY_STRING'] = query
        host = self.address_string()
        if host != self.client_address[0]:
            env['REMOTE_HOST'] = host
        env['REMOTE_ADDR'] = self.client_address[0]
        authorization = self.headers.getheader("authorization")
        if authorization:
            authorization = authorization.split()
            if len(authorization) == 2:
                import base64, binascii
                env['AUTH_TYPE'] = authorization[0]
                if authorization[0].lower() == "basic":
                    try:
                        authorization = base64.decodestring(authorization[1])
                    except binascii.Error:
                        pass
                    else:
                        authorization = authorization.split(':')
                        if len(authorization) == 2:
                            env['REMOTE_USER'] = authorization[0]
        # XXX REMOTE_IDENT
        if self.headers.typeheader is None:
            env['CONTENT_TYPE'] = self.headers.type
        else:
            env['CONTENT_TYPE'] = self.headers.typeheader
        length = self.headers.getheader('content-length')
        if length:
            env['CONTENT_LENGTH'] = length
        referer = self.headers.getheader('referer')
        if referer:
            env['HTTP_REFERER'] = referer
        accept = []
        for line in self.headers.getallmatchingheaders('accept'):
            if line[:1] in "\t\n\r ":
                accept.append(line.strip())
            else:
                accept = accept + line[7:].split(',')
        env['HTTP_ACCEPT'] = ','.join(accept)
        ua = self.headers.getheader('user-agent')
        if ua:
            env['HTTP_USER_AGENT'] = ua
        co = filter(None, self.headers.getheaders('cookie'))
        if co:
            env['HTTP_COOKIE'] = ', '.join(co)
        # XXX Other HTTP_* headers
        # Since we're setting the env in the parent, provide empty
        # values to override previously set values
        for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
                  'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
            env.setdefault(k, "")

        if self.command.lower() == 'post':
            self.send_response(303, 'redirection')
        else:
            self.send_response(200, "Script output follows")

        decoded_query = query.replace('+', ' ')

        if self.have_fork:
            # Unix -- fork as we should
            args = [script]
            if '=' not in decoded_query:
                args.append(decoded_query)
            if sys.platform != 'darwin':
                nobody = CGIHTTPServer.nobody_uid()
            self.wfile.flush() # Always flush before forking
            pid = os.fork()
            if pid != 0:
                # Parent
                pid, sts = os.waitpid(pid, 0)
                # throw away additional data [see bug #427345]
                while select.select([self.rfile], [], [], 0)[0]:
                    if not self.rfile.read(1):
                        break
                if sts:
                    self.log_error("CGI script exit status %#x", sts)
                return
            # Child
            try:
                if sys.platform != 'darwin':
                    try:
                        os.setuid(nobody)
                    except os.error:
                        pass
                os.dup2(self.rfile.fileno(), 0)
                os.dup2(self.wfile.fileno(), 1)
                os.execve(scriptfile, args, env)

            except:
                self.server.handle_error(self.request, self.client_address)
                os._exit(127)

        else:
            # Non Unix - use subprocess
            import subprocess
            cmdline = [scriptfile]
            if self.is_python(scriptfile):
                interp = sys.executable
                if interp.lower().endswith("w.exe"):
                    # On Windows, use python.exe, not pythonw.exe
                    interp = interp[:-5] + interp[-4:]
                cmdline = [interp, '-u'] + cmdline
            if '=' not in query:
                cmdline.append(query)
            self.log_message("command: %s", subprocess.list2cmdline(cmdline))
            try:
                nbytes = int(length)
            except (TypeError, ValueError):
                nbytes = 0
            p = subprocess.Popen(cmdline,
                                 stdin = subprocess.PIPE,
                                 stdout = subprocess.PIPE,
                                 stderr = subprocess.PIPE,
                                 env = env
                                )
            if self.command.lower() == "post" and nbytes > 0:
                data = self.rfile.read(nbytes)
            else:
                data = None
            # throw away additional data [see bug #427345]
            while select.select([self.rfile._sock], [], [], 0)[0]:
                if not self.rfile._sock.recv(1):
                    break
            stdout, stderr = p.communicate(data)
            if 'location' == stdout[:len('location')].lower():

                seeother = stdout[len('location')+1:].strip()
                stdout = '''
<html><head><meta http-equiv="refresh" content="0;url=%s"></head></html>''' % seeother

            self.wfile.write(stdout)
            if stderr:
                self.log_error('%s', stderr)
            p.stderr.close()
            p.stdout.close()
            status = p.returncode
            if status:
                self.log_error("CGI script exit status %#x", status)
            else:
                self.log_message("CGI script exited OK")
#!/usr/bin/env python
# coding:utf-8
'''CGI--通用网关接口'''

import CGIHTTPServer

CGIHTTPServer.test()
'''默认8000,改端口 python cgihttpd.py 8080'''
Beispiel #17
0
    def run_cgi(self):
        """Execute a CGI script."""
        path = self.path
        dir, rest = self.cgi_info

        i = path.find("/", len(dir) + 1)
        while i >= 0:
            nextdir = path[:i]
            nextrest = path[i + 1 :]

            scriptdir = self.translate_path(nextdir)
            if os.path.isdir(scriptdir):
                dir, rest = nextdir, nextrest
                i = path.find("/", len(dir) + 1)
            else:
                break

        # find an explicit query string, if present.
        i = rest.rfind("?")
        if i >= 0:
            rest, query = rest[:i], rest[i + 1 :]
        else:
            query = ""

        # dissect the part after the directory name into a script name &
        # a possible additional path, to be stored in PATH_INFO.
        i = rest.find("/")
        if i >= 0:
            script, rest = rest[:i], rest[i:]
        else:
            script, rest = rest, ""

        scriptname = dir + "/" + script
        scriptfile = self.translate_path(scriptname)
        if not os.path.exists(scriptfile):
            self.send_error(404, "No such CGI script (%r)" % scriptname)
            return
        if not os.path.isfile(scriptfile):
            self.send_error(403, "CGI script is not a plain file (%r)" % scriptname)
            return
        ispy = self.is_python(scriptname)
        isphp = self.is_php(scriptname)
        if not (ispy or isphp):
            if not (self.have_fork or self.have_popen2 or self.have_popen3):
                self.send_error(403, "CGI script is not a Python script (%r)" % scriptname)
                return
            if not self.is_executable(scriptfile):
                self.send_error(403, "CGI script is not executable (%r)" % scriptname)
                return

        # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
        # XXX Much of the following could be prepared ahead of time!
        env = copy.deepcopy(os.environ)
        env["SERVER_SOFTWARE"] = self.version_string()
        env["SERVER_NAME"] = self.server.server_name
        env["GATEWAY_INTERFACE"] = "CGI/1.1"
        env["SERVER_PROTOCOL"] = self.protocol_version
        env["SERVER_PORT"] = str(self.server.server_port)
        env["REQUEST_METHOD"] = self.command
        uqrest = urllib.unquote(rest)
        env["PATH_INFO"] = uqrest
        env["PATH_TRANSLATED"] = self.translate_path(uqrest)
        env["SCRIPT_NAME"] = scriptname
        if query:
            env["QUERY_STRING"] = query
        host = self.address_string()
        if host != self.client_address[0]:
            env["REMOTE_HOST"] = host
        env["REMOTE_ADDR"] = self.client_address[0]
        authorization = self.headers.getheader("authorization")
        if authorization:
            authorization = authorization.split()
            if len(authorization) == 2:
                import base64, binascii

                env["AUTH_TYPE"] = authorization[0]
                if authorization[0].lower() == "basic":
                    try:
                        authorization = base64.decodestring(authorization[1])
                    except binascii.Error:
                        pass
                    else:
                        authorization = authorization.split(":")
                        if len(authorization) == 2:
                            env["REMOTE_USER"] = authorization[0]
        # XXX REMOTE_IDENT
        if self.headers.typeheader is None:
            env["CONTENT_TYPE"] = self.headers.type
        else:
            env["CONTENT_TYPE"] = self.headers.typeheader
        length = self.headers.getheader("content-length")
        if length:
            env["CONTENT_LENGTH"] = length
        referer = self.headers.getheader("referer")
        if referer:
            env["HTTP_REFERER"] = referer
        accept = []
        for line in self.headers.getallmatchingheaders("accept"):
            if line[:1] in "\t\n\r ":
                accept.append(line.strip())
            else:
                accept = accept + line[7:].split(",")
        env["HTTP_ACCEPT"] = ",".join(accept)
        ua = self.headers.getheader("user-agent")
        if ua:
            env["HTTP_USER_AGENT"] = ua
        co = filter(None, self.headers.getheaders("cookie"))
        if co:
            env["HTTP_COOKIE"] = ", ".join(co)
        # XXX Other HTTP_* headers
        # Since we're setting the env in the parent, provide empty
        # values to override previously set values
        for k in ("QUERY_STRING", "REMOTE_HOST", "CONTENT_LENGTH", "HTTP_USER_AGENT", "HTTP_COOKIE", "HTTP_REFERER"):
            env.setdefault(k, "")

        self.send_response(200, "Script output follows")

        decoded_query = query.replace("+", " ")

        if self.is_php(scriptfile):
            env["SCRIPT_FILENAME"] = os.path.abspath(scriptfile)
            self.init_bin()

        # if self.have_fork and not self.is_php(scriptfile):
        if self.have_fork:
            # Unix -- fork as we should
            args = [script]
            if self.is_php(scriptfile):
                args = [scriptfile]
                scriptfile = self.php_bin
            #     args = [scriptfile]
            #     scriptfile = '/usr/bin/php'
            if "=" not in decoded_query:
                args.append(decoded_query)
            nobody = CGIHTTPServer.nobody_uid()
            self.wfile.flush()  # Always flush before forking
            pid = os.fork()
            if pid != 0:
                # Parent
                pid, sts = os.waitpid(pid, 0)
                # throw away additional data [see bug #427345]
                while select.select([self.rfile], [], [], 0)[0]:
                    if not self.rfile.read(1):
                        break
                if sts:
                    self.log_error("CGI script exit status %#x", sts)
                return
            # Child
            try:
                # try:
                #     os.setuid(nobody)
                # except os.error:
                #     pass
                os.dup2(self.rfile.fileno(), 0)
                os.dup2(self.wfile.fileno(), 1)
                os.execve(scriptfile, args, env)
            except:
                self.server.handle_error(self.request, self.client_address)
                os._exit(127)

        else:
            # Non Unix - use subprocess
            import subprocess

            cmdline = [scriptfile]
            if self.is_python(scriptfile):
                interp = sys.executable
                if interp.lower().endswith("w.exe"):
                    # On Windows, use python.exe, not pythonw.exe
                    interp = interp[:-5] + interp[-4:]
                cmdline = [interp, "-u"] + cmdline
            if self.is_php(scriptfile):
                cmdline = [self.php_bin] + cmdline

            if "=" not in query:
                cmdline.append(query)

            self.log_message("command: %s", subprocess.list2cmdline(cmdline))
            try:
                nbytes = int(length)
            except (TypeError, ValueError):
                nbytes = 0
            p = subprocess.Popen(
                cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env
            )
            if self.command.lower() == "post" and nbytes > 0:
                data = self.rfile.read(nbytes)
            else:
                data = None
            # throw away additional data [see bug #427345]
            while select.select([self.rfile._sock], [], [], 0)[0]:
                if not self.rfile._sock.recv(1):
                    break
            stdout, stderr = p.communicate(data)
            self.wfile.write(stdout)
            if stderr:
                self.log_error("%s", stderr)
            p.stderr.close()
            p.stdout.close()
            status = p.returncode
            if status:
                self.log_error("CGI script exit status %#x", status)
            else:
                self.log_message("CGI script exited OK")
Beispiel #18
0
    def run_cgi(self):
        """Execute a CGI script."""
        path = self.path
        dir, rest = self.cgi_info

        i = path.find('/', len(dir) + 1)
        while i >= 0:
            nextdir = path[:i]
            nextrest = path[i+1:]

            scriptdir = self.translate_path(nextdir)
            if os.path.isdir(scriptdir):
                dir, rest = nextdir, nextrest
                i = path.find('/', len(dir) + 1)
            else:
                break

        # find an explicit query string, if present.
        i = rest.rfind('?')
        if i >= 0:
            rest, query = rest[:i], rest[i+1:]
        else:
            query = ''

        # dissect the part after the directory name into a script name &
        # a possible additional path, to be stored in PATH_INFO.
        i = rest.find('/')
        if i >= 0:
            script, rest = rest[:i], rest[i:]
        else:
            script, rest = rest, ''

        scriptname = dir + '/' + script
        scriptfile = self.translate_path(scriptname)
        if not os.path.exists(scriptfile):
            self.send_error(404, "No such CGI script (%r)" % scriptname)
            return
        if not os.path.isfile(scriptfile):
            self.send_error(403, "CGI script is not a plain file (%r)" %
                            scriptname)
            return
        ispy = self.is_python(scriptname)
        if not ispy:
            if not (self.have_fork or self.have_popen2 or self.have_popen3):
                self.send_error(403, "CGI script is not a Python script (%r)" %
                                scriptname)
                return
            if not self.is_executable(scriptfile):
                self.send_error(403, "CGI script is not executable (%r)" %
                                scriptname)
                return

        # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
        # XXX Much of the following could be prepared ahead of time!
        env = {}
        env['SERVER_SOFTWARE'] = self.version_string()
        env['SERVER_NAME'] = self.server.server_name
        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
        env['SERVER_PROTOCOL'] = self.protocol_version
        env['SERVER_PORT'] = str(self.server.server_port)
        env['REQUEST_METHOD'] = self.command
        uqrest = urllib.unquote(rest)
        env['PATH_INFO'] = uqrest
        env['PATH_TRANSLATED'] = self.translate_path(uqrest)
        env['SCRIPT_NAME'] = scriptname
        if query:
            env['QUERY_STRING'] = query
        host = self.address_string()
        if host != self.client_address[0]:
            env['REMOTE_HOST'] = host
        env['REMOTE_ADDR'] = self.client_address[0]
        authorization = self.headers.getheader("authorization")
        if authorization:
            authorization = authorization.split()
            if len(authorization) == 2:
                import base64, binascii
                env['AUTH_TYPE'] = authorization[0]
                if authorization[0].lower() == "basic":
                    try:
                        authorization = base64.decodestring(authorization[1])
                    except binascii.Error:
                        pass
                    else:
                        authorization = authorization.split(':')
                        if len(authorization) == 2:
                            env['REMOTE_USER'] = authorization[0]
        # XXX REMOTE_IDENT
        if self.headers.typeheader is None:
            env['CONTENT_TYPE'] = self.headers.type
        else:
            env['CONTENT_TYPE'] = self.headers.typeheader
        length = self.headers.getheader('content-length')
        if length:
            env['CONTENT_LENGTH'] = length
        referer = self.headers.getheader('referer')
        if referer:
            env['HTTP_REFERER'] = referer
        accept = []
        for line in self.headers.getallmatchingheaders('accept'):
            if line[:1] in "\t\n\r ":
                accept.append(line.strip())
            else:
                accept = accept + line[7:].split(',')
        env['HTTP_ACCEPT'] = ','.join(accept)
        ua = self.headers.getheader('user-agent')
        if ua:
            env['HTTP_USER_AGENT'] = ua
        co = filter(None, self.headers.getheaders('cookie'))
        if co:
            env['HTTP_COOKIE'] = ', '.join(co)
        # XXX Other HTTP_* headers
        # Since we're setting the env in the parent, provide empty
        # values to override previously set values
        for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
                  'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
            env.setdefault(k, "")
        os.environ.update(env)

        self.send_response(200, "Script output follows")

        decoded_query = query.replace('+', ' ')

        if self.have_fork:
            # Unix -- fork as we should
            args = [script]
            if '=' not in decoded_query:
                args.append(decoded_query)
            nobody = CGIHTTPServer.nobody_uid()
            self.wfile.flush() # Always flush before forking
            pid = os.fork()
            if pid != 0:
                # Parent
                pid, sts = os.waitpid(pid, 0)
                # throw away additional data [see bug #427345]
                while select.select([self.rfile], [], [], 0)[0]:
                    if not self.rfile.read(1):
                        break
                if sts:
                    self.log_error("CGI script exit status %#x", sts)
                return
            # Child
            try:
                try:
                    os.setuid(nobody)
                except os.error:
                    pass
                os.dup2(self.rfile.fileno(), 0)
                os.dup2(self.wfile.fileno(), 1)
                #hack to import python scripts due to permission restrictions
                #regarding launching another interpreter instance                                               
                root, ext = os.path.splitext(scriptfile)
                if ext == '.py':
                    root, script = os.path.split(root)
                    sys.path.append(root)
                    __import__(script)
                    os._exit(0)
                else:
                    os.execve(scriptfile, args, os.environ)
            except:
                self.server.handle_error(self.request, self.client_address)
                os._exit(127)
Beispiel #19
0
				break
			head, tail = head[:i], head[i:] + tail
			temp = self.translate_path(head)

		if os.path.isdir(temp):
			for index in self.indices:
				if os.path.exists(os.path.join(temp, index)):
					head = posixpath.join(head, index)
					break

		ctype = self.guess_type(head)
		if ctype in self.actions:
			os.environ['REDIRECT_STATUS'] = '200'			
			head = self.actions[ctype] + head

		self.path = head + tail + query

	def translate_path(self, path):
		path = posixpath.normpath(urllib.unquote(path))
		n = len(self.aliases)
		for i in range(n):
			url, dir = self.aliases[n-i-1]
			length = len(url)
			if path[:length] == url:
				return dir + path[length:]
		return ''


if __name__ == '__main__':
	CGIHTTPServer.test(PHPHTTPRequestHandler)
def test(HandlerClass = SymfonyHTTPRequestHandler, ServerClass = HTTPServer):
    CGIHTTPServer.test(HandlerClass, ServerClass)
Beispiel #21
0
def test(HandlerClass = PTestCGIHandler,
         ServerClass = BaseHTTPServer.HTTPServer):
    CGIHTTPServer.test(HandlerClass, ServerClass)
Beispiel #22
0
def server():
    CGIHTTPServer.test()
Beispiel #23
0
# -*- coding: utf-8 -*-
import CGIHTTPServer
if __name__ == '__main__':
    print('あああ')
    CGIHTTPServer.test();

Beispiel #24
0
import SimpleHTTPServer
import SocketServer
import CGIHTTPServer

PORT = 8000

Handler = CGIHTTPServer.CGIHTTPRequestHandler

httpd = CGIHTTPServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()
Beispiel #25
0
    def run_cgi(self):
        """Execute a CGI script."""
        path = self.path
        dir, rest = self.cgi_info

        i = path.find('/', len(dir) + 1)
        while i >= 0:
            nextdir = path[:i]
            nextrest = path[i+1:]

            scriptdir = self.translate_path(nextdir)
            if os.path.isdir(scriptdir):
                dir, rest = nextdir, nextrest
                i = path.find('/', len(dir) + 1)
            else:
                break

        # find an explicit query string, if present.
        i = rest.rfind('?')
        if i >= 0:
            rest, query = rest[:i], rest[i+1:]
        else:
            query = ''

        # dissect the part after the directory name into a script name &
        # a possible additional path, to be stored in PATH_INFO.
        i = rest.find('/')
        if i >= 0:
            script, rest = rest[:i], rest[i:]
        else:
            script, rest = rest, ''

        scriptname = dir + '/' + script
        scriptfile = self.translate_path(scriptname)
        if not os.path.exists(scriptfile):
            self.send_error(404, "No such CGI script (%r)" % scriptname)
            return
        if not os.path.isfile(scriptfile):
            self.send_error(403, "CGI script is not a plain file (%r)" %
                            scriptname)
            return
        ispy = self.is_python(scriptname)
        isphp = self.is_php(scriptname)
        if not (ispy or isphp):
            if not (self.have_fork or self.have_popen2 or self.have_popen3):
                self.send_error(403, "CGI script is not a Python script (%r)" %
                                scriptname)
                return
            if not self.is_executable(scriptfile):
                self.send_error(403, "CGI script is not executable (%r)" %
                                scriptname)
                return

        # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
        # XXX Much of the following could be prepared ahead of time!
        env = copy.deepcopy(os.environ)
        env['SERVER_SOFTWARE'] = self.version_string()
        env['SERVER_NAME'] = self.server.server_name
        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
        env['SERVER_PROTOCOL'] = self.protocol_version
        env['SERVER_PORT'] = str(self.server.server_port)
        env['REQUEST_METHOD'] = self.command
        uqrest = urllib.unquote(rest)
        env['PATH_INFO'] = uqrest
        env['PATH_TRANSLATED'] = self.translate_path(uqrest)
        env['SCRIPT_NAME'] = scriptname
        if query:
            env['QUERY_STRING'] = query
        host = self.address_string()
        if host != self.client_address[0]:
            env['REMOTE_HOST'] = host
        env['REMOTE_ADDR'] = self.client_address[0]
        authorization = self.headers.getheader("authorization")
        if authorization:
            authorization = authorization.split()
            if len(authorization) == 2:
                import base64, binascii
                env['AUTH_TYPE'] = authorization[0]
                if authorization[0].lower() == "basic":
                    try:
                        authorization = base64.decodestring(authorization[1])
                    except binascii.Error:
                        pass
                    else:
                        authorization = authorization.split(':')
                        if len(authorization) == 2:
                            env['REMOTE_USER'] = authorization[0]
        # XXX REMOTE_IDENT
        if self.headers.typeheader is None:
            env['CONTENT_TYPE'] = self.headers.type
        else:
            env['CONTENT_TYPE'] = self.headers.typeheader
        length = self.headers.getheader('content-length')
        if length:
            env['CONTENT_LENGTH'] = length
        referer = self.headers.getheader('referer')
        if referer:
            env['HTTP_REFERER'] = referer
        accept = []
        for line in self.headers.getallmatchingheaders('accept'):
            if line[:1] in "\t\n\r ":
                accept.append(line.strip())
            else:
                accept = accept + line[7:].split(',')
        env['HTTP_ACCEPT'] = ','.join(accept)
        ua = self.headers.getheader('user-agent')
        if ua:
            env['HTTP_USER_AGENT'] = ua
        co = filter(None, self.headers.getheaders('cookie'))
        if co:
            env['HTTP_COOKIE'] = ', '.join(co)
        # XXX Other HTTP_* headers
        # Since we're setting the env in the parent, provide empty
        # values to override previously set values
        for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
                  'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
            env.setdefault(k, "")

        self.send_response(200, "Script output follows")

        decoded_query = query.replace('+', ' ')

        if self.is_php(scriptfile):
            env['SCRIPT_FILENAME'] = os.path.abspath(scriptfile)
            self.init_bin()

        # if self.have_fork and not self.is_php(scriptfile):
        if self.have_fork:
            # Unix -- fork as we should
            args = [script]
            if self.is_php(scriptfile):
                args = [scriptfile]
                scriptfile = self.php_bin
            #     args = [scriptfile]
            #     scriptfile = '/usr/bin/php'
            if '=' not in decoded_query:
                args.append(decoded_query)
            nobody = CGIHTTPServer.nobody_uid()
            self.wfile.flush() # Always flush before forking
            pid = os.fork()
            if pid != 0:
                # Parent
                pid, sts = os.waitpid(pid, 0)
                # throw away additional data [see bug #427345]
                while select.select([self.rfile], [], [], 0)[0]:
                    if not self.rfile.read(1):
                        break
                if sts:
                    self.log_error("CGI script exit status %#x", sts)
                return
            # Child
            try:
                # try:
                #     os.setuid(nobody)
                # except os.error:
                #     pass
                os.dup2(self.rfile.fileno(), 0)
                os.dup2(self.wfile.fileno(), 1)
                os.execve(scriptfile, args, env)
            except:
                self.server.handle_error(self.request, self.client_address)
                os._exit(127)

        else:
            # Non Unix - use subprocess
            import subprocess
            cmdline = [scriptfile]
            if self.is_python(scriptfile):
                interp = sys.executable
                if interp.lower().endswith("w.exe"):
                    # On Windows, use python.exe, not pythonw.exe
                    interp = interp[:-5] + interp[-4:]
                cmdline = [interp, '-u'] + cmdline
            if self.is_php(scriptfile):
                cmdline = [self.php_bin] + cmdline

            if '=' not in query:
                cmdline.append(query)

            self.log_message("command: %s", subprocess.list2cmdline(cmdline))
            try:
                nbytes = int(length)
            except (TypeError, ValueError):
                nbytes = 0
            p = subprocess.Popen(cmdline,
                                 stdin = subprocess.PIPE,
                                 stdout = subprocess.PIPE,
                                 stderr = subprocess.PIPE,
                                 env = env
                                )
            if self.command.lower() == "post" and nbytes > 0:
                data = self.rfile.read(nbytes)
            else:
                data = None
            # throw away additional data [see bug #427345]
            while select.select([self.rfile._sock], [], [], 0)[0]:
                if not self.rfile._sock.recv(1):
                    break
            stdout, stderr = p.communicate(data)
            self.wfile.write(stdout)
            if stderr:
                self.log_error('%s', stderr)
            p.stderr.close()
            p.stdout.close()
            status = p.returncode
            if status:
                self.log_error("CGI script exit status %#x", status)
            else:
                self.log_message("CGI script exited OK")
Beispiel #26
0
#!/usr/bin/env python
# _* config: utf-8 _*_

import CGIHTTPServer
CGIHTTPServer.test()
Beispiel #27
0
#!/usr/bin/env python

import os
import CGIHTTPServer

class PyCGIHandler(CGIHTTPServer.CGIHTTPRequestHandler):
    def is_cgi(self):
        splitpath = CGIHTTPServer._url_collapse_path_split(self.path)
        script_query = splitpath[1].split("?", 1)
        if script_query[0].endswith(".py"):
            if splitpath[0].startswith("/"):
                # Workaround for some weirdness with how CGIHTTPServer
                # computes the SCRIPT_NAME environment variable.
                splitpath = list(splitpath)
                splitpath[0] = ''
                splitpath = tuple(splitpath)
            self.cgi_info = splitpath
            return True
        return False

os.chdir("www")
CGIHTTPServer.test(HandlerClass=PyCGIHandler)