Skip to content

Commit 9ce57d6

Browse files
authored
Fix handling of invalid end of line in HTTP header parsing. Added tests (helidon-io#8831)
1 parent ea90af9 commit 9ce57d6

3 files changed

Lines changed: 55 additions & 3 deletions

File tree

common/testing/http-junit5/src/main/java/io/helidon/common/testing/http/junit5/SocketHttpClient.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,25 @@ public void request(String method, String path, String protocol, String host, It
460460
}
461461
}
462462

463+
/**
464+
* Send raw data to the server.
465+
*
466+
* @param content content to send over the socket
467+
*/
468+
public void requestRaw(String content) {
469+
if (socket == null) {
470+
connect();
471+
}
472+
473+
try {
474+
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
475+
pw.print(content);
476+
pw.flush();
477+
} catch (IOException e) {
478+
throw new UncheckedIOException(e);
479+
}
480+
}
481+
463482
/**
464483
* Write raw proxy protocol header before a request.
465484
*

webserver/tests/webserver/src/test/java/io/helidon/webserver/tests/BadRequestTest.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2023 Oracle and/or its affiliates.
2+
* Copyright (c) 2022, 2024 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -148,6 +148,39 @@ void testBadHeaderWhitespace() {
148148
assertThat(response, containsString(CUSTOM_ENTITY));
149149
}
150150

151+
@Test
152+
void testCrWithoutLf() {
153+
socketClient.requestRaw("GET / HTTP/1.1\r\nhost: localhost:8080\rcustom: value\r\n");
154+
155+
String response = socketClient.receive();
156+
assertThat(response, containsString("400 " + CUSTOM_REASON_PHRASE));
157+
assertThat(response, containsString(CUSTOM_ENTITY));
158+
}
159+
160+
@Test
161+
void testLfWithoutCr() {
162+
socketClient.requestRaw("GET / HTTP/1.1\r\nhost: localhost:8080\ncustom: value\r\n");
163+
164+
String response = socketClient.receive();
165+
assertThat(response, containsString("400 " + CUSTOM_REASON_PHRASE));
166+
assertThat(response, containsString(CUSTOM_ENTITY));
167+
}
168+
169+
@Test
170+
void testKeepAliveAndMissingLf() {
171+
socketClient.request(Method.GET, "/", null, List.of("Accept: text/plain", "Connection: keep-alive"));
172+
String response = socketClient.receive();
173+
assertThat(response, containsString("200 OK"));
174+
assertThat(response, containsString("Hi"));
175+
176+
socketClient.requestRaw("GET / HTTP/1.1\r\nhost: localhost:8080\rcustom: value\r\n");
177+
178+
response = socketClient.receive();
179+
assertThat(response, containsString("400 " + CUSTOM_REASON_PHRASE));
180+
assertThat(response, containsString("Connection: close"));
181+
assertThat(response, containsString(CUSTOM_ENTITY));
182+
}
183+
151184
private static DirectHandler.TransportResponse badRequestHandler(DirectHandler.TransportRequest request,
152185
DirectHandler.EventType eventType,
153186
Status httpStatus,

webserver/webserver/src/main/java/io/helidon/webserver/http1/Http1Headers.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2023 Oracle and/or its affiliates.
2+
* Copyright (c) 2022, 2024 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -55,7 +55,7 @@ public Http1Headers(DataReader reader, int maxHeadersSize, boolean validateHeade
5555
public WritableHeaders<?> readHeaders(HttpPrologue prologue) {
5656
try {
5757
return Http1HeadersParser.readHeaders(reader, maxHeadersSize, validateHeaders);
58-
} catch (IllegalStateException | IllegalArgumentException e) {
58+
} catch (IllegalStateException | IllegalArgumentException | DataReader.IncorrectNewLineException e) {
5959
throw RequestException.builder()
6060
.type(DirectHandler.EventType.BAD_REQUEST)
6161
.request(DirectTransportRequest.create(prologue, WritableHeaders.create()))

0 commit comments

Comments
 (0)