mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 20:48:06 +01:00
Add websocket-resources as a module
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages;
|
||||
|
||||
public class InvalidMessageException extends Exception {
|
||||
public InvalidMessageException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public InvalidMessageException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages;
|
||||
|
||||
public interface WebSocketMessage {
|
||||
|
||||
public enum Type {
|
||||
UNKNOWN_MESSAGE,
|
||||
REQUEST_MESSAGE,
|
||||
RESPONSE_MESSAGE
|
||||
}
|
||||
|
||||
public Type getType();
|
||||
public WebSocketRequestMessage getRequestMessage();
|
||||
public WebSocketResponseMessage getResponseMessage();
|
||||
public byte[] toByteArray();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public interface WebSocketMessageFactory {
|
||||
|
||||
public WebSocketMessage parseMessage(byte[] serialized, int offset, int len)
|
||||
throws InvalidMessageException;
|
||||
|
||||
public WebSocketMessage createRequest(Optional<Long> requestId,
|
||||
String verb, String path,
|
||||
List<String> headers,
|
||||
Optional<byte[]> body);
|
||||
|
||||
public WebSocketMessage createResponse(long requestId, int status, String message,
|
||||
List<String> headers,
|
||||
Optional<byte[]> body);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages;
|
||||
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface WebSocketRequestMessage {
|
||||
|
||||
public String getVerb();
|
||||
public String getPath();
|
||||
public Map<String,String> getHeaders();
|
||||
public Optional<byte[]> getBody();
|
||||
public long getRequestId();
|
||||
public boolean hasRequestId();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface WebSocketResponseMessage {
|
||||
public long getRequestId();
|
||||
public int getStatus();
|
||||
public String getMessage();
|
||||
public Map<String,String> getHeaders();
|
||||
public Optional<byte[]> getBody();
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages.protobuf;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import org.whispersystems.websocket.messages.InvalidMessageException;
|
||||
import org.whispersystems.websocket.messages.WebSocketMessage;
|
||||
import org.whispersystems.websocket.messages.WebSocketRequestMessage;
|
||||
import org.whispersystems.websocket.messages.WebSocketResponseMessage;
|
||||
|
||||
public class ProtobufWebSocketMessage implements WebSocketMessage {
|
||||
|
||||
private final SubProtocol.WebSocketMessage message;
|
||||
|
||||
ProtobufWebSocketMessage(byte[] buffer, int offset, int length) throws InvalidMessageException {
|
||||
try {
|
||||
this.message = SubProtocol.WebSocketMessage.parseFrom(ByteString.copyFrom(buffer, offset, length));
|
||||
|
||||
if (getType() == Type.REQUEST_MESSAGE) {
|
||||
if (!message.getRequest().hasVerb() || !message.getRequest().hasPath()) {
|
||||
throw new InvalidMessageException("Missing required request attributes!");
|
||||
}
|
||||
} else if (getType() == Type.RESPONSE_MESSAGE) {
|
||||
if (!message.getResponse().hasId() || !message.getResponse().hasStatus() || !message.getResponse().hasMessage()) {
|
||||
throw new InvalidMessageException("Missing required response attributes!");
|
||||
}
|
||||
}
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw new InvalidMessageException(e);
|
||||
}
|
||||
}
|
||||
|
||||
ProtobufWebSocketMessage(SubProtocol.WebSocketMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
if (message.getType().getNumber() == SubProtocol.WebSocketMessage.Type.REQUEST_VALUE &&
|
||||
message.hasRequest())
|
||||
{
|
||||
return Type.REQUEST_MESSAGE;
|
||||
} else if (message.getType().getNumber() == SubProtocol.WebSocketMessage.Type.RESPONSE_VALUE &&
|
||||
message.hasResponse())
|
||||
{
|
||||
return Type.RESPONSE_MESSAGE;
|
||||
} else {
|
||||
return Type.UNKNOWN_MESSAGE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketRequestMessage getRequestMessage() {
|
||||
return new ProtobufWebSocketRequestMessage(message.getRequest());
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketResponseMessage getResponseMessage() {
|
||||
return new ProtobufWebSocketResponseMessage(message.getResponse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
return message.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages.protobuf;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.whispersystems.websocket.messages.InvalidMessageException;
|
||||
import org.whispersystems.websocket.messages.WebSocketMessage;
|
||||
import org.whispersystems.websocket.messages.WebSocketMessageFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ProtobufWebSocketMessageFactory implements WebSocketMessageFactory {
|
||||
|
||||
@Override
|
||||
public WebSocketMessage parseMessage(byte[] serialized, int offset, int len)
|
||||
throws InvalidMessageException
|
||||
{
|
||||
return new ProtobufWebSocketMessage(serialized, offset, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketMessage createRequest(Optional<Long> requestId,
|
||||
String verb, String path,
|
||||
List<String> headers,
|
||||
Optional<byte[]> body)
|
||||
{
|
||||
SubProtocol.WebSocketRequestMessage.Builder requestMessage =
|
||||
SubProtocol.WebSocketRequestMessage.newBuilder()
|
||||
.setVerb(verb)
|
||||
.setPath(path);
|
||||
|
||||
if (requestId.isPresent()) {
|
||||
requestMessage.setId(requestId.get());
|
||||
}
|
||||
|
||||
if (body.isPresent()) {
|
||||
requestMessage.setBody(ByteString.copyFrom(body.get()));
|
||||
}
|
||||
|
||||
if (headers != null) {
|
||||
requestMessage.addAllHeaders(headers);
|
||||
}
|
||||
|
||||
SubProtocol.WebSocketMessage message
|
||||
= SubProtocol.WebSocketMessage.newBuilder()
|
||||
.setType(SubProtocol.WebSocketMessage.Type.REQUEST)
|
||||
.setRequest(requestMessage)
|
||||
.build();
|
||||
|
||||
return new ProtobufWebSocketMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketMessage createResponse(long requestId, int status, String messageString, List<String> headers, Optional<byte[]> body) {
|
||||
SubProtocol.WebSocketResponseMessage.Builder responseMessage =
|
||||
SubProtocol.WebSocketResponseMessage.newBuilder()
|
||||
.setId(requestId)
|
||||
.setStatus(status)
|
||||
.setMessage(messageString);
|
||||
|
||||
if (body.isPresent()) {
|
||||
responseMessage.setBody(ByteString.copyFrom(body.get()));
|
||||
}
|
||||
|
||||
if (headers != null) {
|
||||
responseMessage.addAllHeaders(headers);
|
||||
}
|
||||
|
||||
SubProtocol.WebSocketMessage message =
|
||||
SubProtocol.WebSocketMessage.newBuilder()
|
||||
.setType(SubProtocol.WebSocketMessage.Type.RESPONSE)
|
||||
.setResponse(responseMessage)
|
||||
.build();
|
||||
|
||||
return new ProtobufWebSocketMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages.protobuf;
|
||||
|
||||
import org.whispersystems.websocket.messages.WebSocketRequestMessage;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ProtobufWebSocketRequestMessage implements WebSocketRequestMessage {
|
||||
|
||||
private final SubProtocol.WebSocketRequestMessage message;
|
||||
|
||||
ProtobufWebSocketRequestMessage(SubProtocol.WebSocketRequestMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVerb() {
|
||||
return message.getVerb();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return message.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<byte[]> getBody() {
|
||||
if (message.hasBody()) {
|
||||
return Optional.of(message.getBody().toByteArray());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRequestId() {
|
||||
return message.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRequestId() {
|
||||
return message.hasId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
Map<String, String> results = new HashMap<>();
|
||||
|
||||
for (String header : message.getHeadersList()) {
|
||||
String[] tokenized = header.split(":");
|
||||
|
||||
if (tokenized.length == 2 && tokenized[0] != null && tokenized[1] != null) {
|
||||
results.put(tokenized[0].trim().toLowerCase(), tokenized[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 org.whispersystems.websocket.messages.protobuf;
|
||||
|
||||
import org.whispersystems.websocket.messages.WebSocketResponseMessage;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ProtobufWebSocketResponseMessage implements WebSocketResponseMessage {
|
||||
|
||||
private final SubProtocol.WebSocketResponseMessage message;
|
||||
|
||||
public ProtobufWebSocketResponseMessage(SubProtocol.WebSocketResponseMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRequestId() {
|
||||
return message.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus() {
|
||||
return message.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<byte[]> getBody() {
|
||||
if (message.hasBody()) {
|
||||
return Optional.of(message.getBody().toByteArray());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
Map<String, String> results = new HashMap<>();
|
||||
|
||||
for (String header : message.getHeadersList()) {
|
||||
String[] tokenized = header.split(":");
|
||||
|
||||
if (tokenized.length == 2 && tokenized[0] != null && tokenized[1] != null) {
|
||||
results.put(tokenized[0].trim().toLowerCase(), tokenized[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user