javax.microedition.pki Certificate Failed Verification - java-me

I'm trying to read in a JSON reply from the Google Sheets API in a Java ME MIDP application. I've tried the following with other addresses and it receives their content fine but the actual API I want to use is Sheets and it always returns an "Certificate Failed Verification" exception.
HttpConnection c = null;
InputStream is = null;
StringBuffer str = new StringBuffer();
try
{
c = (HttpsConnection)Connector.open(urlstring);
c.setRequestMethod(HttpConnection.GET);
c.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
c.setRequestProperty("User-Agent","Profile/MIDP-2.1 Configuration/CLDC-1.1");
is = c.openInputStream();
int len = (int)c.getLength();
int ch;
while ( (ch = is.read() ) != -1)
{
str.append((char)ch);
}
}
catch( Exception e ){ alert( ""+e ); }
return str.toString();
Connector.open() implicitly returns a HttpsConnection if the URL starts with Https so it should still work.
An example of a HTTPS request
https://jsonplaceholder.typicode.com/posts/1
Which won't work but the above also allows for HTTP connections
http://jsonplaceholder.typicode.com/posts/1
Which will work.
Google Sheets however requires HTTPS and thus is not obtainable via the above code. How can I make a GET request over HTTPS to the sheets API? Thank you.

I had a similar problem when implementing an online highscore system for one of our games. It would fetch highscores fine on some phones but didn't work on other phones. The explanation:
Some phones have their own built-in "MIME-type checker". When you call (HttpConnection)Connector.open(urlstring) the phone expects a text/html response. When it instead gets a application/json (or other) response, the phone gives its own "Not found" error.
Not sure if your problem is related, but worth a try? See if you can add a mime-type "application/json" in the request header of the HttpConnection.

From what I've gathered it seems that when connecting over HTTPS the phone uses an older version of SSL or TLS which has since been deprecated causing some API's to not respond.
I found that if you make an API request over HTTPs with the Opera Mini web browser it works. Giving you the desired response but on closer inspection it seems Opera gets the response for you and gives it back via a different URL. In attempt to furnish these older devices that cannot use a newer version of SSL/TLS to make the secure connection themselves.

Related

Blue Prism web api service - Cannot send a content-body with this verb-type

I'm having some trouble getting a GET Action with body to work in BluePrism (using web api service).
It seems that when I try to include an Action that sends a GET with body when I reach that stage this error gets thrown:
Internal : Unexpected error Cannot send a content-body with this verb-type.
What I've tried:
Using a different verb-type / passing parameters in the query instead of the body, unfortunately i don't have control over the endpoint i'm trying to reach so this didnt work as it only accepts a GET containing data in the body
Using BluePrism HTTP Utility to send the call, this has the same problem as the Web API Service
Compiling the body via code instead of using a template
I haven't been able to find anyone that made it work in BluePrism and there doesn't seem to be much documentation on this issue in BluePrism so any help would be appreciated.
Thanks!
.NET's WebRequest class that Blue Prism uses under the hood to conduct
these requests will not allow you to send a request body with any GET
request. There is no (documented) way to overcome this limitation.
While other related answers on Stack
Overflow correctly state
that there exists no such prohibition on including request bodies with
GET requests per RFC
9110ยง9.3.1, it is
very unusual for a production-grade service to require that the request
itself include anything in the request body. It's also possible that
intermediaries like HTTP proxies may strip or otherwise mangle the request
body in transit anyway.
There is no out-of-the-box way to force the .NET Framework (which Blue
Prism uses) to send GET requests with a request body. If you're able,
you can install
WinHttpHandler
and implement it as a drop-in replacement for HTTPRequest (this SO
thread will help).
Because this type of solution requires the install of a new library, it's
important to consider the caveats of doing so:
Blue Prism's support for external DLLs is unstable at best, and there's
no guarantee it will even import correctly to begin with. Vendor support
for this type of setup is, anecdotally, limited to nonexistent (and
rightfully so, IMO).
If you're able to successfully implement the functionality described
with WinHttpHandler, you'll need to install it on every Blue Prism
developer's machine and runtime resource in all your environments
(development/SIT/UAT/production). For some organizations, strict IT
security posture makes this rather impractical or outright infeasible.
I managed to get it working using a code block containing C# code and using Reflection, here is a my GET method:
public string GetWithBodyAndAuth(string uri, string data, string token, out int statusCode)
{
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Headers.Add("Authorization", "Basic " + token);
request.ContentType = "application/json; charset=utf-8";
request.Method = "GET";
request.Accept = "application/json";
var type = request.GetType();
var currentMethod = type.GetProperty("CurrentMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(request);
var methodType = currentMethod.GetType();
methodType.GetField("ContentBodyNotAllowed", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(currentMethod, false);
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(data);
}
var response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
statusCode = ((int)response.StatusCode);
return reader.ReadToEnd();
}
It's a bit of a hack and can't say if it'll be supported in the future, but for BluePrism 6.9 this allows you to send GET requests containing a body.
It has the advantage of not requiring any external DLLs, this is the import list:

how to call NSE api for historical data free

I am build some sort of finance report and want to fetch data from NSE. for that I am using following api.
Please replace test placeholder with any valid symbol. now when I hit url from browser it works fine and return simple Json.
https://www.nseindia.com/api/quote-equity?symbol={test}
but when I am trying to call it from code then it did not return anything and hanged for forever.
If calling it from postman then it return 401. now the strange thing is
function nse(url){
let oReq = new XMLHttpRequest();
oReq.onreadystatechange = function() {
if (oReq.readyState === 4) {
console.log(oReq.status);
console.log(oReq.responseText);
}
}
oReq.open("GET", url);
oReq.send();
}
nse("https://www.nseindia.com");
I tried calling the base url of nse site as well and still issue is same. as per my understanding its public site and it should provide data for use.
can someone help me on this?
you have to create headers, to show that you are calling from an user-agent like fire-fox or chrome, then you would have to create a session and then call the site. It should work fine then
Check on bellows git repo, it implement on NSE India web api
jugaad-data

ASP.NET MVC5 OWIN rejects long URLs

I am creating an ASP.NET MVC5 action method that implements a password reset endpoint and accepts a click-through from an email message containing a token. My implementation uses OWIN middleware and closely resembles the ASP.NET Identity 2.1 samples application.
As per the samples application, the token is generated by UserManager and embedded into a URL that is sent to the user by email:
var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
var encoded = HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(token));
var uri = new Uri(Url.Link("ResetPasswordRoute", new { id = user.Id, token = encoded }));
The link in the email message targets an MVC endpoint that accepts the token parameter as one of its route segments:
[Route("reset-password/{id}/{token}"]
public async Task<ActionResult> PasswordResetAsync(int id, string token)
{
token = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(token));
// Implementation here
}
However, requests to this endpoint (using a URL generated in the above manner) fail with Bad Request - Invalid URL.
It appears that this failure occurs because the URL is too long. Specifically, if I truncate the token segment, it connects correctly to the MVC endpoint (although, of course, the token parameter is no longer valid). Specifically, the following truncated URL works ...
http://localhost:53717/account/reset-password/5/QVFBQUFOQ01uZDhCRmRFUmpIb0F3RS9DbCtzQkFBQUFzcko5MEJnYWlrR1RydnVoY2ZwNEpnQUFBQUFDQUFBQUFBQVFaZ0FBQUFFQUFDQUFBQUNVeGZZMzd4OTQ3cE03WWxCakIwRTl4NkVSem1Za2ZUc1JxR2pwYnJSbmJ3QUFBQUFPZ0FBQUFBSUFBQ0FBQUFEcEpnVXFXS0dyM2ZPL2dQcWR1K2x6SkgxN25UVjdMYlE2UCtVRG4rcXBjU0FBQUFE
... but it will fail if one additional character is added ...
http://localhost:53717/account/reset-password/5/QVFBQUFOQ01uZDhCRmRFUmpIb0F3RS9DbCtzQkFBQUFzcko5MEJnYWlrR1RydnVoY2ZwNEpnQUFBQUFDQUFBQUFBQVFaZ0FBQUFFQUFDQUFBQUNVeGZZMzd4OTQ3cE03WWxCakIwRTl4NkVSem1Za2ZUc1JxR2pwYnJSbmJ3QUFBQUFPZ0FBQUFBSUFBQ0FBQUFEcEpnVXFXS0dyM2ZPL2dQcWR1K2x6SkgxN25UVjdMYlE2UCtVRG4rcXBjU0FBQUFEf
I believe that the default IIS configuration setting for maxUrlLength should be compatible with what I am trying to do, but I have also tried explicitly setting it to a larger value, which did not solve the problem.
However, using Fiddler to examine the server response, I can see that the working URL generates a server response with the following header ...
Server: Microsoft-IIS/8.0
... whereas the longer URL is rejected with a response containing the following header ...
Server: Microsoft-HTTPAPI/2.0
This seems to imply that the URL is not being being rejected by IIS, but by a middleware component.
So, I am wondering what that component might be and how I might work around its effect.
Any suggestions please?
Many thanks,
Tim
Note: Although my implementation above Base64 encodes the token before using it in the URL, I have also experimented with the simpler approach used in the sample code, which relies on the URL encoding provided by UrlHelper.RouteUrl. Both techniques suffer from the same issue.
You should not be passing such long values in the application path of the URL as they are limited in length to something like 255 characters.
A slightly better alternative is to use a query string parameter instead:
http://localhost:53717/account/reset-password/5?token=QVFBQUFOQ01uZDhCRmRFUmpIb0F3RS9DbCtzQkFBQUFzcko5MEJnYWlrR1RydnVoY2ZwNEpnQUFBQUFDQUFBQUFBQVFaZ0FBQUFFQUFDQUFBQUNVeGZZMzd4OTQ3cE03WWxCakIwRTl4NkVSem1Za2ZUc1JxR2pwYnJSbmJ3QUFBQUFPZ0FBQUFBSUFBQ0FBQUFEcEpnVXFXS0dyM2ZPL2dQcWR1K2x6SkgxN25UVjdMYlE2UCtVRG4rcXBjU0FBQUFEf
That should be safe for at least 2000 characters (full URL) depending on the browser and IIS settings.
A more secure and scalable approach is to pass a token inside an HTTP header.

