Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: Dynamic content - intraweb / protect files with session ID



Permlink Replies: 9 - Last Post: Mar 13, 2017 2:27 PM Last Post By: Dan Barclay
Bobby Gallagher

Posts: 3
Registered: 10/1/09
Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 20, 2017 1:57 AM
Hi all,

I have an intraweb application on delphi 10.1 berlin, and the latest version of intraweb 14.1.5, where I want to display dynamic pdf like: www.example.com/example.dll?sessionID/show.pdf

In the above url example when the session is not active it should not display the pdf.

The pdf path should be protected by the session ID.

Any suggestions how to achive that.

Thank you.
Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2017 10:19 AM   in response to: Bobby Gallagher in response to: Bobby Gallagher
why do you need the "example.dll?" part?

i think this is what i would do if i understand you correctly :

in your Session's OnCreate add this line :

procedure TIWUserSession.IWUserSessionBaseCreate(Sender: TObject);
begin
  ForceDirectories(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID);
end;

Creat\Copy\Move your file to that folder from where ever you need to, and then in the Session's OnDestroy :

procedure TIWUserSession.IWUserSessionBaseDestroy(Sender: TObject);
begin
  DeleteFile(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID+'\show.pdf');
  RemoveDir(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID);
end;

i use my app as a SA server, so it works fine here.
but i don't know if or how it will work if you use a web server like IIS (is that why "example.dll?" ?).

Dan Barclay

Posts: 889
Registered: 11/9/03
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2017 2:07 PM   in response to: Eitan Arbel in response to: Eitan Arbel
Eitan Arbel wrote:
why do you need the "example.dll?" part?

i think this is what i would do if i understand you correctly :

in your Session's OnCreate add this line :

procedure TIWUserSession.IWUserSessionBaseCreate(Sender: TObject);
begin
  ForceDirectories(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID);
end;

Creat\Copy\Move your file to that folder from where ever you need to, and then in the Session's OnDestroy :

procedure TIWUserSession.IWUserSessionBaseDestroy(Sender: TObject);
begin
  DeleteFile(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID+'\show.pdf');
  RemoveDir(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID);
end;

i use my app as a SA server, so it works fine here.
but i don't know if or how it will work if you use a web server like IIS (is that why "example.dll?" ?).


The same thing, done a slightly different way...

I create a public (under wwwroot) and a private (under the app) session directory in the UserSession Create and I keep their names as properties in UserSession so they're handy.

I kill them in UserSession Destroy, but I use:

    IW.Common.System.IWDelTree(FPrivateDir);
    IW.Common.System.IWDelTree(FPublicDir);


The good news is that IWDelTree kills the whole thing including contents so you don't need to keep up with the droppings.
I guess the bad news is that IWDelTree kills the whole thing including contents so beware where you aim it <g>.

A question: I'm using IW.Common.System.MakeDirectory() to create the directories instead of ForceDirectories(). I'm not sure the difference between the two?

Thanks,
Dan

Dan
Eitan Arbel

Posts: 508
Registered: 2/24/13
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2017 4:50 PM   in response to: Dan Barclay in response to: Dan Barclay
A question: I'm using IW.Common.System.MakeDirectory() to create the directories instead of ForceDirectories(). I'm not sure the difference between the two?

with ForceDirectories you can make the entire directory tree (a long path-size) with one command, while with MakeDirectory (or System.SysUtils.MkDir) you need to make each branch in the directory tree.

an example for creating the path C:\Head\Branch\Leaf when you don't have even the folder "Head" :

ForceDirectories('C:\Head\Branch\Leaf');

MakeDirectory('C:\Head');
MakeDirectory('C:\Head\Branch');
MakeDirectory('C:\Head\Branch\Leaf');
same with MkDir

Bobby Gallagher

Posts: 3
Registered: 10/1/09
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 24, 2017 2:27 AM   in response to: Dan Barclay in response to: Dan Barclay
Dan Barclay wrote:
Eitan Arbel wrote:
why do you need the "example.dll?" part?

i think this is what i would do if i understand you correctly :

in your Session's OnCreate add this line :

procedure TIWUserSession.IWUserSessionBaseCreate(Sender: TObject);
begin
  ForceDirectories(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID);
