Java 1.4.2 IOException in getOutputStream() on AS400 - java

I'm working under a AS400 system using Java 1.4.2, to get an XML but when I do the request using getOutputStream() I got an IOException and the message only returns the domain of the provider.
Here a part of my code:
try {
url = new URL("https://test.example.it/27/xml/"); //Example URL...
} catch(MalformedURLException exMAL) {
return exMAL.getMessage();
}
//Set parameters
LinkedHashMap params = new LinkedHashMap();
params.put("id", id);
params.put("password", password);
...
params.put("description", description);
String data = "";
Set set = params.entrySet();
Iterator i = set.iterator();
//Create URL of parameters
while(i.hasNext()){
if(data != ""){
data += "&";
}
Map.Entry me = (Map.Entry)i.next();
data += me.getKey() + "=" + me.getValue();
}
try {
//Create connection
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
//Do request
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); //Error here
wr.write(data);
wr.flush();
//Get resource
InputStream is = conn.getInputStream();
outputData = readAll(is);
} catch (IOException ioEx) {
return "ERROR IOException: " + ioEx.getMessage();
}
And the message error is "ERROR IOException: test.example.it".
I tested my code in a computer with Windows XP, Netbeans 4.1, Java 1.4.2 Build 19 (the same in the AS400) and I get the XML without problems.
I can compile my code into the AS400 but when I run the class in QSHELL or using a RPG Program i get the error.
Somebody knows what else I have to do or why I get this error?
Thanks!
EDIT:
Its a POST method, and actually I included setDoInput and setDoOutput in the code.
Now printing the exception I get this:
java.net.UnknownHostException: test.example.it
ERROR IOException: test.example.it
EDIT:
Looks like nslookup doesn't resolve the domain but after that I retry using the IP and now I have this error...
java.net.SocketException: The value specified for the argument is not correct.
ERROR IOException: The value specified for the argument is not correct.
I think it would be a problem with AS400 security, probably should I add this domain in a list or edit a system value?
EDIT:
Using TCPCFG and then option 10, in this table of hosts I don't have the domain test.example.it, I suppose that I need to add this domain and IP, isn't it?
EDIT:
The version is V6R1M0. I added the IPs (Option 10. Work with TCP/IP host table entries) and now the AS400 resolve the domain but now I have a new problem.
java.net.ConnectException: A remote host refused an attempted connect operation.
In the option 12 I have *SAME in all the options. For option 1 the following:
Internet Subnet Line Line Opt Address Mask Description Type
127.0.0.1 255.0.0.0 *LOOPBACK *NONE
151.208.xxx.xx 255.255.255.0 ETHLINE *ELAN
I found in a group this: "Is the 8080 port on the 400. Is the 400 setup to accept 8080 traffic via SSL".
How can I able the 400 to accept traffic?

Finally I resolve my problem, adding the IP and Domain in the host table (as I mentioned in a edit) but here is another problem.
The provider gave me one IP for requests and two more IPs for responses, an I added the three IPs with the same domain in the host table. I deleted two of three IPs and then I tried using only the IP for request and it worked!
Now the problem is that the request via Java is too slow! but that's another topic. Thank you very much for all.

Related

How can I read a text file from the internet with Java?

I want to read the second line of the text at this URL: "http://vuln2014.picoctf.com:51818/" (this is a capture-the-flag competition but only asking for flags or direction to flags breaks the competition rules). I am attempting to open an input stream from the URL but I get an Invalid HTTP Response exception. Any help is appreciated, and I recognize that my error is likely quite foolish.
Code:
URL url = new URL("http://vuln2014.picoctf.com:51818");
URLConnection con = url.openConnection();
InputStream is = con.getInputStream()
The error occurs at the third line.
java.io.IOException: Invalid Http response at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1342) at name.main(name.java:41)
curl happily gets the text from the page, and it is perfectly accessible from a web browser.
When you do this:
URL url = new URL("http://vuln2014.picoctf.com:51818");
URLConnection con = url.openConnection();
You are entering into a contract that says that this URL uses the http protocol. When you call openConnection it expects to get http responses because you used http:// in the URL as the protocol. The Java Documentation says:
If for the URL's protocol (such as HTTP or JAR), there exists a public, specialized URLConnection subclass belonging to one of the following packages or one of their subpackages: java.lang, java.io, java.util, java.net, the connection returned will be of that subclass. For example, for HTTP an HttpURLConnection will be returned, and for JAR a JarURLConnection will be returned.
The server you are connecting to just returns a couple lines of data. I retrieved them with the command nc vuln2014.picoctf.com 51818. There is no http response code like HTTP/1.1 200 OK:
Welcome to the Daedalus Corp Spies RSA Key Generation Service. The public modulus you should use to send your updates is below. Remember to use exponent 65537.
b4ab920c4772c5247e7d89ec7570af7295f92e3b584fc1a1a5624d19ca07cd72ab4ab9c8ec58a63c09f382aa319fa5a714a46ffafcb6529026bbc058fc49fb1c29ae9f414db4aa609a5cab6ff5c7b4c4cfc7c18844f048e3899934999510b2fe25fcf8c572514dd2e14c6e19c4668d9ad82fe647cf9e700dcf6dc23496be30bb
In this case I would use java.net.Socket to establish a connection and then read the lines. This is a simplistic approach that assumes there are 2 lines of data:
Socket theSocket;
try {
theSocket = new Socket("vuln2014.picoctf.com", 51818);
BufferedReader inFile = new BufferedReader(new InputStreamReader(theSocket.getInputStream()));
String strGreet = inFile.readLine();
String strData = inFile.readLine();
} catch (IOException e) {
e.printStackTrace();
}
As for why curl and browsers may render it properly? They are likely more lenient about the data they read and will just dump what is read from the port even if it doesn't conform to the specified protocol (like http)

Read session variable using HttpURLConnection

I am trying to log in to a website using an HttpURLConnection.
If the login is successful, the server sets user_id variable in the current session.
Using SO and the Google developer docs on the matter I have been able to POST my credentials to the server, but how do I get the user_id from the session now?
For reference here is my code:
String body = "user=chris&password=geheim";
HttpURLConnection conn = (HttpURLConnection) new URL(LOGIN_URL).openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setInstanceFollowRedirects(false);
conn.connect();
OutputStream out = conn.getOutputStream();
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
out.write(body.getBytes());
int response = conn.getResponseCode();
String s = "";
for (int c = in.read(); c != -1; c = in.read()) {
s += (char) c;
}
System.out.println(response);
System.out.println(s);
System.out.println(conn.getHeaderFields());
Note: to make it easier to read I've left out all exception handling and resource management. Also this is just trial code connecting to my localhost, so no worries about the hardcoded credentials and other insecurities.
Update
Okay, apparently my body is not getting submitted after all. When I do a console.log(util.inspect(req.body)) in my server code, it prints {}. I double-checked the request method and that is POST. What am I doing wrong?
Rewrote the code, and even though I think I did the exact same thing as before it's working now. Weird, but whatever.
The session where the user_id is stored, is kept on the server. All the client usually gets is a session-id in a session cookie (e.g. JSESSIONID) that is passed back to the server so the server can find the correct session and data again.
That's why you also can put large amounts of data into a user's session ... imagine all of that was actually passed to the client!
You can't, unless there is a co-operative active page in the server that will give it to you.

Getting "java.net.ProtocolException: Server redirected too many times" Error

