views:

148

answers:

3

Hi experts! I'm implementing a URL shortener like bit.ly. For this, I have a Java servlet backend which does a response.redirect(targetURL) for every redirection request.

This works fine for HTTP requests, but I'm having a problem with file:// protocols. The problematic case is this:

  1. The target is a directory (such as file:///N:/somefolder where N: is a network drive)
  2. The client browser is IE

For Firefox, this works fine, the directory listing is shown in the browser as if I'd typed 'file:///n:/somefolder' in the address bar (and I have my server added to Firefox's list of trusted URIs)

For IE, if I type 'file:///n:/somefolder' into a browser and hit Enter, it opens a NEW explorer window. This is the exact behavior I want when I do a server side redirection, but this simply doesn't work. I get the "IE Cannot open..." error.

Is this not possible? Or is there some setting akin to the Firefox preferences that add my server to a list of "trusted" URLs for the redirection to happen?

Note that if the target is a file, such as 'file:///n:/somefolder/test.doc' this works fine, even in IE!

Thanks in advance!

A: 

Redirection from remote to local resources should be restricted due to security reasons but not all browsers enforce this correctly.

See this bulletin for an example of the exploit,

https://www.kb.cert.org/vuls/id/713878

ZZ Coder
A: 

This is not possible due to security restrictions. If the server machine has access to those resources at java.io level as well, then you could just act as sort of proxy yourself. Just create a Servlet which gets an InputStream of it using FileInputStream and write it to the OutputStream of the HttpServletResponse along with a correct set of headers.

Here's how the doGet() of such a servlet would look like:

String filename = request.getPathInfo();
File file = new File("n:/somefolder", filename);

response.setContentType(getServletContext().getMimeType(file.getName()));
response.setContentLength(file.length());

BufferedInputStream input = null;
BufferedOutputStream output = null;

try {
    input = new BufferedInputStream(new FileInputStream(file));
    output = new BufferedOutputStream(response.getOutputStream());

    byte[] buffer = new byte[1024];
    for (int length = 0; (length = input.read(buffer)) > 0;) {
        output.write(buffer, 0, length);
    }
} finally {
    if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
    if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}

Map this servlet on an url-pattern like /files/* and call it with http://example.com/contextname/files/test.doc. You can find here another basic example.

BalusC
I know I'm no hotshot in Servlets, so forgive me if this sounds silly : What you've given looks like a file servlet.What I'm asking is - why is it possible to do a response.redirect("N:/somefolder/somefile.doc") BUT not response.redirect("N:/somefolder") - On Internet Explorer?(Both work on Firefox)I fail to see the correlation here...
Raj
A: 

Well, I didn't get any satisfactory answers to my question. I've found a workaround that works while redirecting to directories in IE: have your server send a link to the target, instead of an actual redirect. E.g. the server sends html of the form

<a href="file:///N:/somefolder">click here</a>

This would require an additional click from the user, but would work.

Raj