|
31 | 31 | import java.util.concurrent.ExecutorService; |
32 | 32 | import java.util.concurrent.Executors; |
33 | 33 | import java.util.concurrent.ThreadLocalRandom; |
| 34 | +import java.util.concurrent.TimeUnit; |
34 | 35 |
|
35 | 36 | /** |
36 | 37 | * @author Gianlu |
@@ -94,6 +95,7 @@ public class ZeroconfServer implements Closeable { |
94 | 95 | private final List<SessionListener> sessionListeners; |
95 | 96 | private final Zeroconf zeroconf; |
96 | 97 | private volatile Session session; |
| 98 | + private volatile long connectionTime; |
97 | 99 |
|
98 | 100 | private ZeroconfServer(Session.Inner inner, Configuration conf) throws IOException { |
99 | 101 | this.inner = inner; |
@@ -214,17 +216,24 @@ public void close() throws IOException { |
214 | 216 |
|
215 | 217 | public void closeSession() throws IOException { |
216 | 218 | if (session != null) session.close(); |
| 219 | + |
| 220 | + session = null; |
| 221 | + connectionTime = 0; |
217 | 222 | } |
218 | 223 |
|
219 | | - public boolean hasValidSession() { |
220 | | - boolean valid = session != null && session.valid(); |
221 | | - if (!valid) session = null; |
| 224 | + private boolean hasActiveSession() { |
| 225 | + boolean valid = session != null && session.isValid() && session.isActive(); |
| 226 | + if (!valid) { |
| 227 | + session = null; |
| 228 | + connectionTime = 0; |
| 229 | + } |
| 230 | + |
222 | 231 | return valid; |
223 | 232 | } |
224 | 233 |
|
225 | 234 | private void handleGetInfo(OutputStream out, String httpVersion) throws IOException { |
226 | 235 | JsonObject info = DEFAULT_GET_INFO_FIELDS.deepCopy(); |
227 | | - info.addProperty("activeUser", hasValidSession() ? session.username() : ""); |
| 236 | + info.addProperty("activeUser", hasActiveSession() ? session.username() : ""); |
228 | 237 | info.addProperty("deviceID", inner.deviceId); |
229 | 238 | info.addProperty("remoteName", inner.deviceName); |
230 | 239 | info.addProperty("publicKey", Base64.getEncoder().encodeToString(keys.publicKeyArray())); |
@@ -263,14 +272,13 @@ private void handleAddUser(OutputStream out, Map<String, String> params, String |
263 | 272 | return; |
264 | 273 | } |
265 | 274 |
|
266 | | - if (hasValidSession()) { |
| 275 | + if (hasActiveSession() && System.currentTimeMillis() - connectionTime > TimeUnit.SECONDS.toMillis(60)) { |
267 | 276 | if (session.username().equals(username)) { |
268 | 277 | LOGGER.debug(String.format("Dropped connection attempt because user is already connected. {username: %s}", session.username())); |
269 | | - return; |
| 278 | + } else { |
| 279 | + session.close(); |
| 280 | + LOGGER.trace(String.format("Closed previous session to accept new. {deviceId: %s}", session.deviceId())); |
270 | 281 | } |
271 | | - |
272 | | - session.close(); |
273 | | - LOGGER.trace(String.format("Closed previous session to accept new. {deviceId: %s}", session.deviceId())); |
274 | 282 | } |
275 | 283 |
|
276 | 284 | byte[] sharedKey = Utils.toByteArray(keys.computeSharedKey(Base64.getDecoder().decode(clientKeyStr))); |
@@ -326,6 +334,7 @@ private void handleAddUser(OutputStream out, Map<String, String> params, String |
326 | 334 | Authentication.LoginCredentials credentials = inner.decryptBlob(username, decrypted); |
327 | 335 |
|
328 | 336 | session = Session.from(inner); |
| 337 | + connectionTime = System.currentTimeMillis(); |
329 | 338 | LOGGER.info(String.format("Accepted new user from %s. {deviceId: %s}", params.get("deviceName"), session.deviceId())); |
330 | 339 |
|
331 | 340 | session.connect(); |
@@ -429,7 +438,7 @@ private void handle(@NotNull Socket socket) throws IOException { |
429 | 438 | headers.put(split[0], split[1].trim()); |
430 | 439 | } |
431 | 440 |
|
432 | | - if (!hasValidSession()) |
| 441 | + if (!hasActiveSession()) |
433 | 442 | LOGGER.trace(String.format("Handling request: %s %s %s, headers: %s", method, path, httpVersion, headers)); |
434 | 443 |
|
435 | 444 | Map<String, String> params; |
|
0 commit comments