Skip to content

Commit

Permalink
Merge branch 'master' into nacho/IastUnitTestsDebugCI
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoEchevarria authored Feb 6, 2025
2 parents 1c2271d + 7ea077a commit eb0283d
Show file tree
Hide file tree
Showing 20 changed files with 208 additions and 84 deletions.
4 changes: 0 additions & 4 deletions tracer/missing-nullability-files.csv
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ src/Datadog.Trace/HttpOverStreams/HttpMessage.cs
src/Datadog.Trace/HttpOverStreams/HttpRequest.cs
src/Datadog.Trace/HttpOverStreams/HttpResponse.cs
src/Datadog.Trace/HttpOverStreams/IHttpContent.cs
src/Datadog.Trace/Iast/Iast.cs
src/Datadog.Trace/Iast/ITaintedMap.cs
src/Datadog.Trace/Iast/SourceType.cs
src/Datadog.Trace/PlatformHelpers/AspNetCoreHttpRequestHandler.cs
Expand Down Expand Up @@ -599,12 +598,9 @@ src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/HotChocol
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IError.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IExecutionResult.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IOperationContext.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IOperationContextV13.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IQueryRequest.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/IQueryResult.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/NameStringProxy.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/OperationTypeProxy.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/HotChocolate/PreparedOperationStruct.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/Net/ExecuteAsyncIntegration.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/Net/ExecuteAsyncIntegrationV5AndV7.cs
src/Datadog.Trace/ClrProfiler/AutoInstrumentation/GraphQL/Net/GraphQLCommon.cs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,7 @@ internal class HttpTransport(HttpContext context) : HttpTransportBase

internal override bool IsBlocked
{
get
{
if (Context.Items.TryGetValue(BlockingAction.BlockDefaultActionName, out var value))
{
return value is true;
}

return false;
}
get => GetItems()?.TryGetValue(BlockingAction.BlockDefaultActionName, out var value) == true && value is true;
}

internal override int StatusCode => Context.Response.StatusCode;
Expand All @@ -184,19 +176,26 @@ internal override bool IsBlocked

internal override bool ReportedExternalWafsRequestHeaders
{
get
get => GetItems()?.TryGetValue(ReportedExternalWafsRequestHeadersStr, out var value) == true && value is true;

set
{
if (Context.Items.TryGetValue(ReportedExternalWafsRequestHeadersStr, out var value))
var items = GetItems();
if (items is not null)
{
return value is bool boolValue && boolValue;
items[ReportedExternalWafsRequestHeadersStr] = value;
}

return false;
}
set => Context.Items[ReportedExternalWafsRequestHeadersStr] = value;
}

internal override void MarkBlocked() => Context.Items[BlockingAction.BlockDefaultActionName] = true;
internal override void MarkBlocked()
{
var items = GetItems();
if (items is not null)
{
items[BlockingAction.BlockDefaultActionName] = true;
}
}

internal override IContext? GetAdditiveContext() => IsAdditiveContextDisposed() ? null : GetContextFeatures()?.Get<IContext>();

Expand All @@ -207,9 +206,9 @@ internal override bool ReportedExternalWafsRequestHeaders
internal override IHeadersCollection GetResponseHeaders() => new HeadersCollectionAdapter(Context.Response.Headers);

// In some edge situations we can get an ObjectDisposedException when accessing the context features or other
// properties such as Context.Items or Context.Response.Headers that ultimatelly rely on features
// This means that the context has been uninitiallized and we should not try to access it anymore
// Unfortunatelly, there is no way to know that but catching the exception or using reflection
// properties such as Context.Items or Context.Response.Headers that ultimately rely on features
// This means that the context has been uninitialized, and we should not try to access it anymore
// Unfortunately, there is no way to know that but catching the exception or using reflection
private IFeatureCollection? GetContextFeatures()
{
try
Expand All @@ -223,6 +222,27 @@ internal override bool ReportedExternalWafsRequestHeaders
return null;
}
}

private IDictionary<object, object>? GetItems()
{
if (IsAdditiveContextDisposed())
{
return null;
}

// In some situations the HttpContext could have already been Uninitialized,
// thus throwing an exception when trying to access the Items
try
{
return Context.Items;
}
catch (Exception e) when (e is ObjectDisposedException or NullReferenceException)
{
Log.Debug(e, "Exception while trying to access Items of a Context.");
SetAdditiveContextDisposed(true);
return null;
}
}
}
}
#endif
Expand Down
16 changes: 12 additions & 4 deletions tracer/src/Datadog.Trace/AppSec/Coordinator/SecurityReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,15 @@ internal void ReportWafInitInfoOnce(InitResult? initResult)

