forked from ikurakin/pop3_server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
98 lines (82 loc) · 3.33 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
__author__ = 'ikurakin'
import SocketServer
from controllers import DBQueries
class POP3Handler(SocketServer.BaseRequestHandler):
"""
The RequestHandler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
ERR = "-ERR\r\n"
OK = "+OK\r\n"
def setup(self):
self.request.sendall("Welcome to POP server, 127.0.0.1!\r\n")
self.AUTHORIZATION = True
self.user = None
self.TRANSACTION = False
self.queries = DBQueries()
self.accepted_methods = dict((("USER", self.user_method), ("PASS", self.pass_method),
("LIST", self.list_method), ("RETR", self.retr_method),
("QUIT", self.quit_method)))
def handle(self):
while self.AUTHORIZATION:
self.process_request_data()
def process_request_data(self):
data = self.request.recv(1024).strip()
self.data = data.split()
if self.data:
POP3_method = self.data[0]
if POP3_method in self.accepted_methods:
self.accepted_methods[POP3_method]()
else:
self.request.sendall("Method is not accepted!\r\n")
# implements QUIT POP3 method behavior
def quit_method(self):
self.AUTHORIZATION = False
self.request.sendall("Bye!\r\n")
# implements USER POP3 method behavior
def user_method(self):
if not self.TRANSACTION:
if len(self.data) > 1:
self.user = self.data[1]
if self.queries.user_exists(self.user):
self.request.sendall(self.OK)
return
self.request.sendall(self.ERR)
# implements PASS POP3 method behavior
def pass_method(self):
if not self.TRANSACTION:
if len(self.data) > 1:
passw = self.data[1]
if self.user:
if self.queries.authenticate_user(self.user, passw):
self.TRANSACTION = True
self.request.sendall(self.OK)
return
self.request.sendall(self.ERR)
# implements LIST POP3 method behavior
def list_method(self):
if self.TRANSACTION:
emails = self.queries.get_user_emails(self.user)
if emails:
str_list = [self.OK, "You've got {} letters in your mailbox\r\n".format(len(emails)),
"\r\n".join(emails), "\r\nFeel free to fetch any with RETR command\r\n"]
self.request.sendall("".join(str_list))
return
self.request.sendall(self.ERR)
# implements RETR POP3 method behavior
def retr_method(self):
if len(self.data) > 1:
id = self.data[1]
subject, body = self.queries.get_email(id)
self.request.sendall("Subject: {subject}\r\n{body}".format(subject=subject, body=body))
return
self.request.sendall(self.ERR)
class ThreadingPOP3Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
HOST, PORT = "0.0.0.0", 1110
server = ThreadingPOP3Server((HOST, PORT), POP3Handler)
print("POP3 server starts on localhost:1110")
server.serve_forever()