I'm having a problem getting HTTPUnit to follow a
redirect from a regular URL to a SSL-enabled URL. The sequence should go like this:
1) Request a reuglar HTTP URL that is protected by an authentication mechanism. The server detects via a cookie (or lack of) that you are not authenticated and sends a redirect to the client to go to a SSL URL
2) The client receives the request and navigates to
the SSL URL. The client then enters some information
(username and password) in a form. The form is then submitted.
3) If you are authenticated a page is displayed (still
SSL here) with a link to the protected resource. A
cookie is also set.
4) next time you navigate to the protected URL, the
server detects the cookie and allows access via HTTP
I have verified the actions using the Java Proxy monitor Charles 1.6.
The problem I have is that in HTTPUnit the redirect at
step 1 fails with the stack trace below. I am using
JDK 1.4.1_01. I have built a test case that accesses
an HTTPS URL and that works fine so my SSL
configuration is OK. My test case is shown below the
stack trace. A search of the mailing list and the web
shows nothing.
All help is gladly appreciated,
Rob Cole
java.net.SocketException: Unexpected end of file from
server
at
sun.net.www.http.HttpClient.parseHTTPHeader(Unknown
Source)
at sun.net.www.http.HttpClient.parseHTTP(Unknown
Source)
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
Source)
at
sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(Unknown
Source)
at
com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl.getHeaderFieldKey(Unknown
Source)
at
com.meterware.httpunit.HttpWebResponse.loadHeaders(HttpWebResponse.java:201)
at
com.meterware.httpunit.HttpWebResponse.readHeaders(HttpWebResponse.java:183)
at
com.meterware.httpunit.HttpWebResponse.<init>(HttpWebResponse.java:53)
at
com.meterware.httpunit.WebConversation.newResponse(WebConversation.java:61)
at
com.meterware.httpunit.WebWindow.getResource(WebWindow.java:162)
at
com.meterware.httpunit.WebWindow.getSubframeResponse(WebWindow.java:125)
at
com.meterware.httpunit.WebWindow.getResponse(WebWindow.java:118)
at
com.meterware.httpunit.WebWindow.updateWindow(WebWindow.java:141)
at
com.meterware.httpunit.WebWindow.getSubframeResponse(WebWindow.java:127)
at
com.meterware.httpunit.WebWindow.getResponse(WebWindow.java:118)
at
com.meterware.httpunit.WebWindow.updateWindow(WebWindow.java:141)
at
com.meterware.httpunit.WebWindow.getSubframeResponse(WebWindow.java:127)
at
com.meterware.httpunit.WebWindow.getResponse(WebWindow.java:118)
at
com.meterware.httpunit.WebClient.getResponse(WebClient.java:112)
at
com.db.gmr.eds.test.EDSAdminTestCase.testGetDefaultPage(EDSAdminTestCase.java:91)
at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown
Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
junit.framework.TestCase.runTest(TestCase.java:154)
at
junit.framework.TestCase.runBare(TestCase.java:127)
at
junit.framework.TestResult$1.protect(TestResult.java:106)
at
junit.framework.TestResult.runProtected(TestResult.java:124)
at
junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at
junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
Test Case:
public void testGetDefaultPage() throws Exception
{
Security.addProvider(new
com.sun.net.ssl.internal.ssl.Provider());
WebConversation wc = new WebConversation();
// Set browser properties
ClientProperties clientProperties =
wc.getClientProperties();
clientProperties.setAutoRedirect(true);
clientProperties.setAcceptCookies(true);
WebRequest request = new GetMethodWebRequest(
"http://myserver:myport/jsp_intranet/eds/" );
WebResponse response = wc.getResponse( request );
String pageText = response.getText();
assertTrue(pageText.indexOf("Periodicals") > -1);
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've now explicityly added the certificate to the keystore and I'm still getting the error.
What it strange is that the problem is intermittent. Some times I can get through to the final assertion and sometimes (more often than not) it falls over.
I've tried turning the auto-redirect off and following the redirects manually and this makes no difference. It falls over on different redirects each time.
I've created another test that calls the initial URL once and checks that the response is not null. This works. I.e. the HTTP to HTTPS redirect seems to work fine.
Any more ideas on what I can investigate?
Thanks,
Rob
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Is this a beta/dev environment? Is it possible to run the same tests against an environment with a certified cert?
I would think that if your tests can run without problems on the certified site, the only difference being the certs, then it would be wise to submit this as a bug. Submitting it as a bug might get your issue more attention.
In the bug report make sure you document how you added the cert to the keystore and a sample testcase that duplicates the problem.
On a side note, I am not a member of this project so submitting a bug might not get you any further along.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The SSL stuff works. I've installed the certificate with the keytool utility, following the instructions on the HttpUnit FAQ.
Right, more details. I've narrowed it down to either JDK 1.4.1, my server or HTTPUnit.
HTTPUnit does not use HttpURLConnection.setInstanceFollowRedirect(), or rather it sets this to false for each connection and handles redirects itself and I think this is related to the problem(com.meterware,httpunit.WebConversation.openConnection).
I've coded a test case outside of HttpUnit that errors in the same fashion when I use HttpURLConnection with redirects set to false. It seems that the HttpURLConnection class can not cope with the headers being returned from the server (Netscape-Enterprise/4.1 in the header). The first response is returned with a 302 code and new location. When I call the second URL, i.e. the redirected location from the first, everything fails.
However, if followRedirects is set to true on the HttpURLConnection object, it works. Unfortunately, this is not possible in HttpUnit unless I change the WebConversation class. If I make this change, HttpUnit works as well.
I'm going to do some more investigation and check alternative JDKs if I can.
In the mean time, is there a reason why HttpUnit does not use the HttpURLConnection.setInstanceFollowRedirects(true) if the ClientProperties object specifies that redirects are to be followed?
Thanks,
Rob
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I don't know if this helps, but I did an annotate on WebConversation and it looks like the change to set that to false was made in Mar 19 19:43:46 2003 With the following comment which doesn't make a ton of sense:
"Disable HTTP URL Connection per instance, not globally"
That one line was added and that's it.
When you said
"If I make this change, HttpUnit works as well. ", did you change openConnection() to set redirects to true or did you take the line out completely?
I have a pretty large suite of tests that I can run this change against to see if it breaks anything. If you are interested, I'd be willing to make the change and run it locally to see if it breaks anything.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I made the change to WebConversation.openConnection(URL url) to hardcode the follow redirects to true instead of false. The code seems to disable follow-redirects per-instance, but to every Http connection. I would have thought a better approach would ahve been to set something on HttpUnitOptions or on ClientProperties that changes the underlying behaviour rather than just HTTPUnits internal behaviour
I'm running on JDK 1.4.1 on Windows NT.
I would be very interested in seeing what it breaks by changing this parameter.
Thanks,
Rob
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi all,
I'm having a problem getting HTTPUnit to follow a
redirect from a regular URL to a SSL-enabled URL. The sequence should go like this:
1) Request a reuglar HTTP URL that is protected by an authentication mechanism. The server detects via a cookie (or lack of) that you are not authenticated and sends a redirect to the client to go to a SSL URL
2) The client receives the request and navigates to
the SSL URL. The client then enters some information
(username and password) in a form. The form is then submitted.
3) If you are authenticated a page is displayed (still
SSL here) with a link to the protected resource. A
cookie is also set.
4) next time you navigate to the protected URL, the
server detects the cookie and allows access via HTTP
I have verified the actions using the Java Proxy monitor Charles 1.6.
The problem I have is that in HTTPUnit the redirect at
step 1 fails with the stack trace below. I am using
JDK 1.4.1_01. I have built a test case that accesses
an HTTPS URL and that works fine so my SSL
configuration is OK. My test case is shown below the
stack trace. A search of the mailing list and the web
shows nothing.
All help is gladly appreciated,
Rob Cole
java.net.SocketException: Unexpected end of file from
server
at
sun.net.www.http.HttpClient.parseHTTPHeader(Unknown
Source)
at sun.net.www.http.HttpClient.parseHTTP(Unknown
Source)
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown
Source)
at
sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(Unknown
Source)
at
com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl.getHeaderFieldKey(Unknown
Source)
at
com.meterware.httpunit.HttpWebResponse.loadHeaders(HttpWebResponse.java:201)
at
com.meterware.httpunit.HttpWebResponse.readHeaders(HttpWebResponse.java:183)
at
com.meterware.httpunit.HttpWebResponse.<init>(HttpWebResponse.java:53)
at
com.meterware.httpunit.WebConversation.newResponse(WebConversation.java:61)
at
com.meterware.httpunit.WebWindow.getResource(WebWindow.java:162)
at
com.meterware.httpunit.WebWindow.getSubframeResponse(WebWindow.java:125)
at
com.meterware.httpunit.WebWindow.getResponse(WebWindow.java:118)
at
com.meterware.httpunit.WebWindow.updateWindow(WebWindow.java:141)
at
com.meterware.httpunit.WebWindow.getSubframeResponse(WebWindow.java:127)
at
com.meterware.httpunit.WebWindow.getResponse(WebWindow.java:118)
at
com.meterware.httpunit.WebWindow.updateWindow(WebWindow.java:141)
at
com.meterware.httpunit.WebWindow.getSubframeResponse(WebWindow.java:127)
at
com.meterware.httpunit.WebWindow.getResponse(WebWindow.java:118)
at
com.meterware.httpunit.WebClient.getResponse(WebClient.java:112)
at
com.db.gmr.eds.test.EDSAdminTestCase.testGetDefaultPage(EDSAdminTestCase.java:91)
at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown
Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
junit.framework.TestCase.runTest(TestCase.java:154)
at
junit.framework.TestCase.runBare(TestCase.java:127)
at
junit.framework.TestResult$1.protect(TestResult.java:106)
at
junit.framework.TestResult.runProtected(TestResult.java:124)
at
junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at
junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
Test Case:
public void testGetDefaultPage() throws Exception
{
Security.addProvider(new
com.sun.net.ssl.internal.ssl.Provider());
WebConversation wc = new WebConversation();
// Set browser properties
ClientProperties clientProperties =
wc.getClientProperties();
clientProperties.setAutoRedirect(true);
clientProperties.setAcceptCookies(true);
WebRequest request = new GetMethodWebRequest(
"http://myserver:myport/jsp_intranet/eds/" );
WebResponse response = wc.getResponse( request );
String pageText = response.getText();
assertTrue(pageText.indexOf("Periodicals") > -1);
}
Is you SSL cert certified? If you go to your site via a browser does it ask you to accept the cert first? This was a problem for us.
I've now explicityly added the certificate to the keystore and I'm still getting the error.
What it strange is that the problem is intermittent. Some times I can get through to the final assertion and sometimes (more often than not) it falls over.
I've tried turning the auto-redirect off and following the redirects manually and this makes no difference. It falls over on different redirects each time.
I've created another test that calls the initial URL once and checks that the response is not null. This works. I.e. the HTTP to HTTPS redirect seems to work fine.
Any more ideas on what I can investigate?
Thanks,
Rob
Is this a beta/dev environment? Is it possible to run the same tests against an environment with a certified cert?
I would think that if your tests can run without problems on the certified site, the only difference being the certs, then it would be wise to submit this as a bug. Submitting it as a bug might get your issue more attention.
In the bug report make sure you document how you added the cert to the keystore and a sample testcase that duplicates the problem.
On a side note, I am not a member of this project so submitting a bug might not get you any further along.
The SSL stuff works. I've installed the certificate with the keytool utility, following the instructions on the HttpUnit FAQ.
Right, more details. I've narrowed it down to either JDK 1.4.1, my server or HTTPUnit.
HTTPUnit does not use HttpURLConnection.setInstanceFollowRedirect(), or rather it sets this to false for each connection and handles redirects itself and I think this is related to the problem(com.meterware,httpunit.WebConversation.openConnection).
I've coded a test case outside of HttpUnit that errors in the same fashion when I use HttpURLConnection with redirects set to false. It seems that the HttpURLConnection class can not cope with the headers being returned from the server (Netscape-Enterprise/4.1 in the header). The first response is returned with a 302 code and new location. When I call the second URL, i.e. the redirected location from the first, everything fails.
However, if followRedirects is set to true on the HttpURLConnection object, it works. Unfortunately, this is not possible in HttpUnit unless I change the WebConversation class. If I make this change, HttpUnit works as well.
I'm going to do some more investigation and check alternative JDKs if I can.
In the mean time, is there a reason why HttpUnit does not use the HttpURLConnection.setInstanceFollowRedirects(true) if the ClientProperties object specifies that redirects are to be followed?
Thanks,
Rob
I don't know if this helps, but I did an annotate on WebConversation and it looks like the change to set that to false was made in Mar 19 19:43:46 2003 With the following comment which doesn't make a ton of sense:
"Disable HTTP URL Connection per instance, not globally"
That one line was added and that's it.
When you said
"If I make this change, HttpUnit works as well. ", did you change openConnection() to set redirects to true or did you take the line out completely?
I have a pretty large suite of tests that I can run this change against to see if it breaks anything. If you are interested, I'd be willing to make the change and run it locally to see if it breaks anything.
Christian,
I made the change to WebConversation.openConnection(URL url) to hardcode the follow redirects to true instead of false. The code seems to disable follow-redirects per-instance, but to every Http connection. I would have thought a better approach would ahve been to set something on HttpUnitOptions or on ClientProperties that changes the underlying behaviour rather than just HTTPUnits internal behaviour
I'm running on JDK 1.4.1 on Windows NT.
I would be very interested in seeing what it breaks by changing this parameter.
Thanks,
Rob