-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathHttpSession.java
187 lines (163 loc) · 6.15 KB
/
HttpSession.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
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package io.github.hapjava.server.impl.connections;
import io.github.hapjava.accessories.HomekitAccessory;
import io.github.hapjava.server.HomekitAuthInfo;
import io.github.hapjava.server.impl.HomekitRegistry;
import io.github.hapjava.server.impl.http.HomekitClientConnection;
import io.github.hapjava.server.impl.http.HttpRequest;
import io.github.hapjava.server.impl.http.HttpResponse;
import io.github.hapjava.server.impl.jmdns.JmdnsHomekitAdvertiser;
import io.github.hapjava.server.impl.json.AccessoryController;
import io.github.hapjava.server.impl.json.CharacteristicsController;
import io.github.hapjava.server.impl.pairing.PairSetupManager;
import io.github.hapjava.server.impl.pairing.PairVerifyManager;
import io.github.hapjava.server.impl.pairing.PairingsManager;
import io.github.hapjava.server.impl.responses.BadRequestResponse;
import io.github.hapjava.server.impl.responses.InternalServerErrorResponse;
import io.github.hapjava.server.impl.responses.NoContentResponse;
import io.github.hapjava.server.impl.responses.NotFoundResponse;
import java.io.IOException;
import java.net.InetAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class HttpSession {
private volatile PairSetupManager pairSetupManager;
private volatile PairVerifyManager pairVerifyManager;
private volatile AccessoryController accessoryController;
private volatile CharacteristicsController characteristicsController;
private final HomekitAuthInfo authInfo;
private final HomekitRegistry registry;
private final SubscriptionManager subscriptions;
private final HomekitClientConnection connection;
private final JmdnsHomekitAdvertiser advertiser;
private static final Logger logger = LoggerFactory.getLogger(HttpSession.class);
public HttpSession(
HomekitAuthInfo authInfo,
HomekitRegistry registry,
SubscriptionManager subscriptions,
HomekitClientConnection connection,
JmdnsHomekitAdvertiser advertiser) {
this.authInfo = authInfo;
this.registry = registry;
this.subscriptions = subscriptions;
this.connection = connection;
this.advertiser = advertiser;
}
public HttpResponse handleRequest(HttpRequest request) throws IOException {
switch (request.getUri()) {
case "/identify":
HomekitAccessory accessory = registry.getPrimaryAccessory();
if (accessory != null) {
accessory.identify();
}
return new NoContentResponse();
case "/pair-setup":
return handlePairSetup(request);
case "/pair-verify":
return handlePairVerify(request);
default:
if (registry.isAllowUnauthenticatedRequests()) {
return handleAuthenticatedRequest(request);
} else {
logger.warn("Unrecognized request for " + request.getUri());
return new NotFoundResponse();
}
}
}
public HttpResponse handleAuthenticatedRequest(HttpRequest request) throws IOException {
advertiser.setDiscoverable(
false); // bridge is already bound and should not be discoverable anymore
try {
switch (request.getUri()) {
case "/accessories":
return getAccessoryController().listing();
case "/characteristics":
switch (request.getMethod()) {
case PUT:
return getCharacteristicsController().put(request, connection);
default:
logger.warn("Unrecognized method for " + request.getUri());
return new NotFoundResponse();
}
case "/identify":
return new BadRequestResponse();
case "/pairings":
return new PairingsManager(authInfo, advertiser).handle(request);
default:
if (request.getUri().startsWith("/characteristics?")) {
return getCharacteristicsController().get(request);
}
logger.warn("Unrecognized request for " + request.getUri());
return new NotFoundResponse();
}
} catch (Exception e) {
logger.warn("Could not handle request", e);
return new InternalServerErrorResponse(e);
}
}
private HttpResponse handlePairSetup(HttpRequest request) {
if (pairSetupManager == null) {
synchronized (HttpSession.class) {
if (pairSetupManager == null) {
pairSetupManager = new PairSetupManager(authInfo, registry);
}
}
}
try {
return pairSetupManager.handle(request);
} catch (Exception e) {
logger.warn("Exception encountered during pairing", e);
return new InternalServerErrorResponse(e);
}
}
private HttpResponse handlePairVerify(HttpRequest request) {
if (pairVerifyManager == null) {
synchronized (HttpSession.class) {
if (pairVerifyManager == null) {
pairVerifyManager = new PairVerifyManager(authInfo, registry);
}
}
}
try {
return pairVerifyManager.handle(request);
} catch (Exception e) {
logger.warn("Exception encountered while verifying pairing", e);
return new InternalServerErrorResponse(e);
}
}
private synchronized AccessoryController getAccessoryController() {
if (accessoryController == null) {
accessoryController = new AccessoryController(registry);
}
return accessoryController;
}
private synchronized CharacteristicsController getCharacteristicsController() {
if (characteristicsController == null) {
characteristicsController = new CharacteristicsController(registry, subscriptions);
}
return characteristicsController;
}
public static class SessionKey {
private final InetAddress address;
private final HomekitAccessory accessory;
public SessionKey(InetAddress address, HomekitAccessory accessory) {
this.address = address;
this.accessory = accessory;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof SessionKey) {
return address.equals(((SessionKey) obj).address)
&& accessory.equals(((SessionKey) obj).accessory);
} else {
return false;
}
}
@Override
public int hashCode() {
int hash = 1;
hash = hash * 31 + address.hashCode();
hash = hash * 31 + accessory.hashCode();
return hash;
}
}
}