source: trunk/packages/xen-3.1/xen-3.1/tools/python/xen/web/connection.py @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 3.7 KB
Line 
1#============================================================================
2# This library is free software; you can redistribute it and/or modify
3# it under the terms of the GNU Lesser General Public License as published by
4# the Free Software Foundation; either version 2.1 of the License, or
5# (at your option) any later version.
6#
7# This library is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10# GNU Lesser General Public License for more details.
11#
12# You should have received a copy of the GNU Lesser General Public License
13# along with this library; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15#============================================================================
16# Copyright (C) 2005 Mike Wray <mike.wray@hp.com>
17# Copyright (C) 2005 XenSource Ltd.
18#============================================================================
19
20import sys
21import threading
22import socket
23import fcntl
24
25from errno import EAGAIN, EINTR, EWOULDBLOCK
26
27from xen.xend.XendLogging import log
28
29"""General classes to support server and client sockets, without
30specifying what kind of socket they are. There are subclasses
31for TCP and unix-domain sockets (see tcp.py and unix.py).
32"""
33
34BUFFER_SIZE = 1024
35BACKLOG = 5
36
37
38class SocketServerConnection:
39    """An accepted connection to a server.
40    """
41
42    def __init__(self, sock, protocol_class):
43        self.sock = sock
44        self.protocol = protocol_class()
45        self.protocol.setTransport(self)
46        threading.Thread(target=self.main).start()
47
48
49    def main(self):
50        try:
51            while True:
52                try:
53                    data = self.sock.recv(BUFFER_SIZE)
54                    if data == '':
55                        break
56                    if self.protocol.dataReceived(data):
57                        break
58                except socket.error, ex:
59                    if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR):
60                        break
61        finally:
62            try:
63                self.sock.close()
64            except:
65                pass
66
67
68    def close(self):
69        self.sock.close()
70
71
72    def write(self, data):
73        self.sock.send(data)
74
75
76class SocketListener:
77    """A server socket, running listen in a thread.
78    Accepts connections and runs a thread for each one.
79    """
80
81    def __init__(self, protocol_class):
82        self.protocol_class = protocol_class
83        self.sock = self.createSocket()
84        threading.Thread(target=self.main).start()
85
86
87    def close(self):
88        try:
89            self.sock.close()
90        except:
91            pass
92
93
94    def createSocket(self):
95        raise NotImplementedError()
96
97
98    def acceptConnection(self, sock, protocol, addr):
99        raise NotImplementedError()
100
101
102    def main(self):
103        try:
104            fcntl.fcntl(self.sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
105            self.sock.listen(BACKLOG)
106
107            while True:
108                try:
109                    (sock, addr) = self.sock.accept()
110                    self.acceptConnection(sock, addr)
111                except socket.error, ex:
112                    if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR):
113                        break
114        finally:
115            self.close()
116
117
118def hostAllowed(addrport, hosts_allowed):
119    if hosts_allowed is None:
120        return True
121    else:
122        fqdn = socket.getfqdn(addrport[0])
123        for h in hosts_allowed:
124            if h.match(fqdn) or h.match(addrport[0]):
125                return True
126        log.warn("Rejected connection from %s (%s).", addrport[0], fqdn)
127        return False
Note: See TracBrowser for help on using the repository browser.