views:

64

answers:

5

I have a class that I want to hook and redirect HTTP requests in. I also have a loader class already written, but all it does it replace the functions that contain the HTTP requests I want to change. Is there a way to hook HTTP requests in Java so that I can redirect them all more easily? Sort of like a proxy-wrapper.

Clarification: The app sends out a GET or POST request to a URL. I need the content to remain the same, just change the URL. DNS redirects won't work, the Host HTTP header needs to be correct for the new server.

PS: This is a Desktop App, not a server script.

A: 

Do you control all of the code? If so, I suggest using Dependency Injection to inject the concrete implementation you want, which would allow you to instead inject a proxy class.

Luke Schafer
Unfortunately no, and even if I did, I don't want to put my own version of the program. I want to put out a loader that can redirect any version of the program.
download
+1  A: 

While an older post, this should give some ideas of some kinds of bytecode injects which can be peformed: Java Programming: Bytecode Injection. Another tool is Javassist and you may be able to find some links from the Aspected-oriented programming wiki article (look at the bytecode weavers section).

There are some products which extensively dynamically modify code.

Depending upon what is desired, there may be ... less painful ... methods. If you simply want to 'hook' HTTP requests, another option is just to use a proxy (which could be an external process) and funnel through that. Using a proxy would likely require control over the name resolution used.

pst
I already have a proxy script in Python for this, but thought someone might know a better way in Java.
download
+1  A: 

you can use servlet filters which intercept the requests, the requests can further be wrapped, redirected, forwarded or completed from here.

http://www.oracle.com/technetwork/java/filters-137243.html

keshav.veerapaneni
I had the same idea, but you beat me to it by 30 secs. +1
Adeel Ansari
I should hae mentioned, this is not a JSP server app. Just a plain desktop Java app.
download
@download: In that case, we need a little description about the flow of request and so. PS, you can edit your post(question) to include these things.
Adeel Ansari
A: 
  • If you can change the source code, just change it and add your extra code on each HTTP request.

  • If you can't change the source code, but it uses dependency injection, perhaps you can inject something to catch requests.

  • Otherwise: use aspect-oriented programming and catch to URL class, or whatever you use to do HTTP requests. @AspectJ (http://www.eclipse.org/aspectj/doc/next/adk15notebook/ataspectj.html ) is quite easy and powerful.

iirekm
+2  A: 

A cumbersome but reliable way of doing this would be to make your application use a proxy server, and then write a proxy server which makes the changes you need. The proxy server could be in-process in your application; it wouldn't need to be a separate program.

To use a proxy, set a couple of system properties - http.proxyHost and http.proxyPort. Requests made via HttpURLConnection will then use that proxy (unless they specifically override the default proxy settings). Requests made using some other method like Apache HttpClient will not, i think, be affected, but hopefully, all your requests are using HttpURLConnection.

To implement the proxy, if you're using a Sun JRE, then you should probably use the built-in HTTP server; set up a single handler mapped to the path "/", and this will pick up all requests being sent by your app, and can then determine the right URL to send them to, and make a connection to that URL (with all the right headers too). To make the connection, use URL.openConnection(Proxy.NO_PROXY) to avoid making a request to the proxy and so getting caught in an infinite loop. You'll then need to pump input and output between the two sockets.

The only other way i can think of to do this would be to override HttpURLConnection with a new handler which steers requests to your desired destination; you'd need to find a way to persuade the URL class to use your handler instead of the default one. I don't know how you'd do that in a clean way.

Tom Anderson
I didn't know there were properties to set a proxy. That will work perfectly for what I have in mind. Thanks.
download