J2ME-App not connecting with internet in Nokia c1-01

I have made one Application which requires internet connection so that I can display some data in my app.
But when I test my that app in Nokia c1-01 it can't get data from my server and at the same time if I check my app in any other device they are easily connected with internet and I can see my app.
Here is my code:
HttpConnection httpConn = null;
InputStream is = null;
OutputStream os = null;
StringBuffer sb = new StringBuffer();
try {
// Open an HTTP Connection object
httpConn = (HttpConnection) Connector.open(url);
// Setup HTTP Request to POST
httpConn.setRequestMethod(HttpConnection.POST);
httpConn.setRequestProperty("User-Agent",
"Profile/MIDP-2.0 Confirguration/CLDC-1.1");
httpConn.setRequestProperty("Accept_Language", "en-US");
//Content-Type is must to pass parameters in POST Request
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
os = httpConn.openOutputStream();
os.write(params.getBytes());
/**Caution: os.flush() is controversial. It may create unexpected behavior
on certain mobile devices. Try it out for your mobile device **/
//os.flush();
// Read Response from the Server
//StringBuffer sb = new StringBuffer();
is = httpConn.openDataInputStream();
int chr;
while ((chr = is.read()) != -1) {
sb.append((char) chr);
}
} finally {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
if (httpConn != null) {
httpConn.close();
}
}
What I have to change in my code so that it can run on my Nokia C1-01?
Two things comes to mind.
The first one is trivial, and has to do with Internet settings on the phone. I don't know the Nokia C1 specifically, but I know that many devices have an Internet setting for the device + another Internet setting for Java. Make sure that the Internet setting for Java is correct. Just because you can use the browser on the phone, doesn't mean that Internet connection works for Java MIDlets.
The second thing you can look into, has to do with the Content-Type property.
I had this issue when I was developing a game that retrived and sent highscores to my webserver, via PHP on the server. I found it rather weird that it worked fine on most our test-phones, while a few had issues.
Outputting the data the phone received back revealed a 404 reply (or something similar, it's been a while).
After consulting another JavaME developer, I learned this:
Some devices send specific instructions to the webserver: "Hello. Gimme some data of type text/plain from data.php please".
If data.php contains a header('Content-type: text/plain'), then all is fine. If not, then the server replies: "Sorry mate, I don't have any text/plain stuff at that address".
This only happens on some devices, because only some devices send that specific a request.
So, whatever Content-Type you define in your setRequestProperty() in the JavaME part, must be the same in your server-side script.
Hope one of those two things helps. :-)

getHeaderField("WWW-Authenticate") giving improper value in J2ME

I'm building a client for an api that uses http digest access authentication for authentication. I have studied the rfc to know the setup the required response headers and this works well on my emulator. Problem however is when I test on my phone (nokia E5), I found out that getting the www-authenticate header from the returned headers doesnt get the full value
[code]
// c = (HttpConnection) Connector.open(url) and other declarations
String digest = c.getHeaderField("WWW-Authenticate");
System.out.println(digest); // gives only: Digest
//no realm, qop and others
[/code]
I'm I doing something wrong or it is from the phone? What are my other options?
I have faced this problem in some nokias, and yes, it is a bogus HttpConnection implementation ... I suggest you to try creating a new header from the server side with a base64 encoded WWW-Authenticate-encoded header and using it instead, or you can do it the hard way and implement the whole HttpConnection from scratch ...

Resources