diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java index ec74b84db..cadabfa59 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java @@ -11,6 +11,7 @@ import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.SharedMetricRegistries; import com.codahale.metrics.annotation.Timed; import com.google.common.annotations.VisibleForTesting; +import com.google.common.net.HttpHeaders; import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; import com.google.i18n.phonenumbers.Phonenumber; @@ -22,7 +23,6 @@ import java.security.SecureRandom; import java.time.Clock; import java.time.Duration; import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -101,8 +101,8 @@ import org.whispersystems.textsecuregcm.storage.StoredVerificationCodeManager; import org.whispersystems.textsecuregcm.storage.UsernameNotAvailableException; import org.whispersystems.textsecuregcm.storage.UsernameReservationNotFoundException; import org.whispersystems.textsecuregcm.util.Constants; -import org.whispersystems.textsecuregcm.util.ForwardedIpUtil; import org.whispersystems.textsecuregcm.util.Hex; +import org.whispersystems.textsecuregcm.util.HeaderUtils; import org.whispersystems.textsecuregcm.util.ImpossiblePhoneNumberException; import org.whispersystems.textsecuregcm.util.NonNormalizedPhoneNumberException; import org.whispersystems.textsecuregcm.util.Optionals; @@ -256,9 +256,9 @@ public class AccountController { @Produces(MediaType.APPLICATION_JSON) public Response createAccount(@PathParam("transport") String transport, @PathParam("number") String number, - @HeaderParam("X-Forwarded-For") String forwardedFor, - @HeaderParam("User-Agent") String userAgent, - @HeaderParam("Accept-Language") Optional acceptLanguage, + @HeaderParam(HttpHeaders.X_FORWARDED_FOR) String forwardedFor, + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent, + @HeaderParam(HttpHeaders.ACCEPT_LANGUAGE) Optional acceptLanguage, @QueryParam("client") Optional client, @QueryParam("captcha") Optional captcha, @QueryParam("challenge") Optional pushChallenge) @@ -266,7 +266,7 @@ public class AccountController { Util.requireNormalizedNumber(number); - final String sourceHost = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow(); + final String sourceHost = HeaderUtils.getMostRecentProxy(forwardedFor).orElseThrow(); final Optional maybeStoredVerificationCode = pendingAccounts.getCodeForNumber(number); final String countryCode = Util.getCountryCode(number); @@ -369,9 +369,9 @@ public class AccountController { @Produces(MediaType.APPLICATION_JSON) @Path("/code/{verification_code}") public AccountIdentityResponse verifyAccount(@PathParam("verification_code") String verificationCode, - @HeaderParam("Authorization") BasicAuthorizationHeader authorizationHeader, - @HeaderParam("X-Signal-Agent") String signalAgent, - @HeaderParam("User-Agent") String userAgent, + @HeaderParam(HttpHeaders.AUTHORIZATION) BasicAuthorizationHeader authorizationHeader, + @HeaderParam(HeaderUtils.X_SIGNAL_AGENT) String signalAgent, + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent, @QueryParam("transfer") Optional availableForTransfer, @NotNull @Valid AccountAttributes accountAttributes) throws RateLimitExceededException, InterruptedException { @@ -433,7 +433,7 @@ public class AccountController { @Produces(MediaType.APPLICATION_JSON) public AccountIdentityResponse changeNumber(@Auth final AuthenticatedAccount authenticatedAccount, @NotNull @Valid final ChangePhoneNumberRequest request, - @HeaderParam("User-Agent") String userAgent) + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent) throws RateLimitExceededException, InterruptedException, ImpossiblePhoneNumberException, NonNormalizedPhoneNumberException { if (!authenticatedAccount.getAuthenticatedDevice().isMaster()) { @@ -622,7 +622,7 @@ public class AccountController { @Produces(MediaType.APPLICATION_JSON) @ChangesDeviceEnabledState public void setAccountAttributes(@Auth DisabledPermittedAuthenticatedAccount disabledPermittedAuth, - @HeaderParam("X-Signal-Agent") String userAgent, + @HeaderParam(HeaderUtils.X_SIGNAL_AGENT) String userAgent, @NotNull @Valid AccountAttributes attributes) { Account account = disabledPermittedAuth.getAccount(); long deviceId = disabledPermittedAuth.getAuthenticatedDevice().getId(); @@ -678,7 +678,7 @@ public class AccountController { @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public ReserveUsernameResponse reserveUsername(@Auth AuthenticatedAccount auth, - @HeaderParam("X-Signal-Agent") String userAgent, + @HeaderParam(HeaderUtils.X_SIGNAL_AGENT) String userAgent, @NotNull @Valid ReserveUsernameRequest usernameRequest) throws RateLimitExceededException { rateLimiters.getUsernameReserveLimiter().validate(auth.getAccount().getUuid()); @@ -700,7 +700,7 @@ public class AccountController { @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public UsernameResponse confirmUsername(@Auth AuthenticatedAccount auth, - @HeaderParam("X-Signal-Agent") String userAgent, + @HeaderParam(HeaderUtils.X_SIGNAL_AGENT) String userAgent, @NotNull @Valid ConfirmUsernameRequest confirmRequest) throws RateLimitExceededException { rateLimiters.getUsernameSetLimiter().validate(auth.getAccount().getUuid()); @@ -724,7 +724,7 @@ public class AccountController { @Consumes(MediaType.APPLICATION_JSON) public UsernameResponse setUsername( @Auth AuthenticatedAccount auth, - @HeaderParam("X-Signal-Agent") String userAgent, + @HeaderParam(HeaderUtils.X_SIGNAL_AGENT) String userAgent, @NotNull @Valid UsernameRequest usernameRequest) throws RateLimitExceededException { rateLimiters.getUsernameSetLimiter().validate(auth.getAccount().getUuid()); checkUsername(usernameRequest.existingUsername(), userAgent); @@ -746,8 +746,8 @@ public class AccountController { @Path("/username/{username}") @Produces(MediaType.APPLICATION_JSON) public AccountIdentifierResponse lookupUsername( - @HeaderParam("X-Signal-Agent") final String userAgent, - @HeaderParam("X-Forwarded-For") final String forwardedFor, + @HeaderParam(HeaderUtils.X_SIGNAL_AGENT) final String userAgent, + @HeaderParam(HttpHeaders.X_FORWARDED_FOR) final String forwardedFor, @PathParam("username") final String username, @Context final HttpServletRequest request) throws RateLimitExceededException { @@ -770,7 +770,7 @@ public class AccountController { @HEAD @Path("/account/{uuid}") public Response accountExists( - @HeaderParam("X-Forwarded-For") final String forwardedFor, + @HeaderParam(HttpHeaders.X_FORWARDED_FOR) final String forwardedFor, @PathParam("uuid") final UUID uuid, @Context HttpServletRequest request) throws RateLimitExceededException { @@ -788,7 +788,7 @@ public class AccountController { } private void rateLimitByClientIp(final RateLimiter rateLimiter, final String forwardedFor) throws RateLimitExceededException { - final String mostRecentProxy = ForwardedIpUtil.getMostRecentProxy(forwardedFor) + final String mostRecentProxy = HeaderUtils.getMostRecentProxy(forwardedFor) .orElseThrow(() -> { // Missing/malformed Forwarded-For, so we cannot check for a rate-limit. // This shouldn't happen, so conservatively assume we're over the rate-limit diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ChallengeController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ChallengeController.java index 3a938832a..2320442a7 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ChallengeController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ChallengeController.java @@ -8,6 +8,7 @@ package org.whispersystems.textsecuregcm.controllers; import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name; import com.codahale.metrics.annotation.Timed; +import com.google.common.net.HttpHeaders; import io.dropwizard.auth.Auth; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tags; @@ -19,7 +20,6 @@ import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; @@ -29,7 +29,7 @@ import org.whispersystems.textsecuregcm.entities.AnswerRecaptchaChallengeRequest import org.whispersystems.textsecuregcm.limits.RateLimitChallengeManager; import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil; import org.whispersystems.textsecuregcm.push.NotPushRegisteredException; -import org.whispersystems.textsecuregcm.util.ForwardedIpUtil; +import org.whispersystems.textsecuregcm.util.HeaderUtils; @Path("/v1/challenge") public class ChallengeController { @@ -49,7 +49,7 @@ public class ChallengeController { @Consumes(MediaType.APPLICATION_JSON) public Response handleChallengeResponse(@Auth final AuthenticatedAccount auth, @Valid final AnswerChallengeRequest answerRequest, - @HeaderParam("X-Forwarded-For") final String forwardedFor, + @HeaderParam(HttpHeaders.X_FORWARDED_FOR) final String forwardedFor, @HeaderParam(HttpHeaders.USER_AGENT) final String userAgent) throws RateLimitExceededException { Tags tags = Tags.of(UserAgentTagUtil.getPlatformTag(userAgent)); @@ -64,7 +64,7 @@ public class ChallengeController { try { final AnswerRecaptchaChallengeRequest recaptchaChallengeRequest = (AnswerRecaptchaChallengeRequest) answerRequest; - final String mostRecentProxy = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow(); + final String mostRecentProxy = HeaderUtils.getMostRecentProxy(forwardedFor).orElseThrow(); rateLimitChallengeManager.answerRecaptchaChallenge(auth.getAccount(), recaptchaChallengeRequest.getCaptcha(), mostRecentProxy, userAgent); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/DeviceController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/DeviceController.java index 4f708cb53..bd963d7a8 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/DeviceController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/DeviceController.java @@ -6,6 +6,7 @@ package org.whispersystems.textsecuregcm.controllers; import com.codahale.metrics.annotation.Timed; import com.google.common.annotations.VisibleForTesting; +import com.google.common.net.HttpHeaders; import io.dropwizard.auth.Auth; import java.security.SecureRandom; import java.util.LinkedList; @@ -148,8 +149,8 @@ public class DeviceController { @Path("/{verification_code}") @ChangesDeviceEnabledState public DeviceResponse verifyDeviceToken(@PathParam("verification_code") String verificationCode, - @HeaderParam("Authorization") BasicAuthorizationHeader authorizationHeader, - @HeaderParam("User-Agent") String userAgent, + @HeaderParam(HttpHeaders.AUTHORIZATION) BasicAuthorizationHeader authorizationHeader, + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent, @NotNull @Valid AccountAttributes accountAttributes, @Context ContainerRequest containerRequest) throws RateLimitExceededException, DeviceLimitExceededException { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java index ab899a9da..d36b9fa4e 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java @@ -7,6 +7,7 @@ package org.whispersystems.textsecuregcm.controllers; import static com.codahale.metrics.MetricRegistry.name; import com.codahale.metrics.annotation.Timed; +import com.google.common.net.HttpHeaders; import io.dropwizard.auth.Auth; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tags; @@ -94,7 +95,7 @@ public class KeysController { public void setKeys(@Auth final DisabledPermittedAuthenticatedAccount disabledPermittedAuth, @NotNull @Valid final PreKeyState preKeys, @QueryParam("identity") final Optional identityType, - @HeaderParam("User-Agent") String userAgent) { + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent) { Account account = disabledPermittedAuth.getAccount(); Device device = disabledPermittedAuth.getAuthenticatedDevice(); boolean updateAccount = false; @@ -151,7 +152,7 @@ public class KeysController { @HeaderParam(OptionalAccess.UNIDENTIFIED) Optional accessKey, @PathParam("identifier") UUID targetUuid, @PathParam("device_id") String deviceId, - @HeaderParam("User-Agent") String userAgent) + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent) throws RateLimitExceededException { if (!auth.isPresent() && !accessKey.isPresent()) { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java index 56120af90..258cb581a 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java @@ -8,6 +8,7 @@ import static com.codahale.metrics.MetricRegistry.name; import com.codahale.metrics.annotation.Timed; import com.google.common.annotations.VisibleForTesting; +import com.google.common.net.HttpHeaders; import com.google.protobuf.ByteString; import io.dropwizard.auth.Auth; import io.dropwizard.util.DataSize; @@ -166,8 +167,8 @@ public class MessageController { @FilterAbusiveMessages public Response sendMessage(@Auth Optional source, @HeaderParam(OptionalAccess.UNIDENTIFIED) Optional accessKey, - @HeaderParam("User-Agent") String userAgent, - @HeaderParam("X-Forwarded-For") String forwardedFor, + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent, + @HeaderParam(HttpHeaders.X_FORWARDED_FOR) String forwardedFor, @PathParam("destination") UUID destinationUuid, @QueryParam("story") boolean isStory, @NotNull @Valid IncomingMessageList messages) @@ -324,8 +325,8 @@ public class MessageController { @FilterAbusiveMessages public Response sendMultiRecipientMessage( @HeaderParam(OptionalAccess.UNIDENTIFIED) @Nullable CombinedUnidentifiedSenderAccessKeys accessKeys, - @HeaderParam("User-Agent") String userAgent, - @HeaderParam("X-Forwarded-For") String forwardedFor, + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent, + @HeaderParam(HttpHeaders.X_FORWARDED_FOR) String forwardedFor, @QueryParam("online") boolean online, @QueryParam("ts") long timestamp, @QueryParam("urgent") @DefaultValue("true") final boolean isUrgent, @@ -486,7 +487,7 @@ public class MessageController { @Produces(MediaType.APPLICATION_JSON) public CompletableFuture getPendingMessages(@Auth AuthenticatedAccount auth, @HeaderParam(Stories.X_SIGNAL_RECEIVE_STORIES) String receiveStoriesHeader, - @HeaderParam("User-Agent") String userAgent) { + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent) { boolean shouldReceiveStories = Stories.parseReceiveStoriesHeader(receiveStoriesHeader); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ProfileController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ProfileController.java index a433e2238..32fcbc8c8 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ProfileController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ProfileController.java @@ -317,7 +317,7 @@ public class ProfileController { @Auth Optional auth, @HeaderParam(OptionalAccess.UNIDENTIFIED) Optional accessKey, @Context ContainerRequestContext containerRequestContext, - @HeaderParam("User-Agent") String userAgent, + @HeaderParam(HttpHeaders.USER_AGENT) String userAgent, @PathParam("identifier") UUID identifier, @QueryParam("ca") boolean useCaCertificate) throws RateLimitExceededException { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/filters/RemoteDeprecationFilter.java b/service/src/main/java/org/whispersystems/textsecuregcm/filters/RemoteDeprecationFilter.java index be77d3f11..5d185657a 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/filters/RemoteDeprecationFilter.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/filters/RemoteDeprecationFilter.java @@ -7,6 +7,7 @@ package org.whispersystems.textsecuregcm.filters; import static com.codahale.metrics.MetricRegistry.name; +import com.google.common.net.HttpHeaders; import com.vdurmont.semver4j.Semver; import io.micrometer.core.instrument.Metrics; import java.io.IOException; @@ -63,7 +64,7 @@ public class RemoteDeprecationFilter implements Filter { boolean shouldBlock = false; try { - final String userAgentString = ((HttpServletRequest) request).getHeader("User-Agent"); + final String userAgentString = ((HttpServletRequest) request).getHeader(HttpHeaders.USER_AGENT); final UserAgent userAgent = UserAgentUtil.parseUserAgentString(userAgentString); if (blockedVersionsByPlatform.containsKey(userAgent.getPlatform())) { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/filters/TimestampResponseFilter.java b/service/src/main/java/org/whispersystems/textsecuregcm/filters/TimestampResponseFilter.java index e0dd38f0e..5d9553ccb 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/filters/TimestampResponseFilter.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/filters/TimestampResponseFilter.java @@ -5,11 +5,10 @@ package org.whispersystems.textsecuregcm.filters; -import org.whispersystems.textsecuregcm.util.TimestampHeaderUtil; - import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; +import org.whispersystems.textsecuregcm.util.HeaderUtils; /** * Injects a timestamp header into all outbound responses. @@ -18,6 +17,6 @@ public class TimestampResponseFilter implements ContainerResponseFilter { @Override public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext) { - responseContext.getHeaders().add(TimestampHeaderUtil.TIMESTAMP_HEADER, System.currentTimeMillis()); + responseContext.getHeaders().add(HeaderUtils.TIMESTAMP_HEADER, System.currentTimeMillis()); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListener.java b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListener.java index c00ea33e5..3da6229fc 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListener.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListener.java @@ -7,11 +7,17 @@ package org.whispersystems.textsecuregcm.metrics; import com.codahale.metrics.MetricRegistry; import com.google.common.annotations.VisibleForTesting; +import com.google.common.net.HttpHeaders; import com.vdurmont.semver4j.Semver; import com.vdurmont.semver4j.SemverException; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tag; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.glassfish.jersey.server.monitoring.RequestEvent; import org.glassfish.jersey.server.monitoring.RequestEventListener; import org.whispersystems.textsecuregcm.util.logging.UriInfoUtil; @@ -20,12 +26,6 @@ import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException; import org.whispersystems.textsecuregcm.util.ua.UserAgent; import org.whispersystems.textsecuregcm.util.ua.UserAgentUtil; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * Gathers and reports request-level metrics. */ @@ -75,7 +75,7 @@ public class MetricsRequestEventListener implements RequestEventListener { tags.add(Tag.of(STATUS_CODE_TAG, String.valueOf(event.getContainerResponse().getStatus()))); tags.add(Tag.of(TRAFFIC_SOURCE_TAG, trafficSource.name().toLowerCase())); - final List userAgentValues = event.getContainerRequest().getRequestHeader("User-Agent"); + final List userAgentValues = event.getContainerRequest().getRequestHeader(HttpHeaders.USER_AGENT); // tags.addAll(UserAgentTagUtil.getUserAgentTags(userAgentValues != null ? userAgentValues.stream().findFirst().orElse(null) : null)); tags.add(UserAgentTagUtil.getPlatformTag(userAgentValues != null ? userAgentValues.stream().findFirst().orElse(null) : null)); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/util/ForwardedIpUtil.java b/service/src/main/java/org/whispersystems/textsecuregcm/util/HeaderUtils.java similarity index 64% rename from service/src/main/java/org/whispersystems/textsecuregcm/util/ForwardedIpUtil.java rename to service/src/main/java/org/whispersystems/textsecuregcm/util/HeaderUtils.java index 2251d31e9..9fd7b61e1 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/util/ForwardedIpUtil.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/util/HeaderUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Signal Messenger, LLC + * Copyright 2022 Signal Messenger, LLC * SPDX-License-Identifier: AGPL-3.0-only */ @@ -10,17 +10,23 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.apache.commons.lang3.StringUtils; -/** - * Tools for working with chains of IP addresses in forwarding lists in HTTP headers. - * - * @see X-Forwarded-For - HTTP | MDN - */ -public final class ForwardedIpUtil { +public final class HeaderUtils { - private ForwardedIpUtil() { + public static final String X_SIGNAL_AGENT = "X-Signal-Agent"; + + public static final String X_SIGNAL_KEY = "X-Signal-Key"; + + public static final String TIMESTAMP_HEADER = "X-Signal-Timestamp"; + + private HeaderUtils() { // utility class } + @Nonnull + public static String getTimestampHeader() { + return TIMESTAMP_HEADER + ":" + System.currentTimeMillis(); + } + /** * Returns the most recent proxy in a chain described by an {@code X-Forwarded-For} header. * @@ -28,6 +34,8 @@ public final class ForwardedIpUtil { * * @return the IP address of the most recent proxy in the forwarding chain, or empty if none was found or * {@code forwardedFor} was null + * + * @see X-Forwarded-For - HTTP | MDN */ @Nonnull public static Optional getMostRecentProxy(@Nullable final String forwardedFor) { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/util/TimestampHeaderUtil.java b/service/src/main/java/org/whispersystems/textsecuregcm/util/TimestampHeaderUtil.java deleted file mode 100644 index 5f1cdd6f6..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/util/TimestampHeaderUtil.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2013-2020 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.util; - -public class TimestampHeaderUtil { - - public static final String TIMESTAMP_HEADER = "X-Signal-Timestamp"; - - private TimestampHeaderUtil() { - } - - public static String getTimestampHeader() { - return TIMESTAMP_HEADER + ":" + System.currentTimeMillis(); - } -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/util/logging/LoggingUnhandledExceptionMapper.java b/service/src/main/java/org/whispersystems/textsecuregcm/util/logging/LoggingUnhandledExceptionMapper.java index 9f7ba458a..ca4757022 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/util/logging/LoggingUnhandledExceptionMapper.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/util/logging/LoggingUnhandledExceptionMapper.java @@ -6,6 +6,7 @@ package org.whispersystems.textsecuregcm.util.logging; import com.google.common.annotations.VisibleForTesting; +import com.google.common.net.HttpHeaders; import io.dropwizard.jersey.errors.LoggingExceptionMapper; import javax.inject.Provider; import javax.ws.rs.core.Context; @@ -38,7 +39,7 @@ public class LoggingUnhandledExceptionMapper extends LoggingExceptionMapper body = Optional.of(outgoingMessage.getContent().toByteArray()); - client.sendRequest("PUT", "/v1/message", Collections.singletonList(TimestampHeaderUtil.getTimestampHeader()), body) + client.sendRequest("PUT", "/v1/message", Collections.singletonList(HeaderUtils.getTimestampHeader()), body) .thenAccept(response -> client.close(1001, "All you get.")) .exceptionally(throwable -> { client.close(1001, "That's all!"); @@ -51,7 +50,7 @@ public class ProvisioningConnection implements DispatchChannel { public void onDispatchSubscribed(String channel) { try { ProvisioningAddress address = new ProvisioningAddress(channel); - this.client.sendRequest("PUT", "/v1/address", Collections.singletonList(TimestampHeaderUtil.getTimestampHeader()), + this.client.sendRequest("PUT", "/v1/address", Collections.singletonList(HeaderUtils.getTimestampHeader()), Optional.of(ProvisioningUuid.newBuilder() .setUuid(address.getAddress()) .build() diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java b/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java index 528491abb..86557a96d 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java @@ -48,7 +48,7 @@ import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.MessageAvailabilityListener; import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.util.Constants; -import org.whispersystems.textsecuregcm.util.TimestampHeaderUtil; +import org.whispersystems.textsecuregcm.util.HeaderUtils; import org.whispersystems.websocket.WebSocketClient; import org.whispersystems.websocket.messages.WebSocketResponseMessage; import reactor.core.Disposable; @@ -220,7 +220,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac // X-Signal-Key: false must be sent until Android stops assuming it missing means true return client.sendRequest("PUT", "/api/v1/message", - List.of("X-Signal-Key: false", TimestampHeaderUtil.getTimestampHeader()), body) + List.of(HeaderUtils.X_SIGNAL_KEY + ": false", HeaderUtils.getTimestampHeader()), body) .whenComplete((ignored, throwable) -> { if (throwable != null) { sendFailuresMeter.mark(); @@ -317,7 +317,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac } client.sendRequest("PUT", "/api/v1/queue/empty", - Collections.singletonList(TimestampHeaderUtil.getTimestampHeader()), Optional.empty()); + Collections.singletonList(HeaderUtils.getTimestampHeader()), Optional.empty()); } } else { storedMessageState.compareAndSet(StoredMessageState.EMPTY, state); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/AccountControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/AccountControllerTest.java index e76854196..803a12dc6 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/AccountControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/AccountControllerTest.java @@ -13,7 +13,6 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.anyLong; -import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.eq; @@ -28,6 +27,7 @@ import static org.mockito.Mockito.when; import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.collect.ImmutableSet; +import com.google.common.net.HttpHeaders; import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; import com.google.i18n.phonenumbers.Phonenumber; @@ -481,7 +481,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(200); @@ -502,7 +502,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", "Definitely not a real number")) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(400); @@ -520,7 +520,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", number)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(400); @@ -543,7 +543,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/voice/code/%s", SENDER)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); final Phonenumber.PhoneNumber phoneNumber = PhoneNumberUtil.getInstance().parse(SENDER, null); @@ -564,7 +564,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER_PREAUTH)) .queryParam("challenge", "validchallenge") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(200); @@ -582,7 +582,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER_PREAUTH)) .queryParam("challenge", "invalidchallenge") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(403); @@ -597,7 +597,7 @@ class AccountControllerTest { resources.getJerseyTest() .target(String.format("/v1/accounts/sms/code/%s", SENDER_PREAUTH)) .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(402); @@ -617,7 +617,7 @@ class AccountControllerTest { .queryParam("client", "ios") .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(200); @@ -638,7 +638,7 @@ class AccountControllerTest { .queryParam("client", "android-ng") .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(200); @@ -656,7 +656,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", ABUSIVE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, ABUSIVE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(402); @@ -676,7 +676,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("captcha", VALID_CAPTCHA_TOKEN) .request() - .header("X-Forwarded-For", ABUSIVE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, ABUSIVE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(200); @@ -696,7 +696,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("captcha", INVALID_CAPTCHA_TOKEN) .request() - .header("X-Forwarded-For", ABUSIVE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, ABUSIVE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(402); @@ -713,7 +713,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", RATE_LIMITED_IP_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, RATE_LIMITED_IP_HOST) .get(); assertThat(response.getStatus()).isEqualTo(402); @@ -734,7 +734,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER_OVER_PREFIX)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", RATE_LIMITED_PREFIX_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, RATE_LIMITED_PREFIX_HOST) .get(); assertThat(response.getStatus()).isEqualTo(402); @@ -755,7 +755,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", RATE_LIMITED_HOST2) + .header(HttpHeaders.X_FORWARDED_FOR, RATE_LIMITED_HOST2) .get(); assertThat(response.getStatus()).isEqualTo(402); @@ -776,7 +776,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", NICE_HOST + ", " + ABUSIVE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST + ", " + ABUSIVE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(402); @@ -800,7 +800,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", RESTRICTED_NUMBER)) .queryParam("challenge", challenge) .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(402); @@ -835,7 +835,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", number)) .queryParam("challenge", challenge) .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); if (expectSendCode) { @@ -863,7 +863,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("challenge", challenge) .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(200); @@ -884,7 +884,7 @@ class AccountControllerTest { resources.getJerseyTest() .target(String.format("/v1/accounts/sms/code/%s", TEST_NUMBER)) .request() - .header("X-Forwarded-For", ABUSIVE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, ABUSIVE_HOST) .get(); final ArgumentCaptor captor = ArgumentCaptor.forClass(StoredVerificationCode.class); @@ -1825,7 +1825,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/sms/code/%s", SENDER)) .queryParam("challenge", "1234-push") .request() - .header("X-Forwarded-For", NICE_HOST) + .header(HttpHeaders.X_FORWARDED_FOR, NICE_HOST) .get(); assertThat(response.getStatus()).isEqualTo(expectedResponseStatusCode); @@ -1861,21 +1861,21 @@ class AccountControllerTest { assertThat(resources.getJerseyTest() .target(String.format("/v1/accounts/account/%s", accountIdentifier)) .request() - .header("X-Forwarded-For", "127.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1") .head() .getStatus()).isEqualTo(200); assertThat(resources.getJerseyTest() .target(String.format("/v1/accounts/account/%s", phoneNumberIdentifier)) .request() - .header("X-Forwarded-For", "127.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1") .head() .getStatus()).isEqualTo(200); assertThat(resources.getJerseyTest() .target(String.format("/v1/accounts/account/%s", UUID.randomUUID())) .request() - .header("X-Forwarded-For", "127.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1") .head() .getStatus()).isEqualTo(404); } @@ -1893,7 +1893,7 @@ class AccountControllerTest { final Response response = resources.getJerseyTest() .target(String.format("/v1/accounts/account/%s", accountIdentifier)) .request() - .header("X-Forwarded-For", "127.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1") .head(); assertThat(response.getStatus()).isEqualTo(413); @@ -1905,7 +1905,7 @@ class AccountControllerTest { final Response response = resources.getJerseyTest() .target(String.format("/v1/accounts/account/%s", UUID.randomUUID())) .request() - .header("X-Forwarded-For", "") + .header(HttpHeaders.X_FORWARDED_FOR, "") .head(); assertThat(response.getStatus()).isEqualTo(413); @@ -1918,7 +1918,7 @@ class AccountControllerTest { .target(String.format("/v1/accounts/account/%s", UUID.randomUUID())) .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) - .header("X-Forwarded-For", "127.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1") .head() .getStatus()).isEqualTo(400); } @@ -1933,7 +1933,7 @@ class AccountControllerTest { Response response = resources.getJerseyTest() .target("v1/accounts/username/n00bkiller.1234") .request() - .header("X-Forwarded-For", "127.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1") .get(); assertThat(response.getStatus()).isEqualTo(200); assertThat(response.readEntity(AccountIdentifierResponse.class).uuid()).isEqualTo(uuid); @@ -1945,7 +1945,7 @@ class AccountControllerTest { assertThat(resources.getJerseyTest() .target("v1/accounts/username/n00bkiller.1234") .request() - .header("X-Forwarded-For", "127.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1") .get().getStatus()).isEqualTo(404); } @@ -1955,7 +1955,7 @@ class AccountControllerTest { final Response response = resources.getJerseyTest() .target("/v1/accounts/username/test.123") .request() - .header("X-Forwarded-For", "127.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1") .get(); assertThat(response.getStatus()).isEqualTo(413); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ChallengeControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ChallengeControllerTest.java index a49c534fb..5f29a32f9 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ChallengeControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ChallengeControllerTest.java @@ -15,6 +15,7 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; +import com.google.common.net.HttpHeaders; import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.ResourceExtension; @@ -107,7 +108,7 @@ class ChallengeControllerTest { final Response response = EXTENSION.target("/v1/challenge") .request() - .header("X-Forwarded-For", "10.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "10.0.0.1") .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) .put(Entity.json(recaptchaChallengeJson)); @@ -130,7 +131,7 @@ class ChallengeControllerTest { final Response response = EXTENSION.target("/v1/challenge") .request() - .header("X-Forwarded-For", "10.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "10.0.0.1") .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) .put(Entity.json(recaptchaChallengeJson)); @@ -167,7 +168,7 @@ class ChallengeControllerTest { final Response response = EXTENSION.target("/v1/challenge") .request() - .header("X-Forwarded-For", "10.0.0.1") + .header(HttpHeaders.X_FORWARDED_FOR, "10.0.0.1") .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) .put(Entity.json(unrecognizedJson)); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java index 42ac33d79..c390c0c1d 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java @@ -28,6 +28,7 @@ import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.asJson; import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.jsonFixture; import com.google.common.collect.ImmutableSet; +import com.google.common.net.HttpHeaders; import com.google.protobuf.ByteString; import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; @@ -473,7 +474,7 @@ class MessageControllerTest { .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) .header(Stories.X_SIGNAL_RECEIVE_STORIES, receiveStories ? "true" : "false") - .header("USer-Agent", userAgent) + .header(HttpHeaders.USER_AGENT, userAgent) .accept(MediaType.APPLICATION_JSON_TYPE) .get(OutgoingMessageEntityList.class); @@ -721,7 +722,7 @@ class MessageControllerTest { .target(String.format("/v1/messages/%s", SINGLE_DEVICE_UUID)) .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Test-UA") + .header(HttpHeaders.USER_AGENT, "Test-UA") .put(Entity.entity(SystemMapper.getMapper().readValue(jsonFixture(payloadFilename), IncomingMessageList.class), MediaType.APPLICATION_JSON_TYPE)); @@ -829,7 +830,7 @@ class MessageControllerTest { .queryParam("story", isStory) .queryParam("urgent", urgent) .request() - .header("User-Agent", "FIXME"); + .header(HttpHeaders.USER_AGENT, "FIXME"); // add access header if needed if (authorize) { @@ -962,7 +963,7 @@ class MessageControllerTest { .queryParam("ts", 1663798405641L) .queryParam("story", story) .request() - .header("User-Agent", "Test User Agent") + .header(HttpHeaders.USER_AGENT, "Test User Agent") .header(OptionalAccess.UNIDENTIFIED, accessBytes); // make the PUT request diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/filters/RemoteDeprecationFilterTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/filters/RemoteDeprecationFilterTest.java index f8f075688..164568a07 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/filters/RemoteDeprecationFilterTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/filters/RemoteDeprecationFilterTest.java @@ -12,6 +12,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.google.common.net.HttpHeaders; import com.vdurmont.semver4j.Semver; import java.io.IOException; import java.util.EnumMap; @@ -100,7 +101,7 @@ class RemoteDeprecationFilterTest { final HttpServletResponse servletResponse = mock(HttpServletResponse.class); final FilterChain filterChain = mock(FilterChain.class); - when(servletRequest.getHeader("User-Agent")).thenReturn(userAgent); + when(servletRequest.getHeader(HttpHeaders.USER_AGENT)).thenReturn(userAgent); final RemoteDeprecationFilter filter = new RemoteDeprecationFilter(dynamicConfigurationManager); filter.doFilter(servletRequest, servletResponse, filterChain); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/filters/TimestampResponseFilterTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/filters/TimestampResponseFilterTest.java index c92b2c777..100931eac 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/filters/TimestampResponseFilterTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/filters/TimestampResponseFilterTest.java @@ -14,7 +14,6 @@ import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.core.MultivaluedMap; import org.glassfish.jersey.message.internal.HeaderUtils; import org.junit.jupiter.api.Test; -import org.whispersystems.textsecuregcm.util.TimestampHeaderUtil; class TimestampResponseFilterTest { @@ -29,6 +28,6 @@ class TimestampResponseFilterTest { new TimestampResponseFilter().filter(requestContext, responseContext); - assertTrue(headers.containsKey(TimestampHeaderUtil.TIMESTAMP_HEADER)); + assertTrue(headers.containsKey(org.whispersystems.textsecuregcm.util.HeaderUtils.TIMESTAMP_HEADER)); } } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListenerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListenerTest.java index 6b431a159..b7608e1de 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListenerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListenerTest.java @@ -16,6 +16,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.net.HttpHeaders; import com.google.protobuf.InvalidProtocolBufferException; import com.vdurmont.semver4j.Semver; import io.dropwizard.jersey.DropwizardResourceConfig; @@ -85,7 +86,7 @@ class MetricsRequestEventListenerTest { when(uriInfo.getMatchedTemplates()).thenReturn(Collections.singletonList(new UriTemplate(path))); final ContainerRequest request = mock(ContainerRequest.class); - when(request.getRequestHeader("User-Agent")).thenReturn(Collections.singletonList("Signal-Android 4.53.7 (Android 8.1)")); + when(request.getRequestHeader(HttpHeaders.USER_AGENT)).thenReturn(Collections.singletonList("Signal-Android 4.53.7 (Android 8.1)")); final ContainerResponse response = mock(ContainerResponse.class); when(response.getStatus()).thenReturn(statusCode); @@ -142,8 +143,8 @@ class MetricsRequestEventListenerTest { when(session.getUpgradeRequest()).thenReturn(request); when(session.getRemote()).thenReturn(remoteEndpoint); - when(request.getHeader("User-Agent")).thenReturn("Signal-Android 4.53.7 (Android 8.1)"); - when(request.getHeaders()).thenReturn(Map.of("User-Agent", List.of("Signal-Android 4.53.7 (Android 8.1)"))); + when(request.getHeader(HttpHeaders.USER_AGENT)).thenReturn("Signal-Android 4.53.7 (Android 8.1)"); + when(request.getHeaders()).thenReturn(Map.of(HttpHeaders.USER_AGENT, List.of("Signal-Android 4.53.7 (Android 8.1)"))); final ArgumentCaptor> tagCaptor = ArgumentCaptor.forClass(Iterable.class); when(meterRegistry.counter(eq(MetricsRequestEventListener.REQUEST_COUNTER_NAME), any(Iterable.class))).thenReturn(counter); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/push/PushNotificationManagerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/push/PushNotificationManagerTest.java index aa18886f6..858643c55 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/push/PushNotificationManagerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/push/PushNotificationManagerTest.java @@ -13,6 +13,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; +import com.google.common.net.HttpHeaders; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -264,7 +265,7 @@ class PushNotificationManagerTest { final UUID accountIdentifier = UUID.randomUUID(); final Account account = mock(Account.class); final Device device = mock(Device.class); - final String userAgent = "User-Agent"; + final String userAgent = HttpHeaders.USER_AGENT; when(account.getUuid()).thenReturn(accountIdentifier); when(device.getId()).thenReturn(Device.MASTER_ID); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/DeviceControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/DeviceControllerTest.java index 109e9c19a..cd7c665fb 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/DeviceControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/DeviceControllerTest.java @@ -17,6 +17,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableSet; +import com.google.common.net.HttpHeaders; import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.ResourceExtension; @@ -313,7 +314,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1")) - .header("User-Agent", userAgent) + .header(HttpHeaders.USER_AGENT, userAgent) .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(expectedStatus); @@ -354,7 +355,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1")) - .header("user-agent", "Signal-Android/4.68.3 Android/25") + .header(HttpHeaders.USER_AGENT, "Signal-Android/4.68.3 Android/25") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(409); @@ -365,7 +366,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1")) - .header("user-agent", "Signal-Android/4.68.3 Android/25") + .header(HttpHeaders.USER_AGENT, "Signal-Android/4.68.3 Android/25") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(200); @@ -382,7 +383,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(409); @@ -393,7 +394,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(200); } @@ -409,7 +410,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(409); @@ -420,7 +421,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(200); } @@ -437,7 +438,7 @@ class DeviceControllerTest { .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(409); @@ -449,7 +450,7 @@ class DeviceControllerTest { .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(200); } @@ -465,7 +466,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(409); @@ -477,7 +478,7 @@ class DeviceControllerTest { .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(200); } @@ -494,7 +495,7 @@ class DeviceControllerTest { .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(409); @@ -506,7 +507,7 @@ class DeviceControllerTest { .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(200); } @@ -520,7 +521,7 @@ class DeviceControllerTest { .target("/v1/devices/5678901") .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(409); @@ -532,7 +533,7 @@ class DeviceControllerTest { .request() .header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(200); } @@ -550,7 +551,7 @@ class DeviceControllerTest { .target("/v1/devices/" + deviceId) .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) - .header("User-Agent", "Signal-Android/5.42.8675309 Android/30") + .header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30") .delete(); assertThat(response.getStatus()).isEqualTo(204); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/DirectoryControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/DirectoryControllerTest.java index 1326f4228..4c883d3a2 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/DirectoryControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/DirectoryControllerTest.java @@ -11,6 +11,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableSet; +import com.google.common.net.HttpHeaders; import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.ResourceExtension; @@ -93,7 +94,7 @@ class DirectoryControllerTest { .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) - .header("X-Forwarded-For", "192.168.1.1, 1.1.1.1") + .header(HttpHeaders.X_FORWARDED_FOR, "192.168.1.1, 1.1.1.1") .put(Entity.entity(Collections.emptyMap(), MediaType.APPLICATION_JSON_TYPE)); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/util/ForwardedIpUtilTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/util/HeaderUtilsTest.java similarity index 91% rename from service/src/test/java/org/whispersystems/textsecuregcm/util/ForwardedIpUtilTest.java rename to service/src/test/java/org/whispersystems/textsecuregcm/util/HeaderUtilsTest.java index 39dde54a6..92f2a0b9f 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/util/ForwardedIpUtilTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/util/HeaderUtilsTest.java @@ -14,13 +14,13 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -class ForwardedIpUtilTest { +class HeaderUtilsTest { @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @ParameterizedTest @MethodSource("argumentsForGetMostRecentProxy") void getMostRecentProxy(final String forwardedFor, final Optional expectedMostRecentProxy) { - assertEquals(expectedMostRecentProxy, ForwardedIpUtil.getMostRecentProxy(forwardedFor)); + assertEquals(expectedMostRecentProxy, HeaderUtils.getMostRecentProxy(forwardedFor)); } private static Stream argumentsForGetMostRecentProxy() { diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/util/logging/LoggingUnhandledExceptionMapperTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/util/logging/LoggingUnhandledExceptionMapperTest.java index 2c1ce9453..37cf4a4f5 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/util/logging/LoggingUnhandledExceptionMapperTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/util/logging/LoggingUnhandledExceptionMapperTest.java @@ -16,6 +16,7 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.net.HttpHeaders; import io.dropwizard.jersey.DropwizardResourceConfig; import io.dropwizard.jersey.jackson.JacksonMessageBodyProvider; import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; @@ -83,7 +84,7 @@ class LoggingUnhandledExceptionMapperTest { resources.getJerseyTest() .target(targetPath) .request() - .header("User-Agent", userAgentHeader) + .header(HttpHeaders.USER_AGENT, userAgentHeader) .get(); if (expectException) { @@ -140,8 +141,8 @@ class LoggingUnhandledExceptionMapperTest { when(session.getUpgradeRequest()).thenReturn(request); when(session.getRemote()).thenReturn(remoteEndpoint); - when(request.getHeader("User-Agent")).thenReturn(userAgentHeader); - when(request.getHeaders()).thenReturn(Map.of("User-Agent", List.of(userAgentHeader))); + when(request.getHeader(HttpHeaders.USER_AGENT)).thenReturn(userAgentHeader); + when(request.getHeaders()).thenReturn(Map.of(HttpHeaders.USER_AGENT, List.of(userAgentHeader))); return provider; } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java index 0d04a728f..d7a9b793f 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; +import com.google.common.net.HttpHeaders; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import io.dropwizard.auth.basic.BasicCredentials; @@ -170,7 +171,7 @@ class WebSocketConnectionTest { when(accountsManager.getByE164("sender1")).thenReturn(Optional.of(sender1)); when(accountsManager.getByE164("sender2")).thenReturn(Optional.empty()); - String userAgent = "user-agent"; + String userAgent = HttpHeaders.USER_AGENT; when(storedMessages.getMessagesForDeviceReactive(account.getUuid(), device.getId(), false)) .thenReturn(Flux.fromIterable(outgoingMessages)); @@ -318,7 +319,7 @@ class WebSocketConnectionTest { when(accountsManager.getByE164("sender1")).thenReturn(Optional.of(sender1)); when(accountsManager.getByE164("sender2")).thenReturn(Optional.empty()); - String userAgent = "user-agent"; + String userAgent = HttpHeaders.USER_AGENT; when(storedMessages.getMessagesForDeviceReactive(account.getUuid(), device.getId(), false)) .thenReturn(Flux.fromIterable(pendingMessages)); diff --git a/websocket-resources/src/main/java/org/whispersystems/websocket/WebSocketClient.java b/websocket-resources/src/main/java/org/whispersystems/websocket/WebSocketClient.java index 8977d4c2e..a3dbd33d3 100644 --- a/websocket-resources/src/main/java/org/whispersystems/websocket/WebSocketClient.java +++ b/websocket-resources/src/main/java/org/whispersystems/websocket/WebSocketClient.java @@ -4,6 +4,14 @@ */ package org.whispersystems.websocket; +import com.google.common.net.HttpHeaders; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.security.SecureRandom; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketException; @@ -14,14 +22,6 @@ import org.whispersystems.websocket.messages.WebSocketMessage; import org.whispersystems.websocket.messages.WebSocketMessageFactory; import org.whispersystems.websocket.messages.WebSocketResponseMessage; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.security.SecureRandom; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") public class WebSocketClient { @@ -76,7 +76,7 @@ public class WebSocketClient { } public String getUserAgent() { - return session.getUpgradeRequest().getHeader("User-Agent"); + return session.getUpgradeRequest().getHeader(HttpHeaders.USER_AGENT); } public long getCreatedTimestamp() { diff --git a/websocket-resources/src/test/java/org/whispersystems/websocket/WebSocketResourceProviderTest.java b/websocket-resources/src/test/java/org/whispersystems/websocket/WebSocketResourceProviderTest.java index dc3a84443..80557ae17 100644 --- a/websocket-resources/src/test/java/org/whispersystems/websocket/WebSocketResourceProviderTest.java +++ b/websocket-resources/src/test/java/org/whispersystems/websocket/WebSocketResourceProviderTest.java @@ -17,6 +17,7 @@ import static org.mockito.Mockito.when; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.net.HttpHeaders; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import io.dropwizard.auth.Auth; @@ -651,7 +652,7 @@ class WebSocketResourceProviderTest { assertThat(WebSocketResourceProvider.shouldIncludeUpgradeRequestHeader("Upgrade")).isFalse(); assertThat(WebSocketResourceProvider.shouldIncludeUpgradeRequestHeader("Connection")).isFalse(); assertThat(WebSocketResourceProvider.shouldIncludeUpgradeRequestHeader("Sec-WebSocket-Key")).isFalse(); - assertThat(WebSocketResourceProvider.shouldIncludeUpgradeRequestHeader("User-Agent")).isTrue(); + assertThat(WebSocketResourceProvider.shouldIncludeUpgradeRequestHeader(HttpHeaders.USER_AGENT)).isTrue(); assertThat(WebSocketResourceProvider.shouldIncludeUpgradeRequestHeader("X-Forwarded-For")).isTrue(); assertThat(WebSocketResourceProvider.shouldIncludeUpgradeRequestHeader("X-Signal-Receive-Stories")).isTrue(); } @@ -659,7 +660,7 @@ class WebSocketResourceProviderTest { @Test void testShouldIncludeRequestMessageHeader() { assertThat(WebSocketResourceProvider.shouldIncludeRequestMessageHeader("X-Forwarded-For")).isFalse(); - assertThat(WebSocketResourceProvider.shouldIncludeRequestMessageHeader("User-Agent")).isTrue(); + assertThat(WebSocketResourceProvider.shouldIncludeRequestMessageHeader(HttpHeaders.USER_AGENT)).isTrue(); assertThat(WebSocketResourceProvider.shouldIncludeRequestMessageHeader("X-Signal-Receive-Stories")).isTrue(); } @@ -673,16 +674,16 @@ class WebSocketResourceProviderTest { "Sec-WebSocket-Protocol", List.of("chat, superchat"), "Sec-WebSocket-Version", List.of("13"), "X-Forwarded-For", List.of("127.0.0.1"), - "User-Agent", List.of("Upgrade request user agent")); + HttpHeaders.USER_AGENT, List.of("Upgrade request user agent")); final Map requestMessageHeaders = Map.of( "X-Forwarded-For", "192.168.0.1", - "User-Agent", "Request message user agent"); + HttpHeaders.USER_AGENT, "Request message user agent"); final Map> expectedHeaders = Map.of( "Host", List.of("server.example.com"), "X-Forwarded-For", List.of("127.0.0.1"), - "User-Agent", List.of("Request message user agent")); + HttpHeaders.USER_AGENT, List.of("Request message user agent")); assertThat(WebSocketResourceProvider.getCombinedHeaders(upgradeRequestHeaders, requestMessageHeaders)).isEqualTo( expectedHeaders); diff --git a/websocket-resources/src/test/java/org/whispersystems/websocket/logging/WebSocketRequestLogTest.java b/websocket-resources/src/test/java/org/whispersystems/websocket/logging/WebSocketRequestLogTest.java index e4fbac924..dd4b8fea0 100644 --- a/websocket-resources/src/test/java/org/whispersystems/websocket/logging/WebSocketRequestLogTest.java +++ b/websocket-resources/src/test/java/org/whispersystems/websocket/logging/WebSocketRequestLogTest.java @@ -10,6 +10,7 @@ import static org.mockito.Mockito.mock; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.core.OutputStreamAppender; import ch.qos.logback.core.spi.DeferredProcessingAware; +import com.google.common.net.HttpHeaders; import io.dropwizard.logging.AbstractOutputStreamAppenderFactory; import java.io.ByteArrayOutputStream; import java.net.URI; @@ -78,7 +79,7 @@ public class WebSocketRequestLogTest { ContainerRequest request = new ContainerRequest(null, URI.create("/v1/test"), "GET", new WebSocketSecurityContext(new ContextPrincipal(sessionContext)), new MapPropertiesDelegate(new HashMap<>()), null); - request.header("User-Agent", "SmertZeSmert"); + request.header(HttpHeaders.USER_AGENT, "SmertZeSmert"); request.header("Referer", "https://moxie.org"); ContainerResponse response = new ContainerResponse(request, Response.ok("My response body").build());