[jcifs] Re: directory must end with '/'

Michael B Allen mba2000 at ioplex.com
Wed Dec 8 23:09:16 GMT 2004


[I'm getting the list on this as it clearly explains the position on this
matter.]

Christopher R. Hertel said:
>> Think about HTTP. HTTP servers universally reject requests for
>> directories that don't have a trailing slash.
>
> ...but HTTP clients don't.

HTTP clients do NOT add a trailing slash if it's missing. Web browsers
will interpret an HTTP redirect and display the URL to which the browser
has been redirected thus providing the appearance that a trailing slash
has been "added".

There's no way for an HTTP client to know that a URL refers to a directory
without querying the server (and even then it still doesn't necessarily
know as it is entirely up to the server to send an HTTP redirect) and the
client cannot unconditionally mask the redirect response because the
caller most likely needs to know where it has been redirected.

At least CIFS has the ability to directly query a path to determine if
it's a directory. HTTP has no ability to query a path to determine if it's
a directory and therefore it's not possible for an HTTP client to add a
trailing slash based on such information.

> That in mind, I still feel that jCIFS could easily handle the semantic
> issues just as it handles the semantic differences between a server and a
> workgroup.

Actually the more I think about this it's totally impractical to do this
with JCIFS because URLs are immutable and are not resolved until they are
used. The client would have query the server for every URL to determine if
it is a directory and if so check that it has a "/" and if it doesn't it
would have to throw an exception that get's trapped very high up in the
call so it can reinitialize the request from scratch. It would be very
very messy and probably not possible based on the way SmbFiles are
constructed (can't do super(try {} catch { redo }) inside a constructor).

> In any case, the syntax I present in the article more or less matches the
> syntax presented in RFC 2396 so I don't think there's any reason to change
> it.  I can provide examples that have a trailing slash and I can

The 2936 grammer is for complete URLs, not parent fragments. How parent
fragments are to be interpreted is not defined by that grammer. Our
condensed syntax URL:

  smb://[server/[path/[file]]]

is a non-standard permutation of command line option definitions that was
made up by someone during the original SMB URL discussion on
samba.technical. It is not a real grammer and cannot be compared to the
said section in 2396.

> (and probably will) mention that jCIFS will throw a catchable exception if
> the object turns out to be a directory.  (I think jCIFS is fine if there's
> no trailing slash on a host piece, eg. "smb://foo.bar.biz".)

Actually I don't think jCIFS universally throws the "directory must end
with '/'" exception. It only does it where practical as a warning.

The real problems with no trailing slash start when you combine SmbFiles
with relative URLs like:

SmbFile f = new SmbFile( "smb://foo.bar.biz" );
SmbFile f2 = new SmbFile( f, "path/to/file" ); /* bad */
or
SmbFIle files[] = f.listFiles(); /* bad */

The correct way for a UI to support automatically appending a trailing
slash is to query the path when a user enters or modifies a URL and add it
if necessary. And it should only be necessary when a user actually enters
or modifies the URL. As they drill down and navigate around it should not
be necessary to check again as getName() returns a name with a trailing
slash if it is a directory.

Actually the simple way to do this is to have the UI just check to make
sure that the URL in the address bar at the time the user triggers a
request matches what it displayed. If it doesn't then the path needs to be
checked again.

For example in a file manager with an address bar the initial URL might be
"blank:". If someone then types in "smb://server" that doesn't match
"blank:" so the UI checks for the trailing slash which doesn't exist so it
query's the path to determine if it's a directory and if so add a slash.
Now you have "smb://server/". If the drills down to
"smb://server/path/dir/" by clicking on links at no point should it be
necessary to check these paths. If the user then enters
"smb://othersvr/path/to/file" that does not match what the UI previously
displayed (smb://server/path/dir/) so it check the path, finds it's not a
directory and does nothing.

In truth to handle java.net.URL objects generically in some kind of file
manager or web browser we might have to change something to make it a
little easier for the UI developer. For example the "directory must end
with '/'" MalformedURLException would probably be a nuisance. They should
be able to suppress that so they can do the isDirectory() call in peace.

Mike


More information about the jcifs mailing list