/// <summary>
/// This functions reports the security scan result and the schema extraction if there was one
/// Dont try to test if result should be reported, it's all in here
/// Don't try to test if result should be reported, it's all in here
/// </summary>
/// <param name="result">waf's result</param>
/// <param name="blocked">if request was blocked</param>
/// <param name="status">returned status code</param>
internal void TryReport(IResult result, bool blocked, int? status = null)
{
IHeadersCollection? headers = null;
if (!_httpTransport.ReportedExternalWafsRequestHeaders)
if (!_httpTransport.ReportedExternalWafsRequestHeaders && !_httpTransport.IsAdditiveContextDisposed())
{
headers = _httpTransport.GetRequestHeaders();
AddHeaderTags(_span, headers, ExternalWafsRequestHeaders, SpanContextPropagator.HttpRequestHeadersTagPrefix);
Expand Down Expand Up @@ -219,8 +219,16 @@ internal void TryReport(IResult result, bool blocked, int? status = null)

_span.SetMetric(Metrics.AppSecWafDuration, result.AggregatedTotalRuntime);
_span.SetMetric(Metrics.AppSecWafAndBindingsDuration, result.AggregatedTotalRuntimeWithBindings);
headers ??= _httpTransport.GetRequestHeaders();
AddHeaderTags(_span, headers, RequestHeaders, SpanContextPropagator.HttpRequestHeadersTagPrefix);

if (headers is null && !_httpTransport.IsAdditiveContextDisposed())
{
headers = _httpTransport.GetRequestHeaders();
}

if (headers is not null)
{
AddHeaderTags(_span, headers, RequestHeaders, SpanContextPropagator.HttpRequestHeadersTagPrefix);
}

if (status is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

using System;
using System.ComponentModel;
using Datadog.Trace.ClrProfiler.CallTarget;
using Datadog.Trace.DuckTyping;

namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
{
/// <summary>
/// HotChocolate.Execution.Processing.WorkScheduler calltarget instrumentation to retrieve OperationType
/// </summary>
[InstrumentMethodAttribute(
[InstrumentMethod(
IntegrationName = HotChocolateCommon.IntegrationName,
MethodName = "ExecuteAsync",
ReturnTypeName = "System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]",
Expand All @@ -22,7 +20,7 @@ namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
TypeName = "HotChocolate.Execution.Processing.QueryExecutor",
MinimumVersion = "11",
MaximumVersion = "12.*.*")]
[InstrumentMethodAttribute(
[InstrumentMethod(
IntegrationName = HotChocolateCommon.IntegrationName,
MethodName = "ExecuteAsync",
ReturnTypeName = "System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]",
Expand All @@ -38,24 +36,16 @@ public class ExecuteAsyncIntegrationExtra
internal static CallTargetState OnMethodBegin<TTarget, TOperationContext>(TTarget instance, TOperationContext operationContext)
where TOperationContext : IOperationContext
{
var operation = operationContext.Operation;
var operationType = HotChocolateCommon.GetOperation(operation.OperationType);
var operationName = GetNameStringValue(operation.Name.Value);

HotChocolateCommon.UpdateScopeFromExecuteAsync(Tracer.Instance, operationType, operationName);
return CallTargetState.GetDefault();
}

private static string GetNameStringValue(object nameValue)
{
// Get the string value of the NameString
// The NameString value can be either another NameString or a string
if (nameValue != null && nameValue.TryDuckCast(typeof(NameStringProxy), out var ns))
if (operationContext.Instance != null && operationContext.Operation.HasValue)
{
nameValue = ((NameStringProxy)ns).Value;
var operation = operationContext.Operation.Value;
var operationType = HotChocolateCommon.GetOperation(operation.OperationType);
var operationName = operation.Name.HasValue ? operation.Name.Value.Value : null;

HotChocolateCommon.UpdateScopeFromExecuteAsync(Tracer.Instance, operationType, operationName);
}

return nameValue as string;
return CallTargetState.GetDefault();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,15 @@ public class ExecuteAsyncIntegrationExtraV13
internal static CallTargetState OnMethodBegin<TTarget, TOperationContext>(TTarget instance, TOperationContext operationContext)
where TOperationContext : IOperationContextV13
{
var operation = operationContext.Operation;
var operationType = HotChocolateCommon.GetOperation(operation.OperationType);
var operationName = operation.Name;
if (operationContext.Instance != null && operationContext.Operation.HasValue)
{
var operation = operationContext.Operation.Value;
var operationType = HotChocolateCommon.GetOperation(operation.OperationType);
var operationName = operation.Name;

HotChocolateCommon.UpdateScopeFromExecuteAsync(Tracer.Instance, operationType, operationName);
}

HotChocolateCommon.UpdateScopeFromExecuteAsync(Tracer.Instance, operationType, operationName);
return CallTargetState.GetDefault();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@ namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
[EditorBrowsable(EditorBrowsableState.Never)]
public class ExecuteAsyncIntegrationV13
{
internal static CallTargetState OnMethodBegin<TTarget, TQueyRequest>(TTarget instance, TQueyRequest request, in CancellationToken token)
where TQueyRequest : IQueryRequest
internal static CallTargetState OnMethodBegin<TTarget, TQueryRequest>(TTarget instance, TQueryRequest request, in CancellationToken token)
where TQueryRequest : IQueryRequest
{
return new CallTargetState(scope: HotChocolateCommon.CreateScopeFromQueryRequest(Tracer.Instance, request));
if (request.Instance is not null)
{
return new CallTargetState(scope: HotChocolateCommon.CreateScopeFromQueryRequest(Tracer.Instance, request));
}

return CallTargetState.GetDefault();
}

internal static TExecutionResult OnAsyncMethodEnd<TTarget, TExecutionResult>(TTarget instance, TExecutionResult executionResult, Exception? exception, in CallTargetState state)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ public class ExecuteAsyncIntegrationV14
internal static CallTargetState OnMethodBegin<TTarget, TOperationRequest>(TTarget instance, TOperationRequest request, in CancellationToken token)
where TOperationRequest : IOperationRequest
{
return new CallTargetState(scope: HotChocolateCommon.CreateScopeFromOperationRequest(Tracer.Instance, request));
if (request.Instance is not null)
{
return new CallTargetState(scope: HotChocolateCommon.CreateScopeFromOperationRequest(Tracer.Instance, request));
}

return CallTargetState.GetDefault();
}

internal static TExecutionResult OnAsyncMethodEnd<TTarget, TExecutionResult>(TTarget instance, TExecutionResult executionResult, Exception exception, in CallTargetState state)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
/// <summary>
/// HotChocolate.Execution.Processing.IOperationContext interface for ducktyping
/// </summary>
internal interface IOperationContext
internal interface IOperationContext : IDuckType
{
///// <summary>
///// Gets the context operation
///// </summary>
PreparedOperationStruct Operation { get; }
OperationStruct? Operation { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

#nullable enable

using Datadog.Trace.DuckTyping;

namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
{
/// <summary>
/// HotChocolate.Execution.Processing.OperationContext struct for ducktyping
/// https://github.com/ChilliCream/graphql-platform/blob/35301472065248ce4e2f34894041f39124e3c7b8/src/HotChocolate/Core/src/Execution/Processing/OperationContext.Execution.cs
/// </summary>
internal interface IOperationContextV13
internal interface IOperationContextV13 : IDuckType
{
///// <summary>
///// Gets the context operation
///// </summary>
public OperationStructV13 Operation { get; }
public OperationStructV13? Operation { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

#nullable enable

using Datadog.Trace.DuckTyping;

namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
{
/// <summary>
/// HotChocolate.Execution.IOperationRequest interface for ducktyping
/// </summary>
internal interface IOperationRequest
internal interface IOperationRequest : IDuckType
{
object? Document { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

#nullable enable
using Datadog.Trace.DuckTyping;

namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
{
/// <summary>
/// HotChocolate.Execution.IQueryRequest interface for ducktyping
/// </summary>
internal interface IQueryRequest
internal interface IQueryRequest : IDuckType
{
object Query { get; }
object? Query { get; }

public string OperationName { get; }
public string? OperationName { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
[DuckCopy]
internal struct NameStringProxy
{
public object Value;
public string Value;
}

/// <summary>
/// nullable structs need an explicit proxy
/// </summary>
[DuckCopy]
internal struct NullableNameStringProxy
{
public NameStringProxy Value;
public bool HasValue;
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
// <copyright file="PreparedOperationStruct.cs" company="Datadog">
// <copyright file="OperationStruct.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

#nullable enable
using Datadog.Trace.DuckTyping;

namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate
{
/// <summary>
/// HotChocolate.Execution.Processing.IPreparedOperation interface for ducktyping
/// proxy for ducktyping HotChocolate.Resolvers.IOperation
/// </summary>
[DuckCopy]
internal struct PreparedOperationStruct
internal struct OperationStruct
{
///// <summary>
///// Gets the operation type (Query, Mutation, Subscription)
///// </summary>
[Duck(Name = "Type")]
public OperationTypeProxy OperationType;

public NameStringProxy Name;
public NullableNameStringProxy Name;
}
}
Loading

0 comments on commit eb0283d

Please sign in to comment.