Skip to content

Commit 0dcd979

Browse files
committed
WIP
1 parent d864b1e commit 0dcd979

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

dd-smoke-tests/appsec/springboot/src/main/java/datadog/smoketest/appsec/springboot/controller/WebController.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,16 @@ public ResponseEntity<String> customHeaders() {
222222
return new ResponseEntity<>("Custom headers added", headers, HttpStatus.OK);
223223
}
224224

225+
@GetMapping("/exceedResponseHeaders")
226+
public ResponseEntity<String> exceedResponseHeaders() {
227+
HttpHeaders headers = new HttpHeaders();
228+
for (int i = 1; i <= 50; i++) {
229+
headers.add("X-Test-Header-" + i, "value" + i);
230+
}
231+
headers.add("content-language", "en-US");
232+
return new ResponseEntity<>("Custom headers added", headers, HttpStatus.OK);
233+
}
234+
225235
private void withProcess(final Operation<Process> op) {
226236
Process process = null;
227237
try {

dd-smoke-tests/appsec/springboot/src/test/groovy/datadog/smoketest/appsec/ExtendedDataCollectionSmokeTest.groovy

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,88 @@ class ExtendedDataCollectionSmokeTest extends AbstractAppSecServerSmokeTest {
6363
rootSpan.meta.get('http.response.headers.x-test-header-4') == 'value4'
6464
rootSpan.meta.get('http.response.headers.x-test-header-5') == 'value5'
6565
}
66+
67+
void 'No extended header collection if no appsec event'(){
68+
given:
69+
def url = "http://localhost:${httpPort}/custom-headers"
70+
def client = OkHttpUtils.clientBuilder().build()
71+
def request = new Request.Builder()
72+
.url(url)
73+
.addHeader('X-My-Header-1', "value1")
74+
.addHeader('X-My-Header-2', "value2")
75+
.addHeader('X-My-Header-3', "value3")
76+
.addHeader('X-My-Header-4', "value4")
77+
.addHeader('Content-Type', "text/html")
78+
.get()
79+
.build()
80+
81+
when:
82+
def response = client.newCall(request).execute()
83+
84+
then:
85+
response.code()==200
86+
87+
when:
88+
waitForTraceCount(1)
89+
90+
then:
91+
def rootSpans = this.rootSpans.toList()
92+
rootSpans.size() == 1
93+
def rootSpan = rootSpans[0]
94+
!rootSpan.metrics.containsKey('_dd.appsec.request.header_collection.discarded')
95+
!rootSpan.metrics.containsKey('http.request.headers.x-my-header-1')
96+
!rootSpan.metrics.containsKey('http.request.headers.x-my-header-2')
97+
!rootSpan.metrics.containsKey('http.request.headers.x-my-header-3')
98+
!rootSpan.metrics.containsKey('http.request.headers.x-my-header-4')
99+
rootSpan.meta.get('http.request.headers.content-type') == 'text/html'
100+
!rootSpan.metrics.containsKey('_dd.appsec.response.header_collection.discarded')
101+
!rootSpan.metrics.containsKey('http.response.headers.x-test-header-1')
102+
!rootSpan.metrics.containsKey('http.response.headers.x-test-header-2')
103+
!rootSpan.metrics.containsKey('http.response.headers.x-test-header-3')
104+
!rootSpan.metrics.containsKey('http.response.headers.x-test-header-4')
105+
!rootSpan.metrics.containsKey('http.response.headers.x-test-header-5')
106+
}
107+
108+
void 'test header budget exceeded with 50 headers'() {
109+
given:
110+
def url = "http://localhost:${httpPort}/exceedResponseHeaders"
111+
def client = OkHttpUtils.clientBuilder().build()
112+
// Build request with 50 custom headers
113+
def builder = new Request.Builder().url(url)
114+
builder.addHeader("User-Agent", "Arachni/v1")
115+
(1..50).each { i ->
116+
builder.addHeader("X-My-Header-${i}", "value${i}")
117+
}
118+
// Include content-type to trigger parsing
119+
builder.addHeader('Content-Type', 'text/html')
120+
def request = builder.get().build()
121+
122+
when:
123+
def response = client.newCall(request).execute()
124+
125+
then:
126+
response.code() == 200
127+
128+
when:
129+
waitForTraceCount(1)
130+
131+
then:
132+
def rootSpan = this.rootSpans.toList()[0]
133+
// Check that the discarded metrics exists and are greater than 1
134+
rootSpan.metrics.containsKey('_dd.appsec.request.header_collection.discarded')
135+
rootSpan.metrics['_dd.appsec.request.header_collection.discarded'] > 1
136+
rootSpan.metrics.containsKey('_dd.appsec.response.header_collection.discarded')
137+
rootSpan.metrics['_dd.appsec.response.header_collection.discarded'] > 1
138+
// Ensure no more than 50 request headers collected
139+
def headerRequestKeys = rootSpan.meta.keySet().findAll { it.startsWith('http.request.headers.') }
140+
headerRequestKeys.size() <= 50
141+
def headerResponseKeys = rootSpan.meta.keySet().findAll { it.startsWith('http.response.headers.') }
142+
headerResponseKeys.size() <= 50
143+
// Ensure allowed headers are collected
144+
rootSpan.meta.get('http.request.headers.content-type') == 'text/html'
145+
rootSpan.meta.get('http.response.headers.content-language') == 'en-US'
146+
}
147+
148+
149+
66150
}

0 commit comments

Comments
 (0)