end;

Creat\Copy\Move your file to that folder from where ever you need to, and then in the Session's OnDestroy :

procedure TIWUserSession.IWUserSessionBaseDestroy(Sender: TObject);
begin
  DeleteFile(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID+'\show.pdf');
  RemoveDir(WebApplication.ApplicationPath+'\wwwroot\Sessions\'+WebApplication.AppID);
end;

i use my app as a SA server, so it works fine here.
but i don't know if or how it will work if you use a web server like IIS (is that why "example.dll?" ?).


The same thing, done a slightly different way...

I create a public (under wwwroot) and a private (under the app) session directory in the UserSession Create and I keep their names as properties in UserSession so they're handy.

I kill them in UserSession Destroy, but I use:

    IW.Common.System.IWDelTree(FPrivateDir);
    IW.Common.System.IWDelTree(FPublicDir);


The good news is that IWDelTree kills the whole thing including contents so you don't need to keep up with the droppings.
I guess the bad news is that IWDelTree kills the whole thing including contents so beware where you aim it <g>.

A question: I'm using IW.Common.System.MakeDirectory() to create the directories instead of ForceDirectories(). I'm not sure the difference between the two?

Thanks,
Dan

Dan

Thank you for your response.

But I don't have only one pdf to display, I am talking about 2 GB of pdf files.

So, I cannot afford to create a folder and move all the files in there, and then delete it.

My project folder is relative to the app path, and the relative link path to the pdf will be exposed, making it accesible after the session is killed.

I am using IIS that why I have the .dll extension.

My thought it was to move the project folder to wwwrooot, but it won't cover the full path to the pdf.

Tried to use TIWServerControllerBase by setting the content path to a different location than wwwroot, but still won't hide the path to the pdf behind the session.

I know can be achievable but dunno how. :(

Thank you
Alexandre Machado

Posts: 1,754
Registered: 8/10/13
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2017 2:19 PM   in response to: Dan Barclay in response to: Dan Barclay
A question: I'm using IW.Common.System.MakeDirectory() to create the directories instead of ForceDirectories(). I'm not sure the difference between the two?

MakeDirectory() from IW.Common.System uses ForceDirectories() internally, so they should have the same effect on success (i.e. when the directory is actually created - or exists - they should be identical). However, MakeDirectory raises an exception when the directory can't be created and will show the error message returned by the OS, differently from RTL functions which tend to "hide" the failure from the user, which is useless IMO: If your application can't create the directory, we should know why exactly that happened.

Another difference. Please check this code:

if ForceDirectories('c:\somefolder') then
begin
  if DirectoryExists('c:\somefolder') then
  begin
    ShowMessage('c:\somefolder exists!');
  end;
end;


You would expect that ShowMessage() call will always happen when ForceDirectories() succeed, correct? That's because if ForceDirectories() succeeded, of course DirectoryExists() must also succeed. However that's not true and we have detected that this pattern fails without any reasonable explanation on some Windows servers. Maybe this is related to NTFS cache/system load...

To avoid that, we have added some extra precautions on IW.Common.System.MakeDirectory() to minimize this risk.

Kind regards
Dan Barclay

Posts: 889
Registered: 11/9/03
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2017 2:27 PM   in response to: Alexandre Machado in response to: Alexandre Machado
Alexandre Machado wrote:
A question: I'm using IW.Common.System.MakeDirectory() to create the directories instead of ForceDirectories(). I'm not sure the difference between the two?

MakeDirectory() from IW.Common.System uses ForceDirectories() internally, so they should have the same effect on success (i.e. when the directory is actually created - or exists - they should be identical). However, MakeDirectory raises an exception when the directory can't be created and will show the error message returned by the OS, differently from RTL functions which tend to "hide" the failure from the user, which is useless IMO: If your application can't create the directory, we should know why exactly that happened.

Another difference. Please check this code:

if ForceDirectories('c:\somefolder') then
begin
  if DirectoryExists('c:\somefolder') then
  begin
    ShowMessage('c:\somefolder exists!');
  end;
end;


You would expect that ShowMessage() call will always happen when ForceDirectories() succeed, correct? That's because if ForceDirectories() succeeded, of course DirectoryExists() must also succeed. However that's not true and we have detected that this pattern fails without any reasonable explanation on some Windows servers. Maybe this is related to NTFS cache/system load...

To avoid that, we have added some extra precautions on IW.Common.System.MakeDirectory() to minimize this risk.

I had concluded that ...MakeDirectory() was using a form of ForceDirectories() because I was creating a couple of layers of directories in my code. Sorry to others that I did not follow up and state this. I left the MakeDirectories() code in my work. I had not tracked the other goodies in MakeDirectories(), nice to know about those.

...MakeDirectories() it stays!

Thanks
Dan
Daniel Fields

Posts: 622
Registered: 11/29/04
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 25, 2017 10:30 PM   in response to: Bobby Gallagher in response to: Bobby Gallagher
Please clarify. Does the user select the PDF to be displayed from inside your application? Or, is your application delivering PDFs based upon the session and filename passed to it?

If the selection is being made by your application, you do not need to have a fully qualified PDF name. Do you want users to view a temporary copy of the PDF? That would be easy to do by copying the desired PDF into the UserCache or into a folder in the application folder structure, something like "wwwroot\files\tempview". You could then use a TIWLabel, with RawText=true to render the PDF viewer inside an application page. CGDevTools has a nice PDFViewer component.
Bobby Gallagher

Posts: 3
Registered: 10/1/09
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 10, 2017 12:21 AM   in response to: Daniel Fields in response to: Daniel Fields
Daniel Fields wrote:
Please clarify. Does the user select the PDF to be displayed from inside your application? Or, is your application delivering PDFs based upon the session and filename passed to it?

If the selection is being made by your application, you do not need to have a fully qualified PDF name. Do you want users to view a temporary copy of the PDF? That would be easy to do by copying the desired PDF into the UserCache or into a folder in the application folder structure, something like "wwwroot\files\tempview". You could then use a TIWLabel, with RawText=true to render the PDF viewer inside an application page. CGDevTools has a nice PDFViewer component.

The pdf is displayed on an anchor link like: app.path + '/ProjectNo Folder' + '/PDF Folder' + '/example.pdf'
But what I want to achieve is to have the path to the pdf ( or at least the project NO folder) behind a session like: /SessionID/PDF Folder/example.pdf or better case: '/SessionID/example.pdf'

It suppose to be a setting for dynamic content path in the server controller, where the path can be specified, but it's not working in the newer version of Intraweb.

Thank you for response.

Regards,
Alexandre Machado

Posts: 1,754
Registered: 8/10/13
Re: Dynamic content - intraweb / protect files with session ID
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 13, 2017 1:51 AM   in response to: Bobby Gallagher in response to: Bobby Gallagher
Bobby Gallagher wrote:
Daniel Fields wrote:
Please clarify. Does the user select the PDF to be displayed from inside your application? Or, is your application delivering PDFs based upon the session and filename passed to it?

If the selection is being made by your application, you do not need to have a fully qualified PDF name. Do you want users to view a temporary copy of the PDF? That would be easy to do by copying the desired PDF into the UserCache or into a folder in the application folder structure, something like "wwwroot\files\tempview". You could then use a TIWLabel, with RawText=true to render the PDF viewer inside an application page. CGDevTools has a nice PDFViewer component.

The pdf is displayed on an anchor link like: app.path + '/ProjectNo Folder' + '/PDF Folder' + '/example.pdf'
But what I want to achieve is to have the path to the pdf ( or at least the project NO folder) behind a session like: /SessionID/PDF Folder/example.pdf or better case: '/SessionID/example.pdf'

It suppose to be a setting for dynamic content path in the server controller, where the path can be specified, but it's not working in the newer version of Intraweb.

Thank you for response.

Regards,

Content path is not intended to be used as a dynamic property. It is a static path which should be set when application starts (ServerController.OnConfig event). It works as intended.

I believe this is a case for a content handler which replies with this dynamic content. However, a content handler path must have some "fixed" part. Something like:

www.example.com/example.dll/<your Content handler path here>/sessionID/example.pdf

<your Content handler path here> = path used in content path. This can't be dynamic.

Is this viable?

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02