PDA

View Full Version : QUrl/QNAM access to local login file



mcarter
16th April 2013, 00:02
I want to download a file from a user account on one of our data systems. If I try to use QUrl("ftp://user:passwd@host/file.dat") is does not work. When I try to use it in QNAM the error reports 'Could not get file size'. I can see the file sitting in the user account, but I cannot seem to access the file.

I have played around a bit and have found that if I use "ftp://user:passwd@host/home/user/file.dat" it will download the file. I cannot guarantee that the directory will be the same for all the logins.

Also, if I build the QUrl by its components, setHost/setUserName/setPassword and for setPath just use "file.dat", it will also properly download the file (even though the url.toString() shows the same original "ftp://user:passwd@host/file.dat" string)

Can I use QUrl/QNAM to access a local login file?

wysota
16th April 2013, 00:25
QNetworkAccessManager does what you tell it to -- if you tell it to download a file called "file.dat" in the root directory of the ftp server then it asks the server for a file located in the root directory of the server. Then it is the server's responsibility to find and offer the file to the client, the client side has nothing to do with it.

I am not sure what you mean by "local login file". If you mean that you want to access a file on a local filesystem then you can do that using the file:// protocol.

mcarter
16th April 2013, 00:41
I want to access a file (file.dat) local to the home directory of the 'user' I am logging into on a particular host . . . not the ftp server root.

ChrisW67
16th April 2013, 00:43
I think "local login file" means a file relative to the user's home directory, i.e. the one they get with interactive login. The first URL would do that if the FTP server chooses to make the current working directory the same as the home directory of the authenticated user. That does not seem to be the case; it looks like the FTP server is configured to make the system root directory the CWD.

Using the Qurl methods to build the URL may be encoding a reserved character in the user name or password, which may explain why that method works.

mcarter
16th April 2013, 23:42
it does not seem to be related to the username/password combination . . . it seems to be the path

if I have the following QUrl: QUrl url("ftp://user:passwd@host/file.dat"), this will try to access a file in the root directory and not in the home directory of the user account. If I add the following code immediately after this assignment:



QString path = myUrl.path();
if( path.startsWith("/") ) myUrl.setPath( path.remove(0,1) );


to remove the initial '/' in what it considers the path, then everything works correctly.

It also works if you actually want to access something from root directory, eg QUrl("ftp://user:passwd@host//data/test.dat"), by using two slashes ('//')

wysota
16th April 2013, 23:50
You need to understand that interpretation of the url belongs to the server and not the client. Different servers (that is differently configured) might treat the same url as different canonical paths. Some configurations will chroot the client to a specific directory, others will not.

mcarter
17th April 2013, 00:24
Exactly, so why would QUrl force it to always be from the root directory. There is absolutely no way to access a file in the home directory allowing the default parsing within QUrl. With the modified path, I can get the same access as with curl and mozilla/firefox.

This might just be related to ftp. Since QNetworkRequest with QNAM relies heavily on QUrl, this tweak of the path seemed to be needed. The full url string is not actually sent to the server but the url components are used to access the server (using host/port, setting user/passwd) and the path is used based on the operation to perform, eg get.

ChrisW67
17th April 2013, 00:31
Ultimately it seems that you have a solution anyway:

Also, if I build the QUrl by its components, setHost/setUserName/setPassword and for setPath just use "file.dat", it will also properly download the file (even though the url.toString() shows the same original "ftp://user:passwd@host/file.dat" string)

Why not just use it?

If you want to know why might I suggest you try a few things:

Rather than look at QUrl::toString() look at QUrl::toEncoded() after creating your QUrl.
Use a real FTP program to login to your FTP server as your user. What directory are you in by default? Does file.dat exist there? Can you see its file size? (That was the original complaint)
Try "ftp://user:pass@host/~/file.dat"... it may work if the FTP server is UNIX-ish.
With Wireshark watch the exchange with the server using your broken method and the working one. What's the difference?

mcarter
18th April 2013, 00:36
My response was to wysota's comment . . . and yes I do have a solution and will be using it, i believe for just the ftp scheme


Rather than look at QUrl::toString() look at QUrl::toEncoded() after creating your QUrl.
does not seem to be any difference


Use a real FTP program to login to your FTP server as your user. What directory are you in by default? Does file.dat exist there? Can you see its file size? (That was the original complaint)
I did this originally to verify that the file was actually in the home directory of the user


With Wireshark watch the exchange with the server using your broken method and the working one. What's the difference?
Your great suggestion to use wireshark helped to confirm what I thought was happening . . . it is sending the path component of the QUrl as is, so the tweak to the path to remove the starting '/' is working as expected and accessing the specified file.

ChrisW67
18th April 2013, 00:58
If it is doing that then you should report that as a bug in the QUrl QString constructor. The '/' between the host and the start of the path is not part of the path on the server in FTP URL scheme (http://tools.ietf.org/html/rfc1738)

You best read https://bugreports.qt-project.org/browse/QTBUG-9957 first

mcarter
18th April 2013, 15:48
If it is doing that then you should report that as a bug in the QUrl QString constructor. The '/' between the host and the start of the path is not part of the path on the server in FTP URL scheme (http://tools.ietf.org/html/rfc1738)

You best read https://bugreports.qt-project.org/browse/QTBUG-9957 first
HaHaHa . . . wow, forgot all about that . . . it is interesting you site this bug since I am the one who submitted it 3 years ago . . . i even sited rfc1738 (URL) but assignee sited rfc3986 (http://tools.ietf.org/html/rfc3986) (URI) which is suppose to be an update to standard and that changes the use of path and seems to be the one implemented by QUrl

Looks like the only course of action is to remove the starting '/' in the path for the ftp scheme when using QUrl decoding
thanks ChrisW67 for working thru this with me