HTTP Response Query - java

The query I have has something do with an implementation I`m doing.
When a HTTP request is sent from the client Port to the Server Port, I understand that
the response is also sent back to the same port(Port to Port communication).
In my case, the server is forwarding the response to a URL with Query String to a host server on our network. So what I get when reading the response using the InputStream of the URLConnection object is the HTML content corresponding to the Login page of the forwarded URL with no query string.
I suspect this is because the URL is modified by our host server.
Now the question is, in this scenario there seems to be an intermediate entity which is the our host server to which URL is forwarded. So, when I read the response(URL forwarded by server) back in the InputStream, I`m not sure which of the following 2 is the actual scenario happening:
1.) Response is directly read from the external Server(as this is a Port to Port communication)
OR
2.)Response received from the intermediate Host Server which sees to be the case.
(If the 2nd scenario is correct, would the intermediate host server know which client to correctly forward the response to?)
URL url = new URL(httpsURL);
HttpsURLConnection urlConnection = (HttpsURLConnection) url
.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
///
Omitting code for SSL
///
String urlParameters = "CCNumber=4111111111111111";
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
BufferedReader in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
String inputLine;
if (urlConnection.getResponseCode() == HttpsURLConnection.HTTP_OK){
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
}

You receive the response from the intermediate server.
It sounds like your intermediate server acts as a (reverse) proxy server. When you make a request to your intermediate server, it in turn makes a request to the server on your network (just as you described it). However, the "real" server has usually no idea that the request was initiated by you. In particular, it does not know your IP address or the port you sent your request from. The only thing it does know is the IP address and port of the intermediate (the proxy) server. The proxy server on the other hand still knows the IP address and port from which you sent your request.
So you send your request to the proxy, the proxy sends it to the "real" server, the real server sends its response back to the proxy, which sends it back to you. You and the "real" server do not communicate directly with each other.

Related

Multiple tomcats on host, how to redirect requests so that client only knows about one tomcat

I have deployed two tomcats on my host on different ports. one is listening on port A and one on port B. There are webapps hosted on both the tomcats.
I need to make sure that the client which calls APIS on those webapps on both tomcats doesn't need to know both the ports. The client (angularJS) should be able to call just one tomcat and internally that tomcat should be able to redirect the request for proper service to another tomcat and pass the response back to the client.
That way I will be able to handle same origin policy also as the angularjs webapp is also deployed on the tomcat where I want to send the requests and cookies can also be used with this as there will be only one server where the cookies will be coming from.
Is there any way to achieve that? Is there any configuration that I can do on the first tomcat itself to redirect some request based on the URI to the second tomcat? or any other tool that I can deploy to support that? I heard somewhere of port redirection using iptables. Can that be used here?
The client does a request to port A, and inside the java code does a http request to http://localhost:B
To do a http request just search "java http request" and chose one of hundreds of examples. One possible way from here: How do I do a HTTP GET in Java?
public static String getHTML(String urlToRead) throws Exception {
StringBuilder result = new StringBuilder();
URL url = new URL(urlToRead);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
return result.toString();
}

Can't access server socket with android app

