5
5
using System . Collections . Generic ;
6
6
using System . Linq ;
7
7
using System . Net . Http ;
8
+ using System . Net . Http . Headers ;
8
9
using System . Net . Sockets ;
9
10
using System . Threading ;
10
11
using System . Threading . Tasks ;
@@ -21,17 +22,19 @@ public class DefaultHttpWorkerService : IHttpWorkerService
21
22
private readonly HttpClient _httpClient ;
22
23
private readonly HttpWorkerOptions _httpWorkerOptions ;
23
24
private readonly ILogger _logger ;
25
+ private readonly bool _enableRequestTracing ;
24
26
25
- public DefaultHttpWorkerService ( IOptions < HttpWorkerOptions > httpWorkerOptions , ILoggerFactory loggerFactory )
26
- : this ( new HttpClient ( ) , httpWorkerOptions , loggerFactory . CreateLogger < DefaultHttpWorkerService > ( ) )
27
+ public DefaultHttpWorkerService ( IOptions < HttpWorkerOptions > httpWorkerOptions , ILoggerFactory loggerFactory , IEnvironment environment )
28
+ : this ( new HttpClient ( ) , httpWorkerOptions , loggerFactory . CreateLogger < DefaultHttpWorkerService > ( ) , environment )
27
29
{
28
30
}
29
31
30
- internal DefaultHttpWorkerService ( HttpClient httpClient , IOptions < HttpWorkerOptions > httpWorkerOptions , ILogger logger )
32
+ internal DefaultHttpWorkerService ( HttpClient httpClient , IOptions < HttpWorkerOptions > httpWorkerOptions , ILogger logger , IEnvironment environment )
31
33
{
32
34
_httpClient = httpClient ?? throw new ArgumentNullException ( nameof ( httpClient ) ) ;
33
35
_httpWorkerOptions = httpWorkerOptions . Value ?? throw new ArgumentNullException ( nameof ( httpWorkerOptions . Value ) ) ;
34
36
_logger = logger ?? throw new ArgumentNullException ( nameof ( logger ) ) ;
37
+ _enableRequestTracing = environment . IsCoreTools ( ) ;
35
38
}
36
39
37
40
public Task InvokeAsync ( ScriptInvocationContext scriptInvocationContext )
@@ -74,9 +77,7 @@ internal async Task ProcessHttpInAndOutInvocationRequest(ScriptInvocationContext
74
77
{
75
78
AddHeaders ( httpRequestMessage , scriptInvocationContext . ExecutionContext . InvocationId . ToString ( ) ) ;
76
79
77
- _logger . LogDebug ( "Forwarding http request for httpTrigger function: '{functionName}' invocationId: '{invocationId}'" , scriptInvocationContext . FunctionMetadata . Name , scriptInvocationContext . ExecutionContext . InvocationId ) ;
78
- HttpResponseMessage invocationResponse = await _httpClient . SendAsync ( httpRequestMessage ) ;
79
- _logger . LogDebug ( "Received http response for httpTrigger function: '{functionName}' invocationId: '{invocationId}'" , scriptInvocationContext . FunctionMetadata . Name , scriptInvocationContext . ExecutionContext . InvocationId ) ;
80
+ HttpResponseMessage invocationResponse = await SendInvocationRequestAsync ( scriptInvocationContext , httpRequestMessage ) ;
80
81
81
82
BindingMetadata httpOutputBinding = scriptInvocationContext . FunctionMetadata . OutputBindings . FirstOrDefault ( ) ;
82
83
if ( httpOutputBinding != null )
@@ -95,6 +96,38 @@ internal async Task ProcessHttpInAndOutInvocationRequest(ScriptInvocationContext
95
96
}
96
97
}
97
98
99
+ private async Task < HttpResponseMessage > SendInvocationRequestAsync ( ScriptInvocationContext scriptInvocationContext , HttpRequestMessage httpRequestMessage )
100
+ {
101
+ // Only log Request / Response when running locally
102
+ if ( _enableRequestTracing )
103
+ {
104
+ scriptInvocationContext . Logger . LogTrace ( $ "Invocation Request:{ httpRequestMessage } ") ;
105
+ await TraceHttpContent ( httpRequestMessage . Content , scriptInvocationContext . Logger ) ;
106
+ }
107
+ _logger . LogDebug ( "Sending http request for function:{functionName} invocationId:{invocationId}" , scriptInvocationContext . FunctionMetadata . Name , scriptInvocationContext . ExecutionContext . InvocationId ) ;
108
+ HttpResponseMessage invocationResponse = await _httpClient . SendAsync ( httpRequestMessage ) ;
109
+ if ( _enableRequestTracing )
110
+ {
111
+ scriptInvocationContext . Logger . LogTrace ( $ "Invocation Response:{ invocationResponse } ") ;
112
+ await TraceHttpContent ( invocationResponse . Content , scriptInvocationContext . Logger ) ;
113
+ }
114
+ _logger . LogDebug ( "Received http response for httpTrigger function: '{functionName}' invocationId: '{invocationId}'" , scriptInvocationContext . FunctionMetadata . Name , scriptInvocationContext . ExecutionContext . InvocationId ) ;
115
+ return invocationResponse ;
116
+ }
117
+
118
+ private static async Task TraceHttpContent ( HttpContent content , ILogger logger )
119
+ {
120
+ if ( content != null )
121
+ {
122
+ bool isMediaTypeOctetOrMultipart = content . Headers != null && Utility . IsMediaTypeOctetOrMultipart ( content . Headers . ContentType ) ;
123
+ // do not log binary data as string
124
+ if ( ! isMediaTypeOctetOrMultipart )
125
+ {
126
+ logger . LogTrace ( await content . ReadAsStringAsync ( ) ) ;
127
+ }
128
+ }
129
+ }
130
+
98
131
internal void AddHeaders ( HttpRequestMessage httpRequest , string invocationId )
99
132
{
100
133
httpRequest . Headers . Add ( HttpWorkerConstants . HostVersionHeaderName , ScriptHost . Version ) ;
@@ -125,14 +158,12 @@ internal async Task ProcessDefaultInvocationRequest(ScriptInvocationContext scri
125
158
{
126
159
AddHeaders ( httpRequestMessage , scriptInvocationContext . ExecutionContext . InvocationId . ToString ( ) ) ;
127
160
128
- _logger . LogDebug ( "Sending http request for function:{functionName} invocationId:{invocationId}" , scriptInvocationContext . FunctionMetadata . Name , scriptInvocationContext . ExecutionContext . InvocationId ) ;
129
- HttpResponseMessage response = await _httpClient . SendAsync ( httpRequestMessage ) ;
130
- _logger . LogDebug ( "Received http response for function:{functionName} invocationId:{invocationId}" , scriptInvocationContext . FunctionMetadata . Name , scriptInvocationContext . ExecutionContext . InvocationId ) ;
161
+ HttpResponseMessage invocationResponse = await SendInvocationRequestAsync ( scriptInvocationContext , httpRequestMessage ) ;
131
162
132
163
// Only process output bindings if response is succeess code
133
- response . EnsureSuccessStatusCode ( ) ;
164
+ invocationResponse . EnsureSuccessStatusCode ( ) ;
134
165
135
- HttpScriptInvocationResult httpScriptInvocationResult = await response . Content . ReadAsAsync < HttpScriptInvocationResult > ( ) ;
166
+ HttpScriptInvocationResult httpScriptInvocationResult = await invocationResponse . Content . ReadAsAsync < HttpScriptInvocationResult > ( ) ;
136
167
137
168
if ( httpScriptInvocationResult != null )
138
169
{
0 commit comments