I have been trying to implement the retrieval of a company logo using Clearbits.Logo.
url = new URL(Constants.URL_PREFIX_LOGO + shop.getDomainName());
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoOutput(true);
httpURLConnection.connect();
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
//Download picture from URL
..
}
However, for a reason I simply cannot understand, connect() always returns a 403 error with no further explanations.
The device is connected to the internet and has a permission to access it, the URL is exact, and the most bizarre of all, the URL can be accessed through the device browser without any error.
The URL doesn't require any authentification
https://logo.clearbit.com/carrefour.eu?size=600
I can't find the reason why this 403 keeps occuring ..
has anyone an idea ?
Related
Im experiencing a strange behaviour when using HttpURLConnection getInputStream() on a different devices. On all devices except "Alcatel" im getting a valid input stream only for Alcatel devices im getting a different(empty) kind of input stream:
All devices except alcatel
Alcatel devices
Im making the exact same call and getting 200 for all the devices.
The code is pretty straightforward:
urlObj = new URL(url);
urlConnection = (HttpURLConnection)urlObj.openConnection();
urlConnection.setRequestMethod(method);
urlConnection.setDoInput(true);
urlConnection.setConnectTimeout(timeout);
urlConnection.setReadTimeout(timeout);
urlConnection.setDoOutput(true);
urlConnection.setFixedLengthStreamingMode(body.length);
urlConnection.setRequestProperty(HEADER_KEY_CONTENT_LENGTH, String.valueOf(body.length));
urlConnection.getOutputStream().write(body);
int responseCode = urlConnection.getResponseCode();
InputStream in = urlConnection.getInputStream();
Any suggestions?
Please check if you need to have proxy setting for alcatel. httpurlconnection may fail without proper proxy gateway.
Why is the following code
URL url = new URL(urlStr);
Log.d(TAG, "Opening URL " + url.toString());
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.connect();
String response = streamToString(urlConnection.getInputStream());
always giving me the following Exception at urlConnection.getInputStream()?
W/System.err(16253): java.io.FileNotFoundException: https://api.instagram.com/v1/media/search/access_token=1559619173.3c922fe.4fd71e26225a42a0a03fdd90ef8679a6?lat=48.858318956&lng=2.294427258&distance=500
W/System.err(16253): at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
W/System.err(16253): at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
W/System.err(16253): at br.com.dina.oauth.instagram.InstagramApp$5.run(InstagramApp.java:192)
You should remove urlConnection.setDoOutput(true); line because setDoOutput method force POST but instagram api work GET method.
You can also check this issue.
https://github.com/thiagolocatelli/android-instagram-oauth/issues/2
The code throwing the exception can be found for example in the okhttp github (Android uses that internally). The lines responsible are:
if (getResponseCode() >= HTTP_BAD_REQUEST) {
throw new FileNotFoundException(url.toString());
}
That simply means that the url you've provided did not result in a successful response. Throwing a *File*NotFoundException is behavior okhttp just copies from other implementations. Why someone chose this particular exception is beyond me.
If you simply put the url in the error message into a browser you'll see that you get a "Not found" page.
Explanation is simple: You're building the URL wrong. Instead of
search/access_token=...?lat=...
it needs to be
search?access_token=...&lat=...
access_token is a url parameter, not part of the path so it needs to get the ? as separator while lat becomes the second parameter which means ? needs to turn into &.
i'm trying to get the source code from a site using this code
conn = (HttpURLConnection)url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(20000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.addRequestProperty("User-Agent", "Mozilla/5.0");
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
int response = conn.getResponseCode();
if (response = 307){
String locationHeader = conn.getHeaderField("Location");
URL redirectURL = new URL(locationHeader);
...
}
when the server responds with a 307 code i create a new connection with the same parameters as above with the new url given by the server.
this code works fine while following the first 2 redirects, at the third the server gives a relative url that forces a MalformedURLException when my code executes ' new URL(locationHeader); '.
so i tried to fix that adding the ' http://servername/ ' to the ' locationHeader ' string but doing that creates a loop cause the server then redirects to the first url of his redirection chain.
since my browser gets the source code from that server with no problems is there a way to achieve that with HttpURLConnection?
if someone is interested thanks to Fiddler i worked out a solution to this issue.
first i changed the "User-Agent" property to mimic the one of Mozilla then i manually tweaked the cookie the serer was sending in its reply with the relative path.
that did the trick. thank you Fiddler.
I'm trying around with the HttpURLConnection for quite some time now and I tried several solution posted here and on other places, but nothing seems to work.
I have the following architecture:
A Ruby on Rails Web Service (Rest interface with JSON)
An iPhone Client with RestKit
An Android Client with HttpURLConnection
The iPhone Client works like a charm. It connects to the web service with RestKit.
Now the Android Client is a completely different story. I always get a 401 Unauthorized message from the server (which results in a local FileNotFoundException).
The strange thing is, that the iPhone Client gets the same error, but RestKit somehow manages the handle it by sending the same request again. I tried that of course, but I just get the same error twice.
On the Rails Log Output it looks like this:
Started POST "/api/v1/login" for 127.0.0.1 at 2012-05-03 12:44:56 +0200
Processing by Api::V1::ApiController#session_login as JSON
Parameters: {"device"=>{"model"=>"Simulator", "system"=>"Android", "version"=>"Hugo", "name"=>"Android Simulator"}, "email"=>"florian.letz#simpliflow.com", "api"=>{"device"=>{"model"=>"Simulator", "system"=>"Android", "version"=>"Hugo", "name"=>"Android Simulator"}, "email"=>"florian.letz#simpliflow.com", "action"=>"session_login", "controller"=>"api/v1/api"}}
Filter chain halted as :require_login_from_http_basic rendered or redirected
Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)
The exact same message occurs when the iPhone Client connect's but then suddenly a magical second request occurs and it goes through.
On the Android Client I do the following:
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod(HTTP_POST);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Accept-Encoding", "gzip, deflate");
String userpassword = email + ":" + password;
con.setRequestProperty("Authorization", "Basic " + new String(Base64.encodeBase64(userpassword.getBytes())));
String body = jsonLogin.toString();
byte[] body_bytes = body.getBytes();
con.setRequestProperty("Content-Length", "" + Integer.toString(body_bytes.length));
con.setRequestProperty("Content-Language", "en-US");
con.setInstanceFollowRedirects(false);
con.setUseCaches (false);
con.setDoInput(true);
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream (con.getOutputStream ());
wr.write(body_bytes);
wr.flush ();
wr.close ();
InputStream is = con.getInputStream();
And on the last line the exception occurs.
I've read some things about redirects, but there is no redirect implemented at the server and I do not receive one on the client. I just get the 401 Unauthorized. The code in the web service and the iphone client indicate a quite simple workflow. Just send the data and receive the answer. I don't know where the SECOND login call comes from when the iPhone connects.
Does anyone here have any idea what the problem could be?
Thanks a lot!
EDIT #1:
I have identified the "magical" second request. The RestKit Log shows the following:
Asked if canAuthenticateAgainstProtectionSpace: with authenticationMethod = NSURLAuthenticationMethodDefault
This then results in the second request with quite a buch of headers I cannot make any sense of.
So do you know a way to implement this in Android?
I have an Android app that works fine with Android 2.x and 3.x, but it fails when run on Android 4.x.
The problem is in this section of code:
URL url = new URL("http://blahblah.blah/somedata.xml");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
When the application is running on Android 4.x, the getInputStream() call results in a FileNotFoundException. When the same binary is running on earlier versions of Android, it succeeds. The URLs also work fine in web browsers and with curl.
Apparently something about HttpURLConnection has changed in ICS. Does anybody have any idea what has changed, and/or what the fix might be?
Try removing the setDoOutput call. Taken from this blog:
a blog
Edit: This is needed when using a POST call.
A FileNotFoundException may also been thrown if the server returns a bad error code (e.g., 400 or 401). You can handle this as follows:
int responseCode = con.getResponseCode(); //can call this instead of con.connect()
if (responseCode >= 400 && responseCode <= 499) {
throw new Exception("Bad authentication status: " + responseCode); //provide a more meaningful exception message
}
else {
InputStream in = con.getInputStream();
//etc...
}
I Don't know why, but dealing manually with redirection resolves the problem.
connection.setInstanceFollowRedirects(false);
A little late but you can also verify the accepted content. You can add this line to accept all kinds of contents
urlConnection.setRequestProperty("Accept","*/*");