2012-12-26

Adding Customized HTTP Header in HTTPServletRequest in Jetty

Sometimes we need Adding some customized HTTP header in Jetty's Request.

Here is a way to change Request.getHeader() using java.lang.instrument and javassist.

import java.lang.instrument.*;
import java.util.*;
import javassist.*;
public class HeaderAgent implements ClassFileTransformer {
public static void premain(String agentArgument,
Instrumentation instrumentation) {
instrumentation.addTransformer(new HeaderAgent());
}
public byte[] transform(ClassLoader loader, String className,
Class clazz, java.security.ProtectionDomain domain,
byte[] bytes) {
//To adding customized HTTP Header, we need adding some code in Request.getHeader() method
if (!className.equals("org/mortbay/jetty/Request") && !className.equals("org/apache/catalina/connector/Request")) {
return bytes;
}
System.out.println("[transform jetty class]: " + className);
return doClass(className, clazz, bytes);
}
private byte[] doClass(String name, Class clazz, byte[] b) {
ClassPool pool = ClassPool.getDefault();
CtClass cl = null;
try {
cl = pool.makeClass(new java.io.ByteArrayInputStream(b));
if (cl.isInterface() == false) {
CtBehavior[] methods = cl.getDeclaredBehaviors();
for (int i = 0; i < methods.length; i++) {
//Only Modify getHeader behavior
if (methods[i].getName().equals("getHeader")) {
doMethod(methods[i]);
}
}
b = cl.toBytecode();
}
} catch (Exception e) {
System.err.println("Could not instrument " + name
+ ", exception : " + e.getMessage());
} finally {
if (cl != null) {
cl.detach();
}
}
return b;
}
private void doMethod(CtBehavior method)
throws NotFoundException, CannotCompileException {
//adding code to customize value of "Host" to "hunmr.blogspot.com"
method.insertBefore("if (\"Host\".equals($1)) { return \"hunmr.blogspot.com\"; }");
}
}



contents of MANIFEST.MF:
Premain-Class: HeaderAgent
Boot-Class-Path: /absolute-path-to-javassist-jar-folder/javassist.jar
view raw MANIFEST.MF hosted with ❤ by GitHub


command to compile and pack jar:
javac -classpath ./javassist.jar HeaderAgent.java
jar -cmf MANIFEST.MF sslagent.jar HeaderAgent.class


adding following option to your java command, then Request.getHeader() method will be customized after Request.class loaded.
-javaagent:$HOME/bin/jettySSLPlugin/sslagent.jar

git@github.com:whunmr/jettyHeaderAgent.git

No comments:

Post a Comment