I'm making a simple URL request with code like this:
URL url = new URL(webpage);
URLConnection urlConnection = url.openConnection();
InputStream is = urlConnection.getInputStream();
But on that last line, I'm getting the "redirected too many times error". If my "webpage" var is, say, google.com then it works fine, but when I try to use my servlet's URL then it fails. It seems I can adjust the number of times it follows the redirects (default is 20) with this:
System.setProperty("http.maxRedirects", "100");
But when I crank it up to, say, 100 it definitely takes longer to throw the error so I know it is trying. However, the URL to my servlet works fine in (any) browser and using the "persist" option in firebug it seems to only be redirecting once.
A bit more info on my servlet ... it is running in tomcat and fronted by apache using 'mod-proxy-ajp'. Also of note, it is using form authentication so any URL you enter should redirect you to the login page. As I said, this works correctly in all browsers, but for some reason the redirect isn't working with the URLConnection in Java 6.
Thanks for reading ... ideas?
It's apparently redirecting in an infinite loop because you don't maintain the user session. The session is usually backed by a cookie. You need to create a CookieManager before you use URLConnection.
// First set the default cookie manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
// All the following subsequent URLConnections will use the same cookie manager.
URLConnection connection = new URL(url).openConnection();
// ...
connection = new URL(url).openConnection();
// ...
connection = new URL(url).openConnection();
// ...
See also:
Using java.net.URLConnection to fire and handle HTTP requests
Duse, I have add this lines:
java.net.CookieManager cm = new java.net.CookieManager();
java.net.CookieHandler.setDefault(cm);
See this example:
java.net.CookieManager cm = new java.net.CookieManager();
java.net.CookieHandler.setDefault(cm);
String buf="";
dk = new DAKABrowser(input.getText());
try {
URL url = new URL(dk.toURL(input.getText()));
DataInputStream dis = new DataInputStream(url.openStream());
String inputLine;
while ((inputLine = dis.readLine()) != null) {
buf+=inputLine;
output.append(inputLine+"\n");
}
dis.close();
}
catch (MalformedURLException me) {
System.out.println("MalformedURLException: " + me);
}
catch (IOException ioe) {
System.out.println("IOException: " + ioe);
}
titulo.setText(dk.getTitle(buf));
I was using Jenkins on Tomcat6 on a unix environment and got this bug. For some reason, upgrading to Java7 solved it. I'd be interested to know exactly why that fixed it.
I had faced the same problem and it took considerable amount of time to understand the problem.
So to summarize the problem was in mismatch of headers.
Consider below being my Resource
#GET
#Path("booksMasterData")
#Produces(Array(core.MediaType.APPLICATION_JSON))
def booksMasterData(#QueryParam("stockStatus") stockStatus : String): Response = {
// some logic here to get the books and send it back
}
And here is client code, which was trying to connect to my above resource
ClientResponse clientResponse = restClient.resource("http://localhost:8080/booksService").path("rest").path("catalogue").path("booksMasterData").accept("application/boks-master-data+json").get(ClientResponse.class);
And the error was coming on exactly above line.
What was the problem?
My Resource was using
"application/json"
in
#Produces annotation
and my client was using
accept("application/boks-master-data+json")
and this was the problem.
It took me long to find out this as the error was no where related. Break through was when I tried to access my resource in postman with
Accept-> "application/json" header
it worked fine, however with
Accept-> "application/boks-master-data+json" header
it doesnt.
And again, even Postman was not giving me proper error. The error was too generic. Please see the below image for reference.

set proxy in java

I create a service that post something through the internet and everything's fine. But when I deploy it to our server I get connection status:403, forbidden. I think it is because our server won't allow direct access to the internet without login first. We have to login first in the browser with our username/password to access the internet.
I notice that if I have login and access the internet in the server, the service I deploy run alright. But I don't think it's practical because in that case my service won't run if someone or I don't login first.
I have tried setting the proxy in the java code but to no avail. Could someone help me with this problem? Here is I post my service snippet.
System.getProperties().put("http.proxySet", "true");
System.getProperties().put("http.proxyHost", myHost);
System.getProperties().put("http.proxyPort", "8080");
System.getProperties().put("http.proxyUser", myUser);
System.getProperties().put("http.proxyPassword", myPassword);
System.getProperties().put("http.nonProxyHosts", "localhost|127.0.0.1");
try {
URL url = new URL(urlAddress);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput(true);
...
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
System.out.println("connection OK");
istrm = con.getInputStream();
if (istrm == null) {
System.out.println("istrm == null");
}
...
} else {
System.out.println("Response: " + con.getResponseCode() + ", " + con.getResponseMessage());
}
}
And my process goes to else block and gets response message 403
Try using System.setProperty(String, String) instead.
This is how you set application-wide proxies..
System.setProperty("https.proxyHost", "myproxy.domain.com");
System.setProperty("https.proxyPort", "myport");
NOTE: use http.proxyHost and http.proxyPort if you don't require https.
I think that the problem is that you are setting the properties too late. The HTTP request router code is likely to read those properties once during its initialization. If your code sets the properties after the HTTP request router has initialized, the new property values will have no effect ... unless you can cause the request router to reinitialize.
One way to guarantee that your proxy property settings will take effect is to set them on the java command line that launches the web server; e.g. with Tomcat on Linux, you can do this by setting the relevant "-D..." options in the JAVA_OPTS environment variable.
If you are using a proxy on your system... (I mean on your operating system)
you can use this line of code:
System.setProperty("java.net.useSystemProxies", "true");