I want to see the exact headers my android app is sending while making a web request so I thought I'd simply create a simple server app in java on my local machine and have my android app make a call to it. Then simply dump the request to the console so I could see what the app is sending. However when I tried to connect, the app hangs and stops responding.
I created a simple server the only accepts a connection and sysouts the data it gets. The server runs fine and if I hit it from a web browser on my computer will print the headers from the web browsers request. So I know the server works fine.
Here's the code from my app:
URL url = new URL("http://192.168.1.11:9000");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.connect();
PrintWriter writer = new PrintWriter(connection.getOuputStream(), true);
writer.write("hi");
writer.close();
Simple. I only want the headers after all. Now I started without a post and using:
URL url = new URL("http://192.168.1.11:9000");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
in.close();
but that doesn't work. The app stops responding on the getInputStream() request. It just stops and won't continue. The server gets no connection request either.
So in all, the app is blocking on the url connection's getInputStream and I can't figure out why.
Now I've searched for awhile and found these:
Android app communicating with server via sockets
socket exception socket not connected android
Android embedded browser cant connect to server on LAN
Using java.net.URLConnection to fire and handle HTTP requests
Client Socket cannot connect to running Socket server
But nothing helps. I'm not using the localhost like everyone with this problem seems to be and I've tried using the androids 10.0.0.2 but that doesnt work either.
I'm not on a network that restricts anything (I'm home) and I've tried using the first set of code shown in order to send a message to my server but not even that works (it runs fine but the server never gets a client. Hows that work?).
I tried using both URLConnection and HttpURLConnection, they both have the same problem.
I'm also using the internet permission in my app, so it does have the permission needed.
I'm at a loss at this point. Why can't I make a simple call to my server?
EDIT
I used the exact code from androids documentation:
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500;
try {
URL url = new URL("http://10.0.2.2:9000");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
but even that doesn't work. It still hangs. Only now it hangs on the getResponseCode(). Then throws a timeout exception. The server never gets a request though.
Your address must start with 'http://", try again!
I think the root of your issue is that Android is FCing your app before the connection completes, because I assume you haven't wrapped this in a Loader, AsyncTask or Thread. I suggest you follow the training guide Google provides, wrapping your call in an AsyncTask and seeing if that corrects the issue.
I have a Java class I use for making HTTP GET requests, I'm guessing its near identical to the android code your using so below I've dumped the relevant part of the code. I've used this class many times in Java applications (not on Android).
currentUrl = new URL(getUrl);
conn = (HttpURLConnection)currentUrl.openConnection();
conn.setRequestProperty("Cookie", getCookies(currentUrl.getHost()));
conn.setRequestProperty("User-Agent", "robadob.org/crawler");
if(referrer!=null){conn.setRequestProperty("Referrer",referrer);}
conn.setRequestMethod("GET");
conn.connect();
//Get response
String returnPage = "";
String line;
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = rd.readLine()) != null) {
returnPage+=line+"\n";
}
rd.close();
I can't see anything obvious that would be causing your code to fail, but hopefully you can spot something from this. The setRequestProperty is me setting headers, so you shouldn't need those.
If that fails, flood your code with System.out's so you can see which statement its stalling at.

Taking text from a response web page using Java

I am sending commands to a server using http, and I currently need to parse a response that the server sends back (I am sending the command via the command line, and the servers response appears in my browser).
There are a lot of resources such as this: Saving a web page to a file in Java, that clearly illustrate how to scrape a page such as cnn.com. However, since this is a response page that is only generated when the camera receives a specific command, my attempts to use the method described by Mike Deck (in the link above) have met with failure. (Specifically, when my program requests the page again the server returns a 401 error.)
The response from the server opens a new tab in my browser. Essentially, I need to know how to save the current web page using java, since reading in a file is probably the most simple way to approach this. Do any of you know how to do this?
TL;DR How do you save the current webpage to a webpage.html or webpage.txt file using java?
EDIT: I used Base64 from the Apache commons codec, which solved my 401 authentication issue. However, I am still getting a 400 error when I attempt to connect my InputStream (see below). Does this mean a connection isn't being established in the first place?
URL url = new URL ("http://"+ipAddress+"/axis-cgi/record/record.cgi?diskid=SD_DISK");
byte[] encodedBytes = Base64.encodeBase64("root:pass".getBytes());
String encoding = new String (encodedBytes);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput (true);
connection.setRequestProperty ("Authorization", "Basic " + encoding);
connection.connect();
InputStream content = (InputStream)connection.getInputStream();
BufferedReader in = new BufferedReader (new InputStreamReader (content));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
EDIT 2: Changing the request to a GET resolved the issue.
So while scrutinizing my code above, I decided to change
connection.setRequestMethod("POST");
to
connection.setRequestMethod("GET");
This solved my problem. In hindsight, I think the server was not recognizing the HTTP because it is not set up to handle the various trappings that come along with post.

