All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.kristofa.brave.internal.MaybeAddClientAddress Maven / Gradle / Ivy

There is a newer version: 4.13.6
Show newest version
package com.github.kristofa.brave.internal;

import com.github.kristofa.brave.Brave;
import com.github.kristofa.brave.ServerSpan;
import com.twitter.zipkin.gen.Endpoint;
import com.twitter.zipkin.gen.Span;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import zipkin.Constants;

import static com.github.kristofa.brave.internal.Util.checkNotNull;

/**
 * Parses the {@link Constants#CLIENT_ADDR client address}, possibly by looking at
 * "X-Forwarded-For", then the remote address of the input. This performs no DNS lookups.
 *
 * 

This is a hack as {@code com.github.kristofa.brave.http.HttpServerRequest} is an interface and * would break api if we changed it. Moreover, this can work on non-http input types. */ public abstract class MaybeAddClientAddress { final Brave brave; protected MaybeAddClientAddress(Brave brave) { // accepts brave so we can re-factor thread state this.brave = checkNotNull(brave, "brave"); } public final void accept(T input) { // Kick out if we can't read the current span ServerSpan serverSpan = brave.serverSpanThreadBinder().getCurrentServerSpan(); Span span = serverSpan != null ? serverSpan.getSpan() : null; if (span == null) return; // Kick out if we can't cheaply read the address byte[] addressBytes; try { addressBytes = parseAddressBytes(input); if (addressBytes == null) return; } catch (RuntimeException e) { return; } // Build an endpoint with no service name (rather than risk cluttering the service list!) Endpoint.Builder builder = Endpoint.builder().serviceName(""); if (addressBytes.length == 4) { builder.ipv4(ByteBuffer.wrap(addressBytes).getInt()); } else if (addressBytes.length == 16) { builder.ipv6(addressBytes); } else { return; // invalid } try { int port = parsePort(input); if (port > 0) builder.port(port); } catch (RuntimeException ignore) { // still store the ip address } Endpoint ca = builder.build(); Internal.instance.setClientAddress(brave, ca); } /** * Returns the 4 byte ipv4 address or the 16-byte ipv6 address associated with the input type. * *

{@code
   * byte[] addressBytes = ipStringToBytes(input.getHeader("X-Forwarded-For"));
   * if (addressBytes == null) addressBytes = ipStringToBytes(input.getRemoteAddr());
   * return addressBytes;
   * }
*/ protected abstract byte[] parseAddressBytes(T input); /** Returns port associated with the input or <=0 if unreadable. */ protected abstract int parsePort(T input); /** * Returns the {@link InetAddress#getAddress()} having the given string representation or null if * unable to parse. * *

This deliberately avoids all nameservice lookups (e.g. no DNS). * * @param ipString {@code String} containing an IPv4 or IPv6 string literal, e.g. {@code * "192.168.0.1"} or {@code "2001:db8::1"} */ @Nullable protected byte[] ipStringToBytes(String ipString) { return InetAddresses.ipStringToBytes(ipString); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy