HttpURLConnection: empty header causing NullPointerException in Notes Java Agent - java

A couple of months ago I wrote a Java Agent that synchs documents in Notes databases with tickets in a Redmine system. The agent opens a Notes document through an HttpURLConnection and it worked perfectly until two weeks ago (no changes to the code or server were made). Now a NullPointerException is thrown when conn.getResponseCode() is called and I can't figure out why, since the URL used for the connection works fine when I copy and paste it into my browser (using the same credentials as the agent does). As you can see in the code block below I also tried printing out the header fields of the connection object, but it returns an empty map, {}.
The stack trace I get looks like the one pasted in this question and I tried all the solutions suggested there, but it didn't solve the problem. Interestingly, when I try to save the document to Redmine, the method creating a new issue there (using the Redmine Java API) also fails because it cannot establish an HTTP connection. Again: this used to work flawlessly before.
I have been trying to fix this for two days now with no success. The agent is allowed to run restricted operations with full administration rights (3) and the databases it accesses are on the same server as the DB containig the agent, and the default access in the ACL is "author". Any ideas what could be causing this issue? Thanks in advance!
String issueBody = "";
Session session = getSession();
Name serverName = session.createName(db.getServer());
URL url = null;
java.net.HttpURLConnection conn = null;
InputStream is;
BufferedReader rd;
String line;
String urlString = "http://"+serverName.getCommon()+":80/"+db.getFilePath()+"/"+VIEW_SPRS_BY_SPRNO+"/" + issue.getUniversalID() + "/Body?OpenField";
urlString = urlString.replace("\\", "/");
String userpass = httpUser + ":" + httpPass;
BASE64Encoder encoder = new BASE64Encoder();
String encodedStr = encoder.encode(userpass.getBytes());
String basicAuth = "Basic " + encodedStr;
try {
url = new URL(urlString);
conn = (java.net.HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
conn.setAllowUserInteraction(false);
conn.setInstanceFollowRedirects(false);
conn.setRequestProperty("Host", url.getHost());
conn.setRequestProperty("Authorization", basicAuth);
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.connect();
System.out.println("Headers: " + conn.getHeaderFields());
int responseCode = conn.getResponseCode();
String responseMessage = conn.getResponseMessage();
System.out.println("response code: " + responseCode + ", response message: " + responseMessage);
if (responseCode >= 400) {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
String errorString = "";
while ((line = rd.readLine()) != null) {
errorString += line;
}
rd.close();
System.out.println("error stream: " + errorString);
} else {
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = rd.readLine()) != null) {
issueBody += line;
}
rd.close();
}
} catch (UnknownHostException e) {
OpenLogItem.logError(session, e, "java.net.UnknownHostException: Can't find specified host: "+urlString, Level.SEVERE, null);
issueBody = issue.getItemValueString("Body");
} catch (MalformedURLException e) {
OpenLogItem.logError(session, e, "java.net.MalformedURLException: Can't connect to invalid URL: "+urlString, Level.SEVERE, null);
issueBody = issue.getItemValueString("Body");
} catch (IOException e) {
OpenLogItem.logError(session, e, "java.io.IOException: Failed to read stream at: "+urlString, Level.SEVERE, null);
issueBody = issue.getItemValueString("Body");
} catch (NullPointerException e) {
OpenLogItem.logError(session, e, "java.lang.NullPointerException. Failed to establish HTTP connection. Header fields: "+conn.getHeaderFields()+" URL: "+urlString, Level.SEVERE, null);
issueBody = issue.getItemValueString("Body");
} catch (Exception e) {
OpenLogItem.logError(session, e, "Unknown error. Failed to establish HTTP connection: "+urlString, Level.SEVERE, null);
issueBody = issue.getItemValueString("Body");
} finally {
conn.disconnect();
}
Here is the stack trace:
java.lang.NullPointerException
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:719)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:646)
at COM.ibm.JEmpower.applet.http.HttpURLConnection.getInputStream(HttpURLConnection.java:411)
at COM.ibm.JEmpower.applet.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:692)
at java.net.URLConnection.getContentType(URLConnection.java:509)
at JavaAgent.saveIssueToRedmine(Unknown Source)
at JavaAgent.pushIssueFromNotesToRedmine(Unknown Source)
at JavaAgent.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)

Related

How to implement HTTP POST method in web proxy through Java

I am trying to make a web proxy for HTTP communication between server and client. The GET method is working fine but I am POST method part is not working. I am sure I have missed out something. I want to know what have I missed or not implemented.
// request from client is handle from here
while ((inputLine = in.readLine()) != null) {
try {
StringTokenizer tok = new StringTokenizer(inputLine);
tok.nextToken();
} catch (Exception e) {
break;
}
if (cnt == 0) {
System.out.println("inputLine "+inputLine);
String[] tokens = inputLine.split(" ");
urlToCall = tokens[1];
//hum inputline sy URL nikaal rahay hai
if(tokens[0]=="POST")
{
f=1;
}
System.out.println("Request for : " + urlToCall);
}
cnt++;
}
BufferedReader rd = null;
try {
//yaha sy hum ab server ko request send karay gy
URL url = new URL(urlToCall);
URLConnection conn = url.openConnection();
HttpURLConnection huc = (HttpURLConnection) conn;
conn.setDoInput(true);
conn.setDoOutput(false);
// now we will get the response from the server
if (f == 1) {
huc.setDoOutput(true);
huc.setInstanceFollowRedirects(false);
huc.setRequestMethod("POST");
huc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
huc.setRequestProperty("charset", "utf-8");
}
InputStream is = null;
if (conn.getContentLength() > 0)
{
try {
is = conn.getInputStream();
rd = new BufferedReader(new InputStreamReader(is));
} catch (IOException ioe) {
System.out.println(
"********* IO EXCEPTION **********: " + ioe);
}
}
What is the error you are getting on the post? And what is a sample GET request that is being passed into your code?
When I use a simple GET request, the code fails because the urlToCall does not have the host or protocol. The below code worked for me, but I would highly suggest you change your code to not hide the exceptions that are being thrown because they will have important information about what is going wrong with your code.
if (cnt == 1) {
System.out.println("host: " + inputLine);
String[] tokens = inputLine.split(" ");
urlToCall = "HTTP://" + tokens[1] + urlToCall;
}

How to fix "Connection Reset" in Eclipse for HTTPS url

I am trying to parse a https url link and getting a connection reset problem in eclipse , however it works in eclipse ( returns 301 response code though )
How to solve this ?
Thanks
try {
String url = "http://api.demo.globalgatewaye4.firstdata.com/transaction/search?start_date=2018-01-07&end_date=2018-01-09";
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setReadTimeout(5000);
conn.addRequestProperty("Authorization", "Basic *****************");
System.out.println("Request URL ... " + url);
boolean redirect = false;
// normally, 3xx is redirect
int status = conn.getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
if (status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER)
redirect = true;
}
System.out.println("Response Code ... " + status);
if (redirect) {
// get redirect url from "location" header field
String newUrl = conn.getHeaderField("Location");
// get the cookie if need, for login
String cookies = conn.getHeaderField("Set-Cookie");
// open the new connnection again
conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn.setRequestProperty("Cookie", cookies);
conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
conn.addRequestProperty("User-Agent", "Mozilla");
conn.addRequestProperty("Referer", "google.com");
System.out.println("Redirect to URL : " + newUrl);
}
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer html = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
html.append(inputLine);
}
in.close();
System.out.println("URL Content... \n" + html.toString());
System.out.println("Done");
} catch (Exception e) {
e.printStackTrace();
}
This returns a HTTP response code "301" which redirects it to a HTTPS url which in turn give s a connection reset error .
How to solve this error in eclipse , or is there a generic way .
Thank you . Found the solution . problem was related to TLS not being available in the java version i was using .
Had to switch to a higher java version .

Unable to set Authorization header of HttpsURLConnection

I'm trying to set the OAuth Authorization header of a HttpsURLConnection object and below is the java code for that
String url1 = "/data/ServiceAccount?schema=1.0&form=json&byBillingAccountId={EQUALS,xyz#pqr.edu}";
String url = "https://secure.api.abc.net/data/ServiceAccount?schema=1.0&byBillingAccountId={EQUALS,xyz#pqr.edu}";
String header = OAuthClient.prepareURLWithOAuthSignature(url1);
HttpsURLConnection con = null;
try {
URL obj = new URL(url);
con = (HttpsURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Authorization", "OAuth " + header);
System.out.println("Request properties = " + con.getRequestProperty("Authorization"));
int responseCode = con.getResponseCode();
System.out.println("Response Code = " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
con.disconnect();
//print result
System.out.println("Response = " + response.toString());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(con!=null) con.disconnect();
}
And below is the code for prepareURLWithOAuthSignature
public String prepareURLWithOAuthSignature(String url)
{
String signature = null;
setOAuthParameters();
setOAuthQParams();
try
{
httpURL = URLEncoder.encode(baseURL+url, "UTF-8");
signature = OAuthSignatureService.getSignature(httpURL, URLEncoder.encode(URLEncodedUtils.format(qparams, "UTF-8"), "UTF-8"), consumer_secret);
OAuthParameters.put("oauth_signature", signature);
} catch (Exception e) {
e.printStackTrace();
}
return getOAuthAuthorizationHeader();
}
public String getOAuthAuthorizationHeader()
{
String OAuthHeader = "oauth_consumer_key=\"" + OAuthParameters.get("oauth_consumer_key") + "\"" +
",oauth_signature_method=\"" + OAuthParameters.get("oauth_signature_method") + "\"" +
",oauth_timestamp=\"" + OAuthParameters.get("oauth_timestamp") + "\"" +
",oauth_nonce=\"" + OAuthParameters.get("oauth_nonce") + "\"" +
",oauth_version=\"" + OAuthParameters.get("oauth_version") + "\"" +
",oauth_signature=\"" + OAuthParameters.get("oauth_signature") + "\"";
byte[] authEncBytes = Base64.encodeBase64(OAuthHeader.getBytes());
String authStringEnc = new String(authEncBytes);
return authStringEnc;
}
The problem is that
1) while I'm printing the con.getRequestProperty("Authorization") I'm getting a null value which means the Authorization header is not set
2) The final response I'm getting from the server is 403
Any idea what's going wrong here?
I know this might not be an answer but looks like this issue was submitted as a bug to sun and here is the relevant part of the reply.
This behavior is intentional in order to prevent a security hole that
getRequestProperty() opened. setRequestProperty("Authorization")
should still work, you just won't be able to proof the results via
getRequestProperty().
For the original forum post, please see: http://www.coderanch.com/t/205485/sockets/java/setRequestProperty-authorization-JDK
I would not be able to advice why you're getting a 403 but try adding the "Content-Type" request header to your connection and see if it makes any difference. Until I added that header in my code, I was getting a 404 back from the Spring Security module.

Java IOException "Unexpected end of file from server" when posting large data

I am trying to post XML data to a server which processes this XML and gives a response back, some times the XML data can be very large and the server takes a while to process it, in those cases i fail to get any response back instead i receive a IOException with the message "Unexpected end of file from server". I am positive the XML being sent to the server is not full of errors, is there anything i can do on my end to make sure this doesn't happen or is this a server side issue? Below is code fragment of the method i call to post the data.
Thanks.
String encodedData="some XML"
String urlString="example.com"
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection;
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", contentType);
urlConnection.setRequestProperty("Content-Length", encodedData.length()+"");
OutputStream os = urlConnection.getOutputStream();
os.write(encodedData.getBytes());
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
StringBuffer sb = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
in.close();
} catch (MalformedURLException e) {
logger.debug("MalformedURLException " + e.getMessage());
logger.debug((new StringBuilder()).append("urlString=").append(urlString).toString());
throw (e);
} catch (IOException e) {
logger.debug("IOException " + e.getMessage());
logger.debug((new StringBuilder()).append("urlString=").append(urlString).toString());
throw (e);
}
return sb.toString();
Not much could be done from the client side, it's just a server side issue in which the server takes very long to process the data which results in the servers connection to timeout before it could send a response.

HttpURLConnection error: java.net.SocketTimeoutException: Connection timed out

I am using simple urlconnection like this:
url = URL+"getClient&uid="+cl_id;
URL url = new URL(this.url);
Log.d("Set++","get_t URL: "+ url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
its working fine, but sometimes i get this error:
error: java.net.SocketTimeoutException: Connection timed out
what could be the reason? I have only 4 clients... so i dont think that the server is overloaded with connections.
the code:
try {
URL = Settings.BASE_URL + "_interface.php?" +
"key=" + Settings.KEY +"&app_naam="+Settings.APP_NAAM+ "&action=check&setTime="+c;
URL url = new URL(URL);
if(D)Log.e("ChekTreadAanvr+url", URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
BufferedReader rd = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String response;
if ((response = rd.readLine()) != null) {
rd.close();
}
if(D) Log.d("WebSaveThread+","DATARESIEVED: "+response);
return response;
} catch (MalformedURLException e) {
if(D)Log.d("ERR","server chekc failure ++ ");
return success = false;
} catch (IOException ioex) {
if(D)Log.e("ERR", "error: " + ioex.getMessage(), ioex);
success = false;
}
return Boolean.toString(success);
It may be possible that your Internet Connection Speed is weak. You can increase your Timeout Interval by using following method.
httpURLConnection.setConnectTimeout( 6 * 10 * 1000 ); // One Minute
If you are connecting to a particularly slow server, there are two timeouts that you can set: setConnectTimeout() and setReadTimeout(). The names are fairly self explanatory. For example:
httpURLConnection.setConnectTimeout(60*1000);
httpURLConnection.setReadTimeout(60*1000);

Categories