in apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceContextImpl.java [267:328]
<T> boolean asChildOf(T traceParentHeader, CharAccessor<T> charAccessor) {
int leadingWs = charAccessor.getLeadingWhitespaceCount(traceParentHeader);
int trailingWs = charAccessor.getTrailingWhitespaceCount(traceParentHeader);
try {
int trimmedLen = Math.max(0, charAccessor.length(traceParentHeader) - leadingWs - trailingWs);
if (trimmedLen < TEXT_HEADER_EXPECTED_LENGTH) {
logger.warn("The traceparent header has to be at least 55 chars long, but was '{}'", trimmedLen);
return false;
}
if (noDashAtPosition(traceParentHeader, leadingWs + TEXT_HEADER_TRACE_ID_OFFSET - 1, charAccessor)
|| noDashAtPosition(traceParentHeader, leadingWs + TEXT_HEADER_PARENT_ID_OFFSET - 1, charAccessor)
|| noDashAtPosition(traceParentHeader, leadingWs + TEXT_HEADER_FLAGS_OFFSET - 1, charAccessor)) {
if (logger.isWarnEnabled()) {
logger.warn("The traceparent header has an invalid format: '{}'", charAccessor.asString(traceParentHeader));
}
return false;
}
if (trimmedLen > TEXT_HEADER_EXPECTED_LENGTH
&& noDashAtPosition(traceParentHeader, leadingWs + TEXT_HEADER_EXPECTED_LENGTH, charAccessor)) {
if (logger.isWarnEnabled()) {
logger.warn("The traceparent header has an invalid format: '{}'", charAccessor.asString(traceParentHeader));
}
return false;
}
if (charAccessor.containsAtOffset(traceParentHeader, leadingWs, "ff")) {
if (logger.isWarnEnabled()) {
logger.warn("Version ff is not supported");
}
return false;
}
byte version = charAccessor.readHexByte(traceParentHeader, leadingWs);
if (version == 0 && trimmedLen > TEXT_HEADER_EXPECTED_LENGTH) {
if (logger.isWarnEnabled()) {
logger.warn("The traceparent header has to be exactly 55 chars long for version 00, but was '{}'", charAccessor.asString(traceParentHeader));
}
return false;
}
traceId.fromHexString(traceParentHeader, leadingWs + TEXT_HEADER_TRACE_ID_OFFSET, charAccessor);
if (traceId.isEmpty()) {
return false;
}
parentId.fromHexString(traceParentHeader, leadingWs + TEXT_HEADER_PARENT_ID_OFFSET, charAccessor);
if (parentId.isEmpty()) {
return false;
}
id.setToRandomValue();
transactionId.copyFrom(id);
// TODO don't blindly trust the flags from the caller
// consider implement rate limiting and/or having a list of trusted sources
// trace the request if it's either requested or if the parent has recorded it
flags = charAccessor.readHexByte(traceParentHeader, TEXT_HEADER_FLAGS_OFFSET + leadingWs);
clock.init();
return true;
} catch (IllegalArgumentException e) {
logger.warn(e.getMessage());
return false;
} finally {
onMutation();
}
}