Make raw User-Agent strings available to gRPC services

This commit is contained in:
Jon Chambers
2025-03-31 15:40:50 -04:00
committed by Jon Chambers
parent c2e3ab832c
commit d4031893cc
6 changed files with 55 additions and 4 deletions

View File

@@ -59,6 +59,15 @@ public class RequestAttributesInterceptor implements ServerInterceptor {
}
}
{
final Optional<String> maybeRawUserAgent =
grpcClientConnectionManager.getRawUserAgent(localAddress);
if (maybeRawUserAgent.isPresent()) {
context = context.withValue(RequestAttributesUtil.RAW_USER_AGENT_CONTEXT_KEY, maybeRawUserAgent.get());
}
}
{
final Optional<UserAgent> maybeUserAgent = grpcClientConnectionManager.getUserAgent(localAddress);

View File

@@ -13,7 +13,8 @@ public class RequestAttributesUtil {
static final Context.Key<List<Locale.LanguageRange>> ACCEPT_LANGUAGE_CONTEXT_KEY = Context.key("accept-language");
static final Context.Key<InetAddress> REMOTE_ADDRESS_CONTEXT_KEY = Context.key("remote-address");
static final Context.Key<UserAgent> USER_AGENT_CONTEXT_KEY = Context.key("user-agent");
static final Context.Key<String> RAW_USER_AGENT_CONTEXT_KEY = Context.key("unparsed-user-agent");
static final Context.Key<UserAgent> USER_AGENT_CONTEXT_KEY = Context.key("parsed-user-agent");
private static final List<Locale> AVAILABLE_LOCALES = Arrays.asList(Locale.getAvailableLocales());
@@ -51,9 +52,18 @@ public class RequestAttributesUtil {
/**
* Returns the parsed user-agent of the remote client in the current gRPC request context.
*
* @return the parsed user-agent of the remote client; may be null if unparseable or not specified
* @return the parsed user-agent of the remote client; may be empty if unparseable or not specified
*/
public static Optional<UserAgent> getUserAgent() {
return Optional.ofNullable(USER_AGENT_CONTEXT_KEY.get());
}
/**
* Returns the unparsed user-agent of the remote client in the current gRPC request context.
*
* @return the unparsed user-agent of the remote client; may be empty if not specified
*/
public static Optional<String> getRawUserAgent() {
return Optional.ofNullable(RAW_USER_AGENT_CONTEXT_KEY.get());
}
}

View File

@@ -106,7 +106,21 @@ public class GrpcClientConnectionManager implements DisconnectionRequestListener
}
/**
* Returns the parsed user agent provided by the client the opened the connection associated with the given local
* Returns the unparsed user agent provided by the client that opened the connection associated with the given local
* address. This method may return an empty value if no active local connection is associated with the given local
* address.
*
* @param localAddress the local address for which to find a User-Agent string
*
* @return the user agent string associated with the given local address
*/
public Optional<String> getRawUserAgent(final LocalAddress localAddress) {
return Optional.ofNullable(remoteChannelsByLocalAddress.get(localAddress))
.map(remoteChannel -> remoteChannel.attr(RAW_USER_AGENT_ATTRIBUTE_KEY).get());
}
/**
* Returns the parsed user agent provided by the client that opened the connection associated with the given local
* address. This method may return an empty value if no active local connection is associated with the given local
* address or if the client's user-agent string was not recognized.
*