HttpURLConnection returns 503 error when accessed through proxy

I am working on creating a Video sitemap for a site that has hosted videos on Brightcove video cloud. In order to get all the video information from the site, Brightcove suggests to read the response from their url of following form
http://api.brightcove.com/services/library?token="+accountToken+"&page_size=1&command=find_all_videos&output=JSON&get_item_count=true
the output of the url is in JSON, where accountToken is just an identifier of the account.
When I hit the above url with Token in the browser, it gives me the correct response.
I wrote below program snippet to read from that url
URL jsonURL = new URL("http://api.brightcove.com/services/library?token="+accountToken+"&page_size=1&command=find_all_videos&output=JSON&get_item_count=true");
HttpURLConnection connection = (HttpURLConnection) jsonURL.openConnection();
connection.setRequestMethod("GET");
connection.connect();
BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String lineRead = "";
while (reader.ready()) {
lineRead = lineRead + reader.readLine();
}
As my browser uses proxy, I added below code to include proxy settings
System.setProperty("http.proxyHost", "my.proxyurl.com");
System.setProperty("http.proxyPort", "80");
Without using proxy settings, it returns java.net.ConnectException: Connection refused: connect and with proxy it gives me java.io.IOException: Server returned HTTP response code: 503
So my question is , why is it giving me a 503(Service Unavailable) error ? From the browser its working fine.
Update 1:
It seems like an issue with the Network. I pinged the domain and it said "Request Timed out". Working via HTTP though. Looks like an issue with the Firewall.
I think, it may due to your internet connection, I have tried your code I didn't get any 503(Service Unavailable). Check out with different connection connection(without proxy) and it should work. Or you can try it with slightly different approach:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("host", "port));
conn = new URL(jsonURL).openConnection(proxy);
If you have SOCKS type proxy, change Proxy's constructor parameter to Proxy.Type.SOCKS.
Minor correction to Jamas code
String host="myproxy.com";
int port=8080;
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));

Not getting the value in request/response after establishing the URL connection in my programme?

i have following application(say App1) sitting on port 8888 on tomcat which is opening url connection to another webapplication(say App2) lying on port 8080 on tomcat
String urlStr = "http://localhost:8080/myWebApp/xwiki/auth/my-auth!checkAuth.action"
URLConnection conn = url.openConnection();
/ Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer sb = new StringBuffer();//Line1
With above code it is hitting the my servlet AuthenticationServlet on 8080 port which is setting the attribute XWikiAuthentication in request and return
request.setAttribute("XWikiAuthentication", "Successful");
return;
But i am not getting that value of parameter XWikiAuthentication in my application App1. I tried two approach just below line1 in App1
Approach1 :-
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
result = sb.toString();
}
Approach2 :-
String Response=request.getAttribute("XWikiAuthentication");
String Response1=request().getParameter("XWikiAuthentication");
but got the value as nullthough iam expecting value as successfull
I am not gettting how to value of parameter XWikiAuthentication set in App1 in application in app2?
Update:- I am using Struts2
Not sure I followed the question completely. Restating it - you want to hit another webapplication which is essentially an Authentication servlet and want to read back whether user was authenticated or not ??
Assuming above -
You should send the user details (in request object) to the Authentication servlet and inside it you should set the final status in the response and this is what you should be reading.
you can either set it as a http header value in the response or can directly write it to the outputstream of the Authentication servlet.
Remember - you send the request and get back the response. See Using Url Connection
You probably want to be setting a response header in App 2 and reading it back in App 1.
EDIT
To set a header value (App 2):
response.setHeader(name, value);
To read on client side (App 1):
conn.connect();
value = conn.getHeaderField(name);
You could alternatively write some content directly to the HTTP response stream in App 2. To be read and processed in App 1 as appropriate.
response.getWriter().println("Authenticated!");
Your question specifically this line needs clarity:- "I am not gettting how to value of parameter XWikiAuthentication set in App1 in application in app2?"
Though, what I doubt then in that case if you need to set the parameter in response instead of request.

Categories