Tuesday, November 22, 2011

Signed and Unsigned

Here are some quick scripts to sign every jar in a directory, and then unsign every jar.

Sign

find . -name "*.jar" -exec jarsigner -keystore /path/to/your/key -storepass yourpassword '{}' yourkeystorename \;

Unsign

find . -type f -iname '*.jar' -exec zip -d '{}' META-INF/*.{SF,RSA} \;

Tuesday, April 19, 2011

Http Proxy Server

How does an HTTP proxy server work? I learned a little about this recently while trying to implement one using Apache, mod_python, and Python. HTTP is a relatively simple protocol. A connection is opened to a server, and a request in the form of a string is sent. For example, to get a web page, you just send a simple get request and wait for the web page (or an error code) to be sent back to you.

GET /path/to/file/index.html HTTP/1.0

However, there is no server information in this request, so how does a proxy server know what you want? After you configure your browser or other client to use a proxy, the client opens a connection to the proxy server for each request, and sends a slightly different get request for each page.

GET http://someserver:80/path/to/file/index.html HTTP/1.0

Notice that this get request includes the full URL (including the server and port). This tells the proxy server which server contains the actual content. So the proxy server connects to the specified server, and pipes the appropriate content back to you.

The problem I face is that I need a way to track groups of requests coming from a particular client process. For example, let's say the user has two browsers and I want a separate log file containing all the downloads made by each browser. I can't track by IP address (they are the same), I can't track by modification to the URL since most client apps don't support adding information other than the servername and port. So this leaves the authentication mechanism. Each browser will need to send a unique username, and that username will be used to track which client is making the request. For now, that's the solution I'm going with.

For more information, there is a nice introduction to HTTP here:
http://www.jmarshall.com/easy/http/
And for even more details, look at RFC 2616
http://www.w3.org/Protocols/rfc2616/rfc2616.html

Thursday, February 3, 2011

Extend TestCase and use annotations in JUnit 4

JUnit 3 required that test classes extend, directly or indirectly, the class junit.framework.TestCase, and that each test method begin with the word "test". In contrast, JUnit 4 uses @Test annotations for each test method and does not require the test class to extend junit.framework.TestCase. But what if we have some JUnit 3 and some JUnit 4 tests? JUnit 4 automatically treats classes that extend TestCase as a JUnit 3 test, and therefore ignores the @Test notation. So let's say there is a class like the following.

public class MyTests extends TestCase
{
@Test
public testOne()
{
//do stuff
}

@Test
public anotherTest()
{
//do stuff
}
}

Using JUnit 4, it would appear that both these tests are run, but actually only the first one runs. Why? Because the class extends TestCase, so JUnit 4 will handle this class using a JUnit 3 compatibility mode. This means that the @Test tag is ignored and the method names are examined for the pattern "test*". This can be fixed in two ways. The first is by removing "extends TestCase". This will cause JUnit 4 to run the test in normal mode instead of backwards compat mode.

The second option is to use a class annotation to force the class to be treated as a JUnit 4 test case. It looks like this:

@RunWith(JUnit4.class)
public class MyTests extends TestCase
{
...
}

This forces JUnit 4 to locate tests using annotations instead of using the older method name convention.

The solution using @RunWith was found in the JUnit yahoo group.