Rob Weddell
Rob Weddell

Reputation: 41

Xagent to act as proxy for serving up non SSL data in an SSL environment

Our intranet is required to use https:// at all times which is fine for data stored on our own servers but causes problems for data fetched from third party sites. For example we have a list of currency exchange rates that comes from a third party site. The third party site does not offer an https option. To avoid the content being blocked by IE (and now even Firefox since the latest release!) it seems like a good idea to get the third party data via a proxy. Our admins are not keen on setting up an Apache server to act as a proxy and have asked me to investigate "doing it through Xpages". I'm a complete Java newbie and I'm struggling to understand why my Xagent doesn't work.

Here's what I've done so far: Stephan Wissel has written an HTTPReader class in Java which I've managed to add to my nsf. I've written an Xagent which successfully calls the getURL method of this class and fetches the content of the remote URL as a string. The problem I'm having is reading the string so that I can write it back. I get an "Error while executing JavaScript action expression" error on the BufferedReader line. This is my Xagent code:

<xp:this.beforeRenderResponse><![CDATA[#{javascript:importPackage(org.lotususers.tools);
importPackage(java.io);

var httpReader = org.lotususers.tools.HTTPReader();
var remoteURL = context.getUrlParameter("ru");
var remoteHTML:String = httpReader.getURL(remoteURL);

var bufferedReader:BufferedReader = new BufferedReader(new InputStreamReader(remoteHTML));

var outputString = "";
while(bufferedReader.readLine() != null){
    outputString += bufferedReader.readLine();
};

var externalContext = facesContext.getExternalContext();
var writer = facesContext.getResponseWriter();
var response = externalContext.getResponse();
response.setContentType("text/html");
response.setHeader("Cache-Control", "no-cache");

writer.write(outputString);
writer.endDocument();
}]]></xp:this.beforeRenderResponse>

If I put a line to print remoteHTML to the console (ie. print(remoteHTML)) then I can see the HTML has been fetched successfully, so at least I know that part has worked.

I've spent hours reading documentation about BufferedReader and trying to figure out what I've done wrong. I've tried every variation I can find for the BufferedReader line but nothing works (.openStream() or .getInputStream()). For example:

var bufferedReader:BufferedReader = new BufferedReader(new InputStreamReader(remoteHTML.getInputStream()));

I've tried fully qualifying the paths too but this made no difference:

var bufferedReader:java.io.BufferedReader = new java.io.BufferedReader(new java.io.InputStreamReader(remoteHTML.getInputStream()));

I'd be very grateful if someone could tell me what's wrong with that line. Thanks in advance.

Upvotes: 0

Views: 353

Answers (1)

Knut Herrmann
Knut Herrmann

Reputation: 30960

In your code

while(bufferedReader.readLine() != null){
    outputString += bufferedReader.readLine();
};

you would miss every second line to put in outputString and in addition it might happen after last line was read in while condition that outputString += bufferedReader.readLine(); would throw an JavaScript error because there is no line anymore.

Instead use this code:

var line = bufferedReader.readLine();
while(line != null){
    outputString += line;
    line = bufferedReader.readLine();
};

EDIT:

The following XAgent should do what you are looking for. httpReader.getURL(remoteURL) delivers you already complete HTML so you can use it right away for writer and don't have to deal with stream.

<xp:this.beforeRenderResponse><![CDATA[#{javascript:
try { 
    var httpReader = org.lotususers.tools.HTTPReader();
    var remoteURL = context.getUrlParameter("ru");
    var remoteHTML = httpReader.getURL(remoteURL);
    var externalContext = facesContext.getExternalContext(); 
    var response = externalContext.getResponse(); 
    var writer = response.getWriter(); 
    response.setContentType("text/html"); 
    response.setHeader("Cache-Control", "no-cache"); 
    writer.write(remoteHTML); 
    facesContext.responseComplete(); 
} catch (e) { 
    _dump(e); 
}}]]></xp:this.beforeRenderResponse>

The XAgent returns the page content of a target URL which is defined by parameter "ru". This is an example URL for calling XAgent:

https://Server/Test.nsf/XAgent.xsp?ru=http://www.web.de

Upvotes: 1

Related Questions