-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Store and forward #2423
Store and forward #2423
Changes from all commits
513c6cb
cb7ee38
28cca81
da10c08
7364732
6c4fa6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
|
||
all: | ||
protoc --java_out=../src/main/java/ IncomingPushMessageSignal.proto Provisioning.proto | ||
protoc --java_out=../src/main/java/ IncomingPushMessageSignal.proto Provisioning.proto WebSocketResources.proto |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/** | ||
* Copyright (C) 2014-2015 Open WhisperSystems | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero 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 Affero General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Affero General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package textsecure; | ||
|
||
option java_package = "org.whispersystems.textsecure.internal.websocket"; | ||
option java_outer_classname = "WebSocketProtos"; | ||
|
||
message WebSocketRequestMessage { | ||
optional string verb = 1; | ||
optional string path = 2; | ||
optional bytes body = 3; | ||
optional uint64 id = 4; | ||
} | ||
|
||
message WebSocketResponseMessage { | ||
optional uint64 id = 1; | ||
optional uint32 status = 2; | ||
optional string message = 3; | ||
optional bytes body = 4; | ||
} | ||
|
||
message WebSocketMessage { | ||
enum Type { | ||
UNKNOWN = 0; | ||
REQUEST = 1; | ||
RESPONSE = 2; | ||
} | ||
|
||
optional Type type = 1; | ||
optional WebSocketRequestMessage request = 2; | ||
optional WebSocketResponseMessage response = 3; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package org.whispersystems.textsecure.api; | ||
|
||
import org.whispersystems.libaxolotl.InvalidVersionException; | ||
import org.whispersystems.textsecure.api.messages.TextSecureEnvelope; | ||
import org.whispersystems.textsecure.api.util.CredentialsProvider; | ||
import org.whispersystems.textsecure.internal.websocket.WebSocketConnection; | ||
|
||
import java.io.IOException; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.TimeoutException; | ||
|
||
import static org.whispersystems.textsecure.internal.websocket.WebSocketProtos.WebSocketRequestMessage; | ||
import static org.whispersystems.textsecure.internal.websocket.WebSocketProtos.WebSocketResponseMessage; | ||
|
||
public class TextSecureMessagePipe { | ||
|
||
private final WebSocketConnection websocket; | ||
private final CredentialsProvider credentialsProvider; | ||
|
||
public TextSecureMessagePipe(WebSocketConnection websocket, CredentialsProvider credentialsProvider) { | ||
this.websocket = websocket; | ||
this.credentialsProvider = credentialsProvider; | ||
|
||
this.websocket.connect(); | ||
} | ||
|
||
public TextSecureEnvelope read(long timeout, TimeUnit unit) | ||
throws InvalidVersionException, IOException, TimeoutException | ||
{ | ||
return read(timeout, unit, new NullMessagePipeCallback()); | ||
} | ||
|
||
public TextSecureEnvelope read(long timeout, TimeUnit unit, MessagePipeCallback callback) | ||
throws TimeoutException, IOException, InvalidVersionException | ||
{ | ||
while (true) { | ||
WebSocketRequestMessage request = websocket.readRequest(unit.toMillis(timeout)); | ||
WebSocketResponseMessage response = createWebSocketResponse(request); | ||
|
||
try { | ||
if (isTextSecureEnvelope(request)) { | ||
TextSecureEnvelope envelope = new TextSecureEnvelope(request.getBody().toByteArray(), | ||
credentialsProvider.getSignalingKey()); | ||
|
||
callback.onMessage(envelope); | ||
return envelope; | ||
} | ||
} finally { | ||
websocket.sendResponse(response); | ||
} | ||
} | ||
} | ||
|
||
public void shutdown() throws IOException { | ||
websocket.disconnect(); | ||
} | ||
|
||
private boolean isTextSecureEnvelope(WebSocketRequestMessage message) { | ||
return "PUT".equals(message.getVerb()) && "/api/v1/message".equals(message.getPath()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should the endpoint refer to the PushServiceSocket constants for when the API changes? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This endpoint is unrelated to PushServiceSocket, it's strictly a websocket thing. |
||
} | ||
|
||
private WebSocketResponseMessage createWebSocketResponse(WebSocketRequestMessage request) { | ||
if (isTextSecureEnvelope(request)) { | ||
return WebSocketResponseMessage.newBuilder() | ||
.setId(request.getId()) | ||
.setStatus(200) | ||
.setMessage("OK") | ||
.build(); | ||
} else { | ||
return WebSocketResponseMessage.newBuilder() | ||
.setId(request.getId()) | ||
.setStatus(400) | ||
.setMessage("Unknown") | ||
.build(); | ||
} | ||
} | ||
|
||
public static interface MessagePipeCallback { | ||
public void onMessage(TextSecureEnvelope envelope); | ||
} | ||
|
||
private static class NullMessagePipeCallback implements MessagePipeCallback { | ||
@Override | ||
public void onMessage(TextSecureEnvelope envelope) {} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.whispersystems.textsecure.api.util; | ||
|
||
public interface CredentialsProvider { | ||
public String getUser(); | ||
public String getPassword(); | ||
public String getSignalingKey(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since body is optional in the protobuf, could someone just send an envelope without one and cause NPE here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"someone" here is the server, which i'm willing to trust with an npe