Skip to content

Commit

Permalink
Merge pull request #1 from breakponchito/AddingProperties
Browse files Browse the repository at this point in the history
Adding properties
  • Loading branch information
carryel authored Nov 18, 2024
2 parents ed2eba1 + 59216d7 commit be0e4a1
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
import static org.glassfish.grizzly.utils.Charsets.ASCII_CHARSET;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import java.util.regex.Pattern;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.Grizzly;
Expand Down Expand Up @@ -109,6 +112,16 @@ public abstract class HttpCodecFilter extends HttpBaseFilter implements Monitori
* @see #setRemoveHandledContentEncodingHeaders
*/
private boolean removeHandledContentEncodingHeaders = false;

public static final String STRICT_HEADER_NAME_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_NAME_VALIDATION_RFC_9110";

public static final String STRICT_HEADER_VALUE_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_VALUE_VALIDATION_RFC_9110";

private static final boolean isStrictHeaderNameValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110));

private static final boolean isStrictHeaderValueValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110));

private static final String REGEX_RFC_9110_INVALID_CHARACTERS = "(\\\\n)|(\\\\0)|(\\\\r)|(\\\\x00)|(\\\\x0A)|(\\\\x0D)";

/**
* File cache probes
Expand Down Expand Up @@ -782,7 +795,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim
b -= Constants.LC_OFFSET;
}
input[offset] = b;
} else if (b == Constants.CR) {
} else if (isStrictHeaderNameValidationSet && b == Constants.CR) {
parsingState.offset = offset - arrayOffs;
final int eol = checkEOL(parsingState, input, end);
if (eol == 0) { // EOL
Expand All @@ -794,7 +807,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim
}
}

if (!CookieHeaderParser.isToken(b)) {
if (isStrictHeaderNameValidationSet && !CookieHeaderParser.isToken(b)) {
throw new IllegalStateException(
"An invalid character 0x" + Integer.toHexString(b) + " was found in the header name");
}
Expand Down Expand Up @@ -829,6 +842,10 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP
parsingState.offset = offset + 1 - arrayOffs;
finalizeKnownHeaderValues(httpHeader, parsingState, input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2);
parsingState.headerValueStorage.setBytes(input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2);
if (isStrictHeaderValueValidationSet) {
//make validation with regex mode
validateRFC9110Characters(input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2);
}
return 0;
}
}
Expand All @@ -849,13 +866,37 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP
}
parsingState.checkpoint2 = parsingState.checkpoint;
}

offset++;
}
parsingState.offset = offset - arrayOffs;
return -1;
}

private static void validateRFC9110Characters(final byte[] headerValueContent, int start, int end) {
if (headerValueContent != null) {
if (isInvalidCharacterAvailable(start, end, headerValueContent)) {
throw new IllegalStateException(
"An invalid character NUL, LF or CR found in the header value: " + headerValueContent.toString());
}
}
}

/**
* This method evaluates the String from the bytes that contains Header Value and validates if contains literal value
* of \n, \r or \0 , in case any of those characters are available return true
* @param start index of the starting point to extract characters from the byte array
* @param end index of the end point to extract characters from the byte array
* @param bytesFromByteChunk represents the bytes from the request message to be processed
* @return Boolean true if any of those characters are available
*/
private static boolean isInvalidCharacterAvailable(int start, int end, byte[] bytesFromByteChunk) {
byte[] bytesFromHeaderValue = Arrays.copyOfRange(bytesFromByteChunk, start, end);
String uft8String = new String(bytesFromHeaderValue, StandardCharsets.UTF_8);
Pattern pattern = Pattern.compile(REGEX_RFC_9110_INVALID_CHARACTERS);
return pattern.matcher(uft8String).find();
}

private static void finalizeKnownHeaderNames(final HttpHeader httpHeader, final HeaderParsingState parsingState, final byte[] input, final int start,
final int end) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import java.util.HashMap;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.SocketConnectorHandler;
Expand All @@ -50,6 +49,9 @@

import junit.framework.TestCase;

import static org.glassfish.grizzly.http.HttpCodecFilter.STRICT_HEADER_NAME_VALIDATION_RFC_9110;
import static org.glassfish.grizzly.http.HttpCodecFilter.STRICT_HEADER_VALUE_VALIDATION_RFC_9110;

/**
* Testing HTTP request parsing
*
Expand All @@ -59,6 +61,20 @@ public class HttpRequestParseTest extends TestCase {

public static final int PORT = 19000;

@Override
protected void setUp() throws Exception {
super.setUp();
System.setProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110, String.valueOf(Boolean.TRUE));
System.setProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110, String.valueOf(Boolean.TRUE));
}

@Override
protected void tearDown() throws Exception {
super.tearDown();
System.setProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110, String.valueOf(Boolean.FALSE));
System.setProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110, String.valueOf(Boolean.FALSE));
}

public void testCustomMethod() throws Exception {
doHttpRequestTest("TAKE", "/index.html", "HTTP/1.0", Collections.<String, Pair<String, String>>emptyMap(), "\r\n");
}
Expand Down Expand Up @@ -107,6 +123,27 @@ public void testDisallowedHeaders() {
}
}

public void testDisallowedCharactersForHeaderContentValues() {
try {
doTestDecoder("GET /index.html HTTP/1.1\nHost: loca\\rlhost\nContent -Length: 1234\n\n", 128);
fail("Bad HTTP headers exception had to be thrown");
} catch (IllegalStateException e) {
// expected
}
try {
doTestDecoder("GET /index.html HTTP/1.1\nHost: loca\\nlhost\nContent-Length: 1234\n\n", 128);
fail("Bad HTTP headers exception had to be thrown");
} catch (IllegalStateException e) {
// expected
}
try {
doTestDecoder("GET /index.html HTTP/1.1\nHost: loca\\0lhost\nContent-Length: 1234\n\n", 128);
fail("Bad HTTP headers exception had to be thrown");
} catch (IllegalStateException e) {
// expected
}
}

public void testIgnoredHeaders() throws Exception {
final Map<String, Pair<String, String>> headers = new HashMap<>();
headers.put("Host", new Pair<>("localhost", "localhost"));
Expand Down

0 comments on commit be0e4a1

Please sign in to comment.