This repository has been archived by the owner on Jul 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 218
/
InternalWebSocketHandler.java
108 lines (91 loc) · 3.99 KB
/
InternalWebSocketHandler.java
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
/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2014 Philipp C. Heckel <philipp.heckel@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.syncany.operations.daemon.handlers;
import io.undertow.websockets.WebSocketConnectionCallback;
import io.undertow.websockets.core.AbstractReceiveListener;
import io.undertow.websockets.core.BufferedTextMessage;
import io.undertow.websockets.core.StreamSourceFrameChannel;
import io.undertow.websockets.core.WebSocketChannel;
import io.undertow.websockets.spi.WebSocketHttpExchange;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.syncany.operations.daemon.DaemonEventBus;
import org.syncany.operations.daemon.DaemonWebServer;
import org.syncany.operations.daemon.messages.BadRequestResponse;
import org.syncany.operations.daemon.messages.MessageFactory;
import org.syncany.operations.daemon.messages.Request;
import com.google.common.eventbus.EventBus;
/**
* InternalWebSocketHandler handles the websocket requests sent to the daemon.
*
*/
public class InternalWebSocketHandler implements WebSocketConnectionCallback {
private static final Logger logger = Logger.getLogger(InternalWebSocketHandler.class.getSimpleName());
private DaemonWebServer daemonWebServer;
private DaemonEventBus eventBus;
public InternalWebSocketHandler(DaemonWebServer daemonWebServer) {
this.daemonWebServer = daemonWebServer;
eventBus = DaemonEventBus.getInstance();
eventBus.register(this);
}
@Override
public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel) {
logger.log(Level.INFO, "Connecting to websocket server.");
// Validate origin header (security!)
String originHeader = exchange.getRequestHeader("Origin");
boolean allowedOriginHeader = (originHeader == null ||
DaemonWebServer.WEBSOCKET_ALLOWED_ORIGIN_HEADER.matcher(originHeader).matches());
if (!allowedOriginHeader) {
logger.log(Level.INFO, channel.toString() + " disconnected due to invalid origin header: " + originHeader);
exchange.close();
}
else {
logger.log(Level.INFO, "Valid origin header, setting up connection.");
channel.getReceiveSetter().set(new AbstractReceiveListener() {
@Override
protected void onFullTextMessage(WebSocketChannel clientChannel, BufferedTextMessage message) {
handleWebSocketRequest(clientChannel, message.getData());
}
@Override
protected void onError(WebSocketChannel webSocketChannel, Throwable error) {
logger.log(Level.INFO, "Server error : " + error.toString());
}
@Override
protected void onClose(WebSocketChannel clientChannel, StreamSourceFrameChannel streamSourceChannel) throws IOException {
logger.log(Level.INFO, clientChannel.toString() + " disconnected");
daemonWebServer.removeClientChannel(clientChannel);
}
});
daemonWebServer.addClientChannel(channel);
channel.resumeReceives();
}
}
private void handleWebSocketRequest(WebSocketChannel clientSocket, String message) {
logger.log(Level.INFO, "Web socket message received: " + message);
try {
Request request = MessageFactory.createRequest(message);
daemonWebServer.cacheWebSocketRequest(request.getId(), clientSocket);
eventBus.post(request);
}
catch (Exception e) {
logger.log(Level.WARNING, "Invalid request received; cannot serialize to Request.", e);
eventBus.post(new BadRequestResponse(-1, "Invalid request."));
}
}
}