views:

43

answers:

2

Hi,

I have a webservice to download files. With every incoming request, i check for the checksum and timestamp of the file requested to be downloaded, and the file on the server. In case they are same, i dont have to download it again.

The code on server side is:

string checksum; //calculate this using methods in System.Security.Cryptography
string timestamp = File.GetLastAccessTimeUtc(filename).ToString();

string incCheckSum = WebOperationContext.Current.IncomingRequest.Header["If-None-Match"];
string incTimestamp = WebOperationContext.Current.IncomingRequest.Header["If-Modified-Since"];

if(checksum == incCheckSum && timestamp == incTimeStamp)
{
  WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotModified;
  return null;
}

WebOperationContext.Current.OutgoingResponse.Headers["Last-Modified"] = timestamp;
WebOperationContext.Current.OutgoingResponse.Headers["ETag"] = checksum;
return FileStream("Filename",FileMode.Open, FileAccess.Read,FileShare.Read);

On the client side:

HttpWebRequest request = (HttpWebRequest)WebRequest.create("http://somewebsite.com");
request.Header["If-None-Match"] = //get checksum file on the disk
request.Header["If-Modified-Since"] = "Last Modified Time"  // I get an exception here:

The exception says,

"The header must be modified using the appropriate property"

Then I do

request.IfModifiedSince = //Last Access UTC time of the file

Now, this change causes problems. Whenever a request comes to server, the last access time always is in a different format and it never matches. So if the last modified time of file is 8/13/2010 5:27:12 PM, on the server side i am getting ["If-Modified-Since"] value as "Fri, 13 Aug 2010 17:27:12 GMT"

How can I correct this?

When I use fiddler and add to "request headers" the following:

If-Modified-Since= last access time
If-None-Match= checksum

this works fine.

A: 

You can either read both strings into a DateTime object which you compare, or you can make sure your Date strings are in the same format.

On the server side:

string timestamp = File.GetLastAccessTimeUtc(filename).ToString("yyyy-MM-dd HH:mm:ss");

and

string incTimestamp = WebOperationContext.Current.IncomingRequest.IfModifiedSincee.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss");

You could also drop ToString and compare the DateTime objects directly.

Mikael Svenson
i still did not understand the client side changes fully, should i do: request.IfModifiedSince.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss") = File.GetLastAccessUtc(filename)
Adam
I had to re-read your question in order to understand it completely regarding the server and client, but I think I have fixed my answer now. The server will now compare the File date and the header date from the request in the same format.
Mikael Svenson
A: 

On your server side; you are controlling the format of the header; because you create the string from the date, and then assigns it explicitly to the request header field. You should format that correctly, so it matches the header set by the client.

The IfModifiedSince property sets the header value in the correct format; according to the HTTP specification, see section 3.3 here

driis
What is still unclear to me is: if i mention a request header named "If-Modified-Since" and string value for that, Fiddler sets it exactly to that value but I can't set to a string value.
Adam