Skip to content

Commit

Permalink
UNDERTOW-400 AJP attributes are not set in HttpRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Mar 3, 2015
1 parent 350e533 commit 8c5bfa5
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 15 deletions.
5 changes: 5 additions & 0 deletions core/src/main/java/io/undertow/server/HttpServerExchange.java
Expand Up @@ -100,6 +100,11 @@ public final class HttpServerExchange extends AbstractAttachable {
*/ */
static final AttachmentKey<Pooled<ByteBuffer>[]> BUFFERED_REQUEST_DATA = AttachmentKey.create(Pooled[].class); static final AttachmentKey<Pooled<ByteBuffer>[]> BUFFERED_REQUEST_DATA = AttachmentKey.create(Pooled[].class);


/**
* Attachment key that can be used to hold additional request attributes
*/
public static final AttachmentKey<Map<String, String>> REQUEST_ATTRIBUTES = AttachmentKey.create(Map.class);

private final ServerConnection connection; private final ServerConnection connection;
private final HeaderMap requestHeaders; private final HeaderMap requestHeaders;
private final HeaderMap responseHeaders; private final HeaderMap responseHeaders;
Expand Down
Expand Up @@ -218,6 +218,9 @@ public void handleEvent(AjpServerResponseConduit channel) {
if(scheme != null) { if(scheme != null) {
httpServerExchange.setRequestScheme(scheme); httpServerExchange.setRequestScheme(scheme);
} }
if(state.attributes != null) {
httpServerExchange.putAttachment(HttpServerExchange.REQUEST_ATTRIBUTES, state.attributes);
}
state = null; state = null;
this.httpServerExchange = null; this.httpServerExchange = null;
httpServerExchange.setPersistent(true); httpServerExchange.setPersistent(true);
Expand Down
Expand Up @@ -23,7 +23,6 @@
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Map; import java.util.Map;


import io.undertow.server.BasicSSLSessionInfo; import io.undertow.server.BasicSSLSessionInfo;
Expand Down Expand Up @@ -51,7 +50,6 @@ class AjpRequestParseState {
public static final int READING_HEADERS = 13; public static final int READING_HEADERS = 13;
public static final int READING_ATTRIBUTES = 14; public static final int READING_ATTRIBUTES = 14;
public static final int DONE = 15; public static final int DONE = 15;
public static final String AJP_REMOTE_PORT = "AJP_REMOTE_PORT";


int state; int state;


Expand All @@ -66,9 +64,10 @@ class AjpRequestParseState {
String currentAttribute; String currentAttribute;


//TODO: can there be more than one attribute? //TODO: can there be more than one attribute?
Map<String, String> attributes = new HashMap<>(); Map<String, String> attributes;


String remoteAddress; String remoteAddress;
int remotePort = -1;
int serverPort = 80; int serverPort = 80;
String serverAddress; String serverAddress;


Expand All @@ -91,6 +90,10 @@ class AjpRequestParseState {


boolean containsUrlCharacters = false; boolean containsUrlCharacters = false;
public int readHeaders = 0; public int readHeaders = 0;
public String sslSessionId;
public String sslCipher;
public String sslCert;
public String sslKeySize;


public void reset() { public void reset() {
stringLength = -1; stringLength = -1;
Expand All @@ -103,9 +106,9 @@ public boolean isComplete() {
} }


BasicSSLSessionInfo createSslSessionInfo() { BasicSSLSessionInfo createSslSessionInfo() {
String sessionId = attributes.get(AjpRequestParser.SSL_SESSION); String sessionId = sslSessionId;
String cypher = attributes.get(AjpRequestParser.SSL_CIPHER); String cypher = sslCipher;
String cert = attributes.get(AjpRequestParser.SSL_CERT); String cert = sslCert;
if (cert == null && sessionId == null) { if (cert == null && sessionId == null) {
return null; return null;
} }
Expand All @@ -122,14 +125,7 @@ InetSocketAddress createPeerAddress() {
if (remoteAddress == null) { if (remoteAddress == null) {
return null; return null;
} }
String portString = attributes.get(AJP_REMOTE_PORT); int port = remotePort > 0 ? remotePort : 0;
int port = 0;
if (portString != null) {
try {
port = Integer.parseInt(portString);
} catch (IllegalArgumentException e) {
}
}
try { try {
InetAddress address = InetAddress.getByName(remoteAddress); InetAddress address = InetAddress.getByName(remoteAddress);
return new InetSocketAddress(address, port); return new InetSocketAddress(address, port);
Expand Down
Expand Up @@ -50,6 +50,7 @@
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.TreeMap;


import io.undertow.security.impl.ExternalAuthenticationMechanism; import io.undertow.security.impl.ExternalAuthenticationMechanism;
import io.undertow.server.HttpServerExchange; import io.undertow.server.HttpServerExchange;
Expand Down Expand Up @@ -103,6 +104,8 @@ public class AjpRequestParser {


public static final String STORED_METHOD = "stored_method"; public static final String STORED_METHOD = "stored_method";


public static final String AJP_REMOTE_PORT = "AJP_REMOTE_PORT";

static { static {
HTTP_METHODS = new HttpString[28]; HTTP_METHODS = new HttpString[28];
HTTP_METHODS[1] = OPTIONS; HTTP_METHODS[1] = OPTIONS;
Expand Down Expand Up @@ -391,8 +394,21 @@ public void parse(final ByteBuffer buf, final AjpRequestParseState state, final
exchange.putAttachment(ExternalAuthenticationMechanism.EXTERNAL_AUTHENTICATION_TYPE, result); exchange.putAttachment(ExternalAuthenticationMechanism.EXTERNAL_AUTHENTICATION_TYPE, result);
} else if (state.currentAttribute.equals(STORED_METHOD)) { } else if (state.currentAttribute.equals(STORED_METHOD)) {
exchange.setRequestMethod(new HttpString(result)); exchange.setRequestMethod(new HttpString(result));
} else { } else if (state.currentAttribute.equals(AJP_REMOTE_PORT)) {
state.remotePort = Integer.parseInt(result);
} else if (state.currentAttribute.equals(SSL_SESSION)) {
state.sslSessionId = result;
} else if (state.currentAttribute.equals(SSL_CIPHER)) {
state.sslCipher = result;
} else if (state.currentAttribute.equals(SSL_CERT)) {
state.sslCert = result;
} else if (state.currentAttribute.equals(SSL_KEY_SIZE)) {
state.sslKeySize = result;
} else {
//other attributes //other attributes
if(state.attributes == null) {
state.attributes = new TreeMap<>();
}
state.attributes.put(state.currentAttribute, result); state.attributes.put(state.currentAttribute, result);
} }
state.currentAttribute = null; state.currentAttribute = null;
Expand Down
Expand Up @@ -67,6 +67,7 @@
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.Map;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;


/** /**
Expand Down Expand Up @@ -256,6 +257,15 @@ public void handleFirstRequest(final HttpServerExchange exchange, final ServletC


ThreadSetupAction.Handle handle = setupAction.setup(exchange); ThreadSetupAction.Handle handle = setupAction.setup(exchange);
try { try {
//set request attributes from the connector
//generally this is only applicable if apache is sending AJP_ prefixed environment variables
Map<String, String> attrs = exchange.getAttachment(HttpServerExchange.REQUEST_ATTRIBUTES);
if(attrs != null) {
for(Map.Entry<String, String> entry : attrs.entrySet()) {
request.setAttribute(entry.getKey(), entry.getValue());
}
}

SecurityActions.setCurrentRequestContext(servletRequestContext); SecurityActions.setCurrentRequestContext(servletRequestContext);
servletRequestContext.setRunningInsideHandler(true); servletRequestContext.setRunningInsideHandler(true);
try { try {
Expand Down

0 comments on commit 8c5bfa5

Please sign in to comment.