-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPOP3Client.java
More file actions
138 lines (116 loc) · 4.28 KB
/
Copy pathPOP3Client.java
File metadata and controls
138 lines (116 loc) · 4.28 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import java.io.*;
import java.net.*;
import java.util.*;
public class POP3Client {
private static final int DEFAULT_PORT = 110;
private static final int TIMEOUT_MS = 15_000;
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
private boolean connected = false;
public void connect(String host, int port) throws IOException {
socket = new Socket();
socket.connect(new InetSocketAddress(host, port), TIMEOUT_MS);
socket.setSoTimeout(TIMEOUT_MS);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);
String greeting = reader.readLine();
if (greeting == null || !greeting.startsWith("+OK"))
throw new IOException("Bad greeting: " + greeting);
connected = true;
System.out.println("[POP3] Connected: " + greeting);
}
public void connect(String host) throws IOException {
connect(host, DEFAULT_PORT);
}
public void disconnect() {
if (!connected)
return;
try {
sendCommand("QUIT");
socket.close();
} catch (IOException ignored) {
} finally {
connected = false;
}
}
public void authenticate(String username, String password) throws IOException {
requireOK(sendCommand("USER " + username), "USER");
requireOK(sendCommand("PASS " + password), "PASS");
System.out.println("[POP3] Authenticated as " + username);
}
public int[] stat() throws IOException {
String r = sendCommand("STAT");
requireOK(r, "STAT");
String[] p = r.split("\\s+");
return new int[] { Integer.parseInt(p[1]), Integer.parseInt(p[2]) };
}
public Map<Integer, Integer> list() throws IOException {
Map<Integer, Integer> result = new LinkedHashMap<>();
sendRaw("LIST");
requireOK(reader.readLine(), "LIST");
String line;
while ((line = reader.readLine()) != null && !line.equals(".")) {
String[] p = line.split("\\s+");
result.put(Integer.parseInt(p[0]), Integer.parseInt(p[1]));
}
return result;
}
public String top(int msgNum, int lines) throws IOException {
sendRaw("TOP " + msgNum + " " + lines);
requireOK(reader.readLine(), "TOP");
return readMultiLine();
}
public String retr(int msgNum) throws IOException {
sendRaw("RETR " + msgNum);
requireOK(reader.readLine(), "RETR");
return readMultiLine();
}
public void dele(int msgNum) throws IOException {
requireOK(sendCommand("DELE " + msgNum), "DELE");
}
public Map<Integer, String> uidl() throws IOException {
Map<Integer, String> result = new LinkedHashMap<>();
sendRaw("UIDL");
requireOK(reader.readLine(), "UIDL");
String line;
while ((line = reader.readLine()) != null && !line.equals(".")) {
String[] p = line.split("\\s+");
result.put(Integer.parseInt(p[0]), p[1]);
}
return result;
}
public void rset() throws IOException {
requireOK(sendCommand("RSET"), "RSET");
}
public void noop() throws IOException {
requireOK(sendCommand("NOOP"), "NOOP");
}
private String sendCommand(String cmd) throws IOException {
sendRaw(cmd);
return reader.readLine();
}
private void sendRaw(String cmd) throws IOException {
writer.print(cmd + "\r\n");
writer.flush();
}
private String readMultiLine() throws IOException {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
if (line.equals("."))
break;
if (line.startsWith(".."))
line = line.substring(1);
sb.append(line).append("\r\n");
}
return sb.toString();
}
private void requireOK(String response, String cmd) throws IOException {
if (response == null || !response.startsWith("+OK"))
throw new IOException("Command '" + cmd + "' failed: " + response);
}
public boolean isConnected() {
return connected;
}
}