【问题标题】:How do I generate an http ETag in c#?如何在 c# 中生成 http ETag?
【发布时间】:2011-12-06 16:14:32
【问题描述】:

给定一个作为 http 请求的一部分返回的文件。为该文件创建 ETag 的正确方法是什么?

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

我已经看到了几种方法

【问题讨论】:

    标签: c# http etag


    【解决方案1】:

    答案是视情况而定。

    Etag 有两种,弱的和强的。弱的可以让你做某些条件操作,但大多数都需要强的etag。

    对强 etag 的唯一限制是,如果表示由于某种原因发生变化,则 etag 也会发生变化。如果它是一个文件,您可以生成一个哈希,但这会迫使您在生成该实体时将其保留在内存中。或者,您可以简单地流式传输内容并将 Etag 添加为尾随 http 标头,但目前几乎没有服务器支持该功能(非常有用且不受欢迎)。

    刻度的分辨率较低,即使内容不同,同一文件上的两个连续写入也可能具有相同的刻度数。在那个阶段,如果 etag 很强并且您处于泥水中,则它现在无效。确实与 Last-Modified 相同的问题。大多数 HTTP 服务器处理这个问题的方式是根据文件的多个属性,即时间戳、大小和可能的文件对象 ID(Apache 中的 inode,可能添加到 NT 上的对象存储条目的完整路径,以及IIS 也为该值添加了一个计数器,因此服务器上的两个配置更改将生成不同的 etag,以防发生更改。

    如果您使用某种数据库,则 id + version 应该是一个强大的 etag(再次,前提是您所拥有的内容不是多个事物的集合,每个事物都可以独立更改而无需根更改版本) .

    因此如何计算它实际上取决于您的场景,并且在写入时(开始服务之前)持久保存文件的哈希可能对您帮助最大,特别是因为它是一个非常有用的功能,因为许多其他原因。

    【讨论】:

      【解决方案2】:

      语义上,ETag 应该在内容发生变化时发生变化:

      所以哈希似乎是合适的......但是 ETag 在不同的 URL 和/或重复文件的不同时间戳上也必须是唯一的......所以为了安全起见,将文件与时间戳连接起来最后一次修改和 url 并再次哈希...

      【讨论】:

        【解决方案3】:

        生成与 Nginx 兼容的静态文件的 ETag:

        // 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"
        }
        

        请参阅my comment 了解不同的 ETag 架构

        【讨论】:

          猜你喜欢
          • 2010-09-05
          • 2020-10-14
          • 2018-05-10
          • 1970-01-01
          • 1970-01-01
          • 2013-06-05
          • 2015-08-01
          • 1970-01-01
          • 2010-09-21
          相关资源
          最近更新 更多