Java http call returning response code: 501 - java

I am having an issue with this error:
**Server returned HTTP response code: 501 for URL: http://dev1:8080/data/xml/01423_01.xml**
See this code:
private static Map sendRequest(String hostName, String serviceName) throws Exception {
Map assets = null;
HttpURLConnection connection = null;
Authenticator.setDefault(new Authenticator());
URL serviceURL = new URL(hostName + "/" + serviceName);
connection = (HttpURLConnection)serviceURL.openConnection();
connection.setRequestMethod("GET");
ClientHttpRequest postRequest = new ClientHttpRequest(connection);
InputStream input = null;
/*
At line input = postRequest.post(); I get the following error
Server returned HTTP response code: 501 for URL: http://dev1:8080/data/xml/01423_01.xml
Yet if I enter that url in my browser it opens up fine.
Is this a common problem? Is there some type of content type I need to set?
*/
input = postRequest.post();
connection.disconnect();
return assets;
}

A 501 response means "not implemented", and is usually taken to mean that the server didn't understand the HTTP method that you used (e.g. get, post, etc).
I don't recognise ClientHttpRequest , but you have a line that says
connection.setRequestMethod("GET");
and then a line that says
input = postRequest.post();
I'm not sure what post() actually does, but does that mean send a POST request? If so, then that contradicts the GET specified in the first line.
Either way, the server is saying that it doesn't under the GET or the POST method, whichever one your code is actually sending. You need to find out what method the server does support for that URL, and use that.

Perhaps you should check your port settings:
new URL(hostName + "/" + serviceName);
Looks like the port number ":8080" is missing.
Some server expect additional information from the client in the request like a user agent or some form data. Even cookies could be expected by the application running on the server. You should also check the complete response and not only the response code.
I would recommend you to use a library like httpclient that is more convenient:
https://hc.apache.org/httpcomponents-client-ga/index.html
Here is simple usage example:
https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java

Related

Dealing with Java CookieManager "Invalid cookie" errors

I have defined a CookieStore as follows:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager );
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
Whenever I complete a request using HttpURLConnection:
URL url = new URL(MY_URL);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
I get this in my output:
java.net.CookieManager put SEVERE: Invalid cookie for https://...: ; HttpOnly
How should I deal with this message?
You need to first identify what kind of exception is being thrown. From looking at the documentation for CookieManger: http://www.docjar.com/html/api/java/net/CookieManager.java.html
283 try {
284 cookies = HttpCookie.parse(headerValue);
285 } catch (IllegalArgumentException e) {
286 // Bogus header, make an empty list and log the error
287 cookies = java.util.Collections.EMPTY_LIST;
288 if (logger.isLoggable(PlatformLogger.SEVERE)) {
289 logger.severe("Invalid cookie for " + uri + ": " + headerValue);
290 }
291 }
It seems that the issue is that your headers for your request is incorrect. Might want to look into that and here is a link of example code.
http://www.programcreek.com/java-api-examples/index.php?api=java.net.CookieManager
Also you probably want to use the chrome debugger to see the actual request being sent out and usually it will give you more information on why the request failed. The request could be incorrect, the url you are trying to send it to could be invalid, the service that your sending the request to might expect certain parameters.
From the code, it seems to look for the headers in the response. However, the response itself either contains no headers or there is something wrong with it and as a result HttpCookie.parse will throw a error.
If you look at HttpCookies.parse it throws an exception if:
Throws:
IllegalArgumentException - if header string violates the cookie specification's syntax, or the cookie name contains llegal characters, or the cookie name is one of the tokens reserved for use by the cookie protocol
NullPointerException - if the header string is null
So you need to look at the response and see if the data they put in the header is correct.

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)

Unable to connect to omniture rest API 1.4

We are trying to connect to omniture rest API 1.4 using Java for report.Get. We are unable to create connection. The user id and password are working fine on UI but while making HTTP connection we are getting 400 bad request. Same code works fine with rest API 1.3 for company.reportSuites method. Code if failing while creating input stream. We did checked HTTP response code for connection at it is also coming 400.
public class OMTR_REST {
private static String USERNAME = "XXXXXXX";
private static String PASSWORD = "xXXXXXXXX";
private static String ENDPOINT = "https://api.omniture.com/admin/1.4/rest/"; //san jose endpoint, change for your company's datacenter
private OMTR_REST() {}
public static String callMethod(String method, String data) throws IOException {
URL url = new URL(ENDPOINT + "?method=" + method);
URLConnection connection = url.openConnection();
connection.addRequestProperty("X-WSSE", getHeader());
connection.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
wr.write(data);
wr.flush();
InputStream in = connection.getInputStream();
BufferedReader res = new BufferedReader(new InputStreamReader(in, "UTF-8"));
StringBuffer sBuffer = new StringBuffer();
String inputLine;
while ((inputLine = res.readLine()) != null)
sBuffer.append(inputLine);
res.close();
return sBuffer.toString();
There was a change in the API from version 1.3 to 1.4. The Get method now returns a status of 400 if the report in not ready. To me, it was a bad choice to return a HTTP 400 error (Bad request) when the report in not ready but that is what they are doing. See page 13 in the document below.
https://github.com/AdobeDocs/analytics-1.4-apis
I see few mistakes in your sample:
you should not use api.omniture.com for every request. First request should call api.omniture.com using Company.GetEndpoint method in order to get the correct endpoint, then use it for next requests.
when a wrong endpoint is used you could receive an HTTP 301 response. I'm not sure your implementation handle this case.
when you receive a HTTP 400 error (bad request). Well, that's exactly what has happened, in your example you're JSON writing directly into the body and many things could go wrong. Wrong type for a value, wrong upper/lower case for a key. Using a JAX-RS or another REST client should make your life simpler.
I have built a working Omniture REST API sample with JAX-RS where the model is clear easy to debug/modify.
Update
Recently I have found this:
https://github.com/Adobe-Marketing-Cloud/analytics-java-library

Getting error 502/504 when trying to get InputStream

URL queryUrl = new URL(url);
InputStream inputStream = null;
HttpsURLConnection connection = (HttpsURLConnection) queryUrl.openConnection();
connection.setRequestProperty("User-Agent", "My Client");
connection.setRequestMethod("GET");
connection.setDoInput(true);
inputStream = connection.getInputStream();
Hi,
I'm using the above code to perform an HttpGet query.
I'm getting once in a few tries an exception that server returned error code 502 or 504 (both scenarios occur).
The exception is thrown in the line :
inputStream = connection.getInputStream()
Any ideas?
Your help would be appreciated.
Thanks in advance
The error code in 5xx indicates some issue with Server or proxy. Rfc Statement
Response status codes beginning with the digit "5" indicate cases in which the server is
aware that it has erred or is incapable of performing the request. Except when responding
to a HEAD request, the server SHOULD include an entity containing an explanation of the
error situation, and whether it is a temporary or permanent condition. User agents SHOULD
display any included entity to the user. These response codes are applicable to any request method.
Please check what is the actual error by reading the error steam of url connection as below:
If the HTTP response code is 4nn (Client Error) or 5nn (Server Error), then you may want to read the HttpURLConnection#getErrorStream() to see if the server has sent any useful error information.
InputStream error = ((HttpURLConnection) connection).getErrorStream();
Also I think for working with http requests, you can use Apache HttpClient instead of directly working with HttpUrlConnection. Using HttpClient is lot more easier.

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.

Categories

Resources