Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listing a folder structure in Classic ASP

Tags:

asp-classic

I've developed a secure page in ASP for the company I work for. There is a landing (login page) that once you are authenticated you are taken to a page that has links to several sub pages. Each sub page has a folder structure. For example: There is a heading for Meeting Minutes and then underneath and indented are links referencing PDFs that contain the information. There may be 3 or 4 headings with documents linked beneath.

The original version had a PHP script that ran and would sync up the live site on the server from a folder structure that would be mimicked onto the live site. So if I had a folder called Folder1 and sub folders named test1 test2 test3.. the live site would display them accordingly. Since the site is now in ASP and not PHP.. the PHP script no longer works (since PHP doesn't play well with ASP).

I found a snippet online that somewhat works for what i'm trying to achieve (i.e. Folder/Subfolder/File Name structure), however i'm stuck at the moment with how to link the files so they open when clicked. I keep seeing a %25 in the file name. I know %20 is the same as a blank space and since I am dealing with file and folder names that contain spaces, this appears to be my issue. I've tried adding in a %20 but the spaces become "%2520".

If you look at the code below, there is a link towards the bottom that calls "MapURL". I have that link commented out at the moment as I was trying to figure out where the %25 was coming from. Anyone have any thoughts on how to get the links to work?

Here is the snippet.

dim path 
path = "PATH TO THE FOLDER ON THE SERVER"

ListFolderContents(path)

sub ListFolderContents(path)

 dim fs, folder, file, item, url
 set fs = CreateObject("Scripting.FileSystemObject")
 set folder = fs.GetFolder(path)

'Display the target folder and info.

 Response.Write("<ul><b>" & folder.Name & "</b>") '- " _
 '  & folder.Files.Count & " files, ")
 'if folder.SubFolders.Count > 0 then
 '  Response.Write(folder.SubFolders.Count & " directories, ")
 'end if
 'Response.Write(Round(folder.Size / 1024) & " KB total." _
 '  & "</ul>" & vbCrLf)

 Response.Write("<ul>" & vbCrLf)

 'Display a list of sub folders.

 for each item in folder.SubFolders
   ListFolderContents(item)
 next

 'Display a list of files.

 for each item in folder.Files
   'url = MapURL(item.path)
   'Response.Write("<li><a href=" & url & ">" & item.Name & "</a> - " _

   Response.Write("<li><a href=" & Replace(item.path," ","%") & ">" & item.Name & "</a> - " _
     & item.Name & "</a>" _
     & "</li>" & vbCrLf)
 next

 Response.Write("</ul>" & vbCrLf)
 Response.Write("</ul>" & vbCrLf)

 end sub

function MapURL(path)

 dim rootPath, url

 'Convert a physical file path to a URL for hypertext links.

 rootPath = Server.MapPath("/")
 url = Right(path, Len(path) - Len(rootPath))
 MapURL = Replace(url, "\", "/")

end function
like image 394
Nick Avatar asked Jun 28 '11 13:06

Nick


2 Answers

There are several things wrong with your code.

  • First and foremost, you do not encode the values you output at all. This is a big mistake. You are missing URL-encoding for things that go into the HREF attribute, and you miss HTML-encoding for everything else.
  • Next, you create a new FileSystemObject with every call to the recursive ListFolderContents() function. This is unnecessarily wasteful and will become slow as soon as there are more than a handful of files to be output.
  • Your recursive function should take a Folder object as the first argument, not a path. This makes things a lot easier.
  • The HTML structure you output is invalid. <b> cannot legally be a child of <ul>.

I completely rewrote your code to produce more correct output and to be as fast as possible. Crucial to your problem is the PathEncode() function, it transforms a relative path to a properly encoded URL. The other things should be pretty self-explanatory:

ListFolder "P:\ATH\TO\THE\FOLDER\ON\THE\SERVER"

' -- Main Functions ----------------------------------------------------
Sub ListFolder(path) 
  Dim fs, rootPath

  Set fs   = CreateObject("Scripting.FileSystemObject")
  rootPath = Replace(path, Server.MapPath("/"), "") & "\"

  ListFolderContents fs.GetFolder(path), PathEncode(rootPath)
End Sub

' ----------------------------------------------------------------------
Sub ListFolderContents(folder, relativePath)
  Dim child

  Say "<ul>"
  Say "<li><div class=""folder"">" & h(folder.Name) & "</div>"

  For Each child In folder.SubFolders
    If Not IsHidden(child) Then
      ListFolderContents child, relativePath & PathEncode(child.Name) & "/"
    End If  
  Next

  relativePath = h(relativePath)

  For Each child In folder.Files
    If Not IsHidden(child) Then
      Say "<li><a href=""" & relativePath & h(PathEncode(child.Name)) & """>" & h(child.Name) & "</a></li>"
    End If
  Next

  Say "</ul>"
End Sub

' -- Helper Functions / Shorthands ---------------------------------------
Sub Say(s)
  Response.Write s & vbNewLine
End Sub

Function h(s)
  h = Server.HTMLEncode(s)
End Function

Function PathEncode(s)
  ' this creates a more correct variant of what Server.URLEncode would do
  PathEncode = Replace(s, "\", "/")
  PathEncode = Server.URLEncode(PathEncode)
  PathEncode = Replace(PathEncode, "+", "%20")
  PathEncode = Replace(PathEncode, "%2F", "/")
  PathEncode = Replace(PathEncode, "%2E", ".")
  PathEncode = Replace(PathEncode, "%5F", "_")
End Function

Function IsHidden(File)
  IsHidden = File.Attributes And 2 = 2
End Function

Notes

  • Use the <div class="folder"> to apply CSS styles (i.e. bold etc.) to the folder name.
  • The function will not output hidden files or directories.
  • The relativePath argument is used to keep the workload as low as possible - when a folder has 1000 files, it makes no sense to calculate the entire relative path 1000 times. With the help of this parameter, only the part that actually changes is processed.
  • Having functions like Say() or h() around can save you a lot of typing and it keeps the code more clean, too.
  • You should read up on URL-encoding (and HTML-encoding as well). Seems like you've never come across these things, which is especially bad if your task is to build a secure site.
like image 87
Tomalak Avatar answered Sep 27 '22 20:09

Tomalak


you probably need extra quotes at the href (""). The best way is to see the generated source code (from the resulting page) like <a href=""" & replace(...) & """>"
Basically, if you use only one quote it just closes the string, but you are missing the HTML quote needed after href= and the closing one.

like image 27
Rodolfo Avatar answered Sep 27 '22 20:09

Rodolfo