plugins.file.writeFile

What firewall ports need to be open for this to work?

Hi Allen,

never had problems with this, so what are you trying to accomplish?

  • smart/webclient
  • local filesystem / write to remote filesystem

Hi

Servoy 7.4.4, webclient only. Production environment has a Servoy solution on a Windows Server 2008 R2 accessed over the internet.

Just want to present a PDF for download in the normal way from the local filesystem on the web server using plugins.file.writeFile() as per every example out there. Nothing complicated. Works perfectly on my PC, works perfectly deployed on an Azure test server and accessed via the internet, works perfectly accessing it while on the production server desktop via RDP. When accessed as a normal user would, via a web browser hitting the production server external IP address, nothing happens, i.e. I don’t get the browser’s ‘file save’ dialog as I would expect. No Servoy errors logged, nothing.

This has been driving me insane for several years now - I changed it to email the PDF instead but it should work as a download, dammit!

Maybe the browser tries to open the PDF directly in a new tab and new tabs are blocked?

How exactly does your code snippet look like?

Code is below. Works fine everywhere except it needs to, from any browser. It hits the ‘PDF presented …’ log line no problem.

/**
 * Use built-in WriteFile() function to present a PDF for download or display
 * depending on what the user's browser is set to do.
 * @param {String} pdflocation
 * @param {String} prefix  
 * @properties={typeid:24,uuid:"8211D1E0-2E74-422B-9762-B1EF363C8772"}
 */
function downloadPDF(pdflocation, prefix) 
{
	var attachmentFile = plugins.file.convertToJSFile(pdflocation);
	
	// -- Attempt to present the file to the browser.
	if (attachmentFile.exists()) 
	{
		var fbytes = plugins.file.readFile(pdflocation);
		plugins.file.writeFile(utils.stringTrim(prefix) + '.pdf', fbytes, 'application/pdf');
		plugins.Log.info('Presented ' + pdflocation + ' for download.');	
	}
	else
	{
		plugins.Log.warn('Download requested but ' + pdflocation + ' does not exist.');
	}
}

If you look at the 5th post from the bottom in this thread: https://www.servoy.com/forum/viewtopic.php?f=34&t=19964&hilit=+download#p107621

To me that is strange - 192.168.1.7 is the LAN address of the server that Servoy is on, so why is it trying to use that to download the file from when I access it over the web?

Hi Alan,

So it’s a server error. What do you see in the servoy and tomcat logs?

They don’t show anything untoward.

The files that it is intended to download are not underneath the Servoy server directory, i.e. they are in another location on the disk. Would that mean permissions issues?

Servoy is in

D:\servoy\

The PDFs are in (for example)

D:\myapplication\pdf\a\testuser\

Anything in the admin page referring to this local IP?

@Marc

Not that I can see.

So what’s the internal address? I assume it’s the local address of the cloud server you’re using?

Hi Alan,

I believe the trick is in turning the JSFile into a RemoteJSFile like so:

function downloadPDF(pdflocation, prefix) {
    var attachmentFile = plugins.file.convertToJSFile(pdflocation);

    // -- Attempt to present the file to the browser.
    if (attachmentFile.exists()) {
        var fbytes = plugins.file.readFile(pdflocation);
        var _oFile = plugins.file.createTempFile(utils.stringTrim(prefix), '.pdf');
        _oFile = plugins.file.convertToRemoteJSFile(_oFile.getAbsolutePath());
        if (_oFile) {
            // this will trigger the download
            if (!plugins.file.writeFile(_oFile, fbytes, 'application/pdf')) {
                throw new Error("Error during writing of the pdf");
            }
            // clean up after us
            _oFile.deleteFile();
        }
        plugins.Log.info('Presented ' + pdflocation + ' for download.');   
    } else {
        plugins.Log.warn('Download requested but ' + pdflocation + ' does not exist.');
    }
}

Hope this helps.

I’ll give that a shot, many thanks.

The code above fails on:

_oFile = plugins.file.convertToRemoteJSFile(_oFile.getAbsolutePath());

because getAbsolutePath() returns:

C:\Users\abourke\AppData\Local\Temp\ref 14890999597871051031.pdf

but

Exception Object: java.lang.IllegalArgumentException: Remote path should start with '/'
MSG: Remote path should start with '/'
Remote path should start with '/'
Wrapped java.lang.IllegalArgumentException: Remote path should start with '/'

OK I’ve amended it to rewrite the path in a *nix style (removed drive letters, changed slashes to forward slashes), it works here so will test live.

ROCLASI:
Hi Alan,

I believe the trick is in turning the JSFile into a RemoteJSFile like so:

I doubt that you need to change a JSFile into a RemoteJSFile, to make this work!
When you are in a webclient, a JSFile is already a ‘remote’ file.

the wiki says this: https://wiki.servoy.com/display/Serv7/f … -writeFile

writeFile(file, data, mimeType)
Writes data into a binary file. (Web Enabled: file parameter can be a string ‘mypdffile.pdf’ to hint the browser what it is, if it is a JSFile instance it will be saved on the server)

maybe there is some NAT stuff going on here, where the server does not know it’s public IP, but only it’s local address.
I don’t how, how Servoy copes with such situation.

It feels like some sort of network issue - unfortunately the code from Robert above presents the same problem - the client browser shows ‘connecting’ briefly, then nothing happens. No errors, all logging shows as if the file was downloaded OK.

Driving me nuts :evil:

Hi Alan,

This also happens when you open the web client ON the server (assuming you have a GUI there)?
Just to rule out the network.

Hi, if I RDP onto the server desktop, it works perfectly via a browser there. It’s only when accessed via the internet Tha it doesn’t work.

Hi Alan,

So what is the topology of your network ?
Does the server have a real IP ? Is it behind a VPN? Is it behind a proxy (web) server?