Thuật toán đằng sau thế hệ nginx etag


17

Thuật toán được sử dụng để tạo etags trong Nginx là gì? Chúng trông giống như "554b73dc-6f0d" bây giờ.

Có phải chúng được tạo ra chỉ từ dấu thời gian?


1
Tôi không tin rằng chúng có chứa một nút (không giống như Apache theo mặc định) ... mặc dù tôi gặp khó khăn trong việc tìm kiếm nơi mà tôi đã tìm thấy cách đây rất lâu (tốt hơn cho cụm bộ đệm). Bạn đang làm việc trong một môi trường không có đồng hồ hữu ích (ví dụ: được nhúng)?
Cameron Kerr

1
Có một số thông tin liên quan trong developer.yahoo.com/performance/rules.html#etags (nhưng không liên quan đến Nginx)
Cameron Kerr

Câu trả lời:


32

Từ mã nguồn: http://lxr.nginx.org/ident?_i=ngx_http_set_etag

1803 ngx_int_t
1804 ngx_http_set_etag(ngx_http_request_t *r)
1805 {
1806     ngx_table_elt_t           *etag;
1807     ngx_http_core_loc_conf_t  *clcf;
1808 
1809     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1810 
1811     if (!clcf->etag) {
1812         return NGX_OK;
1813     }
1814 
1815     etag = ngx_list_push(&r->headers_out.headers);
1816     if (etag == NULL) {
1817         return NGX_ERROR;
1818     }
1819 
1820     etag->hash = 1;
1821     ngx_str_set(&etag->key, "ETag");
1822 
1823     etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
1824     if (etag->value.data == NULL) {
1825         etag->hash = 0;
1826         return NGX_ERROR;
1827     }
1828 
1829     etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
1830                                   r->headers_out.last_modified_time,
1831                                   r->headers_out.content_length_n)
1832                       - etag->value.data;
1833 
1834     r->headers_out.etag = etag;
1835 
1836     return NGX_OK;
1837 }

Bạn có thể thấy trên các dòng 1830 và 1831 rằng đầu vào là thời gian sửa đổi cuối cùng và độ dài nội dung.


So sánh với Apache ETags , cũng được tính toán từ thời gian và kích thước sửa đổi, nhưng cũng có thể được cấu hình để phụ thuộc vào nút của tệp.
Raedwald

1

Trong PHP ai sẽ cần nó.

$pathToFile = '/path/to/file.png';

$lastModified = filemtime($pathToFile);
$length = filesize($pathToFile);

header('ETag: "' . sprintf('%x-%x', $lastModified, $length) . '"');

3
Làm thế nào là tốt hơn so với câu trả lời được chấp nhận?
RalfFriedl

1
@RalfFriedl câu trả lời này sẽ tốt hơn cho các lập trình viên PHP, bởi vì trong tương lai một số lập trình viên PHP như tôi sẽ tìm kiếm 3 từ khóa "nginx", "etag", "alg" và anh ta sẽ tìm thấy câu trả lời của tôi. Điều này có lẽ sẽ ngăn chặn việc tạo ra các bản sao của câu hỏi.
Max_Payne
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.