Connect to a site using proxy code in java

I want to connect to as site through proxy in java. This is the code which I have written:
public class ConnectThroughProxy
{
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy ip", 8080));
public static void main(String[] args)
{
try
{
URL url = new URL("http://www.rgagnon.com/javadetails/java-0085.html");
URLConnection connection=url.openConnection();
String encoded = new String(Base64.encode(new String("user_name:pass_word").getBytes()));
connection.setDoOutput(true);
connection.setRequestProperty("Proxy-Authorization","Basic "+encoded);
String page="";
String line;
StringBuffer tmp = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line=in.readLine()) != null)
{
page.concat(line + "\n");
}
System.out.println(page);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
While trying to run this code it throws the following error:
java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic dXNlcl9uYW1lOnBhc3Nfd29yZA==
at sun.net.www.protocol.http.HttpURLConnection.checkMessageHeader(HttpURLConnection.java:323)
at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(HttpURLConnection.java:2054)
at test.ConnectThroughProxy.main(ConnectThroughProxy.java:30)
Any Idea how to do it?
If you're just trying to make HTTP requests through an HTTP proxy server, you shouldn't need to go to this much effort. There's a writeup here: http://java.sun.com/javase/6/docs/technotes/guides/net/proxies.html
But it basically boils down to just setting the http.proxyHost and http.proxyPort environment properties, either on the command line, or in code:
// Set the http proxy to webcache.mydomain.com:8080
System.setProperty("http.proxyHost", "webcache.mydomain.com");
System.setProperty("http.proxyPort", "8080");
// Next connection will be through proxy.
URL url = new URL("http://java.sun.com/");
InputStream in = url.openStream();
// Now, let's 'unset' the proxy.
System.clearProperty("http.proxyHost");
// From now on HTTP connections will be done directly.
It seems to me, that you are not using your Proxy instance at all. I think you should pass it when you are creating URLConnection instance:
URLConnection connection=url.openConnection(proxy);
Setting of environment properties http.proxy is easier and when using some 3rd party libraries without Proxy instance passing support only possible solution, but its drawback is that it is set globally for the whole process.
I was using the Google Data APIs and the only way I got the proxy settings to work was to provide ALL the parameters related to proxy, even thought they are set to be empty:
/usr/java/jdk1.7.0_04/bin/java -Dhttp.proxyHost=10.128.128.13
-Dhttp.proxyPassword -Dhttp.proxyPort=80 -Dhttp.proxyUserName
-Dhttps.proxyHost=10.128.128.13 -Dhttps.proxyPassword -Dhttps.proxyPort=80
-Dhttps.proxyUserName com.stackoverflow.Runner
Where, username and password are NOT required, and the same http and https servers are set to be the same, as well as the port number (if that's your case as well). Note that the same HTTP proxy is also provided as the HTTPS server, as well as its port number (reference from https://code.google.com/p/syncnotes2google/issues/detail?id=2#c16).
If your Java class has an instance of the class "URL", it should pick those configurations up...

Categories

Resources