Mercurial > p > roundup > code
comparison roundup/scripts/roundup_server.py @ 2838:91b2d50f0b1a
eliminate as many pychecker warnings as possible:
unused imports, string exception, unused local variables etc.
| author | Alexander Smishlajev <a1s@users.sourceforge.net> |
|---|---|
| date | Fri, 29 Oct 2004 17:57:17 +0000 |
| parents | 9a6b451b1ba6 |
| children | a212699c21f2 |
comparison
equal
deleted
inserted
replaced
| 2837:bcee075321fc | 2838:91b2d50f0b1a |
|---|---|
| 15 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 15 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 16 # | 16 # |
| 17 | 17 |
| 18 """Command-line script that runs a server over roundup.cgi.client. | 18 """Command-line script that runs a server over roundup.cgi.client. |
| 19 | 19 |
| 20 $Id: roundup_server.py,v 1.67 2004-10-29 13:41:25 a1s Exp $ | 20 $Id: roundup_server.py,v 1.68 2004-10-29 17:57:17 a1s Exp $ |
| 21 """ | 21 """ |
| 22 __docformat__ = 'restructuredtext' | 22 __docformat__ = 'restructuredtext' |
| 23 | 23 |
| 24 import socket | 24 import errno, cgi, getopt, os, socket, sys, traceback, urllib |
| 25 import sys, os, urllib, StringIO, traceback, cgi, binascii, getopt, imp | 25 import ConfigParser, BaseHTTPServer, SocketServer, StringIO |
| 26 import SocketServer, BaseHTTPServer, socket, errno, ConfigParser | |
| 27 | 26 |
| 28 # python version check | 27 # python version check |
| 29 from roundup import configuration, version_check | 28 from roundup import configuration, version_check |
| 30 from roundup import __version__ as roundup_version | 29 from roundup import __version__ as roundup_version |
| 31 | 30 |
| 32 # Roundup modules of use here | 31 # Roundup modules of use here |
| 33 from roundup.cgi import cgitb, client | 32 from roundup.cgi import cgitb, client |
| 34 import roundup.instance | 33 import roundup.instance |
| 35 from roundup.i18n import _ | 34 from roundup.i18n import _ |
| 36 | |
| 37 try: | |
| 38 import signal | |
| 39 except: | |
| 40 signal = None | |
| 41 | 35 |
| 42 # "default" favicon.ico | 36 # "default" favicon.ico |
| 43 # generate by using "icotool" and tools/base64 | 37 # generate by using "icotool" and tools/base64 |
| 44 import zlib, base64 | 38 import zlib, base64 |
| 45 favico = zlib.decompress(base64.decodestring(''' | 39 favico = zlib.decompress(base64.decodestring(''' |
| 144 else: | 138 else: |
| 145 query = '' | 139 query = '' |
| 146 | 140 |
| 147 # no tracker - spit out the index | 141 # no tracker - spit out the index |
| 148 if rest == '/': | 142 if rest == '/': |
| 149 return self.index() | 143 self.index() |
| 144 return | |
| 150 | 145 |
| 151 # figure the tracker | 146 # figure the tracker |
| 152 l_path = rest.split('/') | 147 l_path = rest.split('/') |
| 153 tracker_name = urllib.unquote(l_path[1]) | 148 tracker_name = urllib.unquote(l_path[1]) |
| 154 | 149 |
| 180 env['TRACKER_NAME'] = tracker_name | 175 env['TRACKER_NAME'] = tracker_name |
| 181 env['REQUEST_METHOD'] = self.command | 176 env['REQUEST_METHOD'] = self.command |
| 182 env['PATH_INFO'] = urllib.unquote(rest) | 177 env['PATH_INFO'] = urllib.unquote(rest) |
| 183 if query: | 178 if query: |
| 184 env['QUERY_STRING'] = query | 179 env['QUERY_STRING'] = query |
| 185 host = self.address_string() | |
| 186 if self.headers.typeheader is None: | 180 if self.headers.typeheader is None: |
| 187 env['CONTENT_TYPE'] = self.headers.type | 181 env['CONTENT_TYPE'] = self.headers.type |
| 188 else: | 182 else: |
| 189 env['CONTENT_TYPE'] = self.headers.typeheader | 183 env['CONTENT_TYPE'] = self.headers.typeheader |
| 190 length = self.headers.getheader('content-length') | 184 length = self.headers.getheader('content-length') |
| 197 env['SCRIPT_NAME'] = '' | 191 env['SCRIPT_NAME'] = '' |
| 198 env['SERVER_NAME'] = self.server.server_name | 192 env['SERVER_NAME'] = self.server.server_name |
| 199 env['SERVER_PORT'] = str(self.server.server_port) | 193 env['SERVER_PORT'] = str(self.server.server_port) |
| 200 env['HTTP_HOST'] = self.headers['host'] | 194 env['HTTP_HOST'] = self.headers['host'] |
| 201 | 195 |
| 202 decoded_query = query.replace('+', ' ') | |
| 203 | |
| 204 # do the roundup thang | 196 # do the roundup thang |
| 205 if hasattr(tracker, 'Client'): | 197 tracker.Client(tracker, self, env).main() |
| 206 c = tracker.Client(tracker, self, env) | |
| 207 else: | |
| 208 c = client.Client(tracker, self, env) | |
| 209 c.main() | |
| 210 | 198 |
| 211 def address_string(self): | 199 def address_string(self): |
| 212 if self.LOG_IPADDRESS: | 200 if self.LOG_IPADDRESS: |
| 213 return self.client_address[0] | 201 return self.client_address[0] |
| 214 else: | 202 else: |
| 364 def getopt(self, args, short_options="", long_options=(), | 352 def getopt(self, args, short_options="", long_options=(), |
| 365 config_load_options=("C", "config"), **options | 353 config_load_options=("C", "config"), **options |
| 366 ): | 354 ): |
| 367 options.update(self.OPTIONS) | 355 options.update(self.OPTIONS) |
| 368 return configuration.Config.getopt(self, args, | 356 return configuration.Config.getopt(self, args, |
| 369 short_options, long_options, **options) | 357 short_options, long_options, config_load_options, **options) |
| 370 | 358 |
| 371 def _get_name(self): | 359 def _get_name(self): |
| 372 return "Roundup server" | 360 return "Roundup server" |
| 373 | 361 |
| 374 def trackers(self): | 362 def trackers(self): |
| 381 | 369 |
| 382 def get_server(self): | 370 def get_server(self): |
| 383 """Return HTTP server object to run""" | 371 """Return HTTP server object to run""" |
| 384 # redirect stdout/stderr to our logfile | 372 # redirect stdout/stderr to our logfile |
| 385 # this is done early to have following messages go to this logfile | 373 # this is done early to have following messages go to this logfile |
| 386 if self.LOGFILE: | 374 if self["LOGFILE"]: |
| 387 # appending, unbuffered | 375 # appending, unbuffered |
| 388 sys.stdout = sys.stderr = open(self["LOGFILE"], 'a', 0) | 376 sys.stdout = sys.stderr = open(self["LOGFILE"], 'a', 0) |
| 389 # we don't want the cgi module interpreting the command-line args ;) | 377 # we don't want the cgi module interpreting the command-line args ;) |
| 390 sys.argv = sys.argv[:1] | 378 sys.argv = sys.argv[:1] |
| 391 # build customized request handler class | 379 # build customized request handler class |
| 392 class RequestHandler(RoundupRequestHandler): | 380 class RequestHandler(RoundupRequestHandler): |
| 393 LOG_IPADDRESS = not self.LOG_HOSTNAMES | 381 LOG_IPADDRESS = not self["LOG_HOSTNAMES"] |
| 394 TRACKER_HOMES = dict(self.trackers()) | 382 TRACKER_HOMES = dict(self.trackers()) |
| 395 # obtain request server class | 383 # obtain request server class |
| 396 if self.MULTIPROCESS not in MULTIPROCESS_TYPES: | 384 if self["MULTIPROCESS"] not in MULTIPROCESS_TYPES: |
| 397 print _("Multiprocess mode \"%s\" is not available, " | 385 print _("Multiprocess mode \"%s\" is not available, " |
| 398 "switching to single-process") % self.MULTIPROCESS | 386 "switching to single-process") % self["MULTIPROCESS"] |
| 399 self.MULTIPROCESS = "none" | 387 self["MULTIPROCESS"] = "none" |
| 400 server_class = BaseHTTPServer.HTTPServer | 388 server_class = BaseHTTPServer.HTTPServer |
| 401 elif self.MULTIPROCESS == "fork": | 389 elif self["MULTIPROCESS"] == "fork": |
| 402 class server_class(SocketServer.ForkingMixIn, | 390 class ForkingServer(SocketServer.ForkingMixIn, |
| 403 BaseHTTPServer.HTTPServer): | 391 BaseHTTPServer.HTTPServer): |
| 404 pass | 392 pass |
| 405 elif self.MULTIPROCESS == "thread": | 393 server_class = ForkingServer |
| 406 class server_class(SocketServer.ThreadingMixIn, | 394 elif self["MULTIPROCESS"] == "thread": |
| 395 class ThreadingServer(SocketServer.ThreadingMixIn, | |
| 407 BaseHTTPServer.HTTPServer): | 396 BaseHTTPServer.HTTPServer): |
| 408 pass | 397 pass |
| 398 server_class = ThreadingServer | |
| 409 else: | 399 else: |
| 410 server_class = BaseHTTPServer.HTTPServer | 400 server_class = BaseHTTPServer.HTTPServer |
| 411 # obtain server before changing user id - allows to | 401 # obtain server before changing user id - allows to |
| 412 # use port < 1024 if started as root | 402 # use port < 1024 if started as root |
| 413 try: | 403 try: |
| 414 httpd = server_class((self.HOST, self.PORT), RequestHandler) | 404 httpd = server_class((self["HOST"], self["PORT"]), RequestHandler) |
| 415 except socket.error, e: | 405 except socket.error, e: |
| 416 if e[0] == errno.EADDRINUSE: | 406 if e[0] == errno.EADDRINUSE: |
| 417 raise socket.error, \ | 407 raise socket.error, \ |
| 418 _("Unable to bind to port %s, port already in use.") \ | 408 _("Unable to bind to port %s, port already in use.") \ |
| 419 % self.PORT | 409 % self["PORT"] |
| 420 raise | 410 raise |
| 421 # change user and/or group | 411 # change user and/or group |
| 422 setgid(self.GROUP) | 412 setgid(self["GROUP"]) |
| 423 setuid(self.USER) | 413 setuid(self["USER"]) |
| 424 # return the server | 414 # return the server |
| 425 return httpd | 415 return httpd |
| 426 | 416 |
| 427 try: | 417 try: |
| 428 import win32serviceutil | 418 import win32serviceutil |
| 433 # allow the win32 | 423 # allow the win32 |
| 434 import win32service | 424 import win32service |
| 435 import win32event | 425 import win32event |
| 436 import win32file | 426 import win32file |
| 437 | 427 |
| 438 SvcShutdown = "ServiceShutdown" | 428 class SvcShutdown(Exception): |
| 429 pass | |
| 439 | 430 |
| 440 class RoundupService(win32serviceutil.ServiceFramework, | 431 class RoundupService(win32serviceutil.ServiceFramework, |
| 441 BaseHTTPServer.HTTPServer): | 432 BaseHTTPServer.HTTPServer): |
| 442 ''' A Roundup standalone server for Win32 by Ewout Prangsma | 433 ''' A Roundup standalone server for Win32 by Ewout Prangsma |
| 443 ''' | 434 ''' |
| 628 usage(str(e)) | 619 usage(str(e)) |
| 629 return | 620 return |
| 630 | 621 |
| 631 # if running in windows service mode, don't do any other stuff | 622 # if running in windows service mode, don't do any other stuff |
| 632 if ("-c", "") in optlist: | 623 if ("-c", "") in optlist: |
| 633 return win32serviceutil.HandleCommandLine(RoundupService, | 624 win32serviceutil.HandleCommandLine(RoundupService, |
| 634 argv=sys.argv[:1] + args) | 625 argv=sys.argv[:1] + args) |
| 626 return | |
| 635 | 627 |
| 636 # add tracker names from command line. | 628 # add tracker names from command line. |
| 637 # this is done early to let '--save-config' handle the trackers. | 629 # this is done early to let '--save-config' handle the trackers. |
| 638 if args: | 630 if args: |
| 639 for arg in args: | 631 for arg in args: |
| 661 # port number in function arguments overrides config and command line | 653 # port number in function arguments overrides config and command line |
| 662 if port is not undefined: | 654 if port is not undefined: |
| 663 config.PORT = port | 655 config.PORT = port |
| 664 | 656 |
| 665 # fork the server from our parent if a pidfile is specified | 657 # fork the server from our parent if a pidfile is specified |
| 666 if config.PIDFILE: | 658 if config["PIDFILE"]: |
| 667 if not hasattr(os, 'fork'): | 659 if not hasattr(os, 'fork'): |
| 668 print _("Sorry, you can't run the server as a daemon" | 660 print _("Sorry, you can't run the server as a daemon" |
| 669 " on this Operating System") | 661 " on this Operating System") |
| 670 sys.exit(0) | 662 sys.exit(0) |
| 671 else: | 663 else: |
| 672 daemonize(config.PIDFILE) | 664 daemonize(config["PIDFILE"]) |
| 673 | 665 |
| 674 # create the server | 666 # create the server |
| 675 httpd = config.get_server() | 667 httpd = config.get_server() |
| 676 | 668 |
| 677 if success_message: | 669 if success_message: |
