mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-19 17:48:04 +01:00
refactoring: use constants for header names
This commit is contained in:
@@ -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<String> acceptLanguage,
|
||||
@HeaderParam(HttpHeaders.X_FORWARDED_FOR) String forwardedFor,
|
||||
@HeaderParam(HttpHeaders.USER_AGENT) String userAgent,
|
||||
@HeaderParam(HttpHeaders.ACCEPT_LANGUAGE) Optional<String> acceptLanguage,
|
||||
@QueryParam("client") Optional<String> client,
|
||||
@QueryParam("captcha") Optional<String> captcha,
|
||||
@QueryParam("challenge") Optional<String> 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<StoredVerificationCode> 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<Boolean> 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<String> 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<Anonymous> 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()) {
|
||||
|
||||
@@ -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<AuthenticatedAccount> source,
|
||||
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> 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<OutgoingMessageEntityList> 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);
|
||||
|
||||
|
||||
@@ -317,7 +317,7 @@ public class ProfileController {
|
||||
@Auth Optional<AuthenticatedAccount> auth,
|
||||
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> 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 {
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String> userAgentValues = event.getContainerRequest().getRequestHeader("User-Agent");
|
||||
final List<String> 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));
|
||||
|
||||
|
||||
@@ -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 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For">X-Forwarded-For - HTTP | MDN</a>
|
||||
*/
|
||||
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 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For">X-Forwarded-For - HTTP | MDN</a>
|
||||
*/
|
||||
@Nonnull
|
||||
public static Optional<String> getMostRecentProxy(@Nullable final String forwardedFor) {
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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<Thro
|
||||
// request shouldn’t be `null`, but it is technically possible
|
||||
requestMethod = request.get().getMethod();
|
||||
requestPath = UriInfoUtil.getPathTemplate(request.get().getUriInfo());
|
||||
userAgent = request.get().getHeaderString("user-agent");
|
||||
userAgent = request.get().getHeaderString(HttpHeaders.USER_AGENT);
|
||||
|
||||
// streamline the user-agent if it is recognized
|
||||
final UserAgent ua = UserAgentUtil.parseUserAgentString(userAgent);
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
package org.whispersystems.textsecuregcm.websocket;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.dispatch.DispatchChannel;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.ProvisioningUuid;
|
||||
import org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage;
|
||||
import org.whispersystems.textsecuregcm.util.TimestampHeaderUtil;
|
||||
import org.whispersystems.textsecuregcm.util.HeaderUtils;
|
||||
import org.whispersystems.websocket.WebSocketClient;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ProvisioningConnection implements DispatchChannel {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ProvisioningConnection.class);
|
||||
@@ -35,7 +34,7 @@ public class ProvisioningConnection implements DispatchChannel {
|
||||
if (outgoingMessage.getType() == PubSubMessage.Type.DELIVER) {
|
||||
Optional<byte[]> 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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user