~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/ftp.py

Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
import os.path
33
33
import urllib
34
34
import urlparse
 
35
import select
35
36
import stat
36
37
import threading
37
38
import time
49
50
    split_url,
50
51
    Transport,
51
52
    )
 
53
from bzrlib.transport.local import LocalURLServer
52
54
import bzrlib.ui
53
55
 
54
56
_have_medusa = False
577
579
        """This is used by medusa.ftp_server to log connections, etc."""
578
580
        self.logs.append(message)
579
581
 
580
 
    def setUp(self):
581
 
 
 
582
    def setUp(self, vfs_server=None):
582
583
        if not _have_medusa:
583
584
            raise RuntimeError('Must have medusa to run the FtpServer')
584
585
 
 
586
        assert vfs_server is None or isinstance(vfs_server, LocalURLServer), \
 
587
            "FtpServer currently assumes local transport, got %s" % vfs_server
 
588
 
585
589
        self._root = os.getcwdu()
586
590
        self._ftp_server = _ftp_server(
587
591
            authorizer=_test_authorizer(root=self._root),
593
597
        self._port = self._ftp_server.getsockname()[1]
594
598
        # Don't let it loop forever, or handle an infinite number of requests.
595
599
        # In this case it will run for 100s, or 1000 requests
596
 
        self._async_thread = threading.Thread(target=asyncore.loop,
 
600
        self._async_thread = threading.Thread(
 
601
                target=FtpServer._asyncore_loop_ignore_EBADF,
597
602
                kwargs={'timeout':0.1, 'count':1000})
598
603
        self._async_thread.setDaemon(True)
599
604
        self._async_thread.start()
605
610
        asyncore.close_all()
606
611
        self._async_thread.join()
607
612
 
 
613
    @staticmethod
 
614
    def _asyncore_loop_ignore_EBADF(*args, **kwargs):
 
615
        """Ignore EBADF during server shutdown.
 
616
 
 
617
        We close the socket to get the server to shutdown, but this causes
 
618
        select.select() to raise EBADF.
 
619
        """
 
620
        try:
 
621
            asyncore.loop(*args, **kwargs)
 
622
        except select.error, e:
 
623
            if e.args[0] != errno.EBADF:
 
624
                raise
 
625
 
608
626
 
609
627
_ftp_channel = None
610
628
_ftp_server = None
683
701
            except (IOError, OSError), e:
684
702
                # TODO: jam 20060516 return custom responses based on
685
703
                #       why the command failed
686
 
                self.respond('550 RNTO failed: %s' % (e,))
 
704
                # (bialix 20070418) str(e) on Python 2.5 @ Windows
 
705
                # sometimes don't provide expected error message;
 
706
                # so we obtain such message via os.strerror()
 
707
                self.respond('550 RNTO failed: %s' % os.strerror(e.errno))
687
708
            except:
688
709
                self.respond('550 RNTO failed')
689
710
                # For a test server, we will go ahead and just die
721
742
                    self.filesystem.mkdir (path)
722
743
                    self.respond ('257 MKD command successful.')
723
744
                except (IOError, OSError), e:
724
 
                    self.respond ('550 error creating directory: %s' % (e,))
 
745
                    # (bialix 20070418) str(e) on Python 2.5 @ Windows
 
746
                    # sometimes don't provide expected error message;
 
747
                    # so we obtain such message via os.strerror()
 
748
                    self.respond ('550 error creating directory: %s' %
 
749
                                  os.strerror(e.errno))
725
750
                except:
726
751
                    self.respond ('550 error creating directory.')
727
752