Good morning, I decided to create a http proxy servlet because I'm in a network where almost all pages are blocked, there is a firewall that blocks almost all called fortinet.
My idea is to use a server that I have which is not blocked, but on that server only have installed an archive of web applications (glassfish) and want to create a web application that serves me as an intermediary between the pages you wish to visit and my pc and thus navigate freely without restrictions.
So far I have used the HTTP-Proxy-Servlet project
The problem is: apparently only connects to a single web that previously we configure the web.xml file with the parameter targetUri
<init-param>
<param-name>targetUri</param-name>
<param-value>http://solrserver:8983/solr</param-value>
</init-param>
How to change this parameter dynamically and navigate as a common and current online proxy?
To implement a "real" proxy (not just a "fixed URL" one), you need to use the getRequestURL method to get the real URL which was requested.
For example, in HTTP-Proxy-Servlet, when he writes:
String proxyRequestUri = rewriteUrlFromRequest(servletRequest);
You can write:
String proxyRequestUri = servletRequest.getRequestURL().toString();
I'm not saying that's the only change you'll have to make, but it's a start.
Alternatively, you could reconstruct the URL using the other getters from the request:
getScheme (http, https etc)
getServerName
getServerPort (which might be 80)
getRequestURI
getQueryString or getParameterNames / getParameterValues
(For some reason, when you type "java proxy servlet" into Google, the first result that comes up is HTTP-Proxy-Servlet. However it's not actually that useful IMO, because it only directs to a fixed URL as you mentioned.)
Related
I understand that with GWT RequestFactory, server-side calls are all made to a RequestFactoryServlet. I'd like to write a GWT application (using RequestFactory) that looks to a cookie to determine which base URL all server-side calls are made to.
So, I'd have 3 different WAR files deployed to 3 different Tomcat instances living on 3 different physical servers, mapped to 3 different IP addresses (URLs). Each WAR would have a RequestFactoryServlet defined and would be capable of servicing requests from the same GWT client.
But, on the client-side, if a widgetType cookie has a value of red, I want all server-side requests to go to:
http://red.example.com/RequestFactoryServlet#doGet
If widgetType=blue, then I want all server-side requests to go to:
http://blue.example.com/RequestFactoryServlet#doGet
If widgetType=orange, then I want all server-side requests to go to:
http://orange.example.com/RequestFactoryServlet#doGet
So, in summary, the client-side cookie (widgetType) determines which RequestFactoryServlet on which WAR/server/URL the HTTP requests get sent to and processed by.
Is this possible? If not, why and is there anything that I can do here? If it is possible, how is it possible (what code/techniques/etc do I need to utilize)? Thanks in advance!
Same-Origin potential issues put aside, all you need is to initialize your RequestFactory with a custom RequestTransport. The easiest is to extend DefaultRequestTransport and initialize its setRequestUrl depending on the cookie value.
For my java webapp, I would like a log-in form to appear on each (JSP) page if the user is not yet logged. Pages could be secure (HTTPS) or not (HTTP).
The log-in form must POST on a secured (HTTPS) URL to prevent the username/password to be sent in clear text.
If the user is currently on the page http://localhost:8080/app/home, using jstl [c:url value="/login"] to compute the log-in form URL will not change the scheme from HTTP to HTTPS
(although /login is marked as CONFIDENTIAL in my web.xml).
Instead, it will give an URL like http://localhost:8080/app/login which will send a redirect to https://localhost:8443/app/login when accessed.
So why is the container redirecting instead of rewriting the URL to use the correct scheme (+ port) in the first place?
I could hardcode the log-in form secured URL but that would be less portable.
Or maybe, there are some considerations about web security I'm not aware of...
When you use "/login" as the URL, the browser will interpret the URL as having the same hostname, port and scheme as the URL of the page containing the URL. If you want to use HTTPS, your server-side has to return HTML that uses URL with (at least) the "https:" scheme. This specified in the HTML spec.
However, you don't necessarily have to hard-wire the hostname into the JSP. The JSP could pick up the hostname from configuration property, or figure it out from the current request URL.
But is there a standard way to ask the container (jetty, tomcat...) to convert "/login" into a full secure URL like localhost:8443/app/login ?
AFAIK, no. (BTW, if there was Jetty or Tomcat specific way of doing this, it wouldn't be standard ...)
The container is able to send a redirect to the right secure URL when I try to access the non-secure one, so why not skip the redirection part and make it produce the secure URL through response.encodeURL()?
Good question.
As I understand it, the feature that automatically incoming requests to a secure URL is container specific, and needs to be configured at the container level. Specifically, the container (or something) needs to be told what incoming URLs need this treatment. The JSP engine would need similar information to do the same thing when creating URLs for outgoing messages. AFAIK, there is no such facility in Tomcat's JSP configurations.
You'd need to ask someone on the JSR committee(s) that produced the Java EE specs for an answer as to why there is no standard way to do this.
Even if I can figure the hostname out from the current request URL, I still have to know the HTTPS port (443? 8443?). If this port changes, it must be changed in both server and application config
That is true, but changing a configuration parameter in two places is a minor thing.
And like I said, if you have a beef with the various standards groups for not providing a standard solution for this ... or with the Tomcat / Jetty implementors for not providing a non-standard solution ... you should take this up with THEM.
FWIW, I use a custom "secureURL" tag to solve this problem, but my use-case is significantly more complicated. I'm implementing components that can be dropped into existing sites and that need to work when https is available or is not available, and when secure cookies are used or not used ... for example.
I have a back end process which is initiated on server startup. After completion of this process I send an email to users. I need access to application port in order to construct the complete URL of a web report running on same instance. Is there a way to fetch the port without access to request object ?
I need access to application port in order to construct the complete URL of a web report running on same instance. Is there a way to fetch the port without access to request object ?
Why don't you store this as a property in a configuration file to your back-end process? The code will turn out to be much simpler if just need just the port (or even a website URL fragment that doesn't change) that needs to be embedded in an email.
Besides, the administrators in question have better things to do than change port numbers on a periodic basis.
Related questions (but not quite the same)
Root URl of the servlet
Finding your application's URL with only a ServletContext
Both of them provide reasons, why the path seen by a servlet container, need not be the same as the one seen by an end user. Even if both are the same, there is no way, one can access this information without
reading the server configuration files. In this case, it would be $JETTY_HOME/etc/jetty.xml, which has the necessary info in the Connectors elements.
obtaining a reference to a ServletRequest object, which might not be a valid answer to this question.
If you have at least one http request call in your application, you could get port from it:
int portNumber = request.getServerPort();
Maybe your startup script can make such call.
More details: http://www.kodejava.org/examples/211.html
We have a website which has a decent customer base. We recently started a subdomain which will be used to serve specific content from the website. We need to redirect the users to subdomain when he/she tries to access the designated content from the old domain. For example I have old domain www.marketplace.com and a subdomain www.paper.marketplace.com. The web application serving both the domains is same. So when the user tries access a URL 'www.marketplace.com\paper\viewarticle' he should be redirected to 'www.paper.marketplace.com\paper\viewarticle'. Since it's the same web application serving both the domains I wanted do this using a servlet. The servlet should redirect user to subdomain based on certain configuration. I've thought about using a properties file in each folder that has a flag that determines if the request accessing the .html/.jsp files should be redirected or not.
the .jsp/.html files can be added/removed to deployment at runtime which is also a key for choosing this design.
Please comments on this approach or suggest any other ideas if you think it's better.
Thanks.
you can do this redirect, as long as the redirect follows some sort of convention, using apache rewrite rules. This way the overhead on your server to parse request, redirect and parse request again is reduced to just parsing the CORRECT request. This will for sure improve the performance on your site by reducing the number of requests.
Rewrites can be done with other servers, not just apache. Apache is just the most documented. Read Apache Rewrite Guide for more info.
I have a class that I want to hook and redirect HTTP requests in.
I also have a loader class already written, but all it does it replace the functions that contain the HTTP requests I want to change.
Is there a way to hook HTTP requests in Java so that I can redirect them all more easily?
Sort of like a proxy-wrapper.
Clarification:
The app sends out a GET or POST request to a URL.
I need the content to remain the same, just change the URL.
DNS redirects won't work, the Host HTTP header needs to be correct for the new server.
PS: This is a Desktop App, not a server script.
A cumbersome but reliable way of doing this would be to make your application use a proxy server, and then write a proxy server which makes the changes you need. The proxy server could be in-process in your application; it wouldn't need to be a separate program.
To use a proxy, set a couple of system properties - http.proxyHost and http.proxyPort. Requests made via HttpURLConnection will then use that proxy (unless they specifically override the default proxy settings). Requests made using some other method like Apache HttpClient will not, i think, be affected, but hopefully, all your requests are using HttpURLConnection.
To implement the proxy, if you're using a Sun JRE, then you should probably use the built-in HTTP server; set up a single handler mapped to the path "/", and this will pick up all requests being sent by your app, and can then determine the right URL to send them to, and make a connection to that URL (with all the right headers too). To make the connection, use URL.openConnection(Proxy.NO_PROXY) to avoid making a request to the proxy and so getting caught in an infinite loop. You'll then need to pump input and output between the two sockets.
The only other way i can think of to do this would be to override HttpURLConnection with a new handler which steers requests to your desired destination; you'd need to find a way to persuade the URL class to use your handler instead of the default one. I don't know how you'd do that in a clean way.
While an older post, this should give some ideas of some kinds of bytecode injects which can be peformed: Java Programming: Bytecode Injection. Another tool is Javassist and you may be able to find some links from the Aspected-oriented programming wiki article (look at the bytecode weavers section).
There are some products which extensively dynamically modify code.
Depending upon what is desired, there may be ... less painful ... methods. If you simply want to 'hook' HTTP requests, another option is just to use a proxy (which could be an external process) and funnel through that. Using a proxy would likely require control over the name resolution used.
you can use servlet filters which intercept the requests, the requests can further be wrapped, redirected, forwarded or completed from here.
http://www.oracle.com/technetwork/java/filters-137243.html
Do you control all of the code? If so, I suggest using Dependency Injection to inject the concrete implementation you want, which would allow you to instead inject a proxy class.
If you can change the source code, just change it and add your extra code on each HTTP request.
If you can't change the source code, but it uses dependency injection, perhaps you can inject something to catch requests.
Otherwise: use aspect-oriented programming and catch to URL class, or whatever you use to do HTTP requests. #AspectJ (http://www.eclipse.org/aspectj/doc/next/adk15notebook/ataspectj.html ) is quite easy and powerful.