PDA

View Full Version : Retrieving modified date of file using QHttp



hardgeus
2nd December 2006, 22:25
I am writing a simple GPL app-updater in C++ using QT 4. Basically, the program hits a web server, downloads a file called files.xml, and for any file entries in the .xml file, it hits the server and downloads those files locally. I have this much working, but I now want the app to only download files on the server with a newer modified date than on the local machine (assuming the file is already on the local machine). After looking through the docs, I see no clear way to accomplish this with the QHttp class. It looks like what I should be trying is to make my Get request conditional with the modify date of the local file, and check for a "304 Not Modified" response from the server. Like I said, I don't see any clear way to accomplish this. Anyone have any idea?

jacek
2nd December 2006, 22:45
But which part is problematic for you? Sending the right request to the server or checking its answer?

hardgeus
2nd December 2006, 23:16
But which part is problematic for you? Sending the right request to the server or checking its answer?

I think I'm on the right track right now...Rather than using the convenience function "get" I am modifying it to do the following:

QHttpRequestHeader header("GET", sFilename );
header.setValue("Host", sHost );
header.setValue("If-Modified-Since", sFileDate);
http->setHost( sHost );
http->request(header);

I'm still working on this. The main problem I was having is that I was using the "get" convenience function which didn't seem to have the ability to send custom headers. After I get my request correct, I assume that in my readResponseHeader callback I need to add a case for response code "304" (I'm currently aborting the transfer if I don't get 200)

So I think I'm on the right track...I should be done with the whole project in a couple of days, once I'm done I'll post a link to the code in this thread.

hardgeus
3rd December 2006, 15:49
But which part is problematic for you? Sending the right request to the server or checking its answer?

Hrm...I've got the Get working using the request method, but the server seems to be totally ignoring the If-Modified-Since header. My code is:

QHttpRequestHeader header("GET", url.path() );
header.setValue("Host", url.host() );
header.setValue("If-Modified-Since", "Sun, 31 Dec 2006 19:24:26 GMT");
m_httpGetId = m_http->request(header, NULL, m_pFileHandle );

The file is retrieved, and the If-Modified-Since seems to be ignored. I made one of my retrieved files a .php script with phpinfo(), and the headers ARE being received. After digging, my date format looks to be correct, so I have no idea why it's being ignored.

hardgeus
3rd December 2006, 15:55
header.setValue("If-Modified-Since", "Sun, 31 Dec 2006 19:24:26 GMT");



Ack, I need to stop answering my own questions. After some digging into the HTTP spec, any invalid date is silently ignored, this includes any dates in the future. I have 304 responses now. Now to figure out how to make my local files have the same date stamp as the file on the server :P

jacek
3rd December 2006, 16:29
Now to figure out how to make my local files have the same date stamp as the file on the server
QFileInfo::lastModified()

QDateTime::toUTC()

http://wiki.qtcentre.org/index.php?title=QLocale

hardgeus
3rd December 2006, 17:35
QFileInfo::lastModified()



I already have that much working for determining whether the local file is newer than the file on the server (since I am sending the local stamp in the Get header, and the server is determining whether to send a 304, I don't really need to know the server side time in this step), so far so good, but the problem is that whenever I *save* the file, its local timestamp is set to whenever I downloaded it, and not the timestamp from the server. I was hoping that this would be handled transparently, but it looks like I am going to have to manually retrieve the server side file timestamp and manually set it to my local file.

hardgeus
3rd December 2006, 17:52
OK, I got it. In my slot for readResponseHeader I can pull the last modified date:

QString sModified = responseHeader.value( "Last-Modified" );

I promise I'll shut up now until I have the full code ready to link :P

hardgeus
3rd December 2006, 22:42
I promise I'll shut up now until I have the full code ready to link :P


Unless someone wants to save me a few hours of digging and tell me how to manually set the modify date on a file :P

jacek
3rd December 2006, 23:20
Unless someone wants to save me a few hours of digging and tell me how to manually set the modify date on a file :P
You can use utime(2), it's a part of POSIX, so it should be available on windows too.