diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index fceb9f9fd..9d3273d0c 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -380,7 +380,7 @@ public class WhisperServerService extends Application MAX_MESSAGE_SIZE) { - // TODO Reject the request - rejectOversizeMessageMeter.mark(); + if (source.isPresent() && !source.get().isFor(destinationName)) { + identifiedMeter.mark(); + } else if (!source.isPresent()) { + unidentifiedMeter.mark(); } - } - try { - boolean isSyncMessage = source.isPresent() && source.get().isFor(destinationName); + for (final IncomingMessage message : messages.getMessages()) { + int contentLength = 0; - Optional destination; + if (!Util.isEmpty(message.getContent())) { + contentLength += message.getContent().length(); + } - if (!isSyncMessage) destination = accountsManager.get(destinationName); - else destination = source; + if (!Util.isEmpty(message.getBody())) { + contentLength += message.getBody().length(); + } - OptionalAccess.verify(source, accessKey, destination); - assert(destination.isPresent()); + Metrics.summary(CONTENT_SIZE_DISTRIBUTION_NAME, UserAgentTagUtil.getUserAgentTags(userAgent)).record(contentLength); - validateCompleteDeviceList(destination.get(), messages.getMessages(), isSyncMessage); - validateRegistrationIds(destination.get(), messages.getMessages()); - - for (IncomingMessage incomingMessage : messages.getMessages()) { - Optional destinationDevice = destination.get().getDevice(incomingMessage.getDestinationDeviceId()); - - if (destinationDevice.isPresent()) { - sendMessage(source, destination.get(), destinationDevice.get(), messages.getTimestamp(), messages.isOnline(), incomingMessage); + if (contentLength > MAX_MESSAGE_SIZE) { + // TODO Reject the request + rejectOversizeMessageMeter.mark(); } } - return new SendMessageResponse(!isSyncMessage && source.isPresent() && source.get().getEnabledDeviceCount() > 1); - } catch (NoSuchUserException e) { - throw new WebApplicationException(Response.status(404).build()); - } catch (MismatchedDevicesException e) { - throw new WebApplicationException(Response.status(409) - .type(MediaType.APPLICATION_JSON_TYPE) - .entity(new MismatchedDevices(e.getMissingDevices(), - e.getExtraDevices())) - .build()); - } catch (StaleDevicesException e) { - throw new WebApplicationException(Response.status(410) - .type(MediaType.APPLICATION_JSON) - .entity(new StaleDevices(e.getStaleDevices())) - .build()); - } */ + try { + boolean isSyncMessage = source.isPresent() && source.get().isFor(destinationName); + + Optional destination; + + if (!isSyncMessage) destination = accountsManager.get(destinationName); + else destination = source; + + OptionalAccess.verify(source, accessKey, destination); + assert(destination.isPresent()); + + validateCompleteDeviceList(destination.get(), messages.getMessages(), isSyncMessage); + validateRegistrationIds(destination.get(), messages.getMessages()); + + for (IncomingMessage incomingMessage : messages.getMessages()) { + Optional destinationDevice = destination.get().getDevice(incomingMessage.getDestinationDeviceId()); + + if (destinationDevice.isPresent()) { + sendMessage(source, destination.get(), destinationDevice.get(), messages.getTimestamp(), messages.isOnline(), incomingMessage); + } + } + + return Response.ok(new SendMessageResponse(!isSyncMessage && source.isPresent() && source.get().getEnabledDeviceCount() > 1)).build(); + } catch (NoSuchUserException e) { + throw new WebApplicationException(Response.status(404).build()); + } catch (MismatchedDevicesException e) { + throw new WebApplicationException(Response.status(409) + .type(MediaType.APPLICATION_JSON_TYPE) + .entity(new MismatchedDevices(e.getMissingDevices(), + e.getExtraDevices())) + .build()); + } catch (StaleDevicesException e) { + throw new WebApplicationException(Response.status(410) + .type(MediaType.APPLICATION_JSON) + .entity(new StaleDevices(e.getStaleDevices())) + .build()); + } } else { + return Response.status(503).build(); + } + } + + private double getSuccessPercentage() { + if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_1_PERCENT")) { + return 0.01; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_2_PERCENT")) { + return 0.02; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_4_PERCENT")) { + return 0.04; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_8_PERCENT")) { + return 0.08; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_16_PERCENT")) { + return 0.16; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_32_PERCENT")) { + return 0.32; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_48_PERCENT")) { + return 0.48; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_64_PERCENT")) { + return 0.64; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_80_PERCENT")) { + return 0.80; + } else if (featureFlagsManager.isFeatureFlagActive("SEND_MESSAGE_100_PERCENT")) { + return 1.0d; + } + + return 0; } @Timed diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java index b892bcf9a..310469bc7 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java @@ -35,6 +35,7 @@ import org.whispersystems.textsecuregcm.push.ReceiptSender; import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.Device; +import org.whispersystems.textsecuregcm.storage.FeatureFlagsManager; import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; import org.whispersystems.textsecuregcm.util.Base64; @@ -86,6 +87,7 @@ public class MessageControllerTest { private final RateLimiters rateLimiters = mock(RateLimiters.class); private final RateLimiter rateLimiter = mock(RateLimiter.class); private final ApnFallbackManager apnFallbackManager = mock(ApnFallbackManager.class); + private final FeatureFlagsManager featureFlagsManager = mock(FeatureFlagsManager.class); private final ObjectMapper mapper = new ObjectMapper(); @@ -95,7 +97,7 @@ public class MessageControllerTest { .addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class))) .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .addResource(new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, - messagesManager, apnFallbackManager)) + messagesManager, apnFallbackManager, featureFlagsManager)) .build();