Add a gRPC interceptor for getting client addresses

This commit is contained in:
Jon Chambers 2023-08-29 18:18:06 -04:00 committed by GitHub
parent cfb910e87e
commit 6089f49b9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 93 additions and 0 deletions

View File

@ -0,0 +1,33 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.grpc;
import io.grpc.Context;
import io.grpc.Contexts;
import io.grpc.Grpc;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import java.net.SocketAddress;
public class RemoteAddressInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(final ServerCall<ReqT, RespT> serverCall,
final Metadata headers,
final ServerCallHandler<ReqT, RespT> next) {
// Note: the specific implementation for getting a remote client address may change depending on the client
// connection strategy. The important thing is that the remote address wind up in the context for the current
// call so it can be retrieved by `RemoteAddressUtil`.
final SocketAddress remoteAddress = serverCall.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
return Contexts.interceptCall(
Context.current().withValue(RemoteAddressUtil.REMOTE_ADDRESS_CONTEXT_KEY, remoteAddress),
serverCall, headers, next);
}
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.grpc;
import io.grpc.Context;
import java.net.SocketAddress;
public class RemoteAddressUtil {
static final Context.Key<SocketAddress> REMOTE_ADDRESS_CONTEXT_KEY = Context.key("remote-address");
/**
* Returns the socket address of the remote client in the current gRPC request context.
*
* @return the socket address of the remote client
*/
public static SocketAddress getRemoteAddress() {
return REMOTE_ADDRESS_CONTEXT_KEY.get();
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.grpc;
import io.grpc.Context;
import io.grpc.Contexts;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import java.net.SocketAddress;
import javax.annotation.Nullable;
public class MockRemoteAddressInterceptor implements ServerInterceptor {
@Nullable
private SocketAddress remoteAddress;
public void setRemoteAddress(@Nullable final SocketAddress remoteAddress) {
this.remoteAddress = remoteAddress;
}
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(final ServerCall<ReqT, RespT> serverCall,
final Metadata headers,
final ServerCallHandler<ReqT, RespT> next) {
return remoteAddress != null
? next.startCall(serverCall, headers)
: Contexts.interceptCall(
Context.current().withValue(RemoteAddressUtil.REMOTE_ADDRESS_CONTEXT_KEY, remoteAddress),
serverCall, headers, next);
}
}