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