Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I generate an http ETag in c#?

Tags:

c#

http

etag

Given a file being returned as part of a http request. What is the correct method of creating an ETag for that file?

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19

I have seen it done several ways

  • Using the last write time of the file converted to ticks. Which is what NancyFX does https://github.com/NancyFx/Nancy/blob/master/src/Nancy/Responses/GenericFileResponse.cs
  • Using a hash of the file http://hartzer.wordpress.com/2009/10/04/client-side-caching/
like image 608
Simon Avatar asked Oct 13 '11 05:10

Simon


People also ask

How is ETag generated?

Generating ETag ValueIt can be created and updated manually or can be auto-generated. Common methods of its auto-generation include using a hash of the resource's content or just a hash of the last modification timestamp. The generated hash should be collision-free.

Where is ETag generated?

ETag generationThe method by which ETags are generated has never been specified in the HTTP specification. Common methods of ETag generation include using a collision-resistant hash function of the resource's content, a hash of the last modification timestamp, or even just a revision number.

What is ETag in HTTP response?

An ETag (entity tag) is an HTTP header that is used to validate that the client (such as a mobile device) has the most recent version of a record. When a GET request is made, the ETag is returned as a response header. The ETag also allows the client to make conditional requests.

How do I get ETag headers?

First, you retrieve the current entity data by using a GET request that includes the If-Match request header. The ETag information is returned along with the entity content. Then, you send a PUT update request that includes the If-Match request header with the ETag information from the previous GET request.


2 Answers

To generate a static file's ETag which will be compatible with Nginx:

// Generate ETag from file's size and last modification time as unix timestamp in seconds from 1970
public static string MakeEtag(long lastMod, long size)
{
    string etag = '"' + lastMod.ToString("x") + '-' + size.ToString("x") + '"';
    return etag;
}

public static void Main(string[] args)
{
    long lastMod = 1578315296;
    long size = 1047;
    string etag = MakeEtag(lastMod, size);
    Console.WriteLine("ETag: " + etag);
    //=> ETag: "5e132e20-417"
}

See my comment about different ETag schemas

like image 184
Sergey Ponomarev Avatar answered Sep 21 '22 00:09

Sergey Ponomarev


Semantically the ETag should change when the content changes:

So the Hash seems appropriate... but the ETag must also be unique on different URLs and/or different timestamps of duplicate files... so to be on the safe side hash the file, concatenate that with the timestamp of the last modification and the url and hash that again...

like image 40
Yahia Avatar answered Sep 20 '22 00:09

Yahia