Revision 6526ddcd lib/http.py
b/lib/http.py | ||
---|---|---|
242 | 242 |
try: |
243 | 243 |
self._ReadRequest() |
244 | 244 |
self._ReadPostData() |
245 |
|
|
246 |
self.should_fork = self._server.ForkForRequest(self) |
|
247 | 245 |
except HTTPException, err: |
248 | 246 |
self._SetErrorStatus(err) |
249 | 247 |
|
... | ... | |
454 | 452 |
"""Generic HTTP server class |
455 | 453 |
|
456 | 454 |
Users of this class must subclass it and override the HandleRequest function. |
457 |
Optionally, the ForkForRequest function can be overriden. |
|
458 | 455 |
|
459 | 456 |
""" |
460 | 457 |
MAX_CHILDREN = 20 |
... | ... | |
516 | 513 |
# Don't wait for other processes if it should be a quick check |
517 | 514 |
while len(self._children) > self.MAX_CHILDREN: |
518 | 515 |
try: |
516 |
# Waiting without a timeout brings us into a potential DoS situation. |
|
517 |
# As soon as too many children run, we'll not respond to new |
|
518 |
# requests. The real solution would be to add a timeout for children |
|
519 |
# and killing them after some time. |
|
519 | 520 |
pid, status = os.waitpid(0, 0) |
520 | 521 |
except os.error: |
521 | 522 |
pid = None |
... | ... | |
531 | 532 |
self._children.remove(pid) |
532 | 533 |
|
533 | 534 |
def _IncomingConnection(self): |
534 |
connection, client_addr = self.socket.accept() |
|
535 |
logging.info("Connection from %s:%s", client_addr[0], client_addr[1]) |
|
536 |
try: |
|
537 |
handler = _HttpConnectionHandler(self, connection, client_addr, self._fileio_class) |
|
538 |
except (socket.error, SocketClosed): |
|
539 |
return |
|
535 |
"""Called for each incoming connection |
|
540 | 536 |
|
541 |
def FinishRequest(): |
|
542 |
try: |
|
543 |
try: |
|
544 |
try: |
|
545 |
handler.HandleRequest() |
|
546 |
finally: |
|
547 |
# Try to send a response |
|
548 |
handler.SendResponse() |
|
549 |
handler.Close() |
|
550 |
except SocketClosed: |
|
551 |
pass |
|
552 |
finally: |
|
553 |
logging.info("Disconnected %s:%s", client_addr[0], client_addr[1]) |
|
554 |
|
|
555 |
# Check whether we should fork or not |
|
556 |
if not handler.should_fork: |
|
557 |
FinishRequest() |
|
558 |
return |
|
537 |
""" |
|
538 |
(connection, client_addr) = self.socket.accept() |
|
559 | 539 |
|
560 | 540 |
self._CollectChildren(False) |
561 | 541 |
|
562 | 542 |
pid = os.fork() |
563 | 543 |
if pid == 0: |
564 | 544 |
# Child process |
545 |
logging.info("Connection from %s:%s", client_addr[0], client_addr[1]) |
|
546 |
|
|
565 | 547 |
try: |
566 |
FinishRequest() |
|
548 |
try: |
|
549 |
try: |
|
550 |
handler = None |
|
551 |
try: |
|
552 |
# Read, parse and handle request |
|
553 |
handler = _HttpConnectionHandler(self, connection, client_addr, |
|
554 |
self._fileio_class) |
|
555 |
handler.HandleRequest() |
|
556 |
finally: |
|
557 |
# Try to send a response |
|
558 |
if handler: |
|
559 |
handler.SendResponse() |
|
560 |
handler.Close() |
|
561 |
except SocketClosed: |
|
562 |
pass |
|
563 |
finally: |
|
564 |
logging.info("Disconnected %s:%s", client_addr[0], client_addr[1]) |
|
567 | 565 |
except: |
568 | 566 |
logging.exception("Error while handling request from %s:%s", |
569 | 567 |
client_addr[0], client_addr[1]) |
... | ... | |
575 | 573 |
def HandleRequest(self, req): |
576 | 574 |
raise NotImplementedError() |
577 | 575 |
|
578 |
def ForkForRequest(self, req): |
|
579 |
return True |
|
580 |
|
|
581 | 576 |
|
582 | 577 |
class _SSLFileObject(object): |
583 | 578 |
"""Wrapper around socket._fileobject |
Also available in: Unified diff