Access URL with double slash with HttpClient - java

I'm doing a request on another server like this:
HttpGet req = new HttpGet("http://example.com//foo");
new DefaultHttpClient().execute(req);
However, HttpClient changes example.com//foo to example.com/foo, so the other server (which is not mine) doesn't understand the request.
How can I fix this?

A double-slash is not a legal in the path section of a URI (see RFC2396, sections 3.2, 3.4). The '//' sequence has a defined meaning in the URI, it denotes the authority component (server).
I realize this does not answer your question but the HttpClient is, in fact, behaving in accordance with the HTTP and URL standards. The server your are reading from is not. This appears to be previously reported (https://issues.apache.org/jira/browse/HTTPCLIENT-727) and discarded by the HttpClient team.

It is an illegal URL in fact.
Did you try passing an URI instead of a String?
Did you try / \ \ / ? Or the URL might be equivalent to /default.asp/, /index.html/, /./, /?/, example.com/foo/ or the like.
Otherwise you will need to hack the sources.

I also wanted to do same thing and Apache Http client don't support that.
I managed to get it done using a Netty. I wrote http client using Netty and with that I was able send request with double slash(//) in the path. I used SnoopClient as sample.

Related

Open non-http links in browser in java

I have an url in my app like "zoommtg://us04.zoom.com". I want to open it in browser by Intent. As it is not http or https, it can't be parsed by Uri.parse(url). Again if I try url="http://"+url; it works but deletes the ":" from "zoommtg://" resulting wrong url! I am using the solution of this Question
if it is working for https but not other requests, then you can try setting cleartexttraffic to true in your AndroidManifest.xml file.
Do tell if that fixes it. :)
zoommtg seems to be "custom protocol" declaration, which isn't resolveable by web browser, but if you are shure, that http(s) url version will work then just replace scheme
String url = "zoommtg://us04.zoom.com";
url = url.replaceFirst("zoommtg", "https")
if you really need to use unsecure http then you have to allow app to do such requests, see how to
btw. you still can use Uri class, it isn't limited to web protocols... check out some description of this structure
URI = scheme:[//authority]path[?query][#fragment]
you can parse your String to Uri and just replace scheme part
Uri.Builder builder = Uri.parse(url).buildUpon();
url = builder.scheme("https").build().toString();

Downloading binary file from url

I am using this code to download files from a url:
FileUtils.copyURLToFile(url, new File("C:/Songs/newsong.mp3"));
When I create the url using for instance,
"https://mjcdn.cc/2/282676442/MjUgU2FhbCAtIFZlZXQgQmFsaml0Lm1wMw==",
this works just fine and the mp3 is downloaded.
However,
if I use another url:
"https://dl.jatt.link/hd.jatt.link/a0339e7c772ed44a770a3fe29e3921a8/uttzv/Hummer-(Mr-Jatt.com).mp3",
the file is 0kb.
I am able to download files from both these urls from within a web browser.
What's wrong here, and how can I fix it.
I noticed a difference between your 2 URLs:
The first one just gives back the file without redirection.
But the second one responds with a redirect (HTTP/1.1 302 Moved Temporarily). It's also a special case, because it's a redirect from HTTPS to HTTP protocol.
Browsers can follow redirects, but your program - for some reason (see below) - can't.
I suggest you to use a HTTP client library (e.g. Apache HTTP client or Jsoup), and configure it to follow redirects (if they don't do it by default).
For example, with Jsoup, you would need a code like this:
String url = "https://dl.jatt.link/hd.jatt.link/a0339e7c772ed44a770a3fe29e3921a8/uttzv/Hummer-(Mr-Jatt.com).mp3";
String filename = "C:/Songs/newsong.mp3";
Response r = Jsoup.connect(url)
//.followRedirects(true) // follow redirects (it's the default)
.ignoreContentType(true) // accept not just HTML
.maxBodySize(10*1000*1000) // accept 10M bytes (default is 1M), or set to 0 for unlimited
.execute(); // send GET request
FileOutputStream out = new FileOutputStream(new File(filename));
out.write(r.bodyAsBytes());
out.close();
Update on #EJP's comment:
I looked up Apache Commons IO's FileUtils class on GitHub. It calls openStream() of the received URL object.
openStream() is a shorthand for openConnection().inputStream().
openConnection() returns an URLConnection object. If there is an appropriate subclass for the protocol used by URL, it will return an instance of that subclass. In this case that's a HttpsURLConnection which is the subclass of HttpURLConnection.
The followRedirects option is defined in HttpURLConnection and it's indeed true by default:
Sets whether HTTP redirects (requests with response code 3xx) should be automatically followed by this class. True by default.
So OP's approach would normally work with redirects too, but it seems that redirection from HTTPS to HTTP is not handled (properly) by HttpsURLConnection. - It's the case that #VGR mentioned in the comments below.
It's possible to handle redirects manually by reading the Location header with HttpsURLConnection, then use it in a new HttpURLConnection. (Example) (I wouldn't be surprised if Jsoup did the same.)
I suggested Jsoup because it already implements a way to handle HTTPS to HTTP redirections correctly and also provides tons of useful features.

Url encoding issue with Jersey Client

I need to make a service call such as this:
http://myservice.com/path?var1=value1&var2=value2
The issue I have is value1 and value2 ends up getting encoded, and this makes the service call fail. For example, value1 is something like "a=b&b=c;2&&="... it contains special characters, basically.
I am guessing that this is an issue for the service to fix - to properly handle decoding encoded characters, which I do not think it is currently doing.
Here is a sample of how I am making these requests:
WebTarget target = client.target("http://test.com")
.path("path1")
.queryParam("var1", var1);
Builder builder = target.request();
...
What's puzzling to me is that if I make the same request just using Chrome, everything works. So that makes me to believe that I should have some way with the Jersey API of "disabling" the encoding.
Only way I have found so far to use "raw" Url is to use URI.
So call like this
URI uri = URI.create("http://localhost/~Common~0#/edit?vadf&&sfs&&fdsfd=fs&fsd");
WebTarget target = client.target(uri);
You get request url
1 > GET http://localhost/~Common~0#/edit?vadf&&sfs&&fdsfd=fs&fsd
Everything else I tried resulted in encoding special characters.

Open an authenticated image served by django from java using Apache http client

I Am serving an authenticated image using django. The image is behind a view which require login, and in the end I have to check more things than just the authentication.
Because of a reason to complicated to explain here, I cannot use the real url to the image, but I Am serving it with a custom url leading to the authenticated view.
From java the image must be reachable, to save or display. For this part I use Apache httpclient.
In Apacahe I tried a lot of things (every example and combination of examples...) but can't seem to get it working.
For other parts of the webapp I use django-rest-framwork, which I succesfully connected to from java (and c and curl).
I use the login_reuired decorator in django, which makes the attempt to get to the url redirect to a login page first.
Trying the link and the login in a webviewer, I see the 200 code (OK) in the server console.
Trying the link with the httpclient, I get a 302 Found in the console.... (looking up 302, it means a redirect..)
this is what I do in django:
in urls.py:
url(r'^photolink/(?P<filename>.*)$', 'myapp.views.photolink',name='photolink'),
in views.py:
import mimetypes
import os
#login_required
def photolink(request, filename):
# from the filename I get the image object, for this question not interesting
# there is a good reason for this complicated way to reach a photo, but not the point here
filename_photo = some_image_object.url
base_filename=os.path.basename(filename_photo)
# than this is the real path and filename to the photo:
path_filename=os.path.join(settings.MEDIA_ROOT,'photos',mac,base_filename)
mime = mimetypes.guess_type(filename_photot)[0]
logger.debug("mimetype response = %s" % mime)
image_data = open(path_filename, 'rb').read()
return HttpResponse(image_data, mimetype=mime)
by the way, if i get this working i need another decorator to pass some other tests....
but i first need to get this thing working....
for now it's not a secured url.... plain http.
in java i tried a lot of things... using apache's httpclient 4.2.1
proxy, cookies, authentication negociation, with follow redirects... and so on...
Am I overlooking some basic thing here?...
it seems the login of the website client is not suitable for automated login...
so the problem can be in my code in django....or in the java code....
In the end the problem was, using HTTP authorization.
Which is not by default used in the login_required decorator.
adding a custom decorator that checks for HTTP authorization did the trick:
see this example: http://djangosnippets.org/snippets/243/

Uri not Absolute exception getting while calling Restful Webservice

The below code snippet is using to call my web service using restful API.
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
String uri= "https://127.0.0.1:8443/cas-server-webapp-3.5.0/login";
WebResource resource = client.resource(URLEncoder.encode(uri));
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
queryParams.add("username", "suresh");
queryParams.add("password", "suresh");
resource.queryParams(queryParams);
ClientResponse response = resource.type(
"application/x-www-form-urlencoded").get(ClientResponse.class);
String en = response.getEntity(String.class);
System.out.println(en);
And getting this exception while running the above code
com.sun.jersey.api.client.ClientHandlerException: java.lang.IllegalArgumentException: URI is not absolute
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:151)
at com.sun.jersey.api.client.Client.handle(Client.java:648)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
I googled many articles and did'nt get where i am doing wrong .
Side note :cas-server-webapp-3.5.0 war deployed on my machine in Apache tomacat7
An absolute URI specifies a scheme; a URI that is not absolute is said to be relative.
http://docs.oracle.com/javase/8/docs/api/java/net/URI.html
So, perhaps your URLEncoder isn't working as you're expecting (the https bit)?
URLEncoder.encode(uri)
For others who landed in this error and it's not 100% related to the OP question, please check that you are passing the value and it is not null in case of spring-boot: #Value annotation.
The problem is likely that you are calling URLEncoder.encode() on something that already is a URI.
Maybe the problem only in your IDE encoding settings. Try to set UTF-8 everywhere:
In an API Key Authorization Scenario...
You may be performing the 2nd REST call after getting an AUTH_TOKEN and ENDPOINT_URL from the first REST call.
Check your concatenation of "<ENDPOINT_URL> + <API_METHOD_URI>", you may be sending only the API_METHOD_URI.
This happened to me using the Streamsets integration platform trying to connect to Oracle's Responsys API.
For me, I was getting this error, when configuation in yaml files, which composed my URL was changed. oops,

Categories