views:

777

answers:

4

I'm losing my mind on this one. My curl command works:

curl http://testuser:testpwd@qabox3:8501/xmlcontroller

But, when I try what looks like an equivalent http connection in Java it gives "connection refused". What am I missing? I've tried a dozen flavors of trying to make this connection today and am out of ideas.

        URL url = new URL( "http://qabox3:8051/xmlcontroller" );
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setRequestMethod( "GET" );
        String encoding = new sun.misc.BASE64Encoder().encode( "testuser:testpwd".getBytes() );
        conn.setRequestProperty("Authorization", "Basic " + encoding );
        InputStream content = conn.getInputStream();  // <--- fails here every time.
        BufferedReader in = new BufferedReader( new InputStreamReader( content ) );
        String line;
        while ((line = in.readLine()) != null) {
            System.out.println( line );
        }

Moreover, I can use Java's Runtime.exec() to exec the curl command and that still works...so I'm clearly doing something wrong in the HttpURLConnection stuff.

Here's the stack I'm seeing (now using HttpClient, but basically same stack with the Java libs).

Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:520)
at java.net.Socket.connect(Socket.java:470)
at java.net.Socket.<init>(Socket.java:367)
at java.net.Socket.<init>(Socket.java:240)
at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:80)
at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:122)
at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at MyClass.sendRequest(iQ411RequestHandlerProxy.java:277)

Just for fun, here's the curl verbose output. Nothing special in the header...

> GET /xmlcontroller HTTP/1.1
> Authorization: Basic cWFfc3VwZXI6cWFfc3VwZXI=
> User-Agent: curl/7.16.3 (i686-pc-cygwin) libcurl/7.16.3 OpenSSL/0.9.8k zlib/1.2.3 libssh2/0.15-CVS
> Host: qabox3:8501
> Accept: */*
>
A: 

Take a look at HttpClient. It supports various authentication schemes without you having to resort to manually encoding / specifying headers.

ChssPly76
The authentication scheme doesn't matter until a connection is established.
erickson
Tried HttpClient, same connection refused. I've tried using the IP address as well rather than letting the name resolve, same result.
Chris Kessel
Can you post a full error / stack trace for HttpClient?
ChssPly76
Perhaps this is some sort of a firewall issue? "Connection refused" means the host is likely resolved correctly (you'd get a "connection timed out" otherwise) but refuses to accept connection on given port. Can you connect to some known outside server (www.google.com) from java?
ChssPly76
I can connect to an outside source and see the results. It's the authentication that's getting me, I'm pretty sure. The name/pwd are correct, straight cut/paste. I've even compared curl's verbose mode to see the Authorization header string and verified it matches what I'm setting in Java.
Chris Kessel
I've ran the test on my local machine against Apache's basic authentication. Your code works, and so does HttpClient. If I don't set the authorization property, I'm getting back the "401" code (which is correct behavior). Does that happen for you too? I still think it's either some sort of connection issue OR perhaps whatever is on the other end does not implement the authentication protocol properly.
ChssPly76
I'm not getting a response code, it's throwing the exception on the underlying socket open. Like I said, I'm truly baffled.
Chris Kessel
Exactly. It's a networking problem, and has nothing to do with authentication. It's not getting far enough along to encounter an authentication problem.
erickson
+5  A: 

Hi chriskes

You seem to use two different port numbers: 8501 and 8051? Could that be the problem or was that a typo in posting the question?

curl http://testuser:testpwd@qabox3:8501/xmlcontroller

URL url = new URL( "http://qabox3:8051/xmlcontroller" );

Regards, Ian

IanGalpin
Oh holy mother of god. I'm going to go f'ing kill myself now. I've been cutting/pasting addresses all day to avoid typos, but apparently mangled that one somewhere.
Chris Kessel
Just goes to show that it never hurts to have a second pair of eyes looking at your code. Good catch Ian.
Gandalf
Mangled in my "golden" copy I've kept off to the side no less of the address that's supposed to work. Which of course didn't match the one in my cygwin window's history buffer I was executing over and over for the curl version...
Chris Kessel
I've done similar things before. Probably why I spotted it before I had read thru' the code. Glad to be of assistance :)
IanGalpin
Thanks, now, if I could only vote down my own post to hide my stupidity from others. Much appreciated, really. It's amazing what new eyes will see. I've been comparing the address/name/password over and over, probably 50 times, but never thought to double check the port.
Chris Kessel
A: 

Could this be an HTTP proxy issue? Could curl be using your HTTP proxy and your Java app be trying to connect directly?

Stephen C
A: 

In your code example you never call conn.connect(). The openConnection() calls creates the URLConnection object but you need to actually call the connect method before interacting with the connection.

Gandalf
getInputStream "commits" the request, opening the socket.
erickson
Hmm, doesn't say that anywhere in the JavaDocs - but I'll take your word for it, thanks.
Gandalf