A batteries included HTTP/1.1 client in OCaml

magic mime and dates

+12642 -103
+1
dune-project
··· 34 34 base64 35 35 logs 36 36 decompress 37 + magic-mime 37 38 (odoc :with-doc) 38 39 (alcotest (and :with-test (>= 1.7.0))) 39 40 (eio_main :with-test)))
+9 -21
lib/body.ml
··· 29 29 Stream { source; mime; length } 30 30 31 31 let of_file ?mime file = 32 - let mime = match mime with 33 - | Some m -> m 34 - | None -> 35 - (* Guess MIME type from filename if available *) 36 - let path = Eio.Path.native_exn file in 37 - let mime_map = [ 38 - (".json", Mime.json); 39 - (".html", Mime.html); 40 - (".xml", Mime.xml); 41 - (".txt", Mime.text); 42 - ] in 43 - let guessed = 44 - List.find_map (fun (suffix, mime_type) -> 45 - if String.ends_with ~suffix path then Some mime_type else None 46 - ) mime_map 47 - |> Option.value ~default:Mime.octet_stream 48 - in 49 - Log.debug (fun m -> m "Guessed MIME type %s for file %s" (Mime.to_string guessed) path); 50 - guessed 51 - in 32 + let path = Eio.Path.native_exn file in 33 + let mime = Option.value mime ~default:( 34 + (* Use magic-mime library to guess MIME type from file extension *) 35 + let guessed_str = Magic_mime.lookup path in 36 + let guessed = Mime.of_string guessed_str in 37 + Log.debug (fun m -> m "Guessed MIME type %s for file %s" (Mime.to_string guessed) path); 38 + guessed 39 + ) in 52 40 Log.debug (fun m -> m "Creating file body from %s with MIME type %s" 53 - (Eio.Path.native_exn file) (Mime.to_string mime)); 41 + path (Mime.to_string mime)); 54 42 File { file; mime } 55 43 56 44 let json_encoding_error e =
+4 -2
lib/body.mli
··· 58 58 it will be used for the Content-Length header, otherwise chunked encoding is used. *) 59 59 60 60 val of_file : ?mime:Mime.t -> _ Eio.Path.t -> t 61 - (** [of_file ?mime path] creates a body from a file. The MIME type is inferred from 62 - the file extension if not provided. *) 61 + (** [of_file ?mime path] creates a body from a file. If [mime] is not provided, 62 + the MIME type is automatically detected from the file extension using the 63 + {{:https://github.com/mirage/ocaml-magic-mime}magic-mime} library, 64 + which provides accurate MIME type mappings for hundreds of file extensions. *) 63 65 64 66 (** {1 Convenience Constructors} *) 65 67
+6 -24
lib/cache_control.ml
··· 283 283 2. max-age 284 284 3. Expires - Date 285 285 4. Heuristic (we return None, let caller decide) *) 286 + let ( let* ) = Option.bind in 286 287 match response_cc.max_age with 287 288 | Some age -> Some age 288 289 | None -> 289 290 match expires, date with 290 291 | Some exp_str, Some date_str -> 291 - (* Parse HTTP dates *) 292 - let parse_http_date s = 293 - (* Simple HTTP-date parsing - try RFC 1123 format *) 294 - try 295 - (* "Sun, 06 Nov 1994 08:49:37 GMT" *) 296 - Scanf.sscanf s "%_s %d %s %d %d:%d:%d GMT" 297 - (fun day month_str year hour min sec -> 298 - let month = match String.lowercase_ascii month_str with 299 - | "jan" -> 1 | "feb" -> 2 | "mar" -> 3 | "apr" -> 4 300 - | "may" -> 5 | "jun" -> 6 | "jul" -> 7 | "aug" -> 8 301 - | "sep" -> 9 | "oct" -> 10 | "nov" -> 11 | "dec" -> 12 302 - | _ -> failwith "invalid month" 303 - in 304 - match Ptime.of_date_time ((year, month, day), ((hour, min, sec), 0)) with 305 - | Some t -> t 306 - | None -> failwith "invalid date") 307 - with _ -> failwith "parse failed" 308 - in 309 - (try 310 - let exp_time = parse_http_date exp_str in 311 - let date_time = parse_http_date date_str in 312 - let diff = Ptime.diff exp_time date_time in 313 - Ptime.Span.to_int_s diff 314 - with _ -> None) 292 + (* Use Http_date.parse to parse HTTP dates *) 293 + let* exp_time = Http_date.parse exp_str in 294 + let* date_time = Http_date.parse date_str in 295 + let diff = Ptime.diff exp_time date_time in 296 + Ptime.Span.to_int_s diff 315 297 | _ -> None 316 298 317 299 (** Check if a response is cacheable based on Cache-Control directives *)
+2 -1
lib/dune
··· 27 27 decompress.de 28 28 decompress.zl 29 29 decompress.gz 30 - bigstringaf)) 30 + bigstringaf 31 + magic-mime))
+54
lib/http_date.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** HTTP-date parsing per RFC 9110 Section 5.6.7 *) 7 + 8 + let src = Logs.Src.create "requests.http_date" ~doc:"HTTP Date Parsing" 9 + module Log = (val Logs.src_log src : Logs.LOG) 10 + 11 + (** Parse HTTP-date (RFC 9110 Section 5.6.7) to Ptime.t *) 12 + let parse s = 13 + (* HTTP-date format: "Sun, 06 Nov 1994 08:49:37 GMT" (RFC 1123) *) 14 + (* Also supports obsolete formats per RFC 9110 *) 15 + let s = String.trim s in 16 + 17 + (* Helper to parse month name *) 18 + let parse_month month_str = 19 + match String.lowercase_ascii month_str with 20 + | "jan" -> 1 | "feb" -> 2 | "mar" -> 3 | "apr" -> 4 21 + | "may" -> 5 | "jun" -> 6 | "jul" -> 7 | "aug" -> 8 22 + | "sep" -> 9 | "oct" -> 10 | "nov" -> 11 | "dec" -> 12 23 + | _ -> failwith "invalid month" 24 + in 25 + 26 + (* Try different date formats in order of preference *) 27 + let parsers = [ 28 + (* RFC 1123 format: "Sun, 06 Nov 1994 08:49:37 GMT" *) 29 + (fun () -> 30 + Scanf.sscanf s "%_s %d %s %d %d:%d:%d GMT" 31 + (fun day month_str year hour min sec -> 32 + let month = parse_month month_str in 33 + Ptime.of_date_time ((year, month, day), ((hour, min, sec), 0)))); 34 + 35 + (* RFC 850 format: "Sunday, 06-Nov-94 08:49:37 GMT" *) 36 + (fun () -> 37 + Scanf.sscanf s "%_s %d-%s@-%d %d:%d:%d GMT" 38 + (fun day month_str year2 hour min sec -> 39 + let year = if year2 >= 70 then 1900 + year2 else 2000 + year2 in 40 + let month = parse_month month_str in 41 + Ptime.of_date_time ((year, month, day), ((hour, min, sec), 0)))); 42 + 43 + (* ANSI C asctime() format: "Sun Nov 6 08:49:37 1994" *) 44 + (fun () -> 45 + Scanf.sscanf s "%_s %s %d %d:%d:%d %d" 46 + (fun month_str day hour min sec year -> 47 + let month = parse_month month_str in 48 + Ptime.of_date_time ((year, month, day), ((hour, min, sec), 0)))); 49 + ] in 50 + 51 + (* Try each parser until one succeeds *) 52 + List.find_map (fun parser -> 53 + try parser () with _ -> None 54 + ) parsers
+29
lib/http_date.mli
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** HTTP-date parsing per RFC 9110 Section 5.6.7 7 + 8 + This module provides parsing of HTTP date strings as defined in RFC 9110. 9 + It supports three date formats: 10 + - RFC 1123: "Sun, 06 Nov 1994 08:49:37 GMT" (preferred) 11 + - RFC 850: "Sunday, 06-Nov-94 08:49:37 GMT" (obsolete) 12 + - ANSI C asctime(): "Sun Nov 6 08:49:37 1994" (obsolete) 13 + *) 14 + 15 + (** Log source for HTTP date parsing *) 16 + val src : Logs.Src.t 17 + 18 + (** Parse an HTTP-date string to Ptime.t. 19 + 20 + [parse s] attempts to parse the string [s] as an HTTP-date using 21 + the three supported formats. Returns [None] if parsing fails. 22 + 23 + Examples: 24 + {[ 25 + parse "Sun, 06 Nov 1994 08:49:37 GMT" (* RFC 1123 *) 26 + parse "Sunday, 06-Nov-94 08:49:37 GMT" (* RFC 850 *) 27 + parse "Sun Nov 6 08:49:37 1994" (* asctime *) 28 + ]} *) 29 + val parse : string -> Ptime.t option
+1
lib/requests.ml
··· 11 11 module Method = Method 12 12 module Mime = Mime 13 13 module Headers = Headers 14 + module Http_date = Http_date 14 15 module Auth = Auth 15 16 module Timeout = Timeout 16 17 module Body = Body
+17 -55
lib/response.ml
··· 43 43 44 44 let header name t = Headers.get name t.headers 45 45 46 + (** Option monad operators for cleaner code *) 47 + let ( let* ) = Option.bind 48 + let ( let+ ) x f = Option.map f x 49 + 46 50 let content_type t = 47 - Headers.get "content-type" t.headers 48 - |> Option.map Mime.of_string 51 + let+ ct = Headers.get "content-type" t.headers in 52 + Mime.of_string ct 49 53 50 54 let content_length t = 51 - match Headers.get "content-length" t.headers with 52 - | None -> None 53 - | Some len -> 54 - try Some (Int64.of_string len) 55 - with _ -> None 55 + let* len = Headers.get "content-length" t.headers in 56 + try Some (Int64.of_string len) with _ -> None 56 57 57 58 let location t = Headers.get "location" t.headers 58 59 ··· 65 66 66 67 let last_modified t = Headers.get "last-modified" t.headers 67 68 68 - (** Parse HTTP-date (RFC 9110 Section 5.6.7) to Ptime.t *) 69 - let parse_http_date s = 70 - (* HTTP-date format: "Sun, 06 Nov 1994 08:49:37 GMT" (RFC 1123) *) 71 - (* Also supports obsolete formats per RFC 9110 *) 72 - let s = String.trim s in 73 - try 74 - (* Try RFC 1123 format: "Sun, 06 Nov 1994 08:49:37 GMT" *) 75 - Scanf.sscanf s "%_s %d %s %d %d:%d:%d GMT" 76 - (fun day month_str year hour min sec -> 77 - let month = match String.lowercase_ascii month_str with 78 - | "jan" -> 1 | "feb" -> 2 | "mar" -> 3 | "apr" -> 4 79 - | "may" -> 5 | "jun" -> 6 | "jul" -> 7 | "aug" -> 8 80 - | "sep" -> 9 | "oct" -> 10 | "nov" -> 11 | "dec" -> 12 81 - | _ -> failwith "invalid month" 82 - in 83 - Ptime.of_date_time ((year, month, day), ((hour, min, sec), 0))) 84 - with _ -> 85 - try 86 - (* Try RFC 850 format: "Sunday, 06-Nov-94 08:49:37 GMT" *) 87 - Scanf.sscanf s "%_s %d-%s@-%d %d:%d:%d GMT" 88 - (fun day month_str year2 hour min sec -> 89 - let year = if year2 >= 70 then 1900 + year2 else 2000 + year2 in 90 - let month = match String.lowercase_ascii month_str with 91 - | "jan" -> 1 | "feb" -> 2 | "mar" -> 3 | "apr" -> 4 92 - | "may" -> 5 | "jun" -> 6 | "jul" -> 7 | "aug" -> 8 93 - | "sep" -> 9 | "oct" -> 10 | "nov" -> 11 | "dec" -> 12 94 - | _ -> failwith "invalid month" 95 - in 96 - Ptime.of_date_time ((year, month, day), ((hour, min, sec), 0))) 97 - with _ -> 98 - (* Try ANSI C asctime() format: "Sun Nov 6 08:49:37 1994" *) 99 - try 100 - Scanf.sscanf s "%_s %s %d %d:%d:%d %d" 101 - (fun month_str day hour min sec year -> 102 - let month = match String.lowercase_ascii month_str with 103 - | "jan" -> 1 | "feb" -> 2 | "mar" -> 3 | "apr" -> 4 104 - | "may" -> 5 | "jun" -> 6 | "jul" -> 7 | "aug" -> 8 105 - | "sep" -> 9 | "oct" -> 10 | "nov" -> 11 | "dec" -> 12 106 - | _ -> failwith "invalid month" 107 - in 108 - Ptime.of_date_time ((year, month, day), ((hour, min, sec), 0))) 109 - with _ -> None 69 + let parse_http_date = Http_date.parse 110 70 111 71 let last_modified_ptime t = 112 - Option.bind (last_modified t) parse_http_date 72 + let* lm = last_modified t in 73 + Http_date.parse lm 113 74 114 75 let date t = Headers.get "date" t.headers 115 76 116 77 let date_ptime t = 117 - Option.bind (date t) parse_http_date 78 + let* d = date t in 79 + Http_date.parse d 118 80 119 81 let expires t = Headers.get "expires" t.headers 120 82 121 83 let expires_ptime t = 122 - Option.bind (expires t) parse_http_date 84 + let* exp = expires t in 85 + Http_date.parse exp 123 86 124 87 let age t = 125 - match Headers.get "age" t.headers with 126 - | Some s -> (try Some (int_of_string s) with _ -> None) 127 - | None -> None 88 + let* s = Headers.get "age" t.headers in 89 + try Some (int_of_string s) with _ -> None 128 90 129 91 (** {1 Cache-Control Parsing} 130 92
+7
lib/response.mli
··· 95 95 (** [last_modified response] returns the Last-Modified header as a raw string. 96 96 Format: HTTP-date (e.g., ["Sun, 06 Nov 1994 08:49:37 GMT"]) *) 97 97 98 + val parse_http_date : string -> Ptime.t option 99 + (** [parse_http_date s] parses an HTTP-date string (RFC 9110 Section 5.6.7) to Ptime.t. 100 + Supports RFC 1123, RFC 850, and ANSI C asctime() formats. 101 + Returns [None] if parsing fails. 102 + 103 + This is exposed for use by other modules that need to parse HTTP dates. *) 104 + 98 105 val last_modified_ptime : t -> Ptime.t option 99 106 (** [last_modified_ptime response] parses the Last-Modified header as a Ptime.t. 100 107 Returns [None] if the header is not present or cannot be parsed. *)
+1
requests.opam
··· 20 20 "base64" 21 21 "logs" 22 22 "decompress" 23 + "magic-mime" 23 24 "odoc" {with-doc} 24 25 "alcotest" {with-test & >= "1.7.0"} 25 26 "eio_main" {with-test}
+1660
spec/rfc1950.txt
··· 1 + 2 + <!DOCTYPE html> 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + <html data-bs-theme="auto" lang="en"> 11 + <head> 12 + 13 + <meta charset="utf-8"> 14 + <meta http-equiv="X-UA-Compatible" content="IE=edge"> 15 + <title> 16 + 17 + RFC 1950 - ZLIB Compressed Data Format Specification version 3.3 18 + 19 + </title> 20 + <meta name="viewport" content="width=device-width, initial-scale=1"> 21 + <link href="https://static.ietf.org/fonts/inter/import.css" rel="stylesheet"> 22 + <link href="https://static.ietf.org/fonts/noto-sans-mono/import.css" rel="stylesheet"> 23 + 24 + <link rel="stylesheet" href="https://static.ietf.org/dt/12.54.0/ietf/css/document_html_referenced.css"> 25 + 26 + <script type="module" crossorigin="" src="https://static.ietf.org/dt/12.54.0/assets/embedded-055c333d.js"></script> 27 + <link href="https://static.ietf.org/dt/12.54.0/assets/create-pinia-singleton-8312c5df.js" type="text/javascript" crossorigin="anonymous" rel="modulepreload" as="script" /> 28 + <link href="https://static.ietf.org/dt/12.54.0/assets/Scrollbar-ad8c5330.js" type="text/javascript" crossorigin="anonymous" rel="modulepreload" as="script" /> 29 + <script src="https://static.ietf.org/dt/12.54.0/ietf/js/document_html.js"></script> 30 + <script src="https://static.ietf.org/dt/12.54.0/ietf/js/theme.js"></script> 31 + 32 + <link rel="alternate" type="application/atom+xml" title="Document changes" href="/feed/document-changes/rfc1950/"> 33 + <meta name="description" 34 + 35 + content="ZLIB Compressed Data Format Specification version 3.3 (RFC 1950, )" 36 + > 37 + 38 + 39 + <link rel="apple-touch-icon" 40 + sizes="180x180" 41 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-180.png"> 42 + <link rel="icon" 43 + sizes="32x32" 44 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-32.png"> 45 + <link rel="icon" 46 + sizes="16x16" 47 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-16.png"> 48 + <link rel="manifest" href="/site.webmanifest"> 49 + <link rel="mask-icon" 50 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-mask.svg" 51 + color="#ffffff"> 52 + <meta name="msapplication-TileColor" 53 + content="#ffffff"> 54 + <meta name="theme-color" 55 + content="#ffffff"> 56 + 57 + 58 + 59 + 60 + 61 + <meta property="og:title" content="RFC 1950: ZLIB Compressed Data Format Specification version 3.3"> 62 + <meta property="og:url" content="https://datatracker.ietf.org/doc/html/rfc1950.txt"> 63 + <link rel="canonical" href="https://datatracker.ietf.org/doc/html/rfc1950.txt"> 64 + <meta property="og:site_name" content="IETF Datatracker"> 65 + <meta property="og:description" content="This specification defines a lossless compressed data format. This memo provides information for the Internet community. This memo does not specify an Internet standard of any kind."> 66 + <meta property="og:type" content="article"> 67 + 68 + <meta property="article:section" content="Individual Internet-Draft"> 69 + 70 + <meta property="article:author" content="L. Peter Deutsch"> 71 + <meta property="article:author" content="Jean-loup Gailly"> 72 + 73 + 74 + 75 + 76 + <style> 77 + 78 + .diff-form .select2-selection__rendered { 79 + direction: rtl; 80 + text-align: left; 81 + } 82 + </style> 83 + </head> 84 + <body> 85 + 86 + <noscript><iframe class="status" title="Site status" src="/status/latest"></iframe></noscript> 87 + <div class="vue-embed" data-component="Status"></div> 88 + <div class="btn-toolbar sidebar-toolbar position-fixed top-0 end-0 m-2 m-lg-3 d-print-none"> 89 + <div class="dropdown"> 90 + <button class="btn btn-outline-secondary btn-sm me-1 dropdown-toggle d-flex align-items-center" 91 + id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" 92 + aria-label="Toggle theme"> 93 + <i class="theme-icon-active bi bi-circle-half"></i> 94 + </button> 95 + 96 + <ul class="dropdown-menu" aria-labelledby="bd-theme"> 97 + <li> 98 + <button type="button" class="dropdown-item d-flex align-items-center" 99 + data-bs-theme-value="light" aria-pressed="false"> 100 + <i class="me-2 opacity-50 theme-icon bi bi-sun-fill"></i> 101 + Light<i class="bi bi-check2 ms-auto d-none"></i> 102 + </button> 103 + </li> 104 + <li> 105 + <button type="button" class="dropdown-item d-flex align-items-center" 106 + data-bs-theme-value="dark" aria-pressed="false"> 107 + <i class="me-2 opacity-50 theme-icon bi bi-moon-stars-fill"></i> 108 + Dark<i class="bi bi-check2 ms-auto d-none"></i> 109 + </button> 110 + </li> 111 + <li> 112 + <button type="button" class="dropdown-item d-flex align-items-center active" 113 + data-bs-theme-value="auto" aria-pressed="true"> 114 + <i class="me-2 opacity-50 theme-icon bi bi-circle-half"></i> 115 + Auto<i class="bi bi-check2 ms-auto d-none"></i> 116 + </button> 117 + </li> 118 + </ul> 119 + </div> 120 + <button class="btn btn-outline-secondary btn-sm sidebar-toggle" 121 + type="button" 122 + data-bs-toggle="collapse" 123 + data-bs-target="#sidebar" 124 + aria-expanded="true" 125 + aria-controls="sidebar" 126 + aria-label="Toggle metadata sidebar" 127 + title="Toggle metadata sidebar"> 128 + <i class="bi bi-arrow-bar-left sidebar-shown"></i> 129 + <i class="bi bi-arrow-bar-right sidebar-collapsed"></i> 130 + </button> 131 + </div> 132 + <nav class="navbar bg-light-subtle px-1 fixed-top d-print-none d-md-none"> 133 + <a class="nav-link ps-1" 134 + href="/doc/rfc1950/"> 135 + 136 + RFC 1950 137 + 138 + <br class="d-sm-none"> 139 + 140 + <span class="ms-sm-3 badge rounded-pill badge-inf"> 141 + 142 + Informational 143 + 144 + </span> 145 + </a> 146 + <button class="navbar-toggler p-1" 147 + type="button" 148 + data-bs-toggle="collapse" 149 + data-bs-target="#docinfo-collapse" 150 + aria-controls="docinfo-collapse" 151 + aria-expanded="false" 152 + aria-label="Show document information"> 153 + <span class="navbar-toggler-icon small"></span> 154 + </button> 155 + <div class="navbar-nav navbar-nav-scroll overscroll-none collapse pt-1" id="docinfo-collapse"> 156 + <div class="bg-light-subtle p-0"> 157 + <table class="table table-sm table-borderless small"> 158 + <tbody class="meta align-top"> 159 + <tr> 160 + <th scope="row"></th> 161 + <th scope="row">Title</th> 162 + <td class="edit"></td> 163 + <td>ZLIB Compressed Data Format Specification version 3.3</td> 164 + </tr> 165 + </tbody> 166 + 167 + 168 + 169 + 170 + 171 + 172 + 173 + 174 + <tbody class="meta align-top "> 175 + <tr> 176 + <th scope="row">Document</th> 177 + <th scope="row">Document type</th> 178 + <td class="edit"></td> 179 + <td> 180 + 181 + 182 + 183 + 184 + 185 + 186 + <span class="text-success">RFC 187 + 188 + - Informational 189 + 190 + </span> 191 + 192 + 193 + 194 + <br>May 1996 195 + 196 + <br> 197 + 198 + 199 + <a class="btn btn-sm btn-warning" 200 + title="Click to report an error in the document." 201 + href="https://www.rfc-editor.org/errata.php#reportnew" 202 + target="_blank"> 203 + Report errata 204 + </a> 205 + 206 + 207 + 208 + 209 + 210 + 211 + 212 + 213 + 214 + <div> 215 + Was 216 + <a href="/doc/draft-deutsch-zlib-spec/03/">draft-deutsch-zlib-spec</a> 217 + (individual) 218 + </div> 219 + 220 + 221 + 222 + 223 + 224 + 225 + 226 + 227 + 228 + 229 + <div class="alert alert-warning small p-2 mt-2" role="alert"> 230 + This RFC is labeled as "Legacy"; it was published before a formal source was recorded. 231 + This RFC is <strong>not endorsed by the IETF</strong> and has <strong>no formal standing</strong> in the 232 + <a href="/doc/rfc2026/">IETF standards process</a>. 233 + </div> 234 + 235 + 236 + 237 + 238 + </td> 239 + </tr> 240 + 241 + <tr> 242 + <td></td> 243 + <th scope="row">Select version</th> 244 + <td class="edit"></td> 245 + <td> 246 + 247 + 248 + 249 + 250 + <ul class="revision-list pagination pagination-sm text-center flex-wrap my-0"> 251 + 252 + 253 + 254 + 255 + <li class="page-item"> 256 + <a class="page-link" 257 + href="/doc/html/draft-deutsch-zlib-spec-03" 258 + rel="nofollow"> 259 + 03 260 + </a> 261 + </li> 262 + 263 + 264 + 265 + <li class="page-item rfc active"> 266 + <a class="page-link" 267 + href="/doc/html/rfc1950"> 268 + RFC 1950 269 + </a> 270 + </li> 271 + 272 + </ul> 273 + 274 + </td> 275 + </tr> 276 + 277 + <tr> 278 + <td></td> 279 + <th scope="row">Compare versions</th> 280 + <td class="edit"></td> 281 + <td> 282 + 283 + 284 + 285 + 286 + <form class="form-horizontal diff-form" 287 + action="https://author-tools.ietf.org/iddiff" 288 + method="get" 289 + target="_blank"> 290 + 291 + <select class="form-select form-select-sm mb-1 select2-field" 292 + data-max-entries="1" 293 + data-width="resolve" 294 + data-allow-clear="false" 295 + data-minimum-input-length="0" 296 + aria-label="From revision" 297 + name="url1"> 298 + 299 + <option value="rfc1950"> 300 + RFC 1950 301 + 302 + </option> 303 + 304 + <option value="draft-deutsch-zlib-spec-03" selected> 305 + draft-deutsch-zlib-spec-03 306 + 307 + </option> 308 + 309 + <option value="draft-deutsch-zlib-spec-02"> 310 + draft-deutsch-zlib-spec-02 311 + 312 + </option> 313 + 314 + <option value="draft-deutsch-zlib-spec-01"> 315 + draft-deutsch-zlib-spec-01 316 + 317 + </option> 318 + 319 + <option value="draft-deutsch-zlib-spec-00"> 320 + draft-deutsch-zlib-spec-00 321 + 322 + </option> 323 + 324 + 325 + </select> 326 + 327 + <select class="form-select form-select-sm mb-1 select2-field" 328 + data-max-entries="1" 329 + data-width="resolve" 330 + data-allow-clear="false" 331 + data-minimum-input-length="0" 332 + aria-label="To revision" 333 + name="url2"> 334 + 335 + <option value="rfc1950" selected> 336 + RFC 1950 337 + 338 + </option> 339 + 340 + <option value="draft-deutsch-zlib-spec-03"> 341 + draft-deutsch-zlib-spec-03 342 + 343 + </option> 344 + 345 + <option value="draft-deutsch-zlib-spec-02"> 346 + draft-deutsch-zlib-spec-02 347 + 348 + </option> 349 + 350 + <option value="draft-deutsch-zlib-spec-01"> 351 + draft-deutsch-zlib-spec-01 352 + 353 + </option> 354 + 355 + <option value="draft-deutsch-zlib-spec-00"> 356 + draft-deutsch-zlib-spec-00 357 + 358 + </option> 359 + 360 + 361 + </select> 362 + 363 + <button type="submit" 364 + class="btn btn-primary btn-sm" 365 + value="--html" 366 + name="difftype"> 367 + Side-by-side 368 + </button> 369 + 370 + <button type="submit" 371 + class="btn btn-primary btn-sm" 372 + value="--hwdiff" 373 + name="difftype"> 374 + Inline 375 + </button> 376 + 377 + </form> 378 + </td> 379 + </tr> 380 + 381 + 382 + <tr> 383 + <td></td> 384 + <th scope="row">Authors</th> 385 + <td class="edit"> 386 + 387 + </td> 388 + <td> 389 + 390 + 391 + <span ><a 392 + title="Datatracker profile of L. Peter Deutsch" 393 + href="/person/ghost@aladdin.com" >L. Peter Deutsch</a> <a 394 + href="mailto:ghost%40aladdin.com" 395 + aria-label="Compose email to ghost@aladdin.com" 396 + title="Compose email to ghost@aladdin.com"> 397 + <i class="bi bi-envelope"></i></a></span>, 398 + 399 + <span ><a 400 + title="Datatracker profile of Jean-loup Gailly" 401 + href="/person/gzip@prep.ai.mit.edu" >Jean-loup Gailly</a> <a 402 + href="mailto:gzip%40prep.ai.mit.edu" 403 + aria-label="Compose email to gzip@prep.ai.mit.edu" 404 + title="Compose email to gzip@prep.ai.mit.edu"> 405 + <i class="bi bi-envelope"></i></a></span> 406 + 407 + 408 + <br> 409 + <a class="btn btn-primary btn-sm mt-1" href="mailto:rfc1950@ietf.org?subject=rfc1950" title="Send email to the document authors">Email authors</a> 410 + 411 + </td> 412 + </tr> 413 + 414 + 415 + <tr> 416 + <td></td> 417 + <th scope="row"> 418 + RFC stream 419 + </th> 420 + <td class="edit"> 421 + 422 + </td> 423 + <td > 424 + 425 + 426 + 427 + 428 + Legacy 429 + 430 + 431 + 432 + 433 + </td> 434 + </tr> 435 + 436 + <tr> 437 + <td></td> 438 + <th scope="row"> 439 + Other formats 440 + </th> 441 + <td class="edit"> 442 + </td> 443 + <td> 444 + 445 + 446 + <div class="buttonlist"> 447 + 448 + 449 + <a class="btn btn-primary btn-sm" 450 + 451 + target="_blank" 452 + href="https://www.rfc-editor.org/rfc/rfc1950.txt"> 453 + 454 + <i class="bi bi-file-text"></i> txt 455 + 456 + </a> 457 + 458 + 459 + 460 + <a class="btn btn-primary btn-sm" 461 + 462 + target="_blank" 463 + href="https://www.rfc-editor.org/rfc/rfc1950.html"> 464 + 465 + <i class="bi bi-file-code"></i> html 466 + 467 + </a> 468 + 469 + 470 + 471 + <a class="btn btn-primary btn-sm" 472 + 473 + download="rfc1950.pdf" 474 + 475 + 476 + target="_blank" 477 + href="https://www.rfc-editor.org/rfc/rfc1950.pdf"> 478 + 479 + <i class="bi bi-file-pdf"></i> pdf 480 + 481 + </a> 482 + 483 + 484 + 485 + 486 + 487 + <a class="btn btn-primary btn-sm" 488 + 489 + target="_blank" 490 + href="/doc/rfc1950/bibtex/"> 491 + 492 + <i class="bi bi-file-ruled"></i> bibtex 493 + 494 + </a> 495 + 496 + 497 + </div> 498 + 499 + 500 + </td> 501 + </tr> 502 + 503 + 504 + 505 + 506 + </tbody> 507 + <tr> 508 + <th scope="row"></th> 509 + <th scope="row"></th> 510 + <td class="edit"></td> 511 + <td> 512 + <a class="btn btn-sm btn-warning mb-3" 513 + target="_blank" 514 + href="https://github.com/ietf-tools/datatracker/issues/new/choose"> 515 + Report a bug 516 + <i class="bi bi-bug"></i> 517 + </a> 518 + </td> 519 + </tr> 520 + </table> 521 + </div> 522 + </div> 523 + </nav> 524 + <div class="row g-0"> 525 + <div class="col-md-9 d-flex justify-content-center lh-sm" 526 + data-bs-spy="scroll" 527 + data-bs-target="#toc-nav" 528 + data-bs-smooth-scroll="true" 529 + tabindex="0" 530 + id="content"> 531 + 532 + <div class="rfcmarkup"> 533 + <br class="noprint"> 534 + <!-- [html-validate-disable-block attr-quotes, void-style, element-permitted-content, heading-level -- FIXME: rfcmarkup/rfc2html generates HTML with issues] --> 535 + <div class="rfcmarkup"><pre>Network Working Group P. Deutsch 536 + Request for Comments: 1950 Aladdin Enterprises 537 + Category: Informational J-L. Gailly 538 + Info-ZIP 539 + May 1996 540 + 541 + 542 + <span class="h1">ZLIB Compressed Data Format Specification version 3.3</span> 543 + 544 + Status of This Memo 545 + 546 + This memo provides information for the Internet community. This memo 547 + does not specify an Internet standard of any kind. Distribution of 548 + this memo is unlimited. 549 + 550 + IESG Note: 551 + 552 + The IESG takes no position on the validity of any Intellectual 553 + Property Rights statements contained in this document. 554 + 555 + Notices 556 + 557 + Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly 558 + 559 + Permission is granted to copy and distribute this document for any 560 + purpose and without charge, including translations into other 561 + languages and incorporation into compilations, provided that the 562 + copyright notice and this notice are preserved, and that any 563 + substantive changes or deletions from the original are clearly 564 + marked. 565 + 566 + A pointer to the latest version of this and related documentation in 567 + HTML format can be found at the URL 568 + &lt;<a href="ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html">ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html</a>&gt;. 569 + 570 + Abstract 571 + 572 + This specification defines a lossless compressed data format. The 573 + data can be produced or consumed, even for an arbitrarily long 574 + sequentially presented input data stream, using only an a priori 575 + bounded amount of intermediate storage. The format presently uses 576 + the DEFLATE compression method but can be easily extended to use 577 + other compression methods. It can be implemented readily in a manner 578 + not covered by patents. This specification also defines the ADLER-32 579 + checksum (an extension and improvement of the Fletcher checksum), 580 + used for detection of data corruption, and provides an algorithm for 581 + computing it. 582 + 583 + 584 + 585 + 586 + <span class="grey">Deutsch &amp; Gailly Informational [Page 1]</span></pre> 587 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-2" ></span> 588 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 589 + 590 + 591 + Table of Contents 592 + 593 + <a href="#section-1">1</a>. Introduction ................................................... <a href="#page-2">2</a> 594 + <a href="#section-1.1">1.1</a>. Purpose ................................................... <a href="#page-2">2</a> 595 + <a href="#section-1.2">1.2</a>. Intended audience ......................................... <a href="#page-3">3</a> 596 + <a href="#section-1.3">1.3</a>. Scope ..................................................... <a href="#page-3">3</a> 597 + <a href="#section-1.4">1.4</a>. Compliance ................................................ <a href="#page-3">3</a> 598 + <a href="#section-1.5">1.5</a>. Definitions of terms and conventions used ................ <a href="#page-3">3</a> 599 + <a href="#section-1.6">1.6</a>. Changes from previous versions ............................ <a href="#page-3">3</a> 600 + <a href="#section-2">2</a>. Detailed specification ......................................... <a href="#page-3">3</a> 601 + <a href="#section-2.1">2.1</a>. Overall conventions ....................................... <a href="#page-3">3</a> 602 + <a href="#section-2.2">2.2</a>. Data format ............................................... <a href="#page-4">4</a> 603 + <a href="#section-2.3">2.3</a>. Compliance ................................................ <a href="#page-7">7</a> 604 + <a href="#section-3">3</a>. References ..................................................... <a href="#page-7">7</a> 605 + <a href="#section-4">4</a>. Source code .................................................... <a href="#page-8">8</a> 606 + <a href="#section-5">5</a>. Security Considerations ........................................ <a href="#page-8">8</a> 607 + <a href="#section-6">6</a>. Acknowledgements ............................................... <a href="#page-8">8</a> 608 + <a href="#section-7">7</a>. Authors&#x27; Addresses ............................................. <a href="#page-8">8</a> 609 + <a href="#section-8">8</a>. Appendix: Rationale ............................................ <a href="#page-9">9</a> 610 + <a href="#section-9">9</a>. Appendix: Sample code ..........................................<a href="#page-10">10</a> 611 + 612 + <span class="h2"><a class="selflink" id="section-1" href="#section-1">1</a>. Introduction</span> 613 + 614 + 1.1. Purpose 615 + 616 + The purpose of this specification is to define a lossless 617 + compressed data format that: 618 + 619 + * Is independent of CPU type, operating system, file system, 620 + and character set, and hence can be used for interchange; 621 + 622 + * Can be produced or consumed, even for an arbitrarily long 623 + sequentially presented input data stream, using only an a 624 + priori bounded amount of intermediate storage, and hence can 625 + be used in data communications or similar structures such as 626 + Unix filters; 627 + 628 + * Can use a number of different compression methods; 629 + 630 + * Can be implemented readily in a manner not covered by 631 + patents, and hence can be practiced freely. 632 + 633 + The data format defined by this specification does not attempt to 634 + allow random access to compressed data. 635 + 636 + 637 + 638 + 639 + 640 + 641 + 642 + <span class="grey">Deutsch &amp; Gailly Informational [Page 2]</span></pre> 643 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-3" ></span> 644 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 645 + 646 + 647 + 1.2. Intended audience 648 + 649 + This specification is intended for use by implementors of software 650 + to compress data into zlib format and/or decompress data from zlib 651 + format. 652 + 653 + The text of the specification assumes a basic background in 654 + programming at the level of bits and other primitive data 655 + representations. 656 + 657 + 1.3. Scope 658 + 659 + The specification specifies a compressed data format that can be 660 + used for in-memory compression of a sequence of arbitrary bytes. 661 + 662 + 1.4. Compliance 663 + 664 + Unless otherwise indicated below, a compliant decompressor must be 665 + able to accept and decompress any data set that conforms to all 666 + the specifications presented here; a compliant compressor must 667 + produce data sets that conform to all the specifications presented 668 + here. 669 + 670 + 1.5. Definitions of terms and conventions used 671 + 672 + byte: 8 bits stored or transmitted as a unit (same as an octet). 673 + (For this specification, a byte is exactly 8 bits, even on 674 + machines which store a character on a number of bits different 675 + from 8.) See below, for the numbering of bits within a byte. 676 + 677 + 1.6. Changes from previous versions 678 + 679 + Version 3.1 was the first public release of this specification. 680 + In version 3.2, some terminology was changed and the Adler-32 681 + sample code was rewritten for clarity. In version 3.3, the 682 + support for a preset dictionary was introduced, and the 683 + specification was converted to RFC style. 684 + 685 + <span class="h2"><a class="selflink" id="section-2" href="#section-2">2</a>. Detailed specification</span> 686 + 687 + 2.1. Overall conventions 688 + 689 + In the diagrams below, a box like this: 690 + 691 + +---+ 692 + | | &lt;-- the vertical bars might be missing 693 + +---+ 694 + 695 + 696 + 697 + 698 + <span class="grey">Deutsch &amp; Gailly Informational [Page 3]</span></pre> 699 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-4" ></span> 700 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 701 + 702 + 703 + represents one byte; a box like this: 704 + 705 + +==============+ 706 + | | 707 + +==============+ 708 + 709 + represents a variable number of bytes. 710 + 711 + Bytes stored within a computer do not have a &quot;bit order&quot;, since 712 + they are always treated as a unit. However, a byte considered as 713 + an integer between 0 and 255 does have a most- and least- 714 + significant bit, and since we write numbers with the most- 715 + significant digit on the left, we also write bytes with the most- 716 + significant bit on the left. In the diagrams below, we number the 717 + bits of a byte so that bit 0 is the least-significant bit, i.e., 718 + the bits are numbered: 719 + 720 + +--------+ 721 + |76543210| 722 + +--------+ 723 + 724 + Within a computer, a number may occupy multiple bytes. All 725 + multi-byte numbers in the format described here are stored with 726 + the MOST-significant byte first (at the lower memory address). 727 + For example, the decimal number 520 is stored as: 728 + 729 + 0 1 730 + +--------+--------+ 731 + |00000010|00001000| 732 + +--------+--------+ 733 + ^ ^ 734 + | | 735 + | + less significant byte = 8 736 + + more significant byte = 2 x 256 737 + 738 + 2.2. Data format 739 + 740 + A zlib stream has the following structure: 741 + 742 + 0 1 743 + +---+---+ 744 + |CMF|FLG| (more--&gt;) 745 + +---+---+ 746 + 747 + 748 + 749 + 750 + 751 + 752 + 753 + 754 + <span class="grey">Deutsch &amp; Gailly Informational [Page 4]</span></pre> 755 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-5" ></span> 756 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 757 + 758 + 759 + (if FLG.FDICT set) 760 + 761 + 0 1 2 3 762 + +---+---+---+---+ 763 + | DICTID | (more--&gt;) 764 + +---+---+---+---+ 765 + 766 + +=====================+---+---+---+---+ 767 + |...compressed data...| ADLER32 | 768 + +=====================+---+---+---+---+ 769 + 770 + Any data which may appear after ADLER32 are not part of the zlib 771 + stream. 772 + 773 + CMF (Compression Method and flags) 774 + This byte is divided into a 4-bit compression method and a 4- 775 + bit information field depending on the compression method. 776 + 777 + bits 0 to 3 CM Compression method 778 + bits 4 to 7 CINFO Compression info 779 + 780 + CM (Compression method) 781 + This identifies the compression method used in the file. CM = 8 782 + denotes the &quot;deflate&quot; compression method with a window size up 783 + to 32K. This is the method used by gzip and PNG (see 784 + references [<a href="#ref-1" title="&quot;GZIP Compressed Data Format Specification&quot;">1</a>] and [<a href="#ref-2" title="&quot;PNG (Portable Network Graphics) specification&quot;">2</a>] in Chapter 3, below, for the reference 785 + documents). CM = 15 is reserved. It might be used in a future 786 + version of this specification to indicate the presence of an 787 + extra field before the compressed data. 788 + 789 + CINFO (Compression info) 790 + For CM = 8, CINFO is the base-2 logarithm of the LZ77 window 791 + size, minus eight (CINFO=7 indicates a 32K window size). Values 792 + of CINFO above 7 are not allowed in this version of the 793 + specification. CINFO is not defined in this specification for 794 + CM not equal to 8. 795 + 796 + FLG (FLaGs) 797 + This flag byte is divided as follows: 798 + 799 + bits 0 to 4 FCHECK (check bits for CMF and FLG) 800 + bit 5 FDICT (preset dictionary) 801 + bits 6 to 7 FLEVEL (compression level) 802 + 803 + The FCHECK value must be such that CMF and FLG, when viewed as 804 + a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), 805 + is a multiple of 31. 806 + 807 + 808 + 809 + 810 + <span class="grey">Deutsch &amp; Gailly Informational [Page 5]</span></pre> 811 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-6" ></span> 812 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 813 + 814 + 815 + FDICT (Preset dictionary) 816 + If FDICT is set, a DICT dictionary identifier is present 817 + immediately after the FLG byte. The dictionary is a sequence of 818 + bytes which are initially fed to the compressor without 819 + producing any compressed output. DICT is the Adler-32 checksum 820 + of this sequence of bytes (see the definition of ADLER32 821 + below). The decompressor can use this identifier to determine 822 + which dictionary has been used by the compressor. 823 + 824 + FLEVEL (Compression level) 825 + These flags are available for use by specific compression 826 + methods. The &quot;deflate&quot; method (CM = 8) sets these flags as 827 + follows: 828 + 829 + 0 - compressor used fastest algorithm 830 + 1 - compressor used fast algorithm 831 + 2 - compressor used default algorithm 832 + 3 - compressor used maximum compression, slowest algorithm 833 + 834 + The information in FLEVEL is not needed for decompression; it 835 + is there to indicate if recompression might be worthwhile. 836 + 837 + compressed data 838 + For compression method 8, the compressed data is stored in the 839 + deflate compressed data format as described in the document 840 + &quot;DEFLATE Compressed Data Format Specification&quot; by L. Peter 841 + Deutsch. (See reference [<a href="#ref-3" title="&quot;DEFLATE Compressed Data Format Specification&quot;">3</a>] in Chapter 3, below) 842 + 843 + Other compressed data formats are not specified in this version 844 + of the zlib specification. 845 + 846 + ADLER32 (Adler-32 checksum) 847 + This contains a checksum value of the uncompressed data 848 + (excluding any dictionary data) computed according to Adler-32 849 + algorithm. This algorithm is a 32-bit extension and improvement 850 + of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 851 + standard. See references [<a href="#ref-4" title="&quot;An Arithmetic Checksum for Serial Transmissions,&quot;">4</a>] and [<a href="#ref-5" title="&quot;Checksum Algorithms,&quot;">5</a>] in Chapter 3, below) 852 + 853 + Adler-32 is composed of two sums accumulated per byte: s1 is 854 + the sum of all bytes, s2 is the sum of all s1 values. Both sums 855 + are done modulo 65521. s1 is initialized to 1, s2 to zero. The 856 + Adler-32 checksum is stored as s2*65536 + s1 in most- 857 + significant-byte first (network) order. 858 + 859 + 860 + 861 + 862 + 863 + 864 + 865 + 866 + <span class="grey">Deutsch &amp; Gailly Informational [Page 6]</span></pre> 867 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-7" ></span> 868 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 869 + 870 + 871 + 2.3. Compliance 872 + 873 + A compliant compressor must produce streams with correct CMF, FLG 874 + and ADLER32, but need not support preset dictionaries. When the 875 + zlib data format is used as part of another standard data format, 876 + the compressor may use only preset dictionaries that are specified 877 + by this other data format. If this other format does not use the 878 + preset dictionary feature, the compressor must not set the FDICT 879 + flag. 880 + 881 + A compliant decompressor must check CMF, FLG, and ADLER32, and 882 + provide an error indication if any of these have incorrect values. 883 + A compliant decompressor must give an error indication if CM is 884 + not one of the values defined in this specification (only the 885 + value 8 is permitted in this version), since another value could 886 + indicate the presence of new features that would cause subsequent 887 + data to be interpreted incorrectly. A compliant decompressor must 888 + give an error indication if FDICT is set and DICTID is not the 889 + identifier of a known preset dictionary. A decompressor may 890 + ignore FLEVEL and still be compliant. When the zlib data format 891 + is being used as a part of another standard format, a compliant 892 + decompressor must support all the preset dictionaries specified by 893 + the other format. When the other format does not use the preset 894 + dictionary feature, a compliant decompressor must reject any 895 + stream in which the FDICT flag is set. 896 + 897 + <span class="h2"><a class="selflink" id="section-3" href="#section-3">3</a>. References</span> 898 + 899 + [<a id="ref-1">1</a>] Deutsch, L.P.,&quot;GZIP Compressed Data Format Specification&quot;, 900 + available in <a href="ftp://ftp.uu.net/pub/archiving/zip/doc/">ftp://ftp.uu.net/pub/archiving/zip/doc/</a> 901 + 902 + [<a id="ref-2">2</a>] Thomas Boutell, &quot;PNG (Portable Network Graphics) specification&quot;, 903 + available in <a href="ftp://ftp.uu.net/graphics/png/documents/">ftp://ftp.uu.net/graphics/png/documents/</a> 904 + 905 + [<a id="ref-3">3</a>] Deutsch, L.P.,&quot;DEFLATE Compressed Data Format Specification&quot;, 906 + available in <a href="ftp://ftp.uu.net/pub/archiving/zip/doc/">ftp://ftp.uu.net/pub/archiving/zip/doc/</a> 907 + 908 + [<a id="ref-4">4</a>] Fletcher, J. G., &quot;An Arithmetic Checksum for Serial 909 + Transmissions,&quot; IEEE Transactions on Communications, Vol. COM-30, 910 + No. 1, January 1982, pp. 247-252. 911 + 912 + [<a id="ref-5">5</a>] ITU-T Recommendation X.224, Annex D, &quot;Checksum Algorithms,&quot; 913 + November, 1993, pp. 144, 145. (Available from 914 + gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. 915 + 916 + 917 + 918 + 919 + 920 + 921 + 922 + <span class="grey">Deutsch &amp; Gailly Informational [Page 7]</span></pre> 923 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-8" ></span> 924 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 925 + 926 + 927 + <span class="h2"><a class="selflink" id="section-4" href="#section-4">4</a>. Source code</span> 928 + 929 + Source code for a C language implementation of a &quot;zlib&quot; compliant 930 + library is available at <a href="ftp://ftp.uu.net/pub/archiving/zip/zlib/">ftp://ftp.uu.net/pub/archiving/zip/zlib/</a>. 931 + 932 + <span class="h2"><a class="selflink" id="section-5" href="#section-5">5</a>. Security Considerations</span> 933 + 934 + A decoder that fails to check the ADLER32 checksum value may be 935 + subject to undetected data corruption. 936 + 937 + <span class="h2"><a class="selflink" id="section-6" href="#section-6">6</a>. Acknowledgements</span> 938 + 939 + Trademarks cited in this document are the property of their 940 + respective owners. 941 + 942 + Jean-Loup Gailly and Mark Adler designed the zlib format and wrote 943 + the related software described in this specification. Glenn 944 + Randers-Pehrson converted this document to RFC and HTML format. 945 + 946 + <span class="h2"><a class="selflink" id="section-7" href="#section-7">7</a>. Authors&#x27; Addresses</span> 947 + 948 + L. Peter Deutsch 949 + Aladdin Enterprises 950 + 203 Santa Margarita Ave. 951 + Menlo Park, CA 94025 952 + 953 + Phone: (415) 322-0103 (AM only) 954 + FAX: (415) 322-1734 955 + EMail: &lt;ghost@aladdin.com&gt; 956 + 957 + 958 + Jean-Loup Gailly 959 + 960 + EMail: &lt;gzip@prep.ai.mit.edu&gt; 961 + 962 + Questions about the technical content of this specification can be 963 + sent by email to 964 + 965 + Jean-Loup Gailly &lt;gzip@prep.ai.mit.edu&gt; and 966 + Mark Adler &lt;madler@alumni.caltech.edu&gt; 967 + 968 + Editorial comments on this specification can be sent by email to 969 + 970 + L. Peter Deutsch &lt;ghost@aladdin.com&gt; and 971 + Glenn Randers-Pehrson &lt;randeg@alumni.rpi.edu&gt; 972 + 973 + 974 + 975 + 976 + 977 + 978 + <span class="grey">Deutsch &amp; Gailly Informational [Page 8]</span></pre> 979 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-9" ></span> 980 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 981 + 982 + 983 + <span class="h2"><a class="selflink" id="section-8" href="#section-8">8</a>. Appendix: Rationale</span> 984 + 985 + 8.1. Preset dictionaries 986 + 987 + A preset dictionary is specially useful to compress short input 988 + sequences. The compressor can take advantage of the dictionary 989 + context to encode the input in a more compact manner. The 990 + decompressor can be initialized with the appropriate context by 991 + virtually decompressing a compressed version of the dictionary 992 + without producing any output. However for certain compression 993 + algorithms such as the deflate algorithm this operation can be 994 + achieved without actually performing any decompression. 995 + 996 + The compressor and the decompressor must use exactly the same 997 + dictionary. The dictionary may be fixed or may be chosen among a 998 + certain number of predefined dictionaries, according to the kind 999 + of input data. The decompressor can determine which dictionary has 1000 + been chosen by the compressor by checking the dictionary 1001 + identifier. This document does not specify the contents of 1002 + predefined dictionaries, since the optimal dictionaries are 1003 + application specific. Standard data formats using this feature of 1004 + the zlib specification must precisely define the allowed 1005 + dictionaries. 1006 + 1007 + 8.2. The Adler-32 algorithm 1008 + 1009 + The Adler-32 algorithm is much faster than the CRC32 algorithm yet 1010 + still provides an extremely low probability of undetected errors. 1011 + 1012 + The modulo on unsigned long accumulators can be delayed for 5552 1013 + bytes, so the modulo operation time is negligible. If the bytes 1014 + are a, b, c, the second sum is 3a + 2b + c + 3, and so is position 1015 + and order sensitive, unlike the first sum, which is just a 1016 + checksum. That 65521 is prime is important to avoid a possible 1017 + large class of two-byte errors that leave the check unchanged. 1018 + (The Fletcher checksum uses 255, which is not prime and which also 1019 + makes the Fletcher check insensitive to single byte changes 0 &lt;-&gt; 1020 + 255.) 1021 + 1022 + The sum s1 is initialized to 1 instead of zero to make the length 1023 + of the sequence part of s2, so that the length does not have to be 1024 + checked separately. (Any sequence of zeroes has a Fletcher 1025 + checksum of zero.) 1026 + 1027 + 1028 + 1029 + 1030 + 1031 + 1032 + 1033 + 1034 + <span class="grey">Deutsch &amp; Gailly Informational [Page 9]</span></pre> 1035 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-10" ></span> 1036 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 1037 + 1038 + 1039 + <span class="h2"><a class="selflink" id="section-9" href="#section-9">9</a>. Appendix: Sample code</span> 1040 + 1041 + The following C code computes the Adler-32 checksum of a data buffer. 1042 + It is written for clarity, not for speed. The sample code is in the 1043 + ANSI C programming language. Non C users may find it easier to read 1044 + with these hints: 1045 + 1046 + &amp; Bitwise AND operator. 1047 + &gt;&gt; Bitwise right shift operator. When applied to an 1048 + unsigned quantity, as here, right shift inserts zero bit(s) 1049 + at the left. 1050 + &lt;&lt; Bitwise left shift operator. Left shift inserts zero 1051 + bit(s) at the right. 1052 + ++ &quot;n++&quot; increments the variable n. 1053 + % modulo operator: a % b is the remainder of a divided by b. 1054 + 1055 + #define BASE 65521 /* largest prime smaller than 65536 */ 1056 + 1057 + /* 1058 + Update a running Adler-32 checksum with the bytes buf[0..len-1] 1059 + and return the updated checksum. The Adler-32 checksum should be 1060 + initialized to 1. 1061 + 1062 + Usage example: 1063 + 1064 + unsigned long adler = 1L; 1065 + 1066 + while (read_buffer(buffer, length) != EOF) { 1067 + adler = update_adler32(adler, buffer, length); 1068 + } 1069 + if (adler != original_adler) error(); 1070 + */ 1071 + unsigned long update_adler32(unsigned long adler, 1072 + unsigned char *buf, int len) 1073 + { 1074 + unsigned long s1 = adler &amp; 0xffff; 1075 + unsigned long s2 = (adler &gt;&gt; 16) &amp; 0xffff; 1076 + int n; 1077 + 1078 + for (n = 0; n &lt; len; n++) { 1079 + s1 = (s1 + buf[n]) % BASE; 1080 + s2 = (s2 + s1) % BASE; 1081 + } 1082 + return (s2 &lt;&lt; 16) + s1; 1083 + } 1084 + 1085 + /* Return the adler32 of the bytes buf[0..len-1] */ 1086 + 1087 + 1088 + 1089 + 1090 + <span class="grey">Deutsch &amp; Gailly Informational [Page 10]</span></pre> 1091 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-11" ></span> 1092 + <span class="grey"><a href="/doc/html/rfc1950">RFC 1950</a> ZLIB Compressed Data Format Specification May 1996</span> 1093 + 1094 + 1095 + unsigned long adler32(unsigned char *buf, int len) 1096 + { 1097 + return update_adler32(1L, buf, len); 1098 + } 1099 + 1100 + 1101 + 1102 + 1103 + 1104 + 1105 + 1106 + 1107 + 1108 + 1109 + 1110 + 1111 + 1112 + 1113 + 1114 + 1115 + 1116 + 1117 + 1118 + 1119 + 1120 + 1121 + 1122 + 1123 + 1124 + 1125 + 1126 + 1127 + 1128 + 1129 + 1130 + 1131 + 1132 + 1133 + 1134 + 1135 + 1136 + 1137 + 1138 + 1139 + 1140 + 1141 + 1142 + 1143 + 1144 + 1145 + 1146 + Deutsch &amp; Gailly Informational [Page 11] 1147 + </pre></div> 1148 + </div> 1149 + 1150 + </div> 1151 + <div class="d-print-none col-md-3 bg-light-subtle collapse show" id="sidebar"> 1152 + <div class="position-fixed border-start sidebar overflow-scroll overscroll-none no-scrollbar"> 1153 + <div class="d-flex flex-column vh-100 pt-2 pt-lg-3 ps-3 pl-md-2 pl-lg-3"> 1154 + <div> 1155 + <a class="btn btn-primary btn-sm" href="/doc/rfc1950/">Datatracker</a> 1156 + <p class="fw-bold pt-2"> 1157 + 1158 + RFC 1950 1159 + 1160 + <br> 1161 + 1162 + 1163 + 1164 + 1165 + 1166 + 1167 + <span class="text-success">RFC 1168 + 1169 + - Informational 1170 + 1171 + </span> 1172 + 1173 + </p> 1174 + </div> 1175 + 1176 + <ul class="nav nav-tabs nav-fill small me-2" role="tablist"> 1177 + <li class="nav-item" role="presentation" title="Document information"> 1178 + <button class="nav-link px-2" 1179 + id="docinfo-tab" 1180 + data-bs-toggle="tab" 1181 + data-bs-target="#docinfo-tab-pane" 1182 + type="button" 1183 + role="tab" 1184 + aria-controls="docinfo-tab-pane" 1185 + aria-selected="true"> 1186 + <i class="bi bi-info-circle"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Info</span> 1187 + </button> 1188 + </li> 1189 + <li class="nav-item" role="presentation" title="Table of contents"> 1190 + <button class="nav-link px-2" 1191 + id="toc-tab" 1192 + data-bs-toggle="tab" 1193 + data-bs-target="#toc-tab-pane" 1194 + type="button" 1195 + role="tab" 1196 + aria-controls="toc-tab-pane" 1197 + aria-selected="false"> 1198 + <i class="bi bi-list-ol"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Contents</span> 1199 + </button> 1200 + </li> 1201 + <li class="nav-item" role="presentation" title="Preferences"> 1202 + <button class="nav-link px-2" 1203 + id="pref-tab" 1204 + data-bs-toggle="tab" 1205 + data-bs-target="#pref-tab-pane" 1206 + type="button" 1207 + role="tab" 1208 + aria-controls="pref-tab-pane" 1209 + aria-selected="false"> 1210 + <i class="bi bi-gear"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Prefs</span> 1211 + </button> 1212 + </li> 1213 + </ul> 1214 + <div class="overflow-auto tab-content pt-2 me-2"> 1215 + <div class="tab-pane" 1216 + id="docinfo-tab-pane" 1217 + role="tabpanel" 1218 + aria-labelledby="docinfo-tab" 1219 + tabindex="0"> 1220 + <table class="table table-sm table-borderless"> 1221 + 1222 + 1223 + 1224 + 1225 + 1226 + 1227 + 1228 + 1229 + <tbody class="meta align-top "> 1230 + <tr> 1231 + <th scope="row">Document</th> 1232 + <th scope="row">Document type</th> 1233 + <td class="edit"></td> 1234 + <td> 1235 + 1236 + 1237 + 1238 + 1239 + 1240 + 1241 + <span class="text-success">RFC 1242 + 1243 + - Informational 1244 + 1245 + </span> 1246 + 1247 + 1248 + 1249 + <br>May 1996 1250 + 1251 + <br> 1252 + 1253 + 1254 + <a class="btn btn-sm btn-warning" 1255 + title="Click to report an error in the document." 1256 + href="https://www.rfc-editor.org/errata.php#reportnew" 1257 + target="_blank"> 1258 + Report errata 1259 + </a> 1260 + 1261 + 1262 + 1263 + 1264 + 1265 + 1266 + 1267 + 1268 + 1269 + <div> 1270 + Was 1271 + <a href="/doc/draft-deutsch-zlib-spec/03/">draft-deutsch-zlib-spec</a> 1272 + (individual) 1273 + </div> 1274 + 1275 + 1276 + 1277 + 1278 + 1279 + 1280 + 1281 + 1282 + 1283 + 1284 + <div class="alert alert-warning small p-2 mt-2" role="alert"> 1285 + This RFC is labeled as "Legacy"; it was published before a formal source was recorded. 1286 + This RFC is <strong>not endorsed by the IETF</strong> and has <strong>no formal standing</strong> in the 1287 + <a href="/doc/rfc2026/">IETF standards process</a>. 1288 + </div> 1289 + 1290 + 1291 + 1292 + 1293 + </td> 1294 + </tr> 1295 + 1296 + <tr> 1297 + <td></td> 1298 + <th scope="row">Select version</th> 1299 + <td class="edit"></td> 1300 + <td> 1301 + 1302 + 1303 + 1304 + 1305 + <ul class="revision-list pagination pagination-sm text-center flex-wrap my-0"> 1306 + 1307 + 1308 + 1309 + 1310 + <li class="page-item"> 1311 + <a class="page-link" 1312 + href="/doc/html/draft-deutsch-zlib-spec-03" 1313 + rel="nofollow"> 1314 + 03 1315 + </a> 1316 + </li> 1317 + 1318 + 1319 + 1320 + <li class="page-item rfc active"> 1321 + <a class="page-link" 1322 + href="/doc/html/rfc1950"> 1323 + RFC 1950 1324 + </a> 1325 + </li> 1326 + 1327 + </ul> 1328 + 1329 + </td> 1330 + </tr> 1331 + 1332 + <tr> 1333 + <td></td> 1334 + <th scope="row">Compare versions</th> 1335 + <td class="edit"></td> 1336 + <td> 1337 + 1338 + 1339 + 1340 + 1341 + <form class="form-horizontal diff-form" 1342 + action="https://author-tools.ietf.org/iddiff" 1343 + method="get" 1344 + target="_blank"> 1345 + 1346 + <select class="form-select form-select-sm mb-1 select2-field" 1347 + data-max-entries="1" 1348 + data-width="resolve" 1349 + data-allow-clear="false" 1350 + data-minimum-input-length="0" 1351 + aria-label="From revision" 1352 + name="url1"> 1353 + 1354 + <option value="rfc1950"> 1355 + RFC 1950 1356 + 1357 + </option> 1358 + 1359 + <option value="draft-deutsch-zlib-spec-03" selected> 1360 + draft-deutsch-zlib-spec-03 1361 + 1362 + </option> 1363 + 1364 + <option value="draft-deutsch-zlib-spec-02"> 1365 + draft-deutsch-zlib-spec-02 1366 + 1367 + </option> 1368 + 1369 + <option value="draft-deutsch-zlib-spec-01"> 1370 + draft-deutsch-zlib-spec-01 1371 + 1372 + </option> 1373 + 1374 + <option value="draft-deutsch-zlib-spec-00"> 1375 + draft-deutsch-zlib-spec-00 1376 + 1377 + </option> 1378 + 1379 + 1380 + </select> 1381 + 1382 + <select class="form-select form-select-sm mb-1 select2-field" 1383 + data-max-entries="1" 1384 + data-width="resolve" 1385 + data-allow-clear="false" 1386 + data-minimum-input-length="0" 1387 + aria-label="To revision" 1388 + name="url2"> 1389 + 1390 + <option value="rfc1950" selected> 1391 + RFC 1950 1392 + 1393 + </option> 1394 + 1395 + <option value="draft-deutsch-zlib-spec-03"> 1396 + draft-deutsch-zlib-spec-03 1397 + 1398 + </option> 1399 + 1400 + <option value="draft-deutsch-zlib-spec-02"> 1401 + draft-deutsch-zlib-spec-02 1402 + 1403 + </option> 1404 + 1405 + <option value="draft-deutsch-zlib-spec-01"> 1406 + draft-deutsch-zlib-spec-01 1407 + 1408 + </option> 1409 + 1410 + <option value="draft-deutsch-zlib-spec-00"> 1411 + draft-deutsch-zlib-spec-00 1412 + 1413 + </option> 1414 + 1415 + 1416 + </select> 1417 + 1418 + <button type="submit" 1419 + class="btn btn-primary btn-sm" 1420 + value="--html" 1421 + name="difftype"> 1422 + Side-by-side 1423 + </button> 1424 + 1425 + <button type="submit" 1426 + class="btn btn-primary btn-sm" 1427 + value="--hwdiff" 1428 + name="difftype"> 1429 + Inline 1430 + </button> 1431 + 1432 + </form> 1433 + </td> 1434 + </tr> 1435 + 1436 + 1437 + <tr> 1438 + <td></td> 1439 + <th scope="row">Authors</th> 1440 + <td class="edit"> 1441 + 1442 + </td> 1443 + <td> 1444 + 1445 + 1446 + <span ><a 1447 + title="Datatracker profile of L. Peter Deutsch" 1448 + href="/person/ghost@aladdin.com" >L. Peter Deutsch</a> <a 1449 + href="mailto:ghost%40aladdin.com" 1450 + aria-label="Compose email to ghost@aladdin.com" 1451 + title="Compose email to ghost@aladdin.com"> 1452 + <i class="bi bi-envelope"></i></a></span>, 1453 + 1454 + <span ><a 1455 + title="Datatracker profile of Jean-loup Gailly" 1456 + href="/person/gzip@prep.ai.mit.edu" >Jean-loup Gailly</a> <a 1457 + href="mailto:gzip%40prep.ai.mit.edu" 1458 + aria-label="Compose email to gzip@prep.ai.mit.edu" 1459 + title="Compose email to gzip@prep.ai.mit.edu"> 1460 + <i class="bi bi-envelope"></i></a></span> 1461 + 1462 + 1463 + <br> 1464 + <a class="btn btn-primary btn-sm mt-1" href="mailto:rfc1950@ietf.org?subject=rfc1950" title="Send email to the document authors">Email authors</a> 1465 + 1466 + </td> 1467 + </tr> 1468 + 1469 + 1470 + <tr> 1471 + <td></td> 1472 + <th scope="row"> 1473 + RFC stream 1474 + </th> 1475 + <td class="edit"> 1476 + 1477 + </td> 1478 + <td > 1479 + 1480 + 1481 + 1482 + 1483 + Legacy 1484 + 1485 + 1486 + 1487 + 1488 + </td> 1489 + </tr> 1490 + 1491 + <tr> 1492 + <td></td> 1493 + <th scope="row"> 1494 + Other formats 1495 + </th> 1496 + <td class="edit"> 1497 + </td> 1498 + <td> 1499 + 1500 + 1501 + <div class="buttonlist"> 1502 + 1503 + 1504 + <a class="btn btn-primary btn-sm" 1505 + 1506 + target="_blank" 1507 + href="https://www.rfc-editor.org/rfc/rfc1950.txt"> 1508 + 1509 + <i class="bi bi-file-text"></i> txt 1510 + 1511 + </a> 1512 + 1513 + 1514 + 1515 + <a class="btn btn-primary btn-sm" 1516 + 1517 + target="_blank" 1518 + href="https://www.rfc-editor.org/rfc/rfc1950.html"> 1519 + 1520 + <i class="bi bi-file-code"></i> html 1521 + 1522 + </a> 1523 + 1524 + 1525 + 1526 + <a class="btn btn-primary btn-sm" 1527 + 1528 + download="rfc1950.pdf" 1529 + 1530 + 1531 + target="_blank" 1532 + href="https://www.rfc-editor.org/rfc/rfc1950.pdf"> 1533 + 1534 + <i class="bi bi-file-pdf"></i> pdf 1535 + 1536 + </a> 1537 + 1538 + 1539 + 1540 + 1541 + 1542 + <a class="btn btn-primary btn-sm" 1543 + 1544 + target="_blank" 1545 + href="/doc/rfc1950/bibtex/"> 1546 + 1547 + <i class="bi bi-file-ruled"></i> bibtex 1548 + 1549 + </a> 1550 + 1551 + 1552 + </div> 1553 + 1554 + 1555 + </td> 1556 + </tr> 1557 + 1558 + 1559 + 1560 + 1561 + </tbody> 1562 + </table> 1563 + <a class="btn btn-sm btn-warning mb-3" 1564 + target="_blank" 1565 + href="https://github.com/ietf-tools/datatracker/issues/new/choose"> 1566 + Report a datatracker bug 1567 + <i class="bi bi-bug"></i> 1568 + </a> 1569 + </div> 1570 + <div class="tab-pane mb-5" 1571 + id="toc-tab-pane" 1572 + role="tabpanel" 1573 + aria-labelledby="toc-tab" 1574 + tabindex="0"> 1575 + <nav class="nav nav-pills flex-column small" id="toc-nav"> 1576 + </nav> 1577 + </div> 1578 + <div class="tab-pane mb-5 small" 1579 + id="pref-tab-pane" 1580 + role="tabpanel" 1581 + aria-labelledby="pref-tab" 1582 + tabindex="0"> 1583 + <label class="form-label fw-bold mb-2">Show sidebar by default</label> 1584 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1585 + <input type="radio" class="btn-check" name="sidebar" id="on-radio"> 1586 + <label class="btn btn-outline-primary" for="on-radio">Yes</label> 1587 + <input type="radio" class="btn-check" name="sidebar" id="off-radio"> 1588 + <label class="btn btn-outline-primary" for="off-radio">No</label> 1589 + </div> 1590 + <label class="form-label fw-bold mt-4 mb-2">Tab to show by default</label> 1591 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1592 + <input type="radio" class="btn-check" name="deftab" id="docinfo-radio"> 1593 + <label class="btn btn-outline-primary" for="docinfo-radio"> 1594 + <i class="bi bi-info-circle me-1"></i>Info 1595 + </label> 1596 + <input type="radio" class="btn-check" name="deftab" id="toc-radio"> 1597 + <label class="btn btn-outline-primary" for="toc-radio"> 1598 + <i class="bi bi-list-ol me-1"></i>Contents 1599 + </label> 1600 + </div> 1601 + <label class="form-label fw-bold mt-4 mb-2">HTMLization configuration</label> 1602 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1603 + <input type="radio" class="btn-check" name="htmlconf" id="txt-radio"> 1604 + <label class="btn btn-outline-primary" for="txt-radio" title="This is the traditional HTMLization method."> 1605 + <i class="bi bi-badge-sd me-1"></i>HTMLize the plaintext 1606 + </label> 1607 + <input type="radio" class="btn-check" name="htmlconf" id="html-radio"> 1608 + <label class="btn btn-outline-primary" for="html-radio" title="This is the modern HTMLization method."> 1609 + <i class="bi bi-badge-hd me-1"></i>Plaintextify the HTML 1610 + </label> 1611 + </div> 1612 + <label class="form-label fw-bold mt-4 mb-2" for="ptsize">Maximum font size</label> 1613 + <input type="range" class="form-range" min="7" max="16" id="ptsize" oninput="ptdemo.value = ptsize.value"> 1614 + <label class="form-label fw-bold mt-4 mb-2">Page dependencies</label> 1615 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1616 + <input type="radio" class="btn-check" name="pagedeps" id="inline-radio"> 1617 + <label class="btn btn-outline-primary" for="inline-radio" title="Generate larger, standalone web pages that do not require network access to render."> 1618 + <i class="bi bi-box me-1"></i>Inline 1619 + </label> 1620 + <input type="radio" class="btn-check" name="pagedeps" id="reference-radio"> 1621 + <label class="btn btn-outline-primary" for="reference-radio" title="Generate regular web pages that require network access to render."> 1622 + <i class="bi bi-link-45deg me-1"></i>Reference 1623 + </label> 1624 + </div> 1625 + <label class="form-label fw-bold mt-4 mb-2">Citation links</label> 1626 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1627 + <input type="radio" class="btn-check" name="reflinks" id="refsection-radio"> 1628 + <label class="btn btn-outline-primary" for="refsection-radio" title="Citation links go to the reference section."> 1629 + <i class="bi bi-arrow-clockwise"></i> Go to reference section 1630 + </label> 1631 + <input type="radio" class="btn-check" name="reflinks" id="citation-radio"> 1632 + <label class="btn btn-outline-primary" for="citation-radio" title="Citation links go directly to the cited document."> 1633 + <i class="bi bi-link-45deg me-1"></i>Go to linked document 1634 + </label> 1635 + </div> 1636 + </div> 1637 + </div> 1638 + </div> 1639 + </div> 1640 + </div> 1641 + </div> 1642 + 1643 + <script> 1644 + var _paq = window._paq || []; 1645 + 1646 + _paq.push(['disableCookies']); 1647 + _paq.push(['trackPageView']); 1648 + _paq.push(['enableLinkTracking']); 1649 + (function() { 1650 + var u="//analytics.ietf.org/"; 1651 + _paq.push(['setTrackerUrl', u+'matomo.php']); 1652 + _paq.push(['setSiteId', 7]); 1653 + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 1654 + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); 1655 + })(); 1656 + </script> 1657 + <noscript><p><img src="//analytics.ietf.org/matomo.php?idsite=7" style="border:0;" alt="" /></p></noscript> 1658 + 1659 + </body> 1660 + </html>
+1989
spec/rfc1951.txt
··· 1 + 2 + <!DOCTYPE html> 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + <html data-bs-theme="auto" lang="en"> 11 + <head> 12 + 13 + <meta charset="utf-8"> 14 + <meta http-equiv="X-UA-Compatible" content="IE=edge"> 15 + <title> 16 + 17 + RFC 1951 - DEFLATE Compressed Data Format Specification version 1.3 18 + 19 + </title> 20 + <meta name="viewport" content="width=device-width, initial-scale=1"> 21 + <link href="https://static.ietf.org/fonts/inter/import.css" rel="stylesheet"> 22 + <link href="https://static.ietf.org/fonts/noto-sans-mono/import.css" rel="stylesheet"> 23 + 24 + <link rel="stylesheet" href="https://static.ietf.org/dt/12.54.0/ietf/css/document_html_referenced.css"> 25 + 26 + <script type="module" crossorigin="" src="https://static.ietf.org/dt/12.54.0/assets/embedded-055c333d.js"></script> 27 + <link href="https://static.ietf.org/dt/12.54.0/assets/create-pinia-singleton-8312c5df.js" type="text/javascript" crossorigin="anonymous" rel="modulepreload" as="script" /> 28 + <link href="https://static.ietf.org/dt/12.54.0/assets/Scrollbar-ad8c5330.js" type="text/javascript" crossorigin="anonymous" rel="modulepreload" as="script" /> 29 + <script src="https://static.ietf.org/dt/12.54.0/ietf/js/document_html.js"></script> 30 + <script src="https://static.ietf.org/dt/12.54.0/ietf/js/theme.js"></script> 31 + 32 + <link rel="alternate" type="application/atom+xml" title="Document changes" href="/feed/document-changes/rfc1951/"> 33 + <meta name="description" 34 + 35 + content="DEFLATE Compressed Data Format Specification version 1.3 (RFC 1951, )" 36 + > 37 + 38 + 39 + <link rel="apple-touch-icon" 40 + sizes="180x180" 41 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-180.png"> 42 + <link rel="icon" 43 + sizes="32x32" 44 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-32.png"> 45 + <link rel="icon" 46 + sizes="16x16" 47 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-16.png"> 48 + <link rel="manifest" href="/site.webmanifest"> 49 + <link rel="mask-icon" 50 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-mask.svg" 51 + color="#ffffff"> 52 + <meta name="msapplication-TileColor" 53 + content="#ffffff"> 54 + <meta name="theme-color" 55 + content="#ffffff"> 56 + 57 + 58 + 59 + 60 + 61 + <meta property="og:title" content="RFC 1951: DEFLATE Compressed Data Format Specification version 1.3"> 62 + <meta property="og:url" content="https://datatracker.ietf.org/doc/html/rfc1951.txt"> 63 + <link rel="canonical" href="https://datatracker.ietf.org/doc/html/rfc1951.txt"> 64 + <meta property="og:site_name" content="IETF Datatracker"> 65 + <meta property="og:description" content="This specification defines a lossless compressed data format that compresses data using a combination of the LZ77 algorithm and Huffman coding, with efficiency comparable to the best currently available general-purpose compression methods. This memo provides information for the Internet community. This memo does not specify an Internet standard of any kind."> 66 + <meta property="og:type" content="article"> 67 + 68 + <meta property="article:section" content="Individual Internet-Draft"> 69 + 70 + <meta property="article:author" content="L. Peter Deutsch"> 71 + 72 + 73 + 74 + 75 + <style> 76 + 77 + .diff-form .select2-selection__rendered { 78 + direction: rtl; 79 + text-align: left; 80 + } 81 + </style> 82 + </head> 83 + <body> 84 + 85 + <noscript><iframe class="status" title="Site status" src="/status/latest"></iframe></noscript> 86 + <div class="vue-embed" data-component="Status"></div> 87 + <div class="btn-toolbar sidebar-toolbar position-fixed top-0 end-0 m-2 m-lg-3 d-print-none"> 88 + <div class="dropdown"> 89 + <button class="btn btn-outline-secondary btn-sm me-1 dropdown-toggle d-flex align-items-center" 90 + id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" 91 + aria-label="Toggle theme"> 92 + <i class="theme-icon-active bi bi-circle-half"></i> 93 + </button> 94 + 95 + <ul class="dropdown-menu" aria-labelledby="bd-theme"> 96 + <li> 97 + <button type="button" class="dropdown-item d-flex align-items-center" 98 + data-bs-theme-value="light" aria-pressed="false"> 99 + <i class="me-2 opacity-50 theme-icon bi bi-sun-fill"></i> 100 + Light<i class="bi bi-check2 ms-auto d-none"></i> 101 + </button> 102 + </li> 103 + <li> 104 + <button type="button" class="dropdown-item d-flex align-items-center" 105 + data-bs-theme-value="dark" aria-pressed="false"> 106 + <i class="me-2 opacity-50 theme-icon bi bi-moon-stars-fill"></i> 107 + Dark<i class="bi bi-check2 ms-auto d-none"></i> 108 + </button> 109 + </li> 110 + <li> 111 + <button type="button" class="dropdown-item d-flex align-items-center active" 112 + data-bs-theme-value="auto" aria-pressed="true"> 113 + <i class="me-2 opacity-50 theme-icon bi bi-circle-half"></i> 114 + Auto<i class="bi bi-check2 ms-auto d-none"></i> 115 + </button> 116 + </li> 117 + </ul> 118 + </div> 119 + <button class="btn btn-outline-secondary btn-sm sidebar-toggle" 120 + type="button" 121 + data-bs-toggle="collapse" 122 + data-bs-target="#sidebar" 123 + aria-expanded="true" 124 + aria-controls="sidebar" 125 + aria-label="Toggle metadata sidebar" 126 + title="Toggle metadata sidebar"> 127 + <i class="bi bi-arrow-bar-left sidebar-shown"></i> 128 + <i class="bi bi-arrow-bar-right sidebar-collapsed"></i> 129 + </button> 130 + </div> 131 + <nav class="navbar bg-light-subtle px-1 fixed-top d-print-none d-md-none"> 132 + <a class="nav-link ps-1" 133 + href="/doc/rfc1951/"> 134 + 135 + RFC 1951 136 + 137 + <br class="d-sm-none"> 138 + 139 + <span class="ms-sm-3 badge rounded-pill badge-inf"> 140 + 141 + Informational 142 + 143 + </span> 144 + </a> 145 + <button class="navbar-toggler p-1" 146 + type="button" 147 + data-bs-toggle="collapse" 148 + data-bs-target="#docinfo-collapse" 149 + aria-controls="docinfo-collapse" 150 + aria-expanded="false" 151 + aria-label="Show document information"> 152 + <span class="navbar-toggler-icon small"></span> 153 + </button> 154 + <div class="navbar-nav navbar-nav-scroll overscroll-none collapse pt-1" id="docinfo-collapse"> 155 + <div class="bg-light-subtle p-0"> 156 + <table class="table table-sm table-borderless small"> 157 + <tbody class="meta align-top"> 158 + <tr> 159 + <th scope="row"></th> 160 + <th scope="row">Title</th> 161 + <td class="edit"></td> 162 + <td>DEFLATE Compressed Data Format Specification version 1.3</td> 163 + </tr> 164 + </tbody> 165 + 166 + 167 + 168 + 169 + 170 + 171 + 172 + 173 + <tbody class="meta align-top "> 174 + <tr> 175 + <th scope="row">Document</th> 176 + <th scope="row">Document type</th> 177 + <td class="edit"></td> 178 + <td> 179 + 180 + 181 + 182 + 183 + 184 + 185 + <span class="text-success">RFC 186 + 187 + - Informational 188 + 189 + </span> 190 + 191 + 192 + 193 + <br>May 1996 194 + 195 + <br> 196 + 197 + <a class="btn btn-primary btn-sm my-1" 198 + href="https://www.rfc-editor.org/errata_search.php?rfc=1951" title="Click to view errata." rel="nofollow"> 199 + View errata 200 + </a> 201 + 202 + 203 + <a class="btn btn-sm btn-warning" 204 + title="Click to report an error in the document." 205 + href="https://www.rfc-editor.org/errata.php#reportnew" 206 + target="_blank"> 207 + Report errata 208 + </a> 209 + 210 + 211 + 212 + 213 + 214 + 215 + 216 + 217 + 218 + <div> 219 + Was 220 + <a href="/doc/draft-deutsch-deflate-spec/03/">draft-deutsch-deflate-spec</a> 221 + (individual) 222 + </div> 223 + 224 + 225 + 226 + 227 + 228 + 229 + 230 + 231 + 232 + 233 + <div class="alert alert-warning small p-2 mt-2" role="alert"> 234 + This RFC is labeled as "Legacy"; it was published before a formal source was recorded. 235 + This RFC is <strong>not endorsed by the IETF</strong> and has <strong>no formal standing</strong> in the 236 + <a href="/doc/rfc2026/">IETF standards process</a>. 237 + </div> 238 + 239 + 240 + 241 + 242 + </td> 243 + </tr> 244 + 245 + <tr> 246 + <td></td> 247 + <th scope="row">Select version</th> 248 + <td class="edit"></td> 249 + <td> 250 + 251 + 252 + 253 + 254 + <ul class="revision-list pagination pagination-sm text-center flex-wrap my-0"> 255 + 256 + 257 + 258 + 259 + <li class="page-item"> 260 + <a class="page-link" 261 + href="/doc/html/draft-deutsch-deflate-spec-03" 262 + rel="nofollow"> 263 + 03 264 + </a> 265 + </li> 266 + 267 + 268 + 269 + <li class="page-item rfc active"> 270 + <a class="page-link" 271 + href="/doc/html/rfc1951"> 272 + RFC 1951 273 + </a> 274 + </li> 275 + 276 + </ul> 277 + 278 + </td> 279 + </tr> 280 + 281 + <tr> 282 + <td></td> 283 + <th scope="row">Compare versions</th> 284 + <td class="edit"></td> 285 + <td> 286 + 287 + 288 + 289 + 290 + <form class="form-horizontal diff-form" 291 + action="https://author-tools.ietf.org/iddiff" 292 + method="get" 293 + target="_blank"> 294 + 295 + <select class="form-select form-select-sm mb-1 select2-field" 296 + data-max-entries="1" 297 + data-width="resolve" 298 + data-allow-clear="false" 299 + data-minimum-input-length="0" 300 + aria-label="From revision" 301 + name="url1"> 302 + 303 + <option value="rfc1951"> 304 + RFC 1951 305 + 306 + </option> 307 + 308 + <option value="draft-deutsch-deflate-spec-03" selected> 309 + draft-deutsch-deflate-spec-03 310 + 311 + </option> 312 + 313 + <option value="draft-deutsch-deflate-spec-02"> 314 + draft-deutsch-deflate-spec-02 315 + 316 + </option> 317 + 318 + <option value="draft-deutsch-deflate-spec-01"> 319 + draft-deutsch-deflate-spec-01 320 + 321 + </option> 322 + 323 + <option value="draft-deutsch-deflate-spec-00"> 324 + draft-deutsch-deflate-spec-00 325 + 326 + </option> 327 + 328 + 329 + </select> 330 + 331 + <select class="form-select form-select-sm mb-1 select2-field" 332 + data-max-entries="1" 333 + data-width="resolve" 334 + data-allow-clear="false" 335 + data-minimum-input-length="0" 336 + aria-label="To revision" 337 + name="url2"> 338 + 339 + <option value="rfc1951" selected> 340 + RFC 1951 341 + 342 + </option> 343 + 344 + <option value="draft-deutsch-deflate-spec-03"> 345 + draft-deutsch-deflate-spec-03 346 + 347 + </option> 348 + 349 + <option value="draft-deutsch-deflate-spec-02"> 350 + draft-deutsch-deflate-spec-02 351 + 352 + </option> 353 + 354 + <option value="draft-deutsch-deflate-spec-01"> 355 + draft-deutsch-deflate-spec-01 356 + 357 + </option> 358 + 359 + <option value="draft-deutsch-deflate-spec-00"> 360 + draft-deutsch-deflate-spec-00 361 + 362 + </option> 363 + 364 + 365 + </select> 366 + 367 + <button type="submit" 368 + class="btn btn-primary btn-sm" 369 + value="--html" 370 + name="difftype"> 371 + Side-by-side 372 + </button> 373 + 374 + <button type="submit" 375 + class="btn btn-primary btn-sm" 376 + value="--hwdiff" 377 + name="difftype"> 378 + Inline 379 + </button> 380 + 381 + </form> 382 + </td> 383 + </tr> 384 + 385 + 386 + <tr> 387 + <td></td> 388 + <th scope="row">Author</th> 389 + <td class="edit"> 390 + 391 + </td> 392 + <td> 393 + 394 + 395 + <span ><a 396 + title="Datatracker profile of L. Peter Deutsch" 397 + href="/person/ghost@aladdin.com" >L. Peter Deutsch</a> <a 398 + href="mailto:ghost%40aladdin.com" 399 + aria-label="Compose email to ghost@aladdin.com" 400 + title="Compose email to ghost@aladdin.com"> 401 + <i class="bi bi-envelope"></i></a></span> 402 + 403 + 404 + <br> 405 + <a class="btn btn-primary btn-sm mt-1" href="mailto:rfc1951@ietf.org?subject=rfc1951" title="Send email to the document authors">Email authors</a> 406 + 407 + </td> 408 + </tr> 409 + 410 + 411 + <tr> 412 + <td></td> 413 + <th scope="row"> 414 + RFC stream 415 + </th> 416 + <td class="edit"> 417 + 418 + </td> 419 + <td > 420 + 421 + 422 + 423 + 424 + Legacy 425 + 426 + 427 + 428 + 429 + </td> 430 + </tr> 431 + 432 + <tr> 433 + <td></td> 434 + <th scope="row"> 435 + Other formats 436 + </th> 437 + <td class="edit"> 438 + </td> 439 + <td> 440 + 441 + 442 + <div class="buttonlist"> 443 + 444 + 445 + <a class="btn btn-primary btn-sm" 446 + 447 + target="_blank" 448 + href="https://www.rfc-editor.org/rfc/rfc1951.txt"> 449 + 450 + <i class="bi bi-file-text"></i> txt 451 + 452 + </a> 453 + 454 + 455 + 456 + <a class="btn btn-primary btn-sm" 457 + 458 + target="_blank" 459 + href="https://www.rfc-editor.org/rfc/rfc1951.html"> 460 + 461 + <i class="bi bi-file-code"></i> html 462 + 463 + </a> 464 + 465 + 466 + 467 + <a class="btn btn-primary btn-sm" 468 + 469 + download="rfc1951.pdf" 470 + 471 + 472 + target="_blank" 473 + href="https://www.rfc-editor.org/rfc/rfc1951.pdf"> 474 + 475 + <i class="bi bi-file-pdf"></i> pdf 476 + 477 + </a> 478 + 479 + 480 + 481 + 482 + 483 + <a class="btn btn-primary btn-sm" 484 + 485 + target="_blank" 486 + href="/doc/rfc1951/bibtex/"> 487 + 488 + <i class="bi bi-file-ruled"></i> bibtex 489 + 490 + </a> 491 + 492 + 493 + </div> 494 + 495 + 496 + </td> 497 + </tr> 498 + 499 + 500 + 501 + 502 + </tbody> 503 + <tr> 504 + <th scope="row"></th> 505 + <th scope="row"></th> 506 + <td class="edit"></td> 507 + <td> 508 + <a class="btn btn-sm btn-warning mb-3" 509 + target="_blank" 510 + href="https://github.com/ietf-tools/datatracker/issues/new/choose"> 511 + Report a bug 512 + <i class="bi bi-bug"></i> 513 + </a> 514 + </td> 515 + </tr> 516 + </table> 517 + </div> 518 + </div> 519 + </nav> 520 + <div class="row g-0"> 521 + <div class="col-md-9 d-flex justify-content-center lh-sm" 522 + data-bs-spy="scroll" 523 + data-bs-target="#toc-nav" 524 + data-bs-smooth-scroll="true" 525 + tabindex="0" 526 + id="content"> 527 + 528 + <div class="rfcmarkup"> 529 + <br class="noprint"> 530 + <!-- [html-validate-disable-block attr-quotes, void-style, element-permitted-content, heading-level -- FIXME: rfcmarkup/rfc2html generates HTML with issues] --> 531 + <div class="rfcmarkup"><pre>Network Working Group P. Deutsch 532 + Request for Comments: 1951 Aladdin Enterprises 533 + Category: Informational May 1996 534 + 535 + 536 + <span class="h1">DEFLATE Compressed Data Format Specification version 1.3</span> 537 + 538 + Status of This Memo 539 + 540 + This memo provides information for the Internet community. This memo 541 + does not specify an Internet standard of any kind. Distribution of 542 + this memo is unlimited. 543 + 544 + IESG Note: 545 + 546 + The IESG takes no position on the validity of any Intellectual 547 + Property Rights statements contained in this document. 548 + 549 + Notices 550 + 551 + Copyright (c) 1996 L. Peter Deutsch 552 + 553 + Permission is granted to copy and distribute this document for any 554 + purpose and without charge, including translations into other 555 + languages and incorporation into compilations, provided that the 556 + copyright notice and this notice are preserved, and that any 557 + substantive changes or deletions from the original are clearly 558 + marked. 559 + 560 + A pointer to the latest version of this and related documentation in 561 + HTML format can be found at the URL 562 + &lt;<a href="ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html">ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html</a>&gt;. 563 + 564 + Abstract 565 + 566 + This specification defines a lossless compressed data format that 567 + compresses data using a combination of the LZ77 algorithm and Huffman 568 + coding, with efficiency comparable to the best currently available 569 + general-purpose compression methods. The data can be produced or 570 + consumed, even for an arbitrarily long sequentially presented input 571 + data stream, using only an a priori bounded amount of intermediate 572 + storage. The format can be implemented readily in a manner not 573 + covered by patents. 574 + 575 + 576 + 577 + 578 + 579 + 580 + 581 + 582 + <span class="grey">Deutsch Informational [Page 1]</span></pre> 583 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-2" ></span> 584 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 585 + 586 + 587 + Table of Contents 588 + 589 + <a href="#section-1">1</a>. Introduction ................................................... <a href="#page-2">2</a> 590 + <a href="#section-1.1">1.1</a>. Purpose ................................................... <a href="#page-2">2</a> 591 + <a href="#section-1.2">1.2</a>. Intended audience ......................................... <a href="#page-3">3</a> 592 + <a href="#section-1.3">1.3</a>. Scope ..................................................... <a href="#page-3">3</a> 593 + <a href="#section-1.4">1.4</a>. Compliance ................................................ <a href="#page-3">3</a> 594 + <a href="#section-1.5">1.5</a>. Definitions of terms and conventions used ................ <a href="#page-3">3</a> 595 + <a href="#section-1.6">1.6</a>. Changes from previous versions ............................ <a href="#page-4">4</a> 596 + <a href="#section-2">2</a>. Compressed representation overview ............................. <a href="#page-4">4</a> 597 + <a href="#section-3">3</a>. Detailed specification ......................................... <a href="#page-5">5</a> 598 + <a href="#section-3.1">3.1</a>. Overall conventions ....................................... <a href="#page-5">5</a> 599 + <a href="#section-3.1.1">3.1.1</a>. Packing into bytes .................................. <a href="#page-5">5</a> 600 + <a href="#section-3.2">3.2</a>. Compressed block format ................................... <a href="#page-6">6</a> 601 + <a href="#section-3.2.1">3.2.1</a>. Synopsis of prefix and Huffman coding ............... <a href="#page-6">6</a> 602 + <a href="#section-3.2.2">3.2.2</a>. Use of Huffman coding in the &quot;deflate&quot; format ....... <a href="#page-7">7</a> 603 + <a href="#section-3.2.3">3.2.3</a>. Details of block format ............................. <a href="#page-9">9</a> 604 + <a href="#section-3.2.4">3.2.4</a>. Non-compressed blocks (BTYPE=00) ................... <a href="#page-11">11</a> 605 + <a href="#section-3.2.5">3.2.5</a>. Compressed blocks (length and distance codes) ...... <a href="#page-11">11</a> 606 + <a href="#section-3.2.6">3.2.6</a>. Compression with fixed Huffman codes (BTYPE=01) .... <a href="#page-12">12</a> 607 + <a href="#section-3.2.7">3.2.7</a>. Compression with dynamic Huffman codes (BTYPE=10) .. <a href="#page-13">13</a> 608 + <a href="#section-3.3">3.3</a>. Compliance ............................................... <a href="#page-14">14</a> 609 + <a href="#section-4">4</a>. Compression algorithm details ................................. <a href="#page-14">14</a> 610 + <a href="#section-5">5</a>. References .................................................... <a href="#page-16">16</a> 611 + <a href="#section-6">6</a>. Security Considerations ....................................... <a href="#page-16">16</a> 612 + <a href="#section-7">7</a>. Source code ................................................... <a href="#page-16">16</a> 613 + <a href="#section-8">8</a>. Acknowledgements .............................................. <a href="#page-16">16</a> 614 + <a href="#section-9">9</a>. Author&#x27;s Address .............................................. <a href="#page-17">17</a> 615 + 616 + <span class="h2"><a class="selflink" id="section-1" href="#section-1">1</a>. Introduction</span> 617 + 618 + 1.1. Purpose 619 + 620 + The purpose of this specification is to define a lossless 621 + compressed data format that: 622 + * Is independent of CPU type, operating system, file system, 623 + and character set, and hence can be used for interchange; 624 + * Can be produced or consumed, even for an arbitrarily long 625 + sequentially presented input data stream, using only an a 626 + priori bounded amount of intermediate storage, and hence 627 + can be used in data communications or similar structures 628 + such as Unix filters; 629 + * Compresses data with efficiency comparable to the best 630 + currently available general-purpose compression methods, 631 + and in particular considerably better than the &quot;compress&quot; 632 + program; 633 + * Can be implemented readily in a manner not covered by 634 + patents, and hence can be practiced freely; 635 + 636 + 637 + 638 + <span class="grey">Deutsch Informational [Page 2]</span></pre> 639 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-3" ></span> 640 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 641 + 642 + 643 + * Is compatible with the file format produced by the current 644 + widely used gzip utility, in that conforming decompressors 645 + will be able to read data produced by the existing gzip 646 + compressor. 647 + 648 + The data format defined by this specification does not attempt to: 649 + 650 + * Allow random access to compressed data; 651 + * Compress specialized data (e.g., raster graphics) as well 652 + as the best currently available specialized algorithms. 653 + 654 + A simple counting argument shows that no lossless compression 655 + algorithm can compress every possible input data set. For the 656 + format defined here, the worst case expansion is 5 bytes per 32K- 657 + byte block, i.e., a size increase of 0.015% for large data sets. 658 + English text usually compresses by a factor of 2.5 to 3; 659 + executable files usually compress somewhat less; graphical data 660 + such as raster images may compress much more. 661 + 662 + 1.2. Intended audience 663 + 664 + This specification is intended for use by implementors of software 665 + to compress data into &quot;deflate&quot; format and/or decompress data from 666 + &quot;deflate&quot; format. 667 + 668 + The text of the specification assumes a basic background in 669 + programming at the level of bits and other primitive data 670 + representations. Familiarity with the technique of Huffman coding 671 + is helpful but not required. 672 + 673 + 1.3. Scope 674 + 675 + The specification specifies a method for representing a sequence 676 + of bytes as a (usually shorter) sequence of bits, and a method for 677 + packing the latter bit sequence into bytes. 678 + 679 + 1.4. Compliance 680 + 681 + Unless otherwise indicated below, a compliant decompressor must be 682 + able to accept and decompress any data set that conforms to all 683 + the specifications presented here; a compliant compressor must 684 + produce data sets that conform to all the specifications presented 685 + here. 686 + 687 + 1.5. Definitions of terms and conventions used 688 + 689 + Byte: 8 bits stored or transmitted as a unit (same as an octet). 690 + For this specification, a byte is exactly 8 bits, even on machines 691 + 692 + 693 + 694 + <span class="grey">Deutsch Informational [Page 3]</span></pre> 695 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-4" ></span> 696 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 697 + 698 + 699 + which store a character on a number of bits different from eight. 700 + See below, for the numbering of bits within a byte. 701 + 702 + String: a sequence of arbitrary bytes. 703 + 704 + 1.6. Changes from previous versions 705 + 706 + There have been no technical changes to the deflate format since 707 + version 1.1 of this specification. In version 1.2, some 708 + terminology was changed. Version 1.3 is a conversion of the 709 + specification to RFC style. 710 + 711 + <span class="h2"><a class="selflink" id="section-2" href="#section-2">2</a>. Compressed representation overview</span> 712 + 713 + A compressed data set consists of a series of blocks, corresponding 714 + to successive blocks of input data. The block sizes are arbitrary, 715 + except that non-compressible blocks are limited to 65,535 bytes. 716 + 717 + Each block is compressed using a combination of the LZ77 algorithm 718 + and Huffman coding. The Huffman trees for each block are independent 719 + of those for previous or subsequent blocks; the LZ77 algorithm may 720 + use a reference to a duplicated string occurring in a previous block, 721 + up to 32K input bytes before. 722 + 723 + Each block consists of two parts: a pair of Huffman code trees that 724 + describe the representation of the compressed data part, and a 725 + compressed data part. (The Huffman trees themselves are compressed 726 + using Huffman encoding.) The compressed data consists of a series of 727 + elements of two types: literal bytes (of strings that have not been 728 + detected as duplicated within the previous 32K input bytes), and 729 + pointers to duplicated strings, where a pointer is represented as a 730 + pair &lt;length, backward distance&gt;. The representation used in the 731 + &quot;deflate&quot; format limits distances to 32K bytes and lengths to 258 732 + bytes, but does not limit the size of a block, except for 733 + uncompressible blocks, which are limited as noted above. 734 + 735 + Each type of value (literals, distances, and lengths) in the 736 + compressed data is represented using a Huffman code, using one code 737 + tree for literals and lengths and a separate code tree for distances. 738 + The code trees for each block appear in a compact form just before 739 + the compressed data for that block. 740 + 741 + 742 + 743 + 744 + 745 + 746 + 747 + 748 + 749 + 750 + <span class="grey">Deutsch Informational [Page 4]</span></pre> 751 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-5" ></span> 752 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 753 + 754 + 755 + <span class="h2"><a class="selflink" id="section-3" href="#section-3">3</a>. Detailed specification</span> 756 + 757 + 3.1. Overall conventions In the diagrams below, a box like this: 758 + 759 + +---+ 760 + | | &lt;-- the vertical bars might be missing 761 + +---+ 762 + 763 + represents one byte; a box like this: 764 + 765 + +==============+ 766 + | | 767 + +==============+ 768 + 769 + represents a variable number of bytes. 770 + 771 + Bytes stored within a computer do not have a &quot;bit order&quot;, since 772 + they are always treated as a unit. However, a byte considered as 773 + an integer between 0 and 255 does have a most- and least- 774 + significant bit, and since we write numbers with the most- 775 + significant digit on the left, we also write bytes with the most- 776 + significant bit on the left. In the diagrams below, we number the 777 + bits of a byte so that bit 0 is the least-significant bit, i.e., 778 + the bits are numbered: 779 + 780 + +--------+ 781 + |76543210| 782 + +--------+ 783 + 784 + Within a computer, a number may occupy multiple bytes. All 785 + multi-byte numbers in the format described here are stored with 786 + the least-significant byte first (at the lower memory address). 787 + For example, the decimal number 520 is stored as: 788 + 789 + 0 1 790 + +--------+--------+ 791 + |00001000|00000010| 792 + +--------+--------+ 793 + ^ ^ 794 + | | 795 + | + more significant byte = 2 x 256 796 + + less significant byte = 8 797 + 798 + 3.1.1. Packing into bytes 799 + 800 + This document does not address the issue of the order in which 801 + bits of a byte are transmitted on a bit-sequential medium, 802 + since the final data format described here is byte- rather than 803 + 804 + 805 + 806 + <span class="grey">Deutsch Informational [Page 5]</span></pre> 807 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-6" ></span> 808 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 809 + 810 + 811 + bit-oriented. However, we describe the compressed block format 812 + in below, as a sequence of data elements of various bit 813 + lengths, not a sequence of bytes. We must therefore specify 814 + how to pack these data elements into bytes to form the final 815 + compressed byte sequence: 816 + 817 + * Data elements are packed into bytes in order of 818 + increasing bit number within the byte, i.e., starting 819 + with the least-significant bit of the byte. 820 + * Data elements other than Huffman codes are packed 821 + starting with the least-significant bit of the data 822 + element. 823 + * Huffman codes are packed starting with the most- 824 + significant bit of the code. 825 + 826 + In other words, if one were to print out the compressed data as 827 + a sequence of bytes, starting with the first byte at the 828 + *right* margin and proceeding to the *left*, with the most- 829 + significant bit of each byte on the left as usual, one would be 830 + able to parse the result from right to left, with fixed-width 831 + elements in the correct MSB-to-LSB order and Huffman codes in 832 + bit-reversed order (i.e., with the first bit of the code in the 833 + relative LSB position). 834 + 835 + 3.2. Compressed block format 836 + 837 + 3.2.1. Synopsis of prefix and Huffman coding 838 + 839 + Prefix coding represents symbols from an a priori known 840 + alphabet by bit sequences (codes), one code for each symbol, in 841 + a manner such that different symbols may be represented by bit 842 + sequences of different lengths, but a parser can always parse 843 + an encoded string unambiguously symbol-by-symbol. 844 + 845 + We define a prefix code in terms of a binary tree in which the 846 + two edges descending from each non-leaf node are labeled 0 and 847 + 1 and in which the leaf nodes correspond one-for-one with (are 848 + labeled with) the symbols of the alphabet; then the code for a 849 + symbol is the sequence of 0&#x27;s and 1&#x27;s on the edges leading from 850 + the root to the leaf labeled with that symbol. For example: 851 + 852 + 853 + 854 + 855 + 856 + 857 + 858 + 859 + 860 + 861 + 862 + <span class="grey">Deutsch Informational [Page 6]</span></pre> 863 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-7" ></span> 864 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 865 + 866 + 867 + /\ Symbol Code 868 + 0 1 ------ ---- 869 + / \ A 00 870 + /\ B B 1 871 + 0 1 C 011 872 + / \ D 010 873 + A /\ 874 + 0 1 875 + / \ 876 + D C 877 + 878 + A parser can decode the next symbol from an encoded input 879 + stream by walking down the tree from the root, at each step 880 + choosing the edge corresponding to the next input bit. 881 + 882 + Given an alphabet with known symbol frequencies, the Huffman 883 + algorithm allows the construction of an optimal prefix code 884 + (one which represents strings with those symbol frequencies 885 + using the fewest bits of any possible prefix codes for that 886 + alphabet). Such a code is called a Huffman code. (See 887 + reference [<a href="#ref-1" title="&quot;A Method for the Construction of Minimum Redundancy Codes&quot;">1</a>] in Chapter 5, references for additional 888 + information on Huffman codes.) 889 + 890 + Note that in the &quot;deflate&quot; format, the Huffman codes for the 891 + various alphabets must not exceed certain maximum code lengths. 892 + This constraint complicates the algorithm for computing code 893 + lengths from symbol frequencies. Again, see Chapter 5, 894 + references for details. 895 + 896 + 3.2.2. Use of Huffman coding in the &quot;deflate&quot; format 897 + 898 + The Huffman codes used for each alphabet in the &quot;deflate&quot; 899 + format have two additional rules: 900 + 901 + * All codes of a given bit length have lexicographically 902 + consecutive values, in the same order as the symbols 903 + they represent; 904 + 905 + * Shorter codes lexicographically precede longer codes. 906 + 907 + 908 + 909 + 910 + 911 + 912 + 913 + 914 + 915 + 916 + 917 + 918 + <span class="grey">Deutsch Informational [Page 7]</span></pre> 919 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-8" ></span> 920 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 921 + 922 + 923 + We could recode the example above to follow this rule as 924 + follows, assuming that the order of the alphabet is ABCD: 925 + 926 + Symbol Code 927 + ------ ---- 928 + A 10 929 + B 0 930 + C 110 931 + D 111 932 + 933 + I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are 934 + lexicographically consecutive. 935 + 936 + Given this rule, we can define the Huffman code for an alphabet 937 + just by giving the bit lengths of the codes for each symbol of 938 + the alphabet in order; this is sufficient to determine the 939 + actual codes. In our example, the code is completely defined 940 + by the sequence of bit lengths (2, 1, 3, 3). The following 941 + algorithm generates the codes as integers, intended to be read 942 + from most- to least-significant bit. The code lengths are 943 + initially in tree[I].Len; the codes are produced in 944 + tree[I].Code. 945 + 946 + 1) Count the number of codes for each code length. Let 947 + bl_count[N] be the number of codes of length N, N &gt;= 1. 948 + 949 + 2) Find the numerical value of the smallest code for each 950 + code length: 951 + 952 + code = 0; 953 + bl_count[0] = 0; 954 + for (bits = 1; bits &lt;= MAX_BITS; bits++) { 955 + code = (code + bl_count[bits-1]) &lt;&lt; 1; 956 + next_code[bits] = code; 957 + } 958 + 959 + 3) Assign numerical values to all codes, using consecutive 960 + values for all codes of the same length with the base 961 + values determined at step 2. Codes that are never used 962 + (which have a bit length of zero) must not be assigned a 963 + value. 964 + 965 + for (n = 0; n &lt;= max_code; n++) { 966 + len = tree[n].Len; 967 + if (len != 0) { 968 + tree[n].Code = next_code[len]; 969 + next_code[len]++; 970 + } 971 + 972 + 973 + 974 + <span class="grey">Deutsch Informational [Page 8]</span></pre> 975 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-9" ></span> 976 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 977 + 978 + 979 + } 980 + 981 + Example: 982 + 983 + Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, 984 + 3, 2, 4, 4). After step 1, we have: 985 + 986 + N bl_count[N] 987 + - ----------- 988 + 2 1 989 + 3 5 990 + 4 2 991 + 992 + Step 2 computes the following next_code values: 993 + 994 + N next_code[N] 995 + - ------------ 996 + 1 0 997 + 2 0 998 + 3 2 999 + 4 14 1000 + 1001 + Step 3 produces the following code values: 1002 + 1003 + Symbol Length Code 1004 + ------ ------ ---- 1005 + A 3 010 1006 + B 3 011 1007 + C 3 100 1008 + D 3 101 1009 + E 3 110 1010 + F 2 00 1011 + G 4 1110 1012 + H 4 1111 1013 + 1014 + 3.2.3. Details of block format 1015 + 1016 + Each block of compressed data begins with 3 header bits 1017 + containing the following data: 1018 + 1019 + first bit BFINAL 1020 + next 2 bits BTYPE 1021 + 1022 + Note that the header bits do not necessarily begin on a byte 1023 + boundary, since a block does not necessarily occupy an integral 1024 + number of bytes. 1025 + 1026 + 1027 + 1028 + 1029 + 1030 + <span class="grey">Deutsch Informational [Page 9]</span></pre> 1031 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-10" ></span> 1032 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 1033 + 1034 + 1035 + BFINAL is set if and only if this is the last block of the data 1036 + set. 1037 + 1038 + BTYPE specifies how the data are compressed, as follows: 1039 + 1040 + 00 - no compression 1041 + 01 - compressed with fixed Huffman codes 1042 + 10 - compressed with dynamic Huffman codes 1043 + 11 - reserved (error) 1044 + 1045 + The only difference between the two compressed cases is how the 1046 + Huffman codes for the literal/length and distance alphabets are 1047 + defined. 1048 + 1049 + In all cases, the decoding algorithm for the actual data is as 1050 + follows: 1051 + 1052 + do 1053 + read block header from input stream. 1054 + if stored with no compression 1055 + skip any remaining bits in current partially 1056 + processed byte 1057 + read LEN and NLEN (see next section) 1058 + copy LEN bytes of data to output 1059 + otherwise 1060 + if compressed with dynamic Huffman codes 1061 + read representation of code trees (see 1062 + subsection below) 1063 + loop (until end of block code recognized) 1064 + decode literal/length value from input stream 1065 + if value &lt; 256 1066 + copy value (literal byte) to output stream 1067 + otherwise 1068 + if value = end of block (256) 1069 + break from loop 1070 + otherwise (value = 257..285) 1071 + decode distance from input stream 1072 + 1073 + move backwards distance bytes in the output 1074 + stream, and copy length bytes from this 1075 + position to the output stream. 1076 + end loop 1077 + while not last block 1078 + 1079 + Note that a duplicated string reference may refer to a string 1080 + in a previous block; i.e., the backward distance may cross one 1081 + or more block boundaries. However a distance cannot refer past 1082 + the beginning of the output stream. (An application using a 1083 + 1084 + 1085 + 1086 + <span class="grey">Deutsch Informational [Page 10]</span></pre> 1087 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-11" ></span> 1088 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 1089 + 1090 + 1091 + preset dictionary might discard part of the output stream; a 1092 + distance can refer to that part of the output stream anyway) 1093 + Note also that the referenced string may overlap the current 1094 + position; for example, if the last 2 bytes decoded have values 1095 + X and Y, a string reference with &lt;length = 5, distance = 2&gt; 1096 + adds X,Y,X,Y,X to the output stream. 1097 + 1098 + We now specify each compression method in turn. 1099 + 1100 + 3.2.4. Non-compressed blocks (BTYPE=00) 1101 + 1102 + Any bits of input up to the next byte boundary are ignored. 1103 + The rest of the block consists of the following information: 1104 + 1105 + 0 1 2 3 4... 1106 + +---+---+---+---+================================+ 1107 + | LEN | NLEN |... LEN bytes of literal data...| 1108 + +---+---+---+---+================================+ 1109 + 1110 + LEN is the number of data bytes in the block. NLEN is the 1111 + one&#x27;s complement of LEN. 1112 + 1113 + 3.2.5. Compressed blocks (length and distance codes) 1114 + 1115 + As noted above, encoded data blocks in the &quot;deflate&quot; format 1116 + consist of sequences of symbols drawn from three conceptually 1117 + distinct alphabets: either literal bytes, from the alphabet of 1118 + byte values (0..255), or &lt;length, backward distance&gt; pairs, 1119 + where the length is drawn from (3..258) and the distance is 1120 + drawn from (1..32,768). In fact, the literal and length 1121 + alphabets are merged into a single alphabet (0..285), where 1122 + values 0..255 represent literal bytes, the value 256 indicates 1123 + end-of-block, and values 257..285 represent length codes 1124 + (possibly in conjunction with extra bits following the symbol 1125 + code) as follows: 1126 + 1127 + 1128 + 1129 + 1130 + 1131 + 1132 + 1133 + 1134 + 1135 + 1136 + 1137 + 1138 + 1139 + 1140 + 1141 + 1142 + <span class="grey">Deutsch Informational [Page 11]</span></pre> 1143 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-12" ></span> 1144 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 1145 + 1146 + 1147 + Extra Extra Extra 1148 + Code Bits Length(s) Code Bits Lengths Code Bits Length(s) 1149 + ---- ---- ------ ---- ---- ------- ---- ---- ------- 1150 + 257 0 3 267 1 15,16 277 4 67-82 1151 + 258 0 4 268 1 17,18 278 4 83-98 1152 + 259 0 5 269 2 19-22 279 4 99-114 1153 + 260 0 6 270 2 23-26 280 4 115-130 1154 + 261 0 7 271 2 27-30 281 5 131-162 1155 + 262 0 8 272 2 31-34 282 5 163-194 1156 + 263 0 9 273 3 35-42 283 5 195-226 1157 + 264 0 10 274 3 43-50 284 5 227-257 1158 + 265 1 11,12 275 3 51-58 285 0 258 1159 + 266 1 13,14 276 3 59-66 1160 + 1161 + The extra bits should be interpreted as a machine integer 1162 + stored with the most-significant bit first, e.g., bits 1110 1163 + represent the value 14. 1164 + 1165 + Extra Extra Extra 1166 + Code Bits Dist Code Bits Dist Code Bits Distance 1167 + ---- ---- ---- ---- ---- ------ ---- ---- -------- 1168 + 0 0 1 10 4 33-48 20 9 1025-1536 1169 + 1 0 2 11 4 49-64 21 9 1537-2048 1170 + 2 0 3 12 5 65-96 22 10 2049-3072 1171 + 3 0 4 13 5 97-128 23 10 3073-4096 1172 + 4 1 5,6 14 6 129-192 24 11 4097-6144 1173 + 5 1 7,8 15 6 193-256 25 11 6145-8192 1174 + 6 2 9-12 16 7 257-384 26 12 8193-12288 1175 + 7 2 13-16 17 7 385-512 27 12 12289-16384 1176 + 8 3 17-24 18 8 513-768 28 13 16385-24576 1177 + 9 3 25-32 19 8 769-1024 29 13 24577-32768 1178 + 1179 + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) 1180 + 1181 + The Huffman codes for the two alphabets are fixed, and are not 1182 + represented explicitly in the data. The Huffman code lengths 1183 + for the literal/length alphabet are: 1184 + 1185 + Lit Value Bits Codes 1186 + --------- ---- ----- 1187 + 0 - 143 8 00110000 through 1188 + 10111111 1189 + 144 - 255 9 110010000 through 1190 + 111111111 1191 + 256 - 279 7 0000000 through 1192 + 0010111 1193 + 280 - 287 8 11000000 through 1194 + 11000111 1195 + 1196 + 1197 + 1198 + <span class="grey">Deutsch Informational [Page 12]</span></pre> 1199 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-13" ></span> 1200 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 1201 + 1202 + 1203 + The code lengths are sufficient to generate the actual codes, 1204 + as described above; we show the codes in the table for added 1205 + clarity. Literal/length values 286-287 will never actually 1206 + occur in the compressed data, but participate in the code 1207 + construction. 1208 + 1209 + Distance codes 0-31 are represented by (fixed-length) 5-bit 1210 + codes, with possible additional bits as shown in the table 1211 + shown in Paragraph 3.2.5, above. Note that distance codes 30- 1212 + 31 will never actually occur in the compressed data. 1213 + 1214 + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) 1215 + 1216 + The Huffman codes for the two alphabets appear in the block 1217 + immediately after the header bits and before the actual 1218 + compressed data, first the literal/length code and then the 1219 + distance code. Each code is defined by a sequence of code 1220 + lengths, as discussed in Paragraph 3.2.2, above. For even 1221 + greater compactness, the code length sequences themselves are 1222 + compressed using a Huffman code. The alphabet for code lengths 1223 + is as follows: 1224 + 1225 + 0 - 15: Represent code lengths of 0 - 15 1226 + 16: Copy the previous code length 3 - 6 times. 1227 + The next 2 bits indicate repeat length 1228 + (0 = 3, ... , 3 = 6) 1229 + Example: Codes 8, 16 (+2 bits 11), 1230 + 16 (+2 bits 10) will expand to 1231 + 12 code lengths of 8 (1 + 6 + 5) 1232 + 17: Repeat a code length of 0 for 3 - 10 times. 1233 + (3 bits of length) 1234 + 18: Repeat a code length of 0 for 11 - 138 times 1235 + (7 bits of length) 1236 + 1237 + A code length of 0 indicates that the corresponding symbol in 1238 + the literal/length or distance alphabet will not occur in the 1239 + block, and should not participate in the Huffman code 1240 + construction algorithm given earlier. If only one distance 1241 + code is used, it is encoded using one bit, not zero bits; in 1242 + this case there is a single code length of one, with one unused 1243 + code. One distance code of zero bits means that there are no 1244 + distance codes used at all (the data is all literals). 1245 + 1246 + We can now define the format of the block: 1247 + 1248 + 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) 1249 + 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) 1250 + 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) 1251 + 1252 + 1253 + 1254 + <span class="grey">Deutsch Informational [Page 13]</span></pre> 1255 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-14" ></span> 1256 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 1257 + 1258 + 1259 + (HCLEN + 4) x 3 bits: code lengths for the code length 1260 + alphabet given just above, in the order: 16, 17, 18, 1261 + 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 1262 + 1263 + These code lengths are interpreted as 3-bit integers 1264 + (0-7); as above, a code length of 0 means the 1265 + corresponding symbol (literal/length or distance code 1266 + length) is not used. 1267 + 1268 + HLIT + 257 code lengths for the literal/length alphabet, 1269 + encoded using the code length Huffman code 1270 + 1271 + HDIST + 1 code lengths for the distance alphabet, 1272 + encoded using the code length Huffman code 1273 + 1274 + The actual compressed data of the block, 1275 + encoded using the literal/length and distance Huffman 1276 + codes 1277 + 1278 + The literal/length symbol 256 (end of data), 1279 + encoded using the literal/length Huffman code 1280 + 1281 + The code length repeat codes can cross from HLIT + 257 to the 1282 + HDIST + 1 code lengths. In other words, all code lengths form 1283 + a single sequence of HLIT + HDIST + 258 values. 1284 + 1285 + 3.3. Compliance 1286 + 1287 + A compressor may limit further the ranges of values specified in 1288 + the previous section and still be compliant; for example, it may 1289 + limit the range of backward pointers to some value smaller than 1290 + 32K. Similarly, a compressor may limit the size of blocks so that 1291 + a compressible block fits in memory. 1292 + 1293 + A compliant decompressor must accept the full range of possible 1294 + values defined in the previous section, and must accept blocks of 1295 + arbitrary size. 1296 + 1297 + <span class="h2"><a class="selflink" id="section-4" href="#section-4">4</a>. Compression algorithm details</span> 1298 + 1299 + While it is the intent of this document to define the &quot;deflate&quot; 1300 + compressed data format without reference to any particular 1301 + compression algorithm, the format is related to the compressed 1302 + formats produced by LZ77 (Lempel-Ziv 1977, see reference [<a href="#ref-2" title="&quot;A Universal Algorithm for Sequential Data Compression&quot;">2</a>] below); 1303 + since many variations of LZ77 are patented, it is strongly 1304 + recommended that the implementor of a compressor follow the general 1305 + algorithm presented here, which is known not to be patented per se. 1306 + The material in this section is not part of the definition of the 1307 + 1308 + 1309 + 1310 + <span class="grey">Deutsch Informational [Page 14]</span></pre> 1311 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-15" ></span> 1312 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 1313 + 1314 + 1315 + specification per se, and a compressor need not follow it in order to 1316 + be compliant. 1317 + 1318 + The compressor terminates a block when it determines that starting a 1319 + new block with fresh trees would be useful, or when the block size 1320 + fills up the compressor&#x27;s block buffer. 1321 + 1322 + The compressor uses a chained hash table to find duplicated strings, 1323 + using a hash function that operates on 3-byte sequences. At any 1324 + given point during compression, let XYZ be the next 3 input bytes to 1325 + be examined (not necessarily all different, of course). First, the 1326 + compressor examines the hash chain for XYZ. If the chain is empty, 1327 + the compressor simply writes out X as a literal byte and advances one 1328 + byte in the input. If the hash chain is not empty, indicating that 1329 + the sequence XYZ (or, if we are unlucky, some other 3 bytes with the 1330 + same hash function value) has occurred recently, the compressor 1331 + compares all strings on the XYZ hash chain with the actual input data 1332 + sequence starting at the current point, and selects the longest 1333 + match. 1334 + 1335 + The compressor searches the hash chains starting with the most recent 1336 + strings, to favor small distances and thus take advantage of the 1337 + Huffman encoding. The hash chains are singly linked. There are no 1338 + deletions from the hash chains; the algorithm simply discards matches 1339 + that are too old. To avoid a worst-case situation, very long hash 1340 + chains are arbitrarily truncated at a certain length, determined by a 1341 + run-time parameter. 1342 + 1343 + To improve overall compression, the compressor optionally defers the 1344 + selection of matches (&quot;lazy matching&quot;): after a match of length N has 1345 + been found, the compressor searches for a longer match starting at 1346 + the next input byte. If it finds a longer match, it truncates the 1347 + previous match to a length of one (thus producing a single literal 1348 + byte) and then emits the longer match. Otherwise, it emits the 1349 + original match, and, as described above, advances N bytes before 1350 + continuing. 1351 + 1352 + Run-time parameters also control this &quot;lazy match&quot; procedure. If 1353 + compression ratio is most important, the compressor attempts a 1354 + complete second search regardless of the length of the first match. 1355 + In the normal case, if the current match is &quot;long enough&quot;, the 1356 + compressor reduces the search for a longer match, thus speeding up 1357 + the process. If speed is most important, the compressor inserts new 1358 + strings in the hash table only when no match was found, or when the 1359 + match is not &quot;too long&quot;. This degrades the compression ratio but 1360 + saves time since there are both fewer insertions and fewer searches. 1361 + 1362 + 1363 + 1364 + 1365 + 1366 + <span class="grey">Deutsch Informational [Page 15]</span></pre> 1367 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-16" ></span> 1368 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 1369 + 1370 + 1371 + <span class="h2"><a class="selflink" id="section-5" href="#section-5">5</a>. References</span> 1372 + 1373 + [<a id="ref-1">1</a>] Huffman, D. A., &quot;A Method for the Construction of Minimum 1374 + Redundancy Codes&quot;, Proceedings of the Institute of Radio 1375 + Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. 1376 + 1377 + [<a id="ref-2">2</a>] Ziv J., Lempel A., &quot;A Universal Algorithm for Sequential Data 1378 + Compression&quot;, IEEE Transactions on Information Theory, Vol. 23, 1379 + No. 3, pp. 337-343. 1380 + 1381 + [<a id="ref-3">3</a>] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, 1382 + available in <a href="ftp://ftp.uu.net/pub/archiving/zip/doc/">ftp://ftp.uu.net/pub/archiving/zip/doc/</a> 1383 + 1384 + [<a id="ref-4">4</a>] Gailly, J.-L., and Adler, M., GZIP documentation and sources, 1385 + available as gzip-*.tar in <a href="ftp://prep.ai.mit.edu/pub/gnu/">ftp://prep.ai.mit.edu/pub/gnu/</a> 1386 + 1387 + [<a id="ref-5">5</a>] Schwartz, E. S., and Kallick, B. &quot;Generating a canonical prefix 1388 + encoding.&quot; Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. 1389 + 1390 + [<a id="ref-6">6</a>] Hirschberg and Lelewer, &quot;Efficient decoding of prefix codes,&quot; 1391 + Comm. ACM, 33,4, April 1990, pp. 449-459. 1392 + 1393 + <span class="h2"><a class="selflink" id="section-6" href="#section-6">6</a>. Security Considerations</span> 1394 + 1395 + Any data compression method involves the reduction of redundancy in 1396 + the data. Consequently, any corruption of the data is likely to have 1397 + severe effects and be difficult to correct. Uncompressed text, on 1398 + the other hand, will probably still be readable despite the presence 1399 + of some corrupted bytes. 1400 + 1401 + It is recommended that systems using this data format provide some 1402 + means of validating the integrity of the compressed data. See 1403 + reference [<a href="#ref-3" title="ZLIB documentation and sources">3</a>], for example. 1404 + 1405 + <span class="h2"><a class="selflink" id="section-7" href="#section-7">7</a>. Source code</span> 1406 + 1407 + Source code for a C language implementation of a &quot;deflate&quot; compliant 1408 + compressor and decompressor is available within the zlib package at 1409 + <a href="ftp://ftp.uu.net/pub/archiving/zip/zlib/">ftp://ftp.uu.net/pub/archiving/zip/zlib/</a>. 1410 + 1411 + <span class="h2"><a class="selflink" id="section-8" href="#section-8">8</a>. Acknowledgements</span> 1412 + 1413 + Trademarks cited in this document are the property of their 1414 + respective owners. 1415 + 1416 + Phil Katz designed the deflate format. Jean-Loup Gailly and Mark 1417 + Adler wrote the related software described in this specification. 1418 + Glenn Randers-Pehrson converted this document to RFC and HTML format. 1419 + 1420 + 1421 + 1422 + <span class="grey">Deutsch Informational [Page 16]</span></pre> 1423 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-17" ></span> 1424 + <span class="grey"><a href="/doc/html/rfc1951">RFC 1951</a> DEFLATE Compressed Data Format Specification May 1996</span> 1425 + 1426 + 1427 + <span class="h2"><a class="selflink" id="section-9" href="#section-9">9</a>. Author&#x27;s Address</span> 1428 + 1429 + L. Peter Deutsch 1430 + Aladdin Enterprises 1431 + 203 Santa Margarita Ave. 1432 + Menlo Park, CA 94025 1433 + 1434 + Phone: (415) 322-0103 (AM only) 1435 + FAX: (415) 322-1734 1436 + EMail: &lt;ghost@aladdin.com&gt; 1437 + 1438 + Questions about the technical content of this specification can be 1439 + sent by email to: 1440 + 1441 + Jean-Loup Gailly &lt;gzip@prep.ai.mit.edu&gt; and 1442 + Mark Adler &lt;madler@alumni.caltech.edu&gt; 1443 + 1444 + Editorial comments on this specification can be sent by email to: 1445 + 1446 + L. Peter Deutsch &lt;ghost@aladdin.com&gt; and 1447 + Glenn Randers-Pehrson &lt;randeg@alumni.rpi.edu&gt; 1448 + 1449 + 1450 + 1451 + 1452 + 1453 + 1454 + 1455 + 1456 + 1457 + 1458 + 1459 + 1460 + 1461 + 1462 + 1463 + 1464 + 1465 + 1466 + 1467 + 1468 + 1469 + 1470 + 1471 + 1472 + 1473 + 1474 + 1475 + 1476 + 1477 + 1478 + Deutsch Informational [Page 17] 1479 + </pre></div> 1480 + </div> 1481 + 1482 + </div> 1483 + <div class="d-print-none col-md-3 bg-light-subtle collapse show" id="sidebar"> 1484 + <div class="position-fixed border-start sidebar overflow-scroll overscroll-none no-scrollbar"> 1485 + <div class="d-flex flex-column vh-100 pt-2 pt-lg-3 ps-3 pl-md-2 pl-lg-3"> 1486 + <div> 1487 + <a class="btn btn-primary btn-sm" href="/doc/rfc1951/">Datatracker</a> 1488 + <p class="fw-bold pt-2"> 1489 + 1490 + RFC 1951 1491 + 1492 + <br> 1493 + 1494 + 1495 + 1496 + 1497 + 1498 + 1499 + <span class="text-success">RFC 1500 + 1501 + - Informational 1502 + 1503 + </span> 1504 + 1505 + </p> 1506 + </div> 1507 + 1508 + <ul class="nav nav-tabs nav-fill small me-2" role="tablist"> 1509 + <li class="nav-item" role="presentation" title="Document information"> 1510 + <button class="nav-link px-2" 1511 + id="docinfo-tab" 1512 + data-bs-toggle="tab" 1513 + data-bs-target="#docinfo-tab-pane" 1514 + type="button" 1515 + role="tab" 1516 + aria-controls="docinfo-tab-pane" 1517 + aria-selected="true"> 1518 + <i class="bi bi-info-circle"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Info</span> 1519 + </button> 1520 + </li> 1521 + <li class="nav-item" role="presentation" title="Table of contents"> 1522 + <button class="nav-link px-2" 1523 + id="toc-tab" 1524 + data-bs-toggle="tab" 1525 + data-bs-target="#toc-tab-pane" 1526 + type="button" 1527 + role="tab" 1528 + aria-controls="toc-tab-pane" 1529 + aria-selected="false"> 1530 + <i class="bi bi-list-ol"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Contents</span> 1531 + </button> 1532 + </li> 1533 + <li class="nav-item" role="presentation" title="Preferences"> 1534 + <button class="nav-link px-2" 1535 + id="pref-tab" 1536 + data-bs-toggle="tab" 1537 + data-bs-target="#pref-tab-pane" 1538 + type="button" 1539 + role="tab" 1540 + aria-controls="pref-tab-pane" 1541 + aria-selected="false"> 1542 + <i class="bi bi-gear"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Prefs</span> 1543 + </button> 1544 + </li> 1545 + </ul> 1546 + <div class="overflow-auto tab-content pt-2 me-2"> 1547 + <div class="tab-pane" 1548 + id="docinfo-tab-pane" 1549 + role="tabpanel" 1550 + aria-labelledby="docinfo-tab" 1551 + tabindex="0"> 1552 + <table class="table table-sm table-borderless"> 1553 + 1554 + 1555 + 1556 + 1557 + 1558 + 1559 + 1560 + 1561 + <tbody class="meta align-top "> 1562 + <tr> 1563 + <th scope="row">Document</th> 1564 + <th scope="row">Document type</th> 1565 + <td class="edit"></td> 1566 + <td> 1567 + 1568 + 1569 + 1570 + 1571 + 1572 + 1573 + <span class="text-success">RFC 1574 + 1575 + - Informational 1576 + 1577 + </span> 1578 + 1579 + 1580 + 1581 + <br>May 1996 1582 + 1583 + <br> 1584 + 1585 + <a class="btn btn-primary btn-sm my-1" 1586 + href="https://www.rfc-editor.org/errata_search.php?rfc=1951" title="Click to view errata." rel="nofollow"> 1587 + View errata 1588 + </a> 1589 + 1590 + 1591 + <a class="btn btn-sm btn-warning" 1592 + title="Click to report an error in the document." 1593 + href="https://www.rfc-editor.org/errata.php#reportnew" 1594 + target="_blank"> 1595 + Report errata 1596 + </a> 1597 + 1598 + 1599 + 1600 + 1601 + 1602 + 1603 + 1604 + 1605 + 1606 + <div> 1607 + Was 1608 + <a href="/doc/draft-deutsch-deflate-spec/03/">draft-deutsch-deflate-spec</a> 1609 + (individual) 1610 + </div> 1611 + 1612 + 1613 + 1614 + 1615 + 1616 + 1617 + 1618 + 1619 + 1620 + 1621 + <div class="alert alert-warning small p-2 mt-2" role="alert"> 1622 + This RFC is labeled as "Legacy"; it was published before a formal source was recorded. 1623 + This RFC is <strong>not endorsed by the IETF</strong> and has <strong>no formal standing</strong> in the 1624 + <a href="/doc/rfc2026/">IETF standards process</a>. 1625 + </div> 1626 + 1627 + 1628 + 1629 + 1630 + </td> 1631 + </tr> 1632 + 1633 + <tr> 1634 + <td></td> 1635 + <th scope="row">Select version</th> 1636 + <td class="edit"></td> 1637 + <td> 1638 + 1639 + 1640 + 1641 + 1642 + <ul class="revision-list pagination pagination-sm text-center flex-wrap my-0"> 1643 + 1644 + 1645 + 1646 + 1647 + <li class="page-item"> 1648 + <a class="page-link" 1649 + href="/doc/html/draft-deutsch-deflate-spec-03" 1650 + rel="nofollow"> 1651 + 03 1652 + </a> 1653 + </li> 1654 + 1655 + 1656 + 1657 + <li class="page-item rfc active"> 1658 + <a class="page-link" 1659 + href="/doc/html/rfc1951"> 1660 + RFC 1951 1661 + </a> 1662 + </li> 1663 + 1664 + </ul> 1665 + 1666 + </td> 1667 + </tr> 1668 + 1669 + <tr> 1670 + <td></td> 1671 + <th scope="row">Compare versions</th> 1672 + <td class="edit"></td> 1673 + <td> 1674 + 1675 + 1676 + 1677 + 1678 + <form class="form-horizontal diff-form" 1679 + action="https://author-tools.ietf.org/iddiff" 1680 + method="get" 1681 + target="_blank"> 1682 + 1683 + <select class="form-select form-select-sm mb-1 select2-field" 1684 + data-max-entries="1" 1685 + data-width="resolve" 1686 + data-allow-clear="false" 1687 + data-minimum-input-length="0" 1688 + aria-label="From revision" 1689 + name="url1"> 1690 + 1691 + <option value="rfc1951"> 1692 + RFC 1951 1693 + 1694 + </option> 1695 + 1696 + <option value="draft-deutsch-deflate-spec-03" selected> 1697 + draft-deutsch-deflate-spec-03 1698 + 1699 + </option> 1700 + 1701 + <option value="draft-deutsch-deflate-spec-02"> 1702 + draft-deutsch-deflate-spec-02 1703 + 1704 + </option> 1705 + 1706 + <option value="draft-deutsch-deflate-spec-01"> 1707 + draft-deutsch-deflate-spec-01 1708 + 1709 + </option> 1710 + 1711 + <option value="draft-deutsch-deflate-spec-00"> 1712 + draft-deutsch-deflate-spec-00 1713 + 1714 + </option> 1715 + 1716 + 1717 + </select> 1718 + 1719 + <select class="form-select form-select-sm mb-1 select2-field" 1720 + data-max-entries="1" 1721 + data-width="resolve" 1722 + data-allow-clear="false" 1723 + data-minimum-input-length="0" 1724 + aria-label="To revision" 1725 + name="url2"> 1726 + 1727 + <option value="rfc1951" selected> 1728 + RFC 1951 1729 + 1730 + </option> 1731 + 1732 + <option value="draft-deutsch-deflate-spec-03"> 1733 + draft-deutsch-deflate-spec-03 1734 + 1735 + </option> 1736 + 1737 + <option value="draft-deutsch-deflate-spec-02"> 1738 + draft-deutsch-deflate-spec-02 1739 + 1740 + </option> 1741 + 1742 + <option value="draft-deutsch-deflate-spec-01"> 1743 + draft-deutsch-deflate-spec-01 1744 + 1745 + </option> 1746 + 1747 + <option value="draft-deutsch-deflate-spec-00"> 1748 + draft-deutsch-deflate-spec-00 1749 + 1750 + </option> 1751 + 1752 + 1753 + </select> 1754 + 1755 + <button type="submit" 1756 + class="btn btn-primary btn-sm" 1757 + value="--html" 1758 + name="difftype"> 1759 + Side-by-side 1760 + </button> 1761 + 1762 + <button type="submit" 1763 + class="btn btn-primary btn-sm" 1764 + value="--hwdiff" 1765 + name="difftype"> 1766 + Inline 1767 + </button> 1768 + 1769 + </form> 1770 + </td> 1771 + </tr> 1772 + 1773 + 1774 + <tr> 1775 + <td></td> 1776 + <th scope="row">Author</th> 1777 + <td class="edit"> 1778 + 1779 + </td> 1780 + <td> 1781 + 1782 + 1783 + <span ><a 1784 + title="Datatracker profile of L. Peter Deutsch" 1785 + href="/person/ghost@aladdin.com" >L. Peter Deutsch</a> <a 1786 + href="mailto:ghost%40aladdin.com" 1787 + aria-label="Compose email to ghost@aladdin.com" 1788 + title="Compose email to ghost@aladdin.com"> 1789 + <i class="bi bi-envelope"></i></a></span> 1790 + 1791 + 1792 + <br> 1793 + <a class="btn btn-primary btn-sm mt-1" href="mailto:rfc1951@ietf.org?subject=rfc1951" title="Send email to the document authors">Email authors</a> 1794 + 1795 + </td> 1796 + </tr> 1797 + 1798 + 1799 + <tr> 1800 + <td></td> 1801 + <th scope="row"> 1802 + RFC stream 1803 + </th> 1804 + <td class="edit"> 1805 + 1806 + </td> 1807 + <td > 1808 + 1809 + 1810 + 1811 + 1812 + Legacy 1813 + 1814 + 1815 + 1816 + 1817 + </td> 1818 + </tr> 1819 + 1820 + <tr> 1821 + <td></td> 1822 + <th scope="row"> 1823 + Other formats 1824 + </th> 1825 + <td class="edit"> 1826 + </td> 1827 + <td> 1828 + 1829 + 1830 + <div class="buttonlist"> 1831 + 1832 + 1833 + <a class="btn btn-primary btn-sm" 1834 + 1835 + target="_blank" 1836 + href="https://www.rfc-editor.org/rfc/rfc1951.txt"> 1837 + 1838 + <i class="bi bi-file-text"></i> txt 1839 + 1840 + </a> 1841 + 1842 + 1843 + 1844 + <a class="btn btn-primary btn-sm" 1845 + 1846 + target="_blank" 1847 + href="https://www.rfc-editor.org/rfc/rfc1951.html"> 1848 + 1849 + <i class="bi bi-file-code"></i> html 1850 + 1851 + </a> 1852 + 1853 + 1854 + 1855 + <a class="btn btn-primary btn-sm" 1856 + 1857 + download="rfc1951.pdf" 1858 + 1859 + 1860 + target="_blank" 1861 + href="https://www.rfc-editor.org/rfc/rfc1951.pdf"> 1862 + 1863 + <i class="bi bi-file-pdf"></i> pdf 1864 + 1865 + </a> 1866 + 1867 + 1868 + 1869 + 1870 + 1871 + <a class="btn btn-primary btn-sm" 1872 + 1873 + target="_blank" 1874 + href="/doc/rfc1951/bibtex/"> 1875 + 1876 + <i class="bi bi-file-ruled"></i> bibtex 1877 + 1878 + </a> 1879 + 1880 + 1881 + </div> 1882 + 1883 + 1884 + </td> 1885 + </tr> 1886 + 1887 + 1888 + 1889 + 1890 + </tbody> 1891 + </table> 1892 + <a class="btn btn-sm btn-warning mb-3" 1893 + target="_blank" 1894 + href="https://github.com/ietf-tools/datatracker/issues/new/choose"> 1895 + Report a datatracker bug 1896 + <i class="bi bi-bug"></i> 1897 + </a> 1898 + </div> 1899 + <div class="tab-pane mb-5" 1900 + id="toc-tab-pane" 1901 + role="tabpanel" 1902 + aria-labelledby="toc-tab" 1903 + tabindex="0"> 1904 + <nav class="nav nav-pills flex-column small" id="toc-nav"> 1905 + </nav> 1906 + </div> 1907 + <div class="tab-pane mb-5 small" 1908 + id="pref-tab-pane" 1909 + role="tabpanel" 1910 + aria-labelledby="pref-tab" 1911 + tabindex="0"> 1912 + <label class="form-label fw-bold mb-2">Show sidebar by default</label> 1913 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1914 + <input type="radio" class="btn-check" name="sidebar" id="on-radio"> 1915 + <label class="btn btn-outline-primary" for="on-radio">Yes</label> 1916 + <input type="radio" class="btn-check" name="sidebar" id="off-radio"> 1917 + <label class="btn btn-outline-primary" for="off-radio">No</label> 1918 + </div> 1919 + <label class="form-label fw-bold mt-4 mb-2">Tab to show by default</label> 1920 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1921 + <input type="radio" class="btn-check" name="deftab" id="docinfo-radio"> 1922 + <label class="btn btn-outline-primary" for="docinfo-radio"> 1923 + <i class="bi bi-info-circle me-1"></i>Info 1924 + </label> 1925 + <input type="radio" class="btn-check" name="deftab" id="toc-radio"> 1926 + <label class="btn btn-outline-primary" for="toc-radio"> 1927 + <i class="bi bi-list-ol me-1"></i>Contents 1928 + </label> 1929 + </div> 1930 + <label class="form-label fw-bold mt-4 mb-2">HTMLization configuration</label> 1931 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1932 + <input type="radio" class="btn-check" name="htmlconf" id="txt-radio"> 1933 + <label class="btn btn-outline-primary" for="txt-radio" title="This is the traditional HTMLization method."> 1934 + <i class="bi bi-badge-sd me-1"></i>HTMLize the plaintext 1935 + </label> 1936 + <input type="radio" class="btn-check" name="htmlconf" id="html-radio"> 1937 + <label class="btn btn-outline-primary" for="html-radio" title="This is the modern HTMLization method."> 1938 + <i class="bi bi-badge-hd me-1"></i>Plaintextify the HTML 1939 + </label> 1940 + </div> 1941 + <label class="form-label fw-bold mt-4 mb-2" for="ptsize">Maximum font size</label> 1942 + <input type="range" class="form-range" min="7" max="16" id="ptsize" oninput="ptdemo.value = ptsize.value"> 1943 + <label class="form-label fw-bold mt-4 mb-2">Page dependencies</label> 1944 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1945 + <input type="radio" class="btn-check" name="pagedeps" id="inline-radio"> 1946 + <label class="btn btn-outline-primary" for="inline-radio" title="Generate larger, standalone web pages that do not require network access to render."> 1947 + <i class="bi bi-box me-1"></i>Inline 1948 + </label> 1949 + <input type="radio" class="btn-check" name="pagedeps" id="reference-radio"> 1950 + <label class="btn btn-outline-primary" for="reference-radio" title="Generate regular web pages that require network access to render."> 1951 + <i class="bi bi-link-45deg me-1"></i>Reference 1952 + </label> 1953 + </div> 1954 + <label class="form-label fw-bold mt-4 mb-2">Citation links</label> 1955 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 1956 + <input type="radio" class="btn-check" name="reflinks" id="refsection-radio"> 1957 + <label class="btn btn-outline-primary" for="refsection-radio" title="Citation links go to the reference section."> 1958 + <i class="bi bi-arrow-clockwise"></i> Go to reference section 1959 + </label> 1960 + <input type="radio" class="btn-check" name="reflinks" id="citation-radio"> 1961 + <label class="btn btn-outline-primary" for="citation-radio" title="Citation links go directly to the cited document."> 1962 + <i class="bi bi-link-45deg me-1"></i>Go to linked document 1963 + </label> 1964 + </div> 1965 + </div> 1966 + </div> 1967 + </div> 1968 + </div> 1969 + </div> 1970 + </div> 1971 + 1972 + <script> 1973 + var _paq = window._paq || []; 1974 + 1975 + _paq.push(['disableCookies']); 1976 + _paq.push(['trackPageView']); 1977 + _paq.push(['enableLinkTracking']); 1978 + (function() { 1979 + var u="//analytics.ietf.org/"; 1980 + _paq.push(['setTrackerUrl', u+'matomo.php']); 1981 + _paq.push(['setSiteId', 7]); 1982 + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 1983 + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); 1984 + })(); 1985 + </script> 1986 + <noscript><p><img src="//analytics.ietf.org/matomo.php?idsite=7" style="border:0;" alt="" /></p></noscript> 1987 + 1988 + </body> 1989 + </html>
+3597
spec/rfc7616.txt
··· 1 + 2 + <!DOCTYPE html> 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + <html data-bs-theme="auto" lang="en"> 11 + <head> 12 + 13 + <meta charset="utf-8"> 14 + <meta http-equiv="X-UA-Compatible" content="IE=edge"> 15 + <title> 16 + 17 + RFC 7616 - HTTP Digest Access Authentication 18 + 19 + </title> 20 + <meta name="viewport" content="width=device-width, initial-scale=1"> 21 + <link href="https://static.ietf.org/fonts/inter/import.css" rel="stylesheet"> 22 + <link href="https://static.ietf.org/fonts/noto-sans-mono/import.css" rel="stylesheet"> 23 + 24 + <link rel="stylesheet" href="https://static.ietf.org/dt/12.54.0/ietf/css/document_html_referenced.css"> 25 + 26 + <script type="module" crossorigin="" src="https://static.ietf.org/dt/12.54.0/assets/embedded-055c333d.js"></script> 27 + <link href="https://static.ietf.org/dt/12.54.0/assets/create-pinia-singleton-8312c5df.js" type="text/javascript" crossorigin="anonymous" rel="modulepreload" as="script" /> 28 + <link href="https://static.ietf.org/dt/12.54.0/assets/Scrollbar-ad8c5330.js" type="text/javascript" crossorigin="anonymous" rel="modulepreload" as="script" /> 29 + <script src="https://static.ietf.org/dt/12.54.0/ietf/js/document_html.js"></script> 30 + <script src="https://static.ietf.org/dt/12.54.0/ietf/js/theme.js"></script> 31 + 32 + <link rel="alternate" type="application/atom+xml" title="Document changes" href="/feed/document-changes/rfc7616/"> 33 + <meta name="description" 34 + 35 + content="HTTP Digest Access Authentication (RFC 7616, )" 36 + > 37 + 38 + 39 + <link rel="apple-touch-icon" 40 + sizes="180x180" 41 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-180.png"> 42 + <link rel="icon" 43 + sizes="32x32" 44 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-32.png"> 45 + <link rel="icon" 46 + sizes="16x16" 47 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-16.png"> 48 + <link rel="manifest" href="/site.webmanifest"> 49 + <link rel="mask-icon" 50 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-mask.svg" 51 + color="#ffffff"> 52 + <meta name="msapplication-TileColor" 53 + content="#ffffff"> 54 + <meta name="theme-color" 55 + content="#ffffff"> 56 + 57 + 58 + 59 + 60 + 61 + <meta property="og:title" content="RFC 7616: HTTP Digest Access Authentication"> 62 + <meta property="og:url" content="https://datatracker.ietf.org/doc/html/rfc7616.txt"> 63 + <link rel="canonical" href="https://datatracker.ietf.org/doc/html/rfc7616.txt"> 64 + <meta property="og:site_name" content="IETF Datatracker"> 65 + <meta property="og:description" content="The Hypertext Transfer Protocol (HTTP) provides a simple challenge- response authentication mechanism that may be used by a server to challenge a client request and by a client to provide authentication information. This document defines the HTTP Digest Authentication scheme that can be used with the HTTP authentication mechanism."> 66 + <meta property="og:type" content="article"> 67 + 68 + <meta property="og:image" content="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-card.png"> 69 + <meta property="og:image:alt" content="Logo of the IETF"> 70 + <meta property="article:section" content="IETF - Internet Engineering Task Force"> 71 + <meta property="og:image:type" content="image/png"> 72 + <meta property="og:image:width" content="1200"> 73 + <meta property="og:image:height" content="630"> 74 + <meta name="twitter:card" content="summary_large_image"> 75 + 76 + <meta property="article:author" content="Rifaat Shekh-Yusef"> 77 + <meta property="article:author" content="David Ahrens"> 78 + <meta property="article:author" content="Sophie Bremer"> 79 + 80 + 81 + 82 + 83 + <style> 84 + 85 + .diff-form .select2-selection__rendered { 86 + direction: rtl; 87 + text-align: left; 88 + } 89 + </style> 90 + </head> 91 + <body> 92 + 93 + <noscript><iframe class="status" title="Site status" src="/status/latest"></iframe></noscript> 94 + <div class="vue-embed" data-component="Status"></div> 95 + <div class="btn-toolbar sidebar-toolbar position-fixed top-0 end-0 m-2 m-lg-3 d-print-none"> 96 + <div class="dropdown"> 97 + <button class="btn btn-outline-secondary btn-sm me-1 dropdown-toggle d-flex align-items-center" 98 + id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" 99 + aria-label="Toggle theme"> 100 + <i class="theme-icon-active bi bi-circle-half"></i> 101 + </button> 102 + 103 + <ul class="dropdown-menu" aria-labelledby="bd-theme"> 104 + <li> 105 + <button type="button" class="dropdown-item d-flex align-items-center" 106 + data-bs-theme-value="light" aria-pressed="false"> 107 + <i class="me-2 opacity-50 theme-icon bi bi-sun-fill"></i> 108 + Light<i class="bi bi-check2 ms-auto d-none"></i> 109 + </button> 110 + </li> 111 + <li> 112 + <button type="button" class="dropdown-item d-flex align-items-center" 113 + data-bs-theme-value="dark" aria-pressed="false"> 114 + <i class="me-2 opacity-50 theme-icon bi bi-moon-stars-fill"></i> 115 + Dark<i class="bi bi-check2 ms-auto d-none"></i> 116 + </button> 117 + </li> 118 + <li> 119 + <button type="button" class="dropdown-item d-flex align-items-center active" 120 + data-bs-theme-value="auto" aria-pressed="true"> 121 + <i class="me-2 opacity-50 theme-icon bi bi-circle-half"></i> 122 + Auto<i class="bi bi-check2 ms-auto d-none"></i> 123 + </button> 124 + </li> 125 + </ul> 126 + </div> 127 + <button class="btn btn-outline-secondary btn-sm sidebar-toggle" 128 + type="button" 129 + data-bs-toggle="collapse" 130 + data-bs-target="#sidebar" 131 + aria-expanded="true" 132 + aria-controls="sidebar" 133 + aria-label="Toggle metadata sidebar" 134 + title="Toggle metadata sidebar"> 135 + <i class="bi bi-arrow-bar-left sidebar-shown"></i> 136 + <i class="bi bi-arrow-bar-right sidebar-collapsed"></i> 137 + </button> 138 + </div> 139 + <nav class="navbar bg-light-subtle px-1 fixed-top d-print-none d-md-none"> 140 + <a class="nav-link ps-1" 141 + href="/doc/rfc7616/"> 142 + 143 + RFC 7616 144 + 145 + <br class="d-sm-none"> 146 + 147 + <span class="ms-sm-3 badge rounded-pill badge-ps"> 148 + 149 + Proposed Standard 150 + 151 + </span> 152 + </a> 153 + <button class="navbar-toggler p-1" 154 + type="button" 155 + data-bs-toggle="collapse" 156 + data-bs-target="#docinfo-collapse" 157 + aria-controls="docinfo-collapse" 158 + aria-expanded="false" 159 + aria-label="Show document information"> 160 + <span class="navbar-toggler-icon small"></span> 161 + </button> 162 + <div class="navbar-nav navbar-nav-scroll overscroll-none collapse pt-1" id="docinfo-collapse"> 163 + <div class="bg-light-subtle p-0"> 164 + <table class="table table-sm table-borderless small"> 165 + <tbody class="meta align-top"> 166 + <tr> 167 + <th scope="row"></th> 168 + <th scope="row">Title</th> 169 + <td class="edit"></td> 170 + <td>HTTP Digest Access Authentication</td> 171 + </tr> 172 + </tbody> 173 + 174 + 175 + 176 + 177 + 178 + 179 + 180 + 181 + <tbody class="meta align-top "> 182 + <tr> 183 + <th scope="row">Document</th> 184 + <th scope="row">Document type</th> 185 + <td class="edit"></td> 186 + <td> 187 + 188 + 189 + 190 + 191 + 192 + 193 + <span class="text-success">RFC 194 + 195 + - Proposed Standard 196 + 197 + </span> 198 + 199 + 200 + 201 + <br>September 2015 202 + 203 + <br> 204 + 205 + <a class="btn btn-primary btn-sm my-1" 206 + href="https://www.rfc-editor.org/errata_search.php?rfc=7616" title="Click to view errata." rel="nofollow"> 207 + View errata 208 + </a> 209 + 210 + 211 + <a class="btn btn-sm btn-warning" 212 + title="Click to report an error in the document." 213 + href="https://www.rfc-editor.org/errata.php#reportnew" 214 + target="_blank"> 215 + Report errata 216 + </a> 217 + 218 + 219 + <a title="Click to view IPR declarations." class="btn btn-warning btn-sm my-1" href="/ipr/search/?submit=draft&amp;id=rfc7616">IPR</a> 220 + 221 + 222 + 223 + <div>Obsoletes <a href="/doc/html/rfc2617" title="HTTP Authentication: Basic and Digest Access Authentication">RFC 2617</a></div> 224 + 225 + 226 + 227 + 228 + <div> 229 + Was 230 + <a href="/doc/draft-ietf-httpauth-digest/19/">draft-ietf-httpauth-digest</a> 231 + (<a href="/wg/httpauth/about/">httpauth WG</a>) 232 + </div> 233 + 234 + 235 + 236 + 237 + 238 + 239 + 240 + 241 + 242 + 243 + 244 + 245 + 246 + </td> 247 + </tr> 248 + 249 + <tr> 250 + <td></td> 251 + <th scope="row">Select version</th> 252 + <td class="edit"></td> 253 + <td> 254 + 255 + 256 + 257 + 258 + <ul class="revision-list pagination pagination-sm text-center flex-wrap my-0"> 259 + 260 + 261 + 262 + 263 + <li class="page-item"> 264 + <a class="page-link" 265 + href="/doc/html/draft-ietf-httpauth-digest-00" 266 + rel="nofollow"> 267 + 00 268 + </a> 269 + </li> 270 + 271 + <li class="page-item"> 272 + <a class="page-link" 273 + href="/doc/html/draft-ietf-httpauth-digest-01" 274 + rel="nofollow"> 275 + 01 276 + </a> 277 + </li> 278 + 279 + <li class="page-item"> 280 + <a class="page-link" 281 + href="/doc/html/draft-ietf-httpauth-digest-02" 282 + rel="nofollow"> 283 + 02 284 + </a> 285 + </li> 286 + 287 + <li class="page-item"> 288 + <a class="page-link" 289 + href="/doc/html/draft-ietf-httpauth-digest-03" 290 + rel="nofollow"> 291 + 03 292 + </a> 293 + </li> 294 + 295 + <li class="page-item"> 296 + <a class="page-link" 297 + href="/doc/html/draft-ietf-httpauth-digest-04" 298 + rel="nofollow"> 299 + 04 300 + </a> 301 + </li> 302 + 303 + <li class="page-item"> 304 + <a class="page-link" 305 + href="/doc/html/draft-ietf-httpauth-digest-05" 306 + rel="nofollow"> 307 + 05 308 + </a> 309 + </li> 310 + 311 + <li class="page-item"> 312 + <a class="page-link" 313 + href="/doc/html/draft-ietf-httpauth-digest-06" 314 + rel="nofollow"> 315 + 06 316 + </a> 317 + </li> 318 + 319 + <li class="page-item"> 320 + <a class="page-link" 321 + href="/doc/html/draft-ietf-httpauth-digest-07" 322 + rel="nofollow"> 323 + 07 324 + </a> 325 + </li> 326 + 327 + <li class="page-item"> 328 + <a class="page-link" 329 + href="/doc/html/draft-ietf-httpauth-digest-08" 330 + rel="nofollow"> 331 + 08 332 + </a> 333 + </li> 334 + 335 + <li class="page-item"> 336 + <a class="page-link" 337 + href="/doc/html/draft-ietf-httpauth-digest-09" 338 + rel="nofollow"> 339 + 09 340 + </a> 341 + </li> 342 + 343 + <li class="page-item"> 344 + <a class="page-link" 345 + href="/doc/html/draft-ietf-httpauth-digest-10" 346 + rel="nofollow"> 347 + 10 348 + </a> 349 + </li> 350 + 351 + <li class="page-item"> 352 + <a class="page-link" 353 + href="/doc/html/draft-ietf-httpauth-digest-11" 354 + rel="nofollow"> 355 + 11 356 + </a> 357 + </li> 358 + 359 + <li class="page-item"> 360 + <a class="page-link" 361 + href="/doc/html/draft-ietf-httpauth-digest-12" 362 + rel="nofollow"> 363 + 12 364 + </a> 365 + </li> 366 + 367 + <li class="page-item"> 368 + <a class="page-link" 369 + href="/doc/html/draft-ietf-httpauth-digest-13" 370 + rel="nofollow"> 371 + 13 372 + </a> 373 + </li> 374 + 375 + <li class="page-item"> 376 + <a class="page-link" 377 + href="/doc/html/draft-ietf-httpauth-digest-14" 378 + rel="nofollow"> 379 + 14 380 + </a> 381 + </li> 382 + 383 + <li class="page-item"> 384 + <a class="page-link" 385 + href="/doc/html/draft-ietf-httpauth-digest-15" 386 + rel="nofollow"> 387 + 15 388 + </a> 389 + </li> 390 + 391 + <li class="page-item"> 392 + <a class="page-link" 393 + href="/doc/html/draft-ietf-httpauth-digest-16" 394 + rel="nofollow"> 395 + 16 396 + </a> 397 + </li> 398 + 399 + <li class="page-item"> 400 + <a class="page-link" 401 + href="/doc/html/draft-ietf-httpauth-digest-17" 402 + rel="nofollow"> 403 + 17 404 + </a> 405 + </li> 406 + 407 + <li class="page-item"> 408 + <a class="page-link" 409 + href="/doc/html/draft-ietf-httpauth-digest-18" 410 + rel="nofollow"> 411 + 18 412 + </a> 413 + </li> 414 + 415 + <li class="page-item"> 416 + <a class="page-link" 417 + href="/doc/html/draft-ietf-httpauth-digest-19" 418 + rel="nofollow"> 419 + 19 420 + </a> 421 + </li> 422 + 423 + 424 + 425 + <li class="page-item rfc active"> 426 + <a class="page-link" 427 + href="/doc/html/rfc7616"> 428 + RFC 7616 429 + </a> 430 + </li> 431 + 432 + </ul> 433 + 434 + </td> 435 + </tr> 436 + 437 + <tr> 438 + <td></td> 439 + <th scope="row">Compare versions</th> 440 + <td class="edit"></td> 441 + <td> 442 + 443 + 444 + 445 + 446 + <form class="form-horizontal diff-form" 447 + action="https://author-tools.ietf.org/iddiff" 448 + method="get" 449 + target="_blank"> 450 + 451 + <select class="form-select form-select-sm mb-1 select2-field" 452 + data-max-entries="1" 453 + data-width="resolve" 454 + data-allow-clear="false" 455 + data-minimum-input-length="0" 456 + aria-label="From revision" 457 + name="url1"> 458 + 459 + <option value="rfc7616"> 460 + RFC 7616 461 + 462 + </option> 463 + 464 + <option value="draft-ietf-httpauth-digest-19" selected> 465 + draft-ietf-httpauth-digest-19 466 + 467 + </option> 468 + 469 + <option value="draft-ietf-httpauth-digest-18"> 470 + draft-ietf-httpauth-digest-18 471 + 472 + </option> 473 + 474 + <option value="draft-ietf-httpauth-digest-17"> 475 + draft-ietf-httpauth-digest-17 476 + 477 + </option> 478 + 479 + <option value="draft-ietf-httpauth-digest-16"> 480 + draft-ietf-httpauth-digest-16 481 + 482 + </option> 483 + 484 + <option value="draft-ietf-httpauth-digest-15"> 485 + draft-ietf-httpauth-digest-15 486 + 487 + </option> 488 + 489 + <option value="draft-ietf-httpauth-digest-14"> 490 + draft-ietf-httpauth-digest-14 491 + 492 + </option> 493 + 494 + <option value="draft-ietf-httpauth-digest-13"> 495 + draft-ietf-httpauth-digest-13 496 + 497 + </option> 498 + 499 + <option value="draft-ietf-httpauth-digest-12"> 500 + draft-ietf-httpauth-digest-12 501 + 502 + </option> 503 + 504 + <option value="draft-ietf-httpauth-digest-11"> 505 + draft-ietf-httpauth-digest-11 506 + 507 + </option> 508 + 509 + <option value="draft-ietf-httpauth-digest-10"> 510 + draft-ietf-httpauth-digest-10 511 + 512 + </option> 513 + 514 + <option value="draft-ietf-httpauth-digest-09"> 515 + draft-ietf-httpauth-digest-09 516 + 517 + </option> 518 + 519 + <option value="draft-ietf-httpauth-digest-08"> 520 + draft-ietf-httpauth-digest-08 521 + 522 + </option> 523 + 524 + <option value="draft-ietf-httpauth-digest-07"> 525 + draft-ietf-httpauth-digest-07 526 + 527 + </option> 528 + 529 + <option value="draft-ietf-httpauth-digest-06"> 530 + draft-ietf-httpauth-digest-06 531 + 532 + </option> 533 + 534 + <option value="draft-ietf-httpauth-digest-05"> 535 + draft-ietf-httpauth-digest-05 536 + 537 + </option> 538 + 539 + <option value="draft-ietf-httpauth-digest-04"> 540 + draft-ietf-httpauth-digest-04 541 + 542 + </option> 543 + 544 + <option value="draft-ietf-httpauth-digest-03"> 545 + draft-ietf-httpauth-digest-03 546 + 547 + </option> 548 + 549 + <option value="draft-ietf-httpauth-digest-02"> 550 + draft-ietf-httpauth-digest-02 551 + 552 + </option> 553 + 554 + <option value="draft-ietf-httpauth-digest-01"> 555 + draft-ietf-httpauth-digest-01 556 + 557 + </option> 558 + 559 + <option value="draft-ietf-httpauth-digest-00"> 560 + draft-ietf-httpauth-digest-00 561 + 562 + </option> 563 + 564 + 565 + </select> 566 + 567 + <select class="form-select form-select-sm mb-1 select2-field" 568 + data-max-entries="1" 569 + data-width="resolve" 570 + data-allow-clear="false" 571 + data-minimum-input-length="0" 572 + aria-label="To revision" 573 + name="url2"> 574 + 575 + <option value="rfc7616" selected> 576 + RFC 7616 577 + 578 + </option> 579 + 580 + <option value="draft-ietf-httpauth-digest-19"> 581 + draft-ietf-httpauth-digest-19 582 + 583 + </option> 584 + 585 + <option value="draft-ietf-httpauth-digest-18"> 586 + draft-ietf-httpauth-digest-18 587 + 588 + </option> 589 + 590 + <option value="draft-ietf-httpauth-digest-17"> 591 + draft-ietf-httpauth-digest-17 592 + 593 + </option> 594 + 595 + <option value="draft-ietf-httpauth-digest-16"> 596 + draft-ietf-httpauth-digest-16 597 + 598 + </option> 599 + 600 + <option value="draft-ietf-httpauth-digest-15"> 601 + draft-ietf-httpauth-digest-15 602 + 603 + </option> 604 + 605 + <option value="draft-ietf-httpauth-digest-14"> 606 + draft-ietf-httpauth-digest-14 607 + 608 + </option> 609 + 610 + <option value="draft-ietf-httpauth-digest-13"> 611 + draft-ietf-httpauth-digest-13 612 + 613 + </option> 614 + 615 + <option value="draft-ietf-httpauth-digest-12"> 616 + draft-ietf-httpauth-digest-12 617 + 618 + </option> 619 + 620 + <option value="draft-ietf-httpauth-digest-11"> 621 + draft-ietf-httpauth-digest-11 622 + 623 + </option> 624 + 625 + <option value="draft-ietf-httpauth-digest-10"> 626 + draft-ietf-httpauth-digest-10 627 + 628 + </option> 629 + 630 + <option value="draft-ietf-httpauth-digest-09"> 631 + draft-ietf-httpauth-digest-09 632 + 633 + </option> 634 + 635 + <option value="draft-ietf-httpauth-digest-08"> 636 + draft-ietf-httpauth-digest-08 637 + 638 + </option> 639 + 640 + <option value="draft-ietf-httpauth-digest-07"> 641 + draft-ietf-httpauth-digest-07 642 + 643 + </option> 644 + 645 + <option value="draft-ietf-httpauth-digest-06"> 646 + draft-ietf-httpauth-digest-06 647 + 648 + </option> 649 + 650 + <option value="draft-ietf-httpauth-digest-05"> 651 + draft-ietf-httpauth-digest-05 652 + 653 + </option> 654 + 655 + <option value="draft-ietf-httpauth-digest-04"> 656 + draft-ietf-httpauth-digest-04 657 + 658 + </option> 659 + 660 + <option value="draft-ietf-httpauth-digest-03"> 661 + draft-ietf-httpauth-digest-03 662 + 663 + </option> 664 + 665 + <option value="draft-ietf-httpauth-digest-02"> 666 + draft-ietf-httpauth-digest-02 667 + 668 + </option> 669 + 670 + <option value="draft-ietf-httpauth-digest-01"> 671 + draft-ietf-httpauth-digest-01 672 + 673 + </option> 674 + 675 + <option value="draft-ietf-httpauth-digest-00"> 676 + draft-ietf-httpauth-digest-00 677 + 678 + </option> 679 + 680 + 681 + </select> 682 + 683 + <button type="submit" 684 + class="btn btn-primary btn-sm" 685 + value="--html" 686 + name="difftype"> 687 + Side-by-side 688 + </button> 689 + 690 + <button type="submit" 691 + class="btn btn-primary btn-sm" 692 + value="--hwdiff" 693 + name="difftype"> 694 + Inline 695 + </button> 696 + 697 + </form> 698 + </td> 699 + </tr> 700 + 701 + 702 + <tr> 703 + <td></td> 704 + <th scope="row">Authors</th> 705 + <td class="edit"> 706 + 707 + </td> 708 + <td> 709 + 710 + 711 + <span ><a 712 + title="Datatracker profile of Rifaat Shekh-Yusef" 713 + href="/person/rifaat.s.ietf@gmail.com" >Rifaat Shekh-Yusef</a> <a 714 + href="mailto:rifaat.s.ietf%40gmail.com" 715 + aria-label="Compose email to rifaat.s.ietf@gmail.com" 716 + title="Compose email to rifaat.s.ietf@gmail.com"> 717 + <i class="bi bi-envelope"></i></a></span>, 718 + 719 + <span ><a 720 + title="Datatracker profile of David Ahrens" 721 + href="/person/ahrensdc@gmail.com" >David Ahrens</a> <a 722 + href="mailto:ahrensdc%40gmail.com" 723 + aria-label="Compose email to ahrensdc@gmail.com" 724 + title="Compose email to ahrensdc@gmail.com"> 725 + <i class="bi bi-envelope"></i></a></span>, 726 + 727 + <span ><a 728 + title="Datatracker profile of Sophie Bremer" 729 + href="/person/ietf@sophiebremer.com" >Sophie Bremer</a> <a 730 + href="mailto:ietf%40sophiebremer.com" 731 + aria-label="Compose email to ietf@sophiebremer.com" 732 + title="Compose email to ietf@sophiebremer.com"> 733 + <i class="bi bi-envelope"></i></a></span> 734 + 735 + 736 + <br> 737 + <a class="btn btn-primary btn-sm mt-1" href="mailto:rfc7616@ietf.org?subject=rfc7616" title="Send email to the document authors">Email authors</a> 738 + 739 + </td> 740 + </tr> 741 + 742 + 743 + <tr> 744 + <td></td> 745 + <th scope="row"> 746 + RFC stream 747 + </th> 748 + <td class="edit"> 749 + 750 + </td> 751 + <td > 752 + 753 + 754 + 755 + 756 + 757 + 758 + 759 + 760 + <img alt="IETF Logo" 761 + class="d-lm-none w-25 mt-1" 762 + 763 + 764 + 765 + src="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-white.svg" 766 + 767 + 768 + > 769 + 770 + <img alt="IETF Logo" 771 + class="d-dm-none w-25 mt-1" 772 + 773 + 774 + 775 + src="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor.svg" 776 + 777 + 778 + > 779 + 780 + 781 + 782 + 783 + </td> 784 + </tr> 785 + 786 + <tr> 787 + <td></td> 788 + <th scope="row"> 789 + Other formats 790 + </th> 791 + <td class="edit"> 792 + </td> 793 + <td> 794 + 795 + 796 + <div class="buttonlist"> 797 + 798 + 799 + <a class="btn btn-primary btn-sm" 800 + 801 + target="_blank" 802 + href="https://www.rfc-editor.org/rfc/rfc7616.txt"> 803 + 804 + <i class="bi bi-file-text"></i> txt 805 + 806 + </a> 807 + 808 + 809 + 810 + <a class="btn btn-primary btn-sm" 811 + 812 + target="_blank" 813 + href="https://www.rfc-editor.org/rfc/rfc7616.html"> 814 + 815 + <i class="bi bi-file-code"></i> html 816 + 817 + </a> 818 + 819 + 820 + 821 + <a class="btn btn-primary btn-sm" 822 + 823 + download="rfc7616.pdf" 824 + 825 + 826 + target="_blank" 827 + href="https://www.rfc-editor.org/rfc/pdfrfc/rfc7616.txt.pdf"> 828 + 829 + <i class="bi bi-file-pdf"></i> pdf 830 + 831 + </a> 832 + 833 + 834 + 835 + 836 + 837 + <a class="btn btn-primary btn-sm" 838 + 839 + target="_blank" 840 + href="https://www.rfc-editor.org/rfc/inline-errata/rfc7616.html"> 841 + 842 + <i class="bi bi-file-diff"></i> w/errata 843 + 844 + </a> 845 + 846 + 847 + 848 + <a class="btn btn-primary btn-sm" 849 + 850 + target="_blank" 851 + href="/doc/rfc7616/bibtex/"> 852 + 853 + <i class="bi bi-file-ruled"></i> bibtex 854 + 855 + </a> 856 + 857 + 858 + </div> 859 + 860 + 861 + </td> 862 + </tr> 863 + 864 + 865 + 866 + <tr> 867 + <td> 868 + </td> 869 + <th scope="row"> 870 + Additional resources 871 + </th> 872 + <td class="edit"> 873 + 874 + </td> 875 + <td> 876 + 877 + 878 + 879 + 880 + <a href="https://mailarchive.ietf.org/arch/browse/http-auth/?q=rfc7616 OR %22draft-ietf-httpauth-digest%22"> 881 + Mailing list discussion 882 + </a> 883 + 884 + 885 + 886 + </td> 887 + </tr> 888 + 889 + 890 + </tbody> 891 + <tr> 892 + <th scope="row"></th> 893 + <th scope="row"></th> 894 + <td class="edit"></td> 895 + <td> 896 + <a class="btn btn-sm btn-warning mb-3" 897 + target="_blank" 898 + href="https://github.com/ietf-tools/datatracker/issues/new/choose"> 899 + Report a bug 900 + <i class="bi bi-bug"></i> 901 + </a> 902 + </td> 903 + </tr> 904 + </table> 905 + </div> 906 + </div> 907 + </nav> 908 + <div class="row g-0"> 909 + <div class="col-md-9 d-flex justify-content-center lh-sm" 910 + data-bs-spy="scroll" 911 + data-bs-target="#toc-nav" 912 + data-bs-smooth-scroll="true" 913 + tabindex="0" 914 + id="content"> 915 + 916 + <div class="rfcmarkup"> 917 + <br class="noprint"> 918 + <!-- [html-validate-disable-block attr-quotes, void-style, element-permitted-content, heading-level -- FIXME: rfcmarkup/rfc2html generates HTML with issues] --> 919 + <div class="rfcmarkup"><pre>Internet Engineering Task Force (IETF) R. Shekh-Yusef, Ed. 920 + Request for Comments: 7616 Avaya 921 + Obsoletes: <a href="/doc/html/rfc2617">2617</a> D. Ahrens 922 + Category: Standards Track Independent 923 + ISSN: 2070-1721 S. Bremer 924 + Netzkonform 925 + September 2015 926 + 927 + 928 + <span class="h1">HTTP Digest Access Authentication</span> 929 + 930 + Abstract 931 + 932 + The Hypertext Transfer Protocol (HTTP) provides a simple challenge- 933 + response authentication mechanism that may be used by a server to 934 + challenge a client request and by a client to provide authentication 935 + information. This document defines the HTTP Digest Authentication 936 + scheme that can be used with the HTTP authentication mechanism. 937 + 938 + Status of This Memo 939 + 940 + This is an Internet Standards Track document. 941 + 942 + This document is a product of the Internet Engineering Task Force 943 + (IETF). It represents the consensus of the IETF community. It has 944 + received public review and has been approved for publication by the 945 + Internet Engineering Steering Group (IESG). Further information on 946 + Internet Standards is available in <a href="/doc/html/rfc5741#section-2">Section&nbsp;2 of RFC 5741</a>. 947 + 948 + Information about the current status of this document, any errata, 949 + and how to provide feedback on it may be obtained at 950 + <a href="http://www.rfc-editor.org/info/rfc7616">http://www.rfc-editor.org/info/rfc7616</a>. 951 + 952 + 953 + 954 + 955 + 956 + 957 + 958 + 959 + 960 + 961 + 962 + 963 + 964 + 965 + 966 + 967 + 968 + 969 + 970 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 1]</span></pre> 971 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-2" ></span> 972 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 973 + 974 + 975 + Copyright Notice 976 + 977 + Copyright (c) 2015 IETF Trust and the persons identified as the 978 + document authors. All rights reserved. 979 + 980 + This document is subject to <a href="/doc/html/bcp78">BCP 78</a> and the IETF Trust&#x27;s Legal 981 + Provisions Relating to IETF Documents 982 + (<a href="http://trustee.ietf.org/license-info">http://trustee.ietf.org/license-info</a>) in effect on the date of 983 + publication of this document. Please review these documents 984 + carefully, as they describe your rights and restrictions with respect 985 + to this document. Code Components extracted from this document must 986 + include Simplified BSD License text as described in Section 4.e of 987 + the Trust Legal Provisions and are provided without warranty as 988 + described in the Simplified BSD License. 989 + 990 + This document may contain material from IETF Documents or IETF 991 + Contributions published or made publicly available before November 992 + 10, 2008. The person(s) controlling the copyright in some of this 993 + material may not have granted the IETF Trust the right to allow 994 + modifications of such material outside the IETF Standards Process. 995 + Without obtaining an adequate license from the person(s) controlling 996 + the copyright in such materials, this document may not be modified 997 + outside the IETF Standards Process, and derivative works of it may 998 + not be created outside the IETF Standards Process, except to format 999 + it for publication as an RFC or to translate it into languages other 1000 + than English. 1001 + 1002 + 1003 + 1004 + 1005 + 1006 + 1007 + 1008 + 1009 + 1010 + 1011 + 1012 + 1013 + 1014 + 1015 + 1016 + 1017 + 1018 + 1019 + 1020 + 1021 + 1022 + 1023 + 1024 + 1025 + 1026 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 2]</span></pre> 1027 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-3" ></span> 1028 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1029 + 1030 + 1031 + Table of Contents 1032 + 1033 + <a href="#section-1">1</a>. Introduction . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-4">4</a> 1034 + <a href="#section-1.1">1.1</a>. Terminology . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-4">4</a> 1035 + <a href="#section-2">2</a>. Syntax Convention . . . . . . . . . . . . . . . . . . . . . . <a href="#page-4">4</a> 1036 + <a href="#section-2.1">2.1</a>. Examples . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-4">4</a> 1037 + <a href="#section-2.2">2.2</a>. ABNF . . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-4">4</a> 1038 + <a href="#section-3">3</a>. Digest Access Authentication Scheme . . . . . . . . . . . . . <a href="#page-5">5</a> 1039 + <a href="#section-3.1">3.1</a>. Overall Operation . . . . . . . . . . . . . . . . . . . . <a href="#page-5">5</a> 1040 + <a href="#section-3.2">3.2</a>. Representation of Digest Values . . . . . . . . . . . . . <a href="#page-5">5</a> 1041 + <a href="#section-3.3">3.3</a>. The WWW-Authenticate Response Header Field . . . . . . . <a href="#page-5">5</a> 1042 + <a href="#section-3.4">3.4</a>. The Authorization Header Field . . . . . . . . . . . . . <a href="#page-9">9</a> 1043 + <a href="#section-3.4.1">3.4.1</a>. Response . . . . . . . . . . . . . . . . . . . . . . <a href="#page-11">11</a> 1044 + <a href="#section-3.4.2">3.4.2</a>. A1 . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-11">11</a> 1045 + <a href="#section-3.4.3">3.4.3</a>. A2 . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-12">12</a> 1046 + <a href="#section-3.4.4">3.4.4</a>. Username Hashing . . . . . . . . . . . . . . . . . . <a href="#page-12">12</a> 1047 + <a href="#section-3.4.5">3.4.5</a>. Parameter Values and Quoted-String . . . . . . . . . <a href="#page-12">12</a> 1048 + <a href="#section-3.4.6">3.4.6</a>. Various Considerations . . . . . . . . . . . . . . . <a href="#page-13">13</a> 1049 + 3.5. The Authentication-Info and Proxy-Authentication-Info 1050 + Header Fields . . . . . . . . . . . . . . . . . . . . . . <a href="#page-14">14</a> 1051 + <a href="#section-3.6">3.6</a>. Digest Operation . . . . . . . . . . . . . . . . . . . . <a href="#page-15">15</a> 1052 + <a href="#section-3.7">3.7</a>. Security Protocol Negotiation . . . . . . . . . . . . . . <a href="#page-16">16</a> 1053 + <a href="#section-3.8">3.8</a>. Proxy-Authenticate and Proxy-Authorization . . . . . . . <a href="#page-17">17</a> 1054 + <a href="#section-3.9">3.9</a>. Examples . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-18">18</a> 1055 + <a href="#section-3.9.1">3.9.1</a>. Example with SHA-256 and MD5 . . . . . . . . . . . . <a href="#page-18">18</a> 1056 + <a href="#section-3.9.2">3.9.2</a>. Example with SHA-512-256, Charset, and Userhash . . . <a href="#page-19">19</a> 1057 + <a href="#section-4">4</a>. Internationalization Considerations . . . . . . . . . . . . . <a href="#page-20">20</a> 1058 + <a href="#section-5">5</a>. Security Considerations . . . . . . . . . . . . . . . . . . . <a href="#page-21">21</a> 1059 + <a href="#section-5.1">5.1</a>. Limitations . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-21">21</a> 1060 + <a href="#section-5.2">5.2</a>. Storing Passwords . . . . . . . . . . . . . . . . . . . . <a href="#page-21">21</a> 1061 + <a href="#section-5.3">5.3</a>. Authentication of Clients Using Digest Authentication . . <a href="#page-22">22</a> 1062 + <a href="#section-5.4">5.4</a>. Limited-Use Nonce Values . . . . . . . . . . . . . . . . <a href="#page-23">23</a> 1063 + <a href="#section-5.5">5.5</a>. Replay Attacks . . . . . . . . . . . . . . . . . . . . . <a href="#page-23">23</a> 1064 + <a href="#section-5.6">5.6</a>. Weakness Created by Multiple Authentication Schemes . . . <a href="#page-24">24</a> 1065 + <a href="#section-5.7">5.7</a>. Online Dictionary Attacks . . . . . . . . . . . . . . . . <a href="#page-24">24</a> 1066 + <a href="#section-5.8">5.8</a>. Man-in-the-Middle Attacks . . . . . . . . . . . . . . . . <a href="#page-25">25</a> 1067 + <a href="#section-5.9">5.9</a>. Chosen Plaintext Attacks . . . . . . . . . . . . . . . . <a href="#page-25">25</a> 1068 + <a href="#section-5.10">5.10</a>. Precomputed Dictionary Attacks . . . . . . . . . . . . . <a href="#page-26">26</a> 1069 + <a href="#section-5.11">5.11</a>. Batch Brute-Force Attacks . . . . . . . . . . . . . . . . <a href="#page-26">26</a> 1070 + <a href="#section-5.12">5.12</a>. Parameter Randomness . . . . . . . . . . . . . . . . . . <a href="#page-26">26</a> 1071 + <a href="#section-5.13">5.13</a>. Summary . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-26">26</a> 1072 + <a href="#section-6">6</a>. IANA Considerations . . . . . . . . . . . . . . . . . . . . . <a href="#page-27">27</a> 1073 + <a href="#section-6.1">6.1</a>. Hash Algorithms for HTTP Digest Authentication . . . . . <a href="#page-27">27</a> 1074 + <a href="#section-6.2">6.2</a>. Digest Scheme Registration . . . . . . . . . . . . . . . <a href="#page-28">28</a> 1075 + <a href="#section-7">7</a>. References . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-28">28</a> 1076 + <a href="#section-7.1">7.1</a>. Normative References . . . . . . . . . . . . . . . . . . <a href="#page-28">28</a> 1077 + <a href="#section-7.2">7.2</a>. Informative References . . . . . . . . . . . . . . . . . <a href="#page-30">30</a> 1078 + <a href="#appendix-A">Appendix A</a>. Changes from <a href="/doc/html/rfc2617">RFC 2617</a> . . . . . . . . . . . . . . . <a href="#page-31">31</a> 1079 + 1080 + 1081 + 1082 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 3]</span></pre> 1083 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-4" ></span> 1084 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1085 + 1086 + 1087 + Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-31">31</a> 1088 + Authors&#x27; Addresses . . . . . . . . . . . . . . . . . . . . . . . <a href="#page-32">32</a> 1089 + 1090 + <span class="h2"><a class="selflink" id="section-1" href="#section-1">1</a>. Introduction</span> 1091 + 1092 + HTTP provides a simple challenge-response authentication mechanism 1093 + that may be used by a server to challenge a client request and by a 1094 + client to provide authentication information. This document defines 1095 + the HTTP Digest Authentication scheme that can be used with the HTTP 1096 + authentication mechanism. 1097 + 1098 + This document extends but is generally backward compatible with 1099 + [<a href="/doc/html/rfc2617" title="&quot;HTTP Authentication: Basic and Digest Access Authentication&quot;">RFC2617</a>]. See <a href="#appendix-A">Appendix A</a> for the new capabilities introduced by 1100 + this specification. 1101 + 1102 + The details of the challenge-response authentication mechanism are 1103 + specified in the &quot;Hypertext Transfer Protocol (HTTP/1.1): 1104 + Authentication&quot; [<a href="/doc/html/rfc7235" title="&quot;Hypertext Transfer Protocol (HTTP/1.1): Authentication&quot;">RFC7235</a>]. 1105 + 1106 + The combination of this document with the definition of the &quot;Basic&quot; 1107 + authentication scheme [<a href="/doc/html/rfc7617" title="&quot;The &#x27;Basic&#x27; HTTP Authentication Scheme&quot;">RFC7617</a>], &quot;HTTP Authentication-Info and Proxy- 1108 + Authentication-Info Response Header Fields&quot; [<a href="/doc/html/rfc7615" title="&quot;HTTP Authentication-Info and Proxy- Authentication-Info Response Header Fields&quot;">RFC7615</a>], and &quot;Hypertext 1109 + Transfer Protocol (HTTP/1.1): Authentication&quot; [<a href="/doc/html/rfc7235" title="&quot;Hypertext Transfer Protocol (HTTP/1.1): Authentication&quot;">RFC7235</a>] obsolete 1110 + [<a href="/doc/html/rfc2617" title="&quot;HTTP Authentication: Basic and Digest Access Authentication&quot;">RFC2617</a>]. 1111 + 1112 + <span class="h3"><a class="selflink" id="section-1.1" href="#section-1.1">1.1</a>. Terminology</span> 1113 + 1114 + The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, 1115 + &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and 1116 + &quot;OPTIONAL&quot; in this document are to be interpreted as described in 1117 + [<a href="/doc/html/rfc2119" title="&quot;Key words for use in RFCs to Indicate Requirement Levels&quot;">RFC2119</a>]. 1118 + 1119 + <span class="h2"><a class="selflink" id="section-2" href="#section-2">2</a>. Syntax Convention</span> 1120 + 1121 + <span class="h3"><a class="selflink" id="section-2.1" href="#section-2.1">2.1</a>. Examples</span> 1122 + 1123 + In the interest of clarity and readability, the extended parameters 1124 + or the header fields and parameters in the examples in this document 1125 + might be broken into multiple lines. Any line that is indented in 1126 + this document is a continuation of the preceding line. 1127 + 1128 + <span class="h3"><a class="selflink" id="section-2.2" href="#section-2.2">2.2</a>. ABNF</span> 1129 + 1130 + This specification uses the Augmented Backus-Naur Form (ABNF) 1131 + notation of [<a href="/doc/html/rfc5234" title="&quot;Augmented BNF for Syntax Specifications: ABNF&quot;">RFC5234</a>] and the ABNF List Extension of [<a href="/doc/html/rfc7230" title="&quot;Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing&quot;">RFC7230</a>]. 1132 + 1133 + 1134 + 1135 + 1136 + 1137 + 1138 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 4]</span></pre> 1139 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-5" ></span> 1140 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1141 + 1142 + 1143 + <span class="h2"><a class="selflink" id="section-3" href="#section-3">3</a>. Digest Access Authentication Scheme</span> 1144 + 1145 + <span class="h3"><a class="selflink" id="section-3.1" href="#section-3.1">3.1</a>. Overall Operation</span> 1146 + 1147 + The Digest scheme is based on a simple challenge-response paradigm. 1148 + The Digest scheme challenges using a nonce value and might indicate 1149 + that username hashing is supported. A valid response contains an 1150 + unkeyed digest of the username, the password, the given nonce value, 1151 + the HTTP method, and the requested URI. In this way, the password is 1152 + never sent in the clear, and the username can be hashed, depending on 1153 + the indication received from the server. The username and password 1154 + must be prearranged in some fashion not addressed by this document. 1155 + 1156 + <span class="h3"><a class="selflink" id="section-3.2" href="#section-3.2">3.2</a>. Representation of Digest Values</span> 1157 + 1158 + An optional header field allows the server to specify the algorithm 1159 + used to create the unkeyed digest or digest. This document adds 1160 + SHA-256 and SHA-512/256 algorithms. To maintain backwards 1161 + compatibility with [<a href="/doc/html/rfc2617" title="&quot;HTTP Authentication: Basic and Digest Access Authentication&quot;">RFC2617</a>], the MD5 algorithm is still supported 1162 + but NOT RECOMMENDED. 1163 + 1164 + The size of the digest depends on the algorithm used. The bits in 1165 + the digest are converted from the most significant to the least 1166 + significant bit, four bits at a time, to the ASCII representation as 1167 + follows. Each sequence of four bits is represented by its familiar 1168 + hexadecimal notation from the characters 0123456789abcdef; that is, 1169 + binary 0000 is represented by the character &#x27;0&#x27;, 0001 by &#x27;1&#x27; and so 1170 + on up to the representation of 1111 as &#x27;f&#x27;. If the MD5 algorithm is 1171 + used to calculate the digest, then the MD5 digest will be represented 1172 + as 32 hexadecimal characters, while SHA-256 and SHA-512/256 are 1173 + represented as 64 hexadecimal characters. 1174 + 1175 + <span class="h3"><a class="selflink" id="section-3.3" href="#section-3.3">3.3</a>. The WWW-Authenticate Response Header Field</span> 1176 + 1177 + If a server receives a request for an access-protected object, and an 1178 + acceptable Authorization header field is not sent, the server 1179 + responds with a &quot;401 Unauthorized&quot; status code and a WWW-Authenticate 1180 + header field with Digest scheme as per the framework defined above. 1181 + The value of the header field can include parameters from the 1182 + following list: 1183 + 1184 + realm 1185 + 1186 + A string to be displayed to users so they know which username and 1187 + password to use. This string should contain at least the name of 1188 + the host performing the authentication and might additionally 1189 + indicate the collection of users who might have access. An 1190 + 1191 + 1192 + 1193 + 1194 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 5]</span></pre> 1195 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-6" ></span> 1196 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1197 + 1198 + 1199 + example is &quot;registered_users@example.com&quot;. (See <a href="/doc/html/rfc7235#section-2.2">Section&nbsp;2.2 of 1200 + [RFC7235]</a> for more details.) 1201 + 1202 + domain 1203 + 1204 + A quoted, space-separated list of URIs, as specified in [<a href="/doc/html/rfc3986" title="&quot;Uniform Resource Identifier (URI): Generic Syntax&quot;">RFC3986</a>], 1205 + that define the protection space. If a URI is a path-absolute, it 1206 + is relative to the canonical root URL. (See <a href="/doc/html/rfc7235#section-2.2">Section&nbsp;2.2 of 1207 + [RFC7235]</a>.) An absolute-URI in this list may refer to a different 1208 + server than the web-origin [<a href="/doc/html/rfc6454" title="&quot;The Web Origin Concept&quot;">RFC6454</a>]. The client can use this 1209 + list to determine the set of URIs for which the same 1210 + authentication information may be sent: any URI that has a URI in 1211 + this list as a prefix (after both have been made absolute) MAY be 1212 + assumed to be in the same protection space. If this parameter is 1213 + omitted or its value is empty, the client SHOULD assume that the 1214 + protection space consists of all URIs on the web-origin. 1215 + 1216 + This parameter is not meaningful in Proxy-Authenticate header 1217 + fields, for which the protection space is always the entire proxy; 1218 + if present, it MUST be ignored. 1219 + 1220 + nonce 1221 + 1222 + A server-specified string which should be uniquely generated each 1223 + time a 401 response is made. It is advised that this string be 1224 + Base64 or hexadecimal data. Specifically, since the string is 1225 + passed in the header field lines as a quoted string, the double- 1226 + quote character is not allowed, unless suitably escaped. 1227 + 1228 + The contents of the nonce are implementation dependent. The 1229 + quality of the implementation depends on a good choice. A nonce 1230 + might, for example, be constructed as the Base64 encoding of 1231 + 1232 + timestamp H(timestamp &quot;:&quot; ETag &quot;:&quot; secret-data) 1233 + 1234 + where timestamp is a server-generated time, which preferably 1235 + includes micro- or nanoseconds, or other non-repeating values; 1236 + ETag is the value of the HTTP ETag header field associated with 1237 + the requested entity; and secret-data is data known only to the 1238 + server. With a nonce of this form, a server would recalculate the 1239 + hash portion after receiving the client authentication header 1240 + field and reject the request if it did not match the nonce from 1241 + that header field or if the timestamp value is not recent enough. 1242 + In this way, the server can limit the time of the nonce&#x27;s 1243 + validity. The inclusion of the ETag prevents a replay request for 1244 + an updated version of the resource. Including the IP address of 1245 + the client in the nonce would appear to offer the server the 1246 + ability to limit the reuse of the nonce to the same client that 1247 + 1248 + 1249 + 1250 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 6]</span></pre> 1251 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-7" ></span> 1252 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1253 + 1254 + 1255 + originally got it. However, that would break because requests 1256 + from a single user often go through different proxies. Also, IP 1257 + address spoofing is not that hard. 1258 + 1259 + An implementation might choose not to accept a previously used 1260 + nonce or a previously used digest, in order to protect against a 1261 + replay attack. Or, an implementation might choose to use one-time 1262 + nonces or digests for POST or PUT requests and a timestamp for GET 1263 + requests. For more details on the issues involved, see <a href="#section-5">Section 5</a> 1264 + of this document. 1265 + 1266 + The nonce is opaque to the client. 1267 + 1268 + opaque 1269 + 1270 + A string of data, specified by the server, that SHOULD be returned 1271 + by the client unchanged in the Authorization header field of 1272 + subsequent requests with URIs in the same protection space. It is 1273 + RECOMMENDED that this string be Base64 or hexadecimal data. 1274 + 1275 + stale 1276 + 1277 + A case-insensitive flag indicating that the previous request from 1278 + the client was rejected because the nonce value was stale. If 1279 + stale is true, the client may wish to simply retry the request 1280 + with a new encrypted response, without re-prompting the user for a 1281 + new username and password. The server SHOULD only set stale to 1282 + true if it receives a request for which the nonce is invalid. If 1283 + stale is false, or anything other than true, or the stale 1284 + parameter is not present, the username and/or password are 1285 + invalid, and new values MUST be obtained. 1286 + 1287 + algorithm 1288 + 1289 + A string indicating an algorithm used to produce the digest and an 1290 + unkeyed digest. If this is not present, it is assumed to be 1291 + &quot;MD5&quot;. If the algorithm is not understood, the challenge SHOULD 1292 + be ignored (and a different one used, if there is more than one). 1293 + 1294 + When used with the Digest mechanism, each one of the algorithms 1295 + has two variants: Session variant and non-Session variant. The 1296 + non-Session variant is denoted by &quot;&lt;algorithm&gt;&quot;, e.g., &quot;SHA-256&quot;, 1297 + and the Session variant is denoted by &quot;&lt;algorithm&gt;-sess&quot;, e.g., 1298 + &quot;SHA-256-sess&quot;. 1299 + 1300 + In this document, the string obtained by applying the digest 1301 + algorithm to the data &quot;data&quot; with secret &quot;secret&quot; will be denoted 1302 + by KD(secret, data), and the string obtained by applying the 1303 + 1304 + 1305 + 1306 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 7]</span></pre> 1307 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-8" ></span> 1308 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1309 + 1310 + 1311 + unkeyed digest algorithm to the data &quot;data&quot; will be denoted 1312 + H(data). KD stands for Keyed Digest, and the notation unq(X) 1313 + means the value of the quoted-string X without the surrounding 1314 + quotes and with quoting slashes removed. 1315 + 1316 + For &quot;&lt;algorithm&gt;&quot; and &quot;&lt;algorithm&gt;-sess&quot; 1317 + 1318 + H(data) = &lt;algorithm&gt;(data) 1319 + 1320 + and 1321 + 1322 + KD(secret, data) = H(concat(secret, &quot;:&quot;, data)) 1323 + 1324 + For example: 1325 + 1326 + For the &quot;SHA-256&quot; and &quot;SHA-256-sess&quot; algorithms 1327 + 1328 + H(data) = SHA-256(data) 1329 + 1330 + i.e., the digest is the &quot;&lt;algorithm&gt;&quot; of the secret concatenated 1331 + with a colon concatenated with the data. The &quot;&lt;algorithm&gt;-sess&quot; 1332 + is intended to allow efficient third-party authentication servers; 1333 + for the difference in usage, see the description in <a href="#section-3.4.2">Section 3.4.2</a>. 1334 + 1335 + qop 1336 + 1337 + This parameter MUST be used by all implementations. It is a 1338 + quoted string of one or more tokens indicating the &quot;quality of 1339 + protection&quot; values supported by the server. The value &quot;auth&quot; 1340 + indicates authentication; the value &quot;auth-int&quot; indicates 1341 + authentication with integrity protection. See the descriptions 1342 + below for calculating the response parameter value for the 1343 + application of this choice. Unrecognized options MUST be ignored. 1344 + 1345 + charset 1346 + 1347 + This is an OPTIONAL parameter that is used by the server to 1348 + indicate the encoding scheme it supports. The only allowed value 1349 + is &quot;UTF-8&quot;. 1350 + 1351 + userhash 1352 + 1353 + This is an OPTIONAL parameter that is used by the server to 1354 + indicate that it supports username hashing. Valid values are: 1355 + &quot;true&quot; or &quot;false&quot;. Default value is &quot;false&quot;. 1356 + 1357 + 1358 + 1359 + 1360 + 1361 + 1362 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 8]</span></pre> 1363 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-9" ></span> 1364 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1365 + 1366 + 1367 + For historical reasons, a sender MUST only generate the quoted string 1368 + syntax values for the following parameters: realm, domain, nonce, 1369 + opaque, and qop. 1370 + 1371 + For historical reasons, a sender MUST NOT generate the quoted string 1372 + syntax values for the following parameters: stale and algorithm. 1373 + 1374 + <span class="h3"><a class="selflink" id="section-3.4" href="#section-3.4">3.4</a>. The Authorization Header Field</span> 1375 + 1376 + The client is expected to retry the request, passing an Authorization 1377 + header field line with Digest scheme, which is defined according to 1378 + the framework above. The values of the opaque and algorithm fields 1379 + must be those supplied in the WWW-Authenticate response header field 1380 + for the entity being requested. 1381 + 1382 + The request can include parameters from the following list: 1383 + 1384 + response 1385 + 1386 + A string of the hex digits computed as defined below; it proves 1387 + that the user knows a password. 1388 + 1389 + username 1390 + 1391 + The user&#x27;s name in the specified realm. The quoted string 1392 + contains the name in plaintext or the hash code in hexadecimal 1393 + notation. If the username contains characters not allowed inside 1394 + the ABNF quoted-string production, the username* parameter can be 1395 + used. Sending both username and username* in the same header 1396 + option MUST be treated as an error. 1397 + 1398 + username* 1399 + 1400 + If the userhash parameter value is set &quot;false&quot; and the username 1401 + contains characters not allowed inside the ABNF quoted-string 1402 + production, the user&#x27;s name can be sent with this parameter, using 1403 + the extended notation defined in [<a href="/doc/html/rfc5987" title="&quot;Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters&quot;">RFC5987</a>]. 1404 + 1405 + realm 1406 + 1407 + See &quot;realm&quot; definition in <a href="#section-3.3">Section 3.3</a>. 1408 + 1409 + uri 1410 + 1411 + The Effective Request URI (<a href="/doc/html/rfc7230#section-5.5">Section&nbsp;5.5 of [RFC7230]</a>) of the HTTP 1412 + request; duplicated here because proxies are allowed to change the 1413 + request target (&quot;request-target&quot;, <a href="/doc/html/rfc7230#section-3.1.1">Section&nbsp;3.1.1 of [RFC7230]</a>) in 1414 + transit. 1415 + 1416 + 1417 + 1418 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 9]</span></pre> 1419 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-10" ></span> 1420 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1421 + 1422 + 1423 + qop 1424 + 1425 + Indicates what &quot;quality of protection&quot; the client has applied to 1426 + the message. Its value MUST be one of the alternatives the server 1427 + indicated it supports in the WWW-Authenticate header field. These 1428 + values affect the computation of the response. Note that this is 1429 + a single token, not a quoted list of alternatives as in WWW- 1430 + Authenticate. 1431 + 1432 + cnonce 1433 + 1434 + This parameter MUST be used by all implementations. The cnonce 1435 + value is an opaque quoted ASCII-only string value provided by the 1436 + client and used by both client and server to avoid chosen 1437 + plaintext attacks, to provide mutual authentication, and to 1438 + provide some message integrity protection. See the descriptions 1439 + below of the calculation of the rspauth and response values. 1440 + 1441 + nc 1442 + 1443 + This parameter MUST be used by all implementations. The nc 1444 + parameter stands for &quot;nonce count&quot;. The nc value is the 1445 + hexadecimal count of the number of requests (including the current 1446 + request) that the client has sent with the nonce value in this 1447 + request. For example, in the first request sent in response to a 1448 + given nonce value, the client sends &quot;nc=00000001&quot;. The purpose of 1449 + this parameter is to allow the server to detect request replays by 1450 + maintaining its own copy of this count -- if the same nc value is 1451 + seen twice, then the request is a replay. See the description 1452 + below of the construction of the response value. 1453 + 1454 + userhash 1455 + 1456 + This OPTIONAL parameter is used by the client to indicate that the 1457 + username has been hashed. Valid values are: &quot;true&quot; or &quot;false&quot;. 1458 + Default value is &quot;false&quot;. 1459 + 1460 + For historical reasons, a sender MUST only generate the quoted string 1461 + syntax for the following parameters: username, realm, nonce, uri, 1462 + response, cnonce, and opaque. 1463 + 1464 + For historical reasons, a sender MUST NOT generate the quoted string 1465 + syntax for the following parameters: algorithm, qop, and nc. 1466 + 1467 + If a parameter or its value is improper, or required parameters are 1468 + missing, the proper response is a 4xx error code. If the response is 1469 + invalid, then a login failure SHOULD be logged, since repeated login 1470 + failures from a single client may indicate an attacker attempting to 1471 + 1472 + 1473 + 1474 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 10]</span></pre> 1475 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-11" ></span> 1476 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1477 + 1478 + 1479 + guess passwords. The server implementation SHOULD be careful with 1480 + the information being logged so that it won&#x27;t put a cleartext 1481 + password (e.g., entered into the username field) into the log. 1482 + 1483 + The definition of the response above indicates the encoding for its 1484 + value. The following definitions show how the value is computed. 1485 + 1486 + <span class="h4"><a class="selflink" id="section-3.4.1" href="#section-3.4.1">3.4.1</a>. Response</span> 1487 + 1488 + If the qop value is &quot;auth&quot; or &quot;auth-int&quot;: 1489 + 1490 + response = &lt;&quot;&gt; &lt; KD ( H(A1), unq(nonce) 1491 + &quot;:&quot; nc 1492 + &quot;:&quot; unq(cnonce) 1493 + &quot;:&quot; unq(qop) 1494 + &quot;:&quot; H(A2) 1495 + ) &lt;&quot;&gt; 1496 + 1497 + See below for the definitions for A1 and A2. 1498 + 1499 + <span class="h4"><a class="selflink" id="section-3.4.2" href="#section-3.4.2">3.4.2</a>. A1</span> 1500 + 1501 + If the algorithm parameter&#x27;s value is &quot;&lt;algorithm&gt;&quot;, e.g., &quot;SHA-256&quot;, 1502 + then A1 is: 1503 + 1504 + A1 = unq(username) &quot;:&quot; unq(realm) &quot;:&quot; passwd 1505 + 1506 + where 1507 + 1508 + passwd = &lt; user&#x27;s password &gt; 1509 + 1510 + If the algorithm parameter&#x27;s value is &quot;&lt;algorithm&gt;-sess&quot;, e.g., &quot;SHA- 1511 + 256-sess&quot;, then A1 is calculated using the nonce value provided in 1512 + the challenge from the server, and cnonce value from the request by 1513 + the client following receipt of a WWW-Authenticate challenge from the 1514 + server. It uses the server nonce from that challenge, herein called 1515 + nonce-prime, and the client nonce value from the response, herein 1516 + called cnonce-prime, to construct A1 as follows: 1517 + 1518 + A1 = H( unq(username) &quot;:&quot; unq(realm) &quot;:&quot; passwd ) 1519 + &quot;:&quot; unq(nonce-prime) &quot;:&quot; unq(cnonce-prime) 1520 + 1521 + This creates a &quot;session key&quot; for the authentication of subsequent 1522 + requests and responses that is different for each &quot;authentication 1523 + session&quot;, thus limiting the amount of material hashed with any one 1524 + key. (Note: see further discussion of the authentication session in 1525 + <a href="#section-3.6">Section 3.6</a>.) Because the server needs only use the hash of the user 1526 + credentials in order to create the A1 value, this construction could 1527 + 1528 + 1529 + 1530 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 11]</span></pre> 1531 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-12" ></span> 1532 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1533 + 1534 + 1535 + be used in conjunction with a third-party authentication service so 1536 + that the web server would not need the actual password value. The 1537 + specification of such a protocol is beyond the scope of this 1538 + specification. 1539 + 1540 + <span class="h4"><a class="selflink" id="section-3.4.3" href="#section-3.4.3">3.4.3</a>. A2</span> 1541 + 1542 + If the qop parameter&#x27;s value is &quot;auth&quot; or is unspecified, then A2 is: 1543 + 1544 + A2 = Method &quot;:&quot; request-uri 1545 + 1546 + If the qop value is &quot;auth-int&quot;, then A2 is: 1547 + 1548 + A2 = Method &quot;:&quot; request-uri &quot;:&quot; H(entity-body) 1549 + 1550 + <span class="h4"><a class="selflink" id="section-3.4.4" href="#section-3.4.4">3.4.4</a>. Username Hashing</span> 1551 + 1552 + To protect the transport of the username from the client to the 1553 + server, the server SHOULD set the userhash parameter with the value 1554 + of &quot;true&quot; in the WWW-Authentication header field. 1555 + 1556 + If the client supports the userhash parameter, and the userhash 1557 + parameter value in the WWW-Authentication header field is set to 1558 + &quot;true&quot;, then the client MUST calculate a hash of the username after 1559 + any other hash calculation and include the userhash parameter with 1560 + the value of &quot;true&quot; in the Authorization header field. If the client 1561 + does not provide the username as a hash value or the userhash 1562 + parameter with the value of &quot;true&quot;, the server MAY reject the 1563 + request. 1564 + 1565 + The following is the operation that the client will perform to hash 1566 + the username, using the same algorithm used to hash the credentials: 1567 + 1568 + username = H( unq(username) &quot;:&quot; unq(realm) ) 1569 + 1570 + <span class="h4"><a class="selflink" id="section-3.4.5" href="#section-3.4.5">3.4.5</a>. Parameter Values and Quoted-String</span> 1571 + 1572 + Note that the value of many of the parameters, such as username 1573 + value, are defined as a &quot;quoted-string&quot;. However, the &quot;unq&quot; notation 1574 + indicates that surrounding quotation marks are removed in forming the 1575 + string A1. Thus, if the Authorization header field includes the 1576 + fields 1577 + 1578 + username=&quot;Mufasa&quot;, realm=&quot;myhost@example.com&quot; 1579 + 1580 + and the user Mufasa has password &quot;Circle Of Life&quot;, then H(A1) would 1581 + be H(Mufasa:myhost@example.com:Circle Of Life) with no quotation 1582 + marks in the digested string. 1583 + 1584 + 1585 + 1586 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 12]</span></pre> 1587 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-13" ></span> 1588 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1589 + 1590 + 1591 + No white space is allowed in any of the strings to which the digest 1592 + function H() is applied, unless that white space exists in the quoted 1593 + strings or entity body whose contents make up the string to be 1594 + digested. For example, the string A1 illustrated above must be 1595 + 1596 + Mufasa:myhost@example.com:Circle Of Life 1597 + 1598 + with no white space on either side of the colons, but with the white 1599 + space between the words used in the password value. Likewise, the 1600 + other strings digested by H() must not have white space on either 1601 + side of the colons that delimit their fields, unless that white space 1602 + was in the quoted strings or entity body being digested. 1603 + 1604 + Also, note that if integrity protection is applied (qop=auth-int), 1605 + the H(entity-body) is the hash of the entity body, not the message 1606 + body -- it is computed before any transfer encoding is applied by the 1607 + sender and after it has been removed by the recipient. Note that 1608 + this includes multipart boundaries and embedded header fields in each 1609 + part of any multipart content-type. 1610 + 1611 + <span class="h4"><a class="selflink" id="section-3.4.6" href="#section-3.4.6">3.4.6</a>. Various Considerations</span> 1612 + 1613 + The &quot;Method&quot; value is the HTTP request method, in US-ASCII letters, 1614 + as specified in <a href="/doc/html/rfc7230#section-3.1.1">Section&nbsp;3.1.1 of [RFC7230]</a>. The &quot;request-target&quot; 1615 + value is the request-target from the request line as specified in 1616 + <a href="/doc/html/rfc7230#section-3.1.1">Section&nbsp;3.1.1 of [RFC7230]</a>. This MAY be &quot;*&quot;, an &quot;absolute-URI&quot;, or 1617 + an &quot;absolute-path&quot; as specified in <a href="/doc/html/rfc7230#section-2.7">Section&nbsp;2.7 of [RFC7230]</a>, but it 1618 + MUST agree with the request-target. In particular, it MUST be an 1619 + &quot;absolute-URI&quot; if the request-target is an &quot;absolute-URI&quot;. The 1620 + cnonce value is a client-chosen value whose purpose is to foil chosen 1621 + plaintext attacks. 1622 + 1623 + The authenticating server MUST assure that the resource designated by 1624 + the &quot;uri&quot; parameter is the same as the resource specified in the 1625 + Request-Line; if they are not, the server SHOULD return a 400 Bad 1626 + Request error. (Since this may be a symptom of an attack, server 1627 + implementers may want to consider logging such errors.) The purpose 1628 + of duplicating information from the request URL in this field is to 1629 + deal with the possibility that an intermediate proxy may alter the 1630 + client&#x27;s Request-Line. This altered (but presumably semantically 1631 + equivalent) request would not result in the same digest as that 1632 + calculated by the client. 1633 + 1634 + Implementers should be aware of how authenticated transactions need 1635 + to interact with shared caches (see [<a href="/doc/html/rfc7234" title="&quot;Hypertext Transfer Protocol (HTTP/1.1): Caching&quot;">RFC7234</a>]). 1636 + 1637 + 1638 + 1639 + 1640 + 1641 + 1642 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 13]</span></pre> 1643 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-14" ></span> 1644 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1645 + 1646 + 1647 + <span class="h3"><a class="selflink" id="section-3.5" href="#section-3.5">3.5</a>. The Authentication-Info and Proxy-Authentication-Info Header</span> 1648 + <span class="h3"> Fields</span> 1649 + 1650 + The Authentication-Info header field and the Proxy-Authentication- 1651 + Info header field [<a href="/doc/html/rfc7615" title="&quot;HTTP Authentication-Info and Proxy- Authentication-Info Response Header Fields&quot;">RFC7615</a>] are generic fields that MAY be used by a 1652 + server to communicate some information regarding the successful 1653 + authentication of a client response. 1654 + 1655 + The Digest Authentication scheme MAY add the Authentication-Info 1656 + header field in the confirmation request and include parameters from 1657 + the following list: 1658 + 1659 + nextnonce 1660 + 1661 + The value of the nextnonce parameter is the nonce the server 1662 + wishes the client to use for a future authentication response. 1663 + The server MAY send the Authentication-Info header field with a 1664 + nextnonce field as a means of implementing one-time nonces or 1665 + otherwise changing nonces. If the nextnonce field is present, the 1666 + client SHOULD use it when constructing the Authorization header 1667 + field for its next request. Failure of the client to do so MAY 1668 + result in a request to re-authenticate from the server with the 1669 + &quot;stale=true&quot;. 1670 + 1671 + Server implementations SHOULD carefully consider the 1672 + performance implications of the use of this mechanism; 1673 + pipelined requests will not be possible if every response 1674 + includes a nextnonce parameter that MUST be used on the next 1675 + request received by the server. Consideration SHOULD be given 1676 + to the performance vs. security tradeoffs of allowing an old 1677 + nonce value to be used for a limited time to permit request 1678 + pipelining. Use of the nc parameter can retain most of the 1679 + security advantages of a new server nonce without the 1680 + deleterious effects on pipelining. 1681 + 1682 + qop 1683 + 1684 + Indicates the &quot;quality of protection&quot; options applied to the 1685 + response by the server. The value &quot;auth&quot; indicates 1686 + authentication; the value &quot;auth-int&quot; indicates authentication with 1687 + integrity protection. The server SHOULD use the same value for 1688 + the qop parameter in the response as was sent by the client in the 1689 + corresponding request. 1690 + 1691 + 1692 + 1693 + 1694 + 1695 + 1696 + 1697 + 1698 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 14]</span></pre> 1699 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-15" ></span> 1700 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1701 + 1702 + 1703 + rspauth 1704 + 1705 + The optional response digest in the rspauth parameter supports 1706 + mutual authentication -- the server proves that it knows the 1707 + user&#x27;s secret, and with qop=auth-int also provides limited 1708 + integrity protection of the response. The rspauth value is 1709 + calculated as for the response in the Authorization header field, 1710 + except that if qop is set to &quot;auth&quot; or is not specified in the 1711 + Authorization header field for the request, A2 is 1712 + 1713 + A2 = &quot;:&quot; request-uri 1714 + 1715 + and if &quot;qop=auth-int&quot;, then A2 is 1716 + 1717 + A2 = &quot;:&quot; request-uri &quot;:&quot; H(entity-body) 1718 + 1719 + cnonce and nc 1720 + 1721 + The cnonce value and nc value MUST be the ones for the client 1722 + request to which this message is the response. The rspauth, 1723 + cnonce, and nc parameters MUST be present if &quot;qop=auth&quot; or 1724 + &quot;qop=auth-int&quot; is specified. 1725 + 1726 + The Authentication-Info header field is allowed in the trailer of an 1727 + HTTP message transferred via chunked transfer coding. 1728 + 1729 + For historical reasons, a sender MUST only generate the quoted string 1730 + syntax for the following parameters: nextnonce, rspauth, and cnonce. 1731 + 1732 + For historical reasons, a sender MUST NOT generate the quoted string 1733 + syntax for the following parameters: qop and nc. 1734 + 1735 + For historical reasons, the nc value MUST be exactly 8 hexadecimal 1736 + digits. 1737 + 1738 + <span class="h3"><a class="selflink" id="section-3.6" href="#section-3.6">3.6</a>. Digest Operation</span> 1739 + 1740 + Upon receiving the Authorization header field, the server MAY check 1741 + its validity by looking up the password that corresponds to the 1742 + submitted username. Then, the server MUST perform the same digest 1743 + operation (e.g., MD5, SHA-256) performed by the client and compare 1744 + the result to the given response value. 1745 + 1746 + Note that the HTTP server does not actually need to know the user&#x27;s 1747 + cleartext password. As long as H(A1) is available to the server, the 1748 + validity of an Authorization header field can be verified. 1749 + 1750 + 1751 + 1752 + 1753 + 1754 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 15]</span></pre> 1755 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-16" ></span> 1756 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1757 + 1758 + 1759 + The client response to a WWW-Authenticate challenge for a protection 1760 + space starts an authentication session with that protection space. 1761 + The authentication session lasts until the client receives another 1762 + WWW-Authenticate challenge from any server in the protection space. 1763 + A client SHOULD remember the username, password, nonce, nonce count, 1764 + and opaque values associated with an authentication session to use to 1765 + construct the Authorization header field in future requests within 1766 + that protection space. The Authorization header field MAY be 1767 + included preemptively; doing so improves server efficiency and avoids 1768 + extra round trips for authentication challenges. The server MAY 1769 + choose to accept the old Authorization header field information, even 1770 + though the nonce value included might not be fresh. Alternatively, 1771 + the server MAY return a 401 response with a new nonce value in the 1772 + WWW-Authenticate header field, causing the client to retry the 1773 + request; by specifying &quot;stale=true&quot; with this response, the server 1774 + tells the client to retry with the new nonce, but without prompting 1775 + for a new username and password. 1776 + 1777 + Because the client is required to return the value of the opaque 1778 + parameter given to it by the server for the duration of a session, 1779 + the opaque data can be used to transport authentication session state 1780 + information. (Note that any such use can also be accomplished more 1781 + easily and safely by including the state in the nonce.) For example, 1782 + a server could be responsible for authenticating content that 1783 + actually sits on another server. It would achieve this by having the 1784 + first 401 response include a domain parameter whose value includes a 1785 + URI on the second server, and an opaque parameter whose value 1786 + contains the state information. The client will retry the request, 1787 + at which time the server might respond with &quot;HTTP Redirection&quot; 1788 + (<a href="/doc/html/rfc7231#section-6.4">Section&nbsp;6.4 of [RFC7231]</a>), pointing to the URI on the second server. 1789 + The client will follow the redirection and pass an Authorization 1790 + header field, including the &lt;opaque&gt; data. 1791 + 1792 + Proxies MUST be completely transparent in the Digest access 1793 + authentication scheme. That is, they MUST forward the WWW- 1794 + Authenticate, Authentication-Info, and Authorization header fields 1795 + untouched. If a proxy wants to authenticate a client before a 1796 + request is forwarded to the server, it can be done using the Proxy- 1797 + Authenticate and Proxy-Authorization header fields described in 1798 + <a href="#section-3.8">Section 3.8</a> below. 1799 + 1800 + <span class="h3"><a class="selflink" id="section-3.7" href="#section-3.7">3.7</a>. Security Protocol Negotiation</span> 1801 + 1802 + It is useful for a server to be able to know which security schemes a 1803 + client is capable of handling. 1804 + 1805 + It is possible that a server wants to require Digest as its 1806 + authentication method, even if the server does not know that the 1807 + 1808 + 1809 + 1810 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 16]</span></pre> 1811 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-17" ></span> 1812 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1813 + 1814 + 1815 + client supports it. A client is encouraged to fail gracefully if the 1816 + server specifies only authentication schemes it cannot handle. 1817 + 1818 + When a server receives a request to access a resource, the server 1819 + might challenge the client by responding with &quot;401 Unauthorized&quot; 1820 + response and include one or more WWW-Authenticate header fields. If 1821 + the server responds with multiple challenges, then each one of these 1822 + challenges MUST use a different digest algorithm. The server MUST 1823 + add these challenges to the response in order of preference, starting 1824 + with the most preferred algorithm, followed by the less preferred 1825 + algorithm. 1826 + 1827 + This specification defines the following algorithms: 1828 + 1829 + o SHA2-256 (mandatory to implement) 1830 + 1831 + o SHA2-512/256 (as a backup algorithm) 1832 + 1833 + o MD5 (for backward compatibility). 1834 + 1835 + When the client receives the first challenge, it SHOULD use the first 1836 + challenge it supports, unless a local policy dictates otherwise. 1837 + 1838 + <span class="h3"><a class="selflink" id="section-3.8" href="#section-3.8">3.8</a>. Proxy-Authenticate and Proxy-Authorization</span> 1839 + 1840 + The Digest Authentication scheme can also be used for authenticating 1841 + users to proxies, proxies to proxies, or proxies to origin servers by 1842 + use of the Proxy-Authenticate and Proxy-Authorization header fields. 1843 + These header fields are instances of the Proxy-Authenticate and 1844 + Proxy-Authorization header fields specified in Sections <a href="#section-4.3">4.3</a> and <a href="#section-4.4">4.4</a> 1845 + of the HTTP/1.1 specification [<a href="/doc/html/rfc7235" title="&quot;Hypertext Transfer Protocol (HTTP/1.1): Authentication&quot;">RFC7235</a>], and their behavior is 1846 + subject to restrictions described there. The transactions for proxy 1847 + authentication are very similar to those already described. Upon 1848 + receiving a request that requires authentication, the proxy/server 1849 + MUST issue the &quot;407 Proxy Authentication Required&quot; response with a 1850 + &quot;Proxy-Authenticate&quot; header field. The digest-challenge used in the 1851 + Proxy-Authenticate header field is the same as that for the WWW- 1852 + Authenticate header field as defined above in <a href="#section-3.3">Section 3.3</a>. 1853 + 1854 + The client/proxy MUST then reissue the request with a Proxy- 1855 + Authorization header field, with parameters as specified for the 1856 + Authorization header field in <a href="#section-3.4">Section 3.4</a> above. 1857 + 1858 + On subsequent responses, the server sends Proxy-Authentication-Info 1859 + with parameters the same as those for the Authentication-Info header 1860 + field. 1861 + 1862 + 1863 + 1864 + 1865 + 1866 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 17]</span></pre> 1867 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-18" ></span> 1868 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1869 + 1870 + 1871 + Note that, in principle, a client could be asked to authenticate 1872 + itself to both a proxy and an end-server, but never in the same 1873 + response. 1874 + 1875 + <span class="h3"><a class="selflink" id="section-3.9" href="#section-3.9">3.9</a>. Examples</span> 1876 + 1877 + <span class="h4"><a class="selflink" id="section-3.9.1" href="#section-3.9.1">3.9.1</a>. Example with SHA-256 and MD5</span> 1878 + 1879 + The following example assumes that an access-protected document is 1880 + being requested from the server via a GET request. The URI of the 1881 + document is &quot;http://www.example.org/dir/index.html&quot;. Both client and 1882 + server know that the username for this document is &quot;Mufasa&quot; and the 1883 + password is &quot;Circle of Life&quot; (with one space between each of the 1884 + three words). 1885 + 1886 + The first time the client requests the document, no Authorization 1887 + header field is sent, so the server responds with: 1888 + 1889 + HTTP/1.1 401 Unauthorized 1890 + WWW-Authenticate: Digest 1891 + realm=&quot;http-auth@example.org&quot;, 1892 + qop=&quot;auth, auth-int&quot;, 1893 + algorithm=SHA-256, 1894 + nonce=&quot;7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v&quot;, 1895 + opaque=&quot;FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS&quot; 1896 + WWW-Authenticate: Digest 1897 + realm=&quot;http-auth@example.org&quot;, 1898 + qop=&quot;auth, auth-int&quot;, 1899 + algorithm=MD5, 1900 + nonce=&quot;7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v&quot;, 1901 + opaque=&quot;FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS&quot; 1902 + 1903 + The client can prompt the user for their username and password, after 1904 + which it will respond with a new request, including the following 1905 + Authorization header field if the client chooses MD5 digest: 1906 + 1907 + Authorization: Digest username=&quot;Mufasa&quot;, 1908 + realm=&quot;http-auth@example.org&quot;, 1909 + uri=&quot;/dir/index.html&quot;, 1910 + algorithm=MD5, 1911 + nonce=&quot;7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v&quot;, 1912 + nc=00000001, 1913 + cnonce=&quot;f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ&quot;, 1914 + qop=auth, 1915 + response=&quot;8ca523f5e9506fed4657c9700eebdbec&quot;, 1916 + opaque=&quot;FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS&quot; 1917 + 1918 + 1919 + 1920 + 1921 + 1922 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 18]</span></pre> 1923 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-19" ></span> 1924 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1925 + 1926 + 1927 + If the client chooses to use the SHA-256 algorithm for calculating 1928 + the response, the client responds with a new request including the 1929 + following Authorization header field: 1930 + 1931 + Authorization: Digest username=&quot;Mufasa&quot;, 1932 + realm=&quot;http-auth@example.org&quot;, 1933 + uri=&quot;/dir/index.html&quot;, 1934 + algorithm=SHA-256, 1935 + nonce=&quot;7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v&quot;, 1936 + nc=00000001, 1937 + cnonce=&quot;f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ&quot;, 1938 + qop=auth, 1939 + response=&quot;753927fa0e85d155564e2e272a28d1802ca10daf449 1940 + 6794697cf8db5856cb6c1&quot;, 1941 + opaque=&quot;FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS&quot; 1942 + 1943 + <span class="h4"><a class="selflink" id="section-3.9.2" href="#section-3.9.2">3.9.2</a>. Example with SHA-512-256, Charset, and Userhash</span> 1944 + 1945 + The following example assumes that an access-protected document is 1946 + being requested from the server via a GET request. The URI for the 1947 + request is &quot;http://api.example.org/doe.json&quot;. Both client and server 1948 + know the userhash of the username, support the UTF-8 character 1949 + encoding scheme, and use the SHA-512-256 algorithm. The username for 1950 + the request is a variation of &quot;Jason Doe&quot;, where the &#x27;a&#x27; actually is 1951 + Unicode code point U+00E4 (&quot;LATIN SMALL LETTER A WITH DIAERESIS&quot;), 1952 + and the first &#x27;o&#x27; is Unicode code point U+00F8 (&quot;LATIN SMALL LETTER O 1953 + WITH STROKE&quot;), leading to the octet sequence using the UTF-8 encoding 1954 + scheme: 1955 + 1956 + J U+00E4 s U+00F8 n D o e 1957 + 4A C3A4 73 C3B8 6E 20 44 6F 65 1958 + 1959 + The password is &quot;Secret, or not?&quot;. 1960 + 1961 + The first time the client requests the document, no Authorization 1962 + header field is sent, so the server responds with: 1963 + 1964 + HTTP/1.1 401 Unauthorized 1965 + WWW-Authenticate: Digest 1966 + realm=&quot;api@example.org&quot;, 1967 + qop=&quot;auth&quot;, 1968 + algorithm=SHA-512-256, 1969 + nonce=&quot;5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK&quot;, 1970 + opaque=&quot;HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS&quot;, 1971 + charset=UTF-8, 1972 + userhash=true 1973 + 1974 + 1975 + 1976 + 1977 + 1978 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 19]</span></pre> 1979 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-20" ></span> 1980 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 1981 + 1982 + 1983 + The client can prompt the user for the required credentials and send 1984 + a new request with following Authorization header field: 1985 + 1986 + Authorization: Digest 1987 + username=&quot;488869477bf257147b804c45308cd62ac4e25eb717 1988 + b12b298c79e62dcea254ec&quot;, 1989 + realm=&quot;api@example.org&quot;, 1990 + uri=&quot;/doe.json&quot;, 1991 + algorithm=SHA-512-256, 1992 + nonce=&quot;5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK&quot;, 1993 + nc=00000001, 1994 + cnonce=&quot;NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v&quot;, 1995 + qop=auth, 1996 + response=&quot;ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d 1997 + 6c861229025f607a79dd&quot;, 1998 + opaque=&quot;HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS&quot;, 1999 + userhash=true 2000 + 2001 + If the client cannot provide a hashed username for any reason, the 2002 + client can try a request with this Authorization header field: 2003 + 2004 + Authorization: Digest 2005 + username*=UTF-8&#x27;&#x27;J%C3%A4s%C3%B8n%20Doe, 2006 + realm=&quot;api@example.org&quot;, 2007 + uri=&quot;/doe.json&quot;, 2008 + algorithm=SHA-512-256, 2009 + nonce=&quot;5TsQWLVdgBdmrQ0XsxbDODV+57QdFR34I9HAbC/RVvkK&quot;, 2010 + nc=00000001, 2011 + cnonce=&quot;NTg6RKcb9boFIAS3KrFK9BGeh+iDa/sm6jUMp2wds69v&quot;, 2012 + qop=auth, 2013 + response=&quot;ae66e67d6b427bd3f120414a82e4acff38e8ecd9101d 2014 + 6c861229025f607a79dd&quot;, 2015 + opaque=&quot;HRPCssKJSGjCrkzDg8OhwpzCiGPChXYjwrI2QmXDnsOS&quot;, 2016 + userhash=false 2017 + 2018 + <span class="h2"><a class="selflink" id="section-4" href="#section-4">4</a>. Internationalization Considerations</span> 2019 + 2020 + In challenges, servers SHOULD use the &quot;charset&quot; authentication 2021 + parameter (case-insensitive) to express the character encoding they 2022 + expect the user agent to use when generating A1 (see <a href="#section-3.4.2">Section 3.4.2</a>) 2023 + and username hashing (see <a href="#section-3.4.4">Section 3.4.4</a>). 2024 + 2025 + The only allowed value is &quot;UTF-8&quot;, to be matched case-insensitively 2026 + (see <a href="/doc/html/rfc2978#section-2.3">Section&nbsp;2.3 in [RFC2978]</a>). It indicates that the server expects 2027 + the username and password to be converted to Unicode Normalization 2028 + Form C (&quot;NFC&quot;, see <a href="/doc/html/rfc5198#section-3">Section&nbsp;3 of [RFC5198]</a>) and to be encoded into 2029 + octets using the UTF-8 character encoding scheme [<a href="/doc/html/rfc3629" title="&quot;UTF-8, a transformation format of ISO 10646&quot;">RFC3629</a>]. 2030 + 2031 + 2032 + 2033 + 2034 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 20]</span></pre> 2035 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-21" ></span> 2036 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2037 + 2038 + 2039 + For the username, recipients MUST support all characters defined in 2040 + the &quot;UsernameCasePreserved&quot; profile defined in <a href="/doc/html/rfc7613#section-3.3">Section&nbsp;3.3 of 2041 + [RFC7613]</a>, with the exception of the colon (&quot;:&quot;) character. 2042 + 2043 + For the password, recipients MUST support all characters defined in 2044 + the &quot;OpaqueString&quot; profile defined in <a href="/doc/html/rfc7613#section-4.2">Section&nbsp;4.2 of [RFC7613]</a>. 2045 + 2046 + If the user agent does not support the encoding indicated by the 2047 + server, it can fail the request. 2048 + 2049 + When usernames cannot be sent hashed and include non-ASCII 2050 + characters, clients can include the username* parameter instead 2051 + (using the value encoding defined in [<a href="/doc/html/rfc5987" title="&quot;Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters&quot;">RFC5987</a>]). 2052 + 2053 + <span class="h2"><a class="selflink" id="section-5" href="#section-5">5</a>. Security Considerations</span> 2054 + 2055 + <span class="h3"><a class="selflink" id="section-5.1" href="#section-5.1">5.1</a>. Limitations</span> 2056 + 2057 + HTTP Digest Authentication, when used with human-memorable passwords, 2058 + is vulnerable to dictionary attacks. Such attacks are much easier 2059 + than cryptographic attacks on any widely used algorithm, including 2060 + those that are no longer considered secure. In other words, 2061 + algorithm agility does not make this usage any more secure. 2062 + 2063 + As a result, Digest Authentication SHOULD be used only with passwords 2064 + that have a reasonable amount of entropy, e.g., 128-bit or more. 2065 + Such passwords typically cannot be memorized by humans but can be 2066 + used for automated web services. 2067 + 2068 + If Digest Authentication is being used, it SHOULD be over a secure 2069 + channel like HTTPS [<a href="/doc/html/rfc2818" title="&quot;HTTP Over TLS&quot;">RFC2818</a>]. 2070 + 2071 + <span class="h3"><a class="selflink" id="section-5.2" href="#section-5.2">5.2</a>. Storing Passwords</span> 2072 + 2073 + Digest Authentication requires that the authenticating agent (usually 2074 + the server) store some data derived from the user&#x27;s name and password 2075 + in a &quot;password file&quot; associated with a given realm. Normally, this 2076 + might contain pairs consisting of username and H(A1), where H(A1) is 2077 + the digested value of the username, realm, and password as described 2078 + above. 2079 + 2080 + The security implications of this are that if this password file is 2081 + compromised, then an attacker gains immediate access to documents on 2082 + the server using this realm. Unlike, say, a standard UNIX password 2083 + file, this information needs not be decrypted in order to access 2084 + documents in the server realm associated with this file. On the 2085 + other hand, decryption, or more likely a brute-force attack, would be 2086 + necessary to obtain the user&#x27;s password. This is the reason that the 2087 + 2088 + 2089 + 2090 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 21]</span></pre> 2091 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-22" ></span> 2092 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2093 + 2094 + 2095 + realm is part of the digested data stored in the password file. It 2096 + means that if one Digest Authentication password file is compromised, 2097 + it does not automatically compromise others with the same username 2098 + and password (though it does expose them to brute-force attack). 2099 + 2100 + There are two important security consequences of this. First, the 2101 + password file must be protected as if it contained unencrypted 2102 + passwords, because, for the purpose of accessing documents in its 2103 + realm, it effectively does. 2104 + 2105 + A second consequence of this is that the realm string SHOULD be 2106 + unique among all realms that any single user is likely to use. In 2107 + particular, a realm string SHOULD include the name of the host doing 2108 + the authentication. The inability of the client to authenticate the 2109 + server is a weakness of Digest Authentication. 2110 + 2111 + <span class="h3"><a class="selflink" id="section-5.3" href="#section-5.3">5.3</a>. Authentication of Clients Using Digest Authentication</span> 2112 + 2113 + Digest Authentication does not provide a strong authentication 2114 + mechanism, when compared to public-key-based mechanisms, for example. 2115 + 2116 + However, it is significantly stronger than, e.g., CRAM-MD5, which has 2117 + been proposed for use with Lightweight Directory Access Protocol 2118 + (LDAP) [<a href="/doc/html/rfc4513" title="&quot;Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms&quot;">RFC4513</a>] and IMAP/POP (see [<a href="/doc/html/rfc2195" title="&quot;IMAP/POP AUTHorize Extension for Simple Challenge/Response&quot;">RFC2195</a>]). It was intended to 2119 + replace the much weaker and even more dangerous Basic mechanism. 2120 + 2121 + Digest Authentication offers no confidentiality protection beyond 2122 + protecting the actual username and password. All of the rest of the 2123 + request and response are available to an eavesdropper. 2124 + 2125 + Digest Authentication offers only limited integrity protection for 2126 + the messages in either direction. If the &quot;qop=auth-int&quot; mechanism is 2127 + used, those parts of the message used in the calculation of the WWW- 2128 + Authenticate and Authorization header field response parameter values 2129 + (see <a href="#section-3.2">Section 3.2</a> above) are protected. Most header fields and their 2130 + values could be modified as a part of a man-in-the-middle attack. 2131 + 2132 + Many needs for secure HTTP transactions cannot be met by Digest 2133 + Authentication. For those needs, TLS is a more appropriate protocol. 2134 + In particular, Digest Authentication cannot be used for any 2135 + transaction requiring confidentiality protection. Nevertheless, many 2136 + functions remain for which Digest Authentication is both useful and 2137 + appropriate. 2138 + 2139 + 2140 + 2141 + 2142 + 2143 + 2144 + 2145 + 2146 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 22]</span></pre> 2147 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-23" ></span> 2148 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2149 + 2150 + 2151 + <span class="h3"><a class="selflink" id="section-5.4" href="#section-5.4">5.4</a>. Limited-Use Nonce Values</span> 2152 + 2153 + The Digest scheme uses a server-specified nonce to seed the 2154 + generation of the response value (as specified in <a href="#section-3.4.1">Section 3.4.1</a> 2155 + above). As shown in the example nonce in <a href="#section-3.3">Section 3.3</a>, the server is 2156 + free to construct the nonce such that it MAY only be used from a 2157 + particular client, for a particular resource, for a limited period of 2158 + time or number of uses, or any other restrictions. Doing so 2159 + strengthens the protection provided against, for example, replay 2160 + attacks (see <a href="#section-5.5">Section 5.5</a>). However, it should be noted that the 2161 + method chosen for generating and checking the nonce also has 2162 + performance and resource implications. For example, a server MAY 2163 + choose to allow each nonce value to be used only once by maintaining 2164 + a record of whether or not each recently issued nonce has been 2165 + returned and sending a next-nonce parameter in the Authentication- 2166 + Info header field of every response. This protects against even an 2167 + immediate replay attack, but it has a high cost due to checking nonce 2168 + values; perhaps more important, it will cause authentication failures 2169 + for any pipelined requests (presumably returning a stale nonce 2170 + indication). Similarly, incorporating a request-specific element 2171 + such as the ETag value for a resource limits the use of the nonce to 2172 + that version of the resource and also defeats pipelining. Thus, it 2173 + MAY be useful to do so for methods with side effects but have 2174 + unacceptable performance for those that do not. 2175 + 2176 + <span class="h3"><a class="selflink" id="section-5.5" href="#section-5.5">5.5</a>. Replay Attacks</span> 2177 + 2178 + A replay attack against Digest Authentication would usually be 2179 + pointless for a simple GET request since an eavesdropper would 2180 + already have seen the only document he could obtain with a replay. 2181 + This is because the URI of the requested document is digested in the 2182 + client request, and the server will only deliver that document. By 2183 + contrast, under Basic Authentication, once the eavesdropper has the 2184 + user&#x27;s password, any document protected by that password is open to 2185 + him. 2186 + 2187 + Thus, for some purposes, it is necessary to protect against replay 2188 + attacks. A good Digest implementation can do this in various ways. 2189 + The server-created &quot;nonce&quot; value is implementation dependent, but if 2190 + it contains a digest of the client IP, a timestamp, the resource 2191 + ETag, and a private server key (as recommended above), then a replay 2192 + attack is not simple. An attacker must convince the server that the 2193 + request is coming from a false IP address and must cause the server 2194 + to deliver the document to an IP address different from the address 2195 + to which it believes it is sending the document. An attack can only 2196 + succeed in the period before the timestamp expires. Digesting the 2197 + client IP and timestamp in the nonce permits an implementation that 2198 + does not maintain state between transactions. 2199 + 2200 + 2201 + 2202 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 23]</span></pre> 2203 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-24" ></span> 2204 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2205 + 2206 + 2207 + For applications where no possibility of replay attack can be 2208 + tolerated, the server can use one-time nonce values that will not be 2209 + honored for a second use. This requires the overhead of the server 2210 + remembering which nonce values have been used until the nonce 2211 + timestamp (and hence the digest built with it) has expired, but it 2212 + effectively protects against replay attacks. 2213 + 2214 + An implementation must give special attention to the possibility of 2215 + replay attacks with POST and PUT requests. Unless the server employs 2216 + one-time or otherwise limited-use nonces and/or insists on the use of 2217 + the integrity protection of &quot;qop=auth-int&quot;, an attacker could replay 2218 + valid credentials from a successful request with counterfeit data or 2219 + other message body. Even with the use of integrity protection, most 2220 + metadata in header fields is not protected. Proper nonce generation 2221 + and checking provides some protection against replay of previously 2222 + used valid credentials, but see <a href="#section-5.8">Section 5.8</a>. 2223 + 2224 + <span class="h3"><a class="selflink" id="section-5.6" href="#section-5.6">5.6</a>. Weakness Created by Multiple Authentication Schemes</span> 2225 + 2226 + An HTTP/1.1 server MAY return multiple challenges with a 401 2227 + (Authenticate) response, and each challenge MAY use a different auth- 2228 + scheme. A user agent MUST choose to use the strongest auth-scheme it 2229 + understands and request credentials from the user based upon that 2230 + challenge. 2231 + 2232 + When the server offers choices of authentication schemes using the 2233 + WWW-Authenticate header field, the strength of the resulting 2234 + authentication is only as good as that of the of the weakest of the 2235 + authentication schemes. See <a href="#section-5.7">Section 5.7</a> below for discussion of 2236 + particular attack scenarios that exploit multiple authentication 2237 + schemes. 2238 + 2239 + <span class="h3"><a class="selflink" id="section-5.7" href="#section-5.7">5.7</a>. Online Dictionary Attacks</span> 2240 + 2241 + If the attacker can eavesdrop, then it can test any overheard nonce/ 2242 + response pairs against a list of common words. Such a list is 2243 + usually much smaller than the total number of possible passwords. 2244 + The cost of computing the response for each password on the list is 2245 + paid once for each challenge. 2246 + 2247 + The server can mitigate this attack by not allowing users to select 2248 + passwords that are in a dictionary. 2249 + 2250 + 2251 + 2252 + 2253 + 2254 + 2255 + 2256 + 2257 + 2258 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 24]</span></pre> 2259 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-25" ></span> 2260 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2261 + 2262 + 2263 + <span class="h3"><a class="selflink" id="section-5.8" href="#section-5.8">5.8</a>. Man-in-the-Middle Attacks</span> 2264 + 2265 + Digest Authentication is vulnerable to man-in-the-middle (MITM) 2266 + attacks, for example, from a hostile or compromised proxy. Clearly, 2267 + this would present all the problems of eavesdropping. But, it also 2268 + offers some additional opportunities to the attacker. 2269 + 2270 + A possible man-in-the-middle attack would be to add a weak 2271 + authentication scheme to the set of choices, hoping that the client 2272 + will use one that exposes the user&#x27;s credentials (e.g., password). 2273 + For this reason, the client SHOULD always use the strongest scheme 2274 + that it understands from the choices offered. 2275 + 2276 + An even better MITM attack would be to remove all offered choices, 2277 + replacing them with a challenge that requests only Basic 2278 + authentication, then uses the cleartext credentials from the Basic 2279 + authentication to authenticate to the origin server using the 2280 + stronger scheme it requested. A particularly insidious way to mount 2281 + such a MITM attack would be to offer a &quot;free&quot; proxy caching service 2282 + to gullible users. 2283 + 2284 + User agents should consider measures such as presenting a visual 2285 + indication at the time of the credentials request of what 2286 + authentication scheme is to be used, or remembering the strongest 2287 + authentication scheme ever requested by a server and producing a 2288 + warning message before using a weaker one. It might also be a good 2289 + idea for the user agent to be configured to demand Digest 2290 + authentication in general or from specific sites. 2291 + 2292 + Or, a hostile proxy might spoof the client into making a request the 2293 + attacker wanted rather than one the client wanted. Of course, this 2294 + is still much harder than a comparable attack against Basic 2295 + Authentication. 2296 + 2297 + <span class="h3"><a class="selflink" id="section-5.9" href="#section-5.9">5.9</a>. Chosen Plaintext Attacks</span> 2298 + 2299 + With Digest Authentication, a MITM or a malicious server can 2300 + arbitrarily choose the nonce that the client will use to compute the 2301 + response. This is called a &quot;chosen plaintext&quot; attack. The ability 2302 + to choose the nonce is known to make cryptanalysis much easier. 2303 + 2304 + However, a method to analyze the one-way functions used by Digest 2305 + using chosen plaintext is not currently known. 2306 + 2307 + The countermeasure against this attack is for clients to use the 2308 + cnonce parameter; this allows the client to vary the input to the 2309 + hash in a way not chosen by the attacker. 2310 + 2311 + 2312 + 2313 + 2314 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 25]</span></pre> 2315 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-26" ></span> 2316 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2317 + 2318 + 2319 + <span class="h3"><a class="selflink" id="section-5.10" href="#section-5.10">5.10</a>. Precomputed Dictionary Attacks</span> 2320 + 2321 + With Digest Authentication, if the attacker can execute a chosen 2322 + plaintext attack, the attacker can precompute the response for many 2323 + common words to a nonce of its choice and store a dictionary of 2324 + response/password pairs. Such precomputation can often be done in 2325 + parallel on many machines. It can then use the chosen plaintext 2326 + attack to acquire a response corresponding to that challenge and just 2327 + look up the password in the dictionary. Even if most passwords are 2328 + not in the dictionary, some might be. Since the attacker gets to 2329 + pick the challenge, the cost of computing the response for each 2330 + password on the list can be amortized over finding many passwords. A 2331 + dictionary with 100 million password/response pairs would take about 2332 + 3.2 gigabytes of disk storage. 2333 + 2334 + The countermeasure against this attack is for clients to use the 2335 + cnonce parameter. 2336 + 2337 + <span class="h3"><a class="selflink" id="section-5.11" href="#section-5.11">5.11</a>. Batch Brute-Force Attacks</span> 2338 + 2339 + With Digest Authentication, a MITM can execute a chosen plaintext 2340 + attack and can gather responses from many users to the same nonce. 2341 + It can then find all the passwords within any subset of password 2342 + space that would generate one of the nonce/response pairs in a single 2343 + pass over that space. It also reduces the time to find the first 2344 + password by a factor equal to the number of nonce/response pairs 2345 + gathered. This search of the password space can often be done in 2346 + parallel on many machines, and even a single machine can search large 2347 + subsets of the password space very quickly -- reports exist of 2348 + searching all passwords with six or fewer letters in a few hours. 2349 + 2350 + The countermeasure against this attack is for clients to use the 2351 + cnonce parameter. 2352 + 2353 + <span class="h3"><a class="selflink" id="section-5.12" href="#section-5.12">5.12</a>. Parameter Randomness</span> 2354 + 2355 + The security of this protocol is critically dependent on the 2356 + randomness of the randomly chosen parameters, such as client and 2357 + server nonces. These should be generated by a strong random or 2358 + properly seeded pseudorandom source (see [<a href="/doc/html/rfc4086" title="&quot;Randomness Requirements for Security&quot;">RFC4086</a>]). 2359 + 2360 + <span class="h3"><a class="selflink" id="section-5.13" href="#section-5.13">5.13</a>. Summary</span> 2361 + 2362 + By modern cryptographic standards, Digest Authentication is weak. 2363 + But, for a large range of purposes, it is valuable as a replacement 2364 + for Basic Authentication. It remedies some, but not all, weaknesses 2365 + of Basic Authentication. Its strength may vary depending on the 2366 + implementation. In particular, the structure of the nonce (which is 2367 + 2368 + 2369 + 2370 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 26]</span></pre> 2371 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-27" ></span> 2372 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2373 + 2374 + 2375 + dependent on the server implementation) may affect the ease of 2376 + mounting a replay attack. A range of server options is appropriate 2377 + since, for example, some implementations may be willing to accept the 2378 + server overhead of one-time nonces or digests to eliminate the 2379 + possibility of replay. Others may be satisfied with a nonce like the 2380 + one recommended above, i.e., restricted to a single IP address and a 2381 + single ETag or with a limited lifetime. 2382 + 2383 + The bottom line is that *any* compliant implementation will be 2384 + relatively weak by cryptographic standards, but *any* compliant 2385 + implementation will be far superior to Basic Authentication. 2386 + 2387 + <span class="h2"><a class="selflink" id="section-6" href="#section-6">6</a>. IANA Considerations</span> 2388 + 2389 + <span class="h3"><a class="selflink" id="section-6.1" href="#section-6.1">6.1</a>. Hash Algorithms for HTTP Digest Authentication</span> 2390 + 2391 + This specification creates a new IANA registry named &quot;Hash Algorithms 2392 + for HTTP Digest Authentication&quot; under the existing &quot;Hypertext 2393 + Transfer Protocol (HTTP) Digest Algorithm Values&quot; category. This 2394 + registry lists the hash algorithms that can be used in HTTP Digest 2395 + Authentication. 2396 + 2397 + When registering a new hash algorithm, the following information MUST 2398 + be provided: 2399 + 2400 + Hash Algorithm 2401 + 2402 + The textual name of the hash algorithm. 2403 + 2404 + Digest Size 2405 + 2406 + The size of the algorithm&#x27;s output in bits. 2407 + 2408 + Reference 2409 + 2410 + A reference to the specification adding the algorithm to this 2411 + registry. 2412 + 2413 + The update policy for this registry shall be Specification Required 2414 + [<a href="/doc/html/rfc5226" title="">RFC5226</a>]. 2415 + 2416 + 2417 + 2418 + 2419 + 2420 + 2421 + 2422 + 2423 + 2424 + 2425 + 2426 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 27]</span></pre> 2427 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-28" ></span> 2428 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2429 + 2430 + 2431 + The initial registry contains the following entries: 2432 + 2433 + +----------------+-------------+-----------+ 2434 + | Hash Algorithm | Digest Size | Reference | 2435 + +----------------+-------------+-----------+ 2436 + | &quot;MD5&quot; | 128 | <a href="/doc/html/rfc7616">RFC 7616</a> | 2437 + | &quot;SHA-512-256&quot; | 256 | <a href="/doc/html/rfc7616">RFC 7616</a> | 2438 + | &quot;SHA-256&quot; | 256 | <a href="/doc/html/rfc7616">RFC 7616</a> | 2439 + +----------------+-------------+-----------+ 2440 + 2441 + Each one of the algorithms defined in the registry might have a 2442 + &quot;-sess&quot; variant, e.g., MD5-sess, SHA-256-sess, etc. 2443 + 2444 + To clarify the purpose of the existing &quot;HTTP Digest Algorithm Values&quot; 2445 + registry and to avoid confusion between the two registries, IANA has 2446 + added the following description to the existing &quot;HTTP Digest 2447 + Algorithm Values&quot; registry: 2448 + 2449 + This registry lists the algorithms that can be used when creating 2450 + digests of an HTTP message body, as specified in <a href="/doc/html/rfc3230">RFC 3230</a>. 2451 + 2452 + <span class="h3"><a class="selflink" id="section-6.2" href="#section-6.2">6.2</a>. Digest Scheme Registration</span> 2453 + 2454 + This specification updates the existing entry of the Digest scheme in 2455 + the &quot;Hypertext Transfer Protocol (HTTP) Authentication Scheme 2456 + Registry&quot; and adds a new reference to this specification. 2457 + 2458 + Authentication Scheme Name: Digest 2459 + 2460 + Pointer to specification text: <a href="/doc/html/rfc7616">RFC 7616</a> 2461 + 2462 + <span class="h2"><a class="selflink" id="section-7" href="#section-7">7</a>. References</span> 2463 + 2464 + <span class="h3"><a class="selflink" id="section-7.1" href="#section-7.1">7.1</a>. Normative References</span> 2465 + 2466 + [<a id="ref-RFC2119">RFC2119</a>] Bradner, S., &quot;Key words for use in RFCs to Indicate 2467 + Requirement Levels&quot;, <a href="/doc/html/bcp14">BCP 14</a>, <a href="/doc/html/rfc2119">RFC 2119</a>, 2468 + DOI 10.17487/RFC2119, March 1997, 2469 + &lt;<a href="http://www.rfc-editor.org/info/rfc2119">http://www.rfc-editor.org/info/rfc2119</a>&gt;. 2470 + 2471 + [<a id="ref-RFC2978">RFC2978</a>] Freed, N. and J. Postel, &quot;IANA Charset Registration 2472 + Procedures&quot;, <a href="/doc/html/bcp19">BCP 19</a>, <a href="/doc/html/rfc2978">RFC 2978</a>, DOI 10.17487/RFC2978, 2473 + October 2000, &lt;<a href="http://www.rfc-editor.org/info/rfc2978">http://www.rfc-editor.org/info/rfc2978</a>&gt;. 2474 + 2475 + [<a id="ref-RFC3629">RFC3629</a>] Yergeau, F., &quot;UTF-8, a transformation format of ISO 2476 + 10646&quot;, STD 63, <a href="/doc/html/rfc3629">RFC 3629</a>, DOI 10.17487/RFC3629, November 2477 + 2003, &lt;<a href="http://www.rfc-editor.org/info/rfc3629">http://www.rfc-editor.org/info/rfc3629</a>&gt;. 2478 + 2479 + 2480 + 2481 + 2482 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 28]</span></pre> 2483 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-29" ></span> 2484 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2485 + 2486 + 2487 + [<a id="ref-RFC3986">RFC3986</a>] Berners-Lee, T., Fielding, R., and L. Masinter, &quot;Uniform 2488 + Resource Identifier (URI): Generic Syntax&quot;, STD 66, 2489 + <a href="/doc/html/rfc3986">RFC 3986</a>, DOI 10.17487/RFC3986, January 2005, 2490 + &lt;<a href="http://www.rfc-editor.org/info/rfc3986">http://www.rfc-editor.org/info/rfc3986</a>&gt;. 2491 + 2492 + [<a id="ref-RFC4086">RFC4086</a>] Eastlake 3rd, D., Schiller, J., and S. Crocker, 2493 + &quot;Randomness Requirements for Security&quot;, <a href="/doc/html/bcp106">BCP 106</a>, <a href="/doc/html/rfc4086">RFC 4086</a>, 2494 + DOI 10.17487/RFC4086, June 2005, 2495 + &lt;<a href="http://www.rfc-editor.org/info/rfc4086">http://www.rfc-editor.org/info/rfc4086</a>&gt;. 2496 + 2497 + [<a id="ref-RFC5198">RFC5198</a>] Klensin, J. and M. Padlipsky, &quot;Unicode Format for Network 2498 + Interchange&quot;, <a href="/doc/html/rfc5198">RFC 5198</a>, DOI 10.17487/RFC5198, March 2008, 2499 + &lt;<a href="http://www.rfc-editor.org/info/rfc5198">http://www.rfc-editor.org/info/rfc5198</a>&gt;. 2500 + 2501 + [<a id="ref-RFC5234">RFC5234</a>] Crocker, D., Ed. and P. Overell, &quot;Augmented BNF for Syntax 2502 + Specifications: ABNF&quot;, STD 68, <a href="/doc/html/rfc5234">RFC 5234</a>, 2503 + DOI 10.17487/RFC5234, January 2008, 2504 + &lt;<a href="http://www.rfc-editor.org/info/rfc5234">http://www.rfc-editor.org/info/rfc5234</a>&gt;. 2505 + 2506 + [<a id="ref-RFC5987">RFC5987</a>] Reschke, J., &quot;Character Set and Language Encoding for 2507 + Hypertext Transfer Protocol (HTTP) Header Field 2508 + Parameters&quot;, <a href="/doc/html/rfc5987">RFC 5987</a>, DOI 10.17487/RFC5987, August 2010, 2509 + &lt;<a href="http://www.rfc-editor.org/info/rfc5987">http://www.rfc-editor.org/info/rfc5987</a>&gt;. 2510 + 2511 + [<a id="ref-RFC6454">RFC6454</a>] Barth, A., &quot;The Web Origin Concept&quot;, <a href="/doc/html/rfc6454">RFC 6454</a>, 2512 + DOI 10.17487/RFC6454, December 2011, 2513 + &lt;<a href="http://www.rfc-editor.org/info/rfc6454">http://www.rfc-editor.org/info/rfc6454</a>&gt;. 2514 + 2515 + [<a id="ref-RFC7230">RFC7230</a>] Fielding, R., Ed. and J. Reschke, Ed., &quot;Hypertext Transfer 2516 + Protocol (HTTP/1.1): Message Syntax and Routing&quot;, 2517 + <a href="/doc/html/rfc7230">RFC 7230</a>, DOI 10.17487/RFC7230, June 2014, 2518 + &lt;<a href="http://www.rfc-editor.org/info/rfc7230">http://www.rfc-editor.org/info/rfc7230</a>&gt;. 2519 + 2520 + [<a id="ref-RFC7231">RFC7231</a>] Fielding, R., Ed. and J. Reschke, Ed., &quot;Hypertext Transfer 2521 + Protocol (HTTP/1.1): Semantics and Content&quot;, <a href="/doc/html/rfc7231">RFC 7231</a>, 2522 + DOI 10.17487/RFC7231, June 2014, 2523 + &lt;<a href="http://www.rfc-editor.org/info/rfc7231">http://www.rfc-editor.org/info/rfc7231</a>&gt;. 2524 + 2525 + [<a id="ref-RFC7234">RFC7234</a>] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, 2526 + Ed., &quot;Hypertext Transfer Protocol (HTTP/1.1): Caching&quot;, 2527 + <a href="/doc/html/rfc7234">RFC 7234</a>, DOI 10.17487/RFC7234, June 2014, 2528 + &lt;<a href="http://www.rfc-editor.org/info/rfc7234">http://www.rfc-editor.org/info/rfc7234</a>&gt;. 2529 + 2530 + [<a id="ref-RFC7235">RFC7235</a>] Fielding, R., Ed. and J. Reschke, Ed., &quot;Hypertext Transfer 2531 + Protocol (HTTP/1.1): Authentication&quot;, <a href="/doc/html/rfc7235">RFC 7235</a>, 2532 + DOI 10.17487/RFC7235, June 2014, 2533 + &lt;<a href="http://www.rfc-editor.org/info/rfc7235">http://www.rfc-editor.org/info/rfc7235</a>&gt;. 2534 + 2535 + 2536 + 2537 + 2538 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 29]</span></pre> 2539 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-30" ></span> 2540 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2541 + 2542 + 2543 + [<a id="ref-RFC7613">RFC7613</a>] Saint-Andre, P. and A. Melnikov, &quot;Preparation, 2544 + Enforcement, and Comparison of Internationalized Strings 2545 + Representing Usernames and Passwords&quot;, <a href="/doc/html/rfc7613">RFC 7613</a>, 2546 + DOI 10.17487/RFC7613, August 2015, 2547 + &lt;<a href="http://www.rfc-editor.org/info/rfc7613">http://www.rfc-editor.org/info/rfc7613</a>&gt;. 2548 + 2549 + [<a id="ref-RFC7615">RFC7615</a>] Reschke, J., &quot;HTTP Authentication-Info and Proxy- 2550 + Authentication-Info Response Header Fields&quot;, <a href="/doc/html/rfc7615">RFC 7615</a>, 2551 + DOI 10.17487/RFC7615, September 2015, 2552 + &lt;<a href="http://www.rfc-editor.org/info/rfc7615">http://www.rfc-editor.org/info/rfc7615</a>&gt;. 2553 + 2554 + <span class="h3"><a class="selflink" id="section-7.2" href="#section-7.2">7.2</a>. Informative References</span> 2555 + 2556 + [<a id="ref-RFC2195">RFC2195</a>] Klensin, J., Catoe, R., and P. Krumviede, &quot;IMAP/POP 2557 + AUTHorize Extension for Simple Challenge/Response&quot;, 2558 + <a href="/doc/html/rfc2195">RFC 2195</a>, DOI 10.17487/RFC2195, September 1997, 2559 + &lt;<a href="http://www.rfc-editor.org/info/rfc2195">http://www.rfc-editor.org/info/rfc2195</a>&gt;. 2560 + 2561 + [<a id="ref-RFC2617">RFC2617</a>] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., 2562 + Leach, P., Luotonen, A., and L. Stewart, &quot;HTTP 2563 + Authentication: Basic and Digest Access Authentication&quot;, 2564 + <a href="/doc/html/rfc2617">RFC 2617</a>, DOI 10.17487/RFC2617, June 1999, 2565 + &lt;<a href="http://www.rfc-editor.org/info/rfc2617">http://www.rfc-editor.org/info/rfc2617</a>&gt;. 2566 + 2567 + [<a id="ref-RFC2818">RFC2818</a>] Rescorla, E., &quot;HTTP Over TLS&quot;, <a href="/doc/html/rfc2818">RFC 2818</a>, 2568 + DOI 10.17487/RFC2818, May 2000, 2569 + &lt;<a href="http://www.rfc-editor.org/info/rfc2818">http://www.rfc-editor.org/info/rfc2818</a>&gt;. 2570 + 2571 + [<a id="ref-RFC4513">RFC4513</a>] Harrison, R., Ed., &quot;Lightweight Directory Access Protocol 2572 + (LDAP): Authentication Methods and Security Mechanisms&quot;, 2573 + <a href="/doc/html/rfc4513">RFC 4513</a>, DOI 10.17487/RFC4513, June 2006, 2574 + &lt;<a href="http://www.rfc-editor.org/info/rfc4513">http://www.rfc-editor.org/info/rfc4513</a>&gt;. 2575 + 2576 + [<a id="ref-RFC5226">RFC5226</a>] Narten, T. and H. Alvestrand, &quot;Guidelines for Writing an 2577 + IANA Considerations Section in RFCs&quot;, <a href="/doc/html/bcp26">BCP 26</a>, <a href="/doc/html/rfc5226">RFC 5226</a>, 2578 + DOI 10.17487/RFC5226, May 2008, 2579 + &lt;<a href="http://www.rfc-editor.org/info/rfc5226">http://www.rfc-editor.org/info/rfc5226</a>&gt;. 2580 + 2581 + [<a id="ref-RFC7617">RFC7617</a>] Reschke, J., &quot;The &#x27;Basic&#x27; HTTP Authentication Scheme&quot;, 2582 + <a href="/doc/html/rfc7617">RFC 7617</a>, DOI 10.17487/RFC7617, September 2015, 2583 + &lt;<a href="http://www.rfc-editor.org/info/rfc7617">http://www.rfc-editor.org/info/rfc7617</a>&gt;. 2584 + 2585 + 2586 + 2587 + 2588 + 2589 + 2590 + 2591 + 2592 + 2593 + 2594 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 30]</span></pre> 2595 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-31" ></span> 2596 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2597 + 2598 + 2599 + <span class="h2"><a class="selflink" id="appendix-A" href="#appendix-A">Appendix A</a>. Changes from <a href="/doc/html/rfc2617">RFC 2617</a></span> 2600 + 2601 + This document introduces the following changes: 2602 + 2603 + o Adds support for two new algorithms, SHA2-256 as mandatory and 2604 + SHA2-512/256 as a backup, and defines the proper algorithm 2605 + negotiation. The document keeps the MD5 algorithm support but 2606 + only for backward compatibility. 2607 + 2608 + o Introduces the username hashing capability and the parameter 2609 + associated with that, mainly for privacy reasons. 2610 + 2611 + o Adds various internationalization considerations that impact the 2612 + A1 calculation and username and password encoding. 2613 + 2614 + o Introduces a new IANA registry, &quot;Hash Algorithms for HTTP Digest 2615 + Authentication&quot;, that lists the hash algorithms that can be used 2616 + in HTTP Digest Authentication. 2617 + 2618 + o Deprecates backward compatibility with <a href="/doc/html/rfc2069">RFC 2069</a>. 2619 + 2620 + Acknowledgments 2621 + 2622 + To provide a complete description for the Digest mechanism and its 2623 + operation, this document borrows text heavily from [<a href="/doc/html/rfc2617" title="&quot;HTTP Authentication: Basic and Digest Access Authentication&quot;">RFC2617</a>]. The 2624 + authors of this document would like to thank John Franks, Phillip M. 2625 + Hallam-Baker, Jeffery L. Hostetler, Scott D. Lawrence, Paul J. Leach, 2626 + Ari Luotonen, and Lawrence C. Stewart for their work on that 2627 + specification. 2628 + 2629 + Special thanks to Julian Reschke for his many reviews, comments, 2630 + suggestions, and text provided to various areas in this document. 2631 + 2632 + The authors would like to thank Stephen Farrell, Yoav Nir, Phillip 2633 + Hallam-Baker, Manu Sporny, Paul Hoffman, Yaron Sheffer, Sean Turner, 2634 + Geoff Baskwill, Eric Cooper, Bjoern Hoehrmann, Martin Durst, Peter 2635 + Saint-Andre, Michael Sweet, Daniel Stenberg, Brett Tate, Paul Leach, 2636 + Ilari Liusvaara, Gary Mort, Alexey Melnikov, Benjamin Kaduk, Kathleen 2637 + Moriarty, Francis Dupont, Hilarie Orman, and Ben Campbell for their 2638 + careful review and comments. 2639 + 2640 + The authors would like to thank Jonathan Stoke, Nico Williams, Harry 2641 + Halpin, and Phil Hunt for their comments on the mailing list when 2642 + discussing various aspects of this document. 2643 + 2644 + The authors would like to thank Paul Kyzivat and Dale Worley for 2645 + their careful review and feedback on some aspects of this document. 2646 + 2647 + 2648 + 2649 + 2650 + <span class="grey">Shekh-Yusef, et al. Standards Track [Page 31]</span></pre> 2651 + <hr class='noprint'/><!--NewPage--><pre class='newpage'><span id="page-32" ></span> 2652 + <span class="grey"><a href="/doc/html/rfc7616">RFC 7616</a> HTTP Digest Access Authentication September 2015</span> 2653 + 2654 + 2655 + The authors would like to thank Barry Leiba for his help with the 2656 + registry. 2657 + 2658 + Authors&#x27; Addresses 2659 + 2660 + Rifaat Shekh-Yusef (editor) 2661 + Avaya 2662 + 250 Sidney Street 2663 + Belleville, Ontario 2664 + Canada 2665 + 2666 + Phone: +1-613-967-5267 2667 + Email: rifaat.ietf@gmail.com 2668 + 2669 + 2670 + David Ahrens 2671 + Independent 2672 + California 2673 + United States 2674 + 2675 + Email: ahrensdc@gmail.com 2676 + 2677 + 2678 + Sophie Bremer 2679 + Netzkonform 2680 + Germany 2681 + 2682 + Email: sophie.bremer@netzkonform.de 2683 + 2684 + 2685 + 2686 + 2687 + 2688 + 2689 + 2690 + 2691 + 2692 + 2693 + 2694 + 2695 + 2696 + 2697 + 2698 + 2699 + 2700 + 2701 + 2702 + 2703 + 2704 + 2705 + 2706 + Shekh-Yusef, et al. Standards Track [Page 32] 2707 + </pre></div> 2708 + </div> 2709 + 2710 + </div> 2711 + <div class="d-print-none col-md-3 bg-light-subtle collapse show" id="sidebar"> 2712 + <div class="position-fixed border-start sidebar overflow-scroll overscroll-none no-scrollbar"> 2713 + <div class="d-flex flex-column vh-100 pt-2 pt-lg-3 ps-3 pl-md-2 pl-lg-3"> 2714 + <div> 2715 + <a class="btn btn-primary btn-sm" href="/doc/rfc7616/">Datatracker</a> 2716 + <p class="fw-bold pt-2"> 2717 + 2718 + RFC 7616 2719 + 2720 + <br> 2721 + 2722 + 2723 + 2724 + 2725 + 2726 + 2727 + <span class="text-success">RFC 2728 + 2729 + - Proposed Standard 2730 + 2731 + </span> 2732 + 2733 + </p> 2734 + </div> 2735 + 2736 + <ul class="nav nav-tabs nav-fill small me-2" role="tablist"> 2737 + <li class="nav-item" role="presentation" title="Document information"> 2738 + <button class="nav-link px-2" 2739 + id="docinfo-tab" 2740 + data-bs-toggle="tab" 2741 + data-bs-target="#docinfo-tab-pane" 2742 + type="button" 2743 + role="tab" 2744 + aria-controls="docinfo-tab-pane" 2745 + aria-selected="true"> 2746 + <i class="bi bi-info-circle"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Info</span> 2747 + </button> 2748 + </li> 2749 + <li class="nav-item" role="presentation" title="Table of contents"> 2750 + <button class="nav-link px-2" 2751 + id="toc-tab" 2752 + data-bs-toggle="tab" 2753 + data-bs-target="#toc-tab-pane" 2754 + type="button" 2755 + role="tab" 2756 + aria-controls="toc-tab-pane" 2757 + aria-selected="false"> 2758 + <i class="bi bi-list-ol"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Contents</span> 2759 + </button> 2760 + </li> 2761 + <li class="nav-item" role="presentation" title="Preferences"> 2762 + <button class="nav-link px-2" 2763 + id="pref-tab" 2764 + data-bs-toggle="tab" 2765 + data-bs-target="#pref-tab-pane" 2766 + type="button" 2767 + role="tab" 2768 + aria-controls="pref-tab-pane" 2769 + aria-selected="false"> 2770 + <i class="bi bi-gear"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Prefs</span> 2771 + </button> 2772 + </li> 2773 + </ul> 2774 + <div class="overflow-auto tab-content pt-2 me-2"> 2775 + <div class="tab-pane" 2776 + id="docinfo-tab-pane" 2777 + role="tabpanel" 2778 + aria-labelledby="docinfo-tab" 2779 + tabindex="0"> 2780 + <table class="table table-sm table-borderless"> 2781 + 2782 + 2783 + 2784 + 2785 + 2786 + 2787 + 2788 + 2789 + <tbody class="meta align-top "> 2790 + <tr> 2791 + <th scope="row">Document</th> 2792 + <th scope="row">Document type</th> 2793 + <td class="edit"></td> 2794 + <td> 2795 + 2796 + 2797 + 2798 + 2799 + 2800 + 2801 + <span class="text-success">RFC 2802 + 2803 + - Proposed Standard 2804 + 2805 + </span> 2806 + 2807 + 2808 + 2809 + <br>September 2015 2810 + 2811 + <br> 2812 + 2813 + <a class="btn btn-primary btn-sm my-1" 2814 + href="https://www.rfc-editor.org/errata_search.php?rfc=7616" title="Click to view errata." rel="nofollow"> 2815 + View errata 2816 + </a> 2817 + 2818 + 2819 + <a class="btn btn-sm btn-warning" 2820 + title="Click to report an error in the document." 2821 + href="https://www.rfc-editor.org/errata.php#reportnew" 2822 + target="_blank"> 2823 + Report errata 2824 + </a> 2825 + 2826 + 2827 + <a title="Click to view IPR declarations." class="btn btn-warning btn-sm my-1" href="/ipr/search/?submit=draft&amp;id=rfc7616">IPR</a> 2828 + 2829 + 2830 + 2831 + <div>Obsoletes <a href="/doc/html/rfc2617" title="HTTP Authentication: Basic and Digest Access Authentication">RFC 2617</a></div> 2832 + 2833 + 2834 + 2835 + 2836 + <div> 2837 + Was 2838 + <a href="/doc/draft-ietf-httpauth-digest/19/">draft-ietf-httpauth-digest</a> 2839 + (<a href="/wg/httpauth/about/">httpauth WG</a>) 2840 + </div> 2841 + 2842 + 2843 + 2844 + 2845 + 2846 + 2847 + 2848 + 2849 + 2850 + 2851 + 2852 + 2853 + 2854 + </td> 2855 + </tr> 2856 + 2857 + <tr> 2858 + <td></td> 2859 + <th scope="row">Select version</th> 2860 + <td class="edit"></td> 2861 + <td> 2862 + 2863 + 2864 + 2865 + 2866 + <ul class="revision-list pagination pagination-sm text-center flex-wrap my-0"> 2867 + 2868 + 2869 + 2870 + 2871 + <li class="page-item"> 2872 + <a class="page-link" 2873 + href="/doc/html/draft-ietf-httpauth-digest-00" 2874 + rel="nofollow"> 2875 + 00 2876 + </a> 2877 + </li> 2878 + 2879 + <li class="page-item"> 2880 + <a class="page-link" 2881 + href="/doc/html/draft-ietf-httpauth-digest-01" 2882 + rel="nofollow"> 2883 + 01 2884 + </a> 2885 + </li> 2886 + 2887 + <li class="page-item"> 2888 + <a class="page-link" 2889 + href="/doc/html/draft-ietf-httpauth-digest-02" 2890 + rel="nofollow"> 2891 + 02 2892 + </a> 2893 + </li> 2894 + 2895 + <li class="page-item"> 2896 + <a class="page-link" 2897 + href="/doc/html/draft-ietf-httpauth-digest-03" 2898 + rel="nofollow"> 2899 + 03 2900 + </a> 2901 + </li> 2902 + 2903 + <li class="page-item"> 2904 + <a class="page-link" 2905 + href="/doc/html/draft-ietf-httpauth-digest-04" 2906 + rel="nofollow"> 2907 + 04 2908 + </a> 2909 + </li> 2910 + 2911 + <li class="page-item"> 2912 + <a class="page-link" 2913 + href="/doc/html/draft-ietf-httpauth-digest-05" 2914 + rel="nofollow"> 2915 + 05 2916 + </a> 2917 + </li> 2918 + 2919 + <li class="page-item"> 2920 + <a class="page-link" 2921 + href="/doc/html/draft-ietf-httpauth-digest-06" 2922 + rel="nofollow"> 2923 + 06 2924 + </a> 2925 + </li> 2926 + 2927 + <li class="page-item"> 2928 + <a class="page-link" 2929 + href="/doc/html/draft-ietf-httpauth-digest-07" 2930 + rel="nofollow"> 2931 + 07 2932 + </a> 2933 + </li> 2934 + 2935 + <li class="page-item"> 2936 + <a class="page-link" 2937 + href="/doc/html/draft-ietf-httpauth-digest-08" 2938 + rel="nofollow"> 2939 + 08 2940 + </a> 2941 + </li> 2942 + 2943 + <li class="page-item"> 2944 + <a class="page-link" 2945 + href="/doc/html/draft-ietf-httpauth-digest-09" 2946 + rel="nofollow"> 2947 + 09 2948 + </a> 2949 + </li> 2950 + 2951 + <li class="page-item"> 2952 + <a class="page-link" 2953 + href="/doc/html/draft-ietf-httpauth-digest-10" 2954 + rel="nofollow"> 2955 + 10 2956 + </a> 2957 + </li> 2958 + 2959 + <li class="page-item"> 2960 + <a class="page-link" 2961 + href="/doc/html/draft-ietf-httpauth-digest-11" 2962 + rel="nofollow"> 2963 + 11 2964 + </a> 2965 + </li> 2966 + 2967 + <li class="page-item"> 2968 + <a class="page-link" 2969 + href="/doc/html/draft-ietf-httpauth-digest-12" 2970 + rel="nofollow"> 2971 + 12 2972 + </a> 2973 + </li> 2974 + 2975 + <li class="page-item"> 2976 + <a class="page-link" 2977 + href="/doc/html/draft-ietf-httpauth-digest-13" 2978 + rel="nofollow"> 2979 + 13 2980 + </a> 2981 + </li> 2982 + 2983 + <li class="page-item"> 2984 + <a class="page-link" 2985 + href="/doc/html/draft-ietf-httpauth-digest-14" 2986 + rel="nofollow"> 2987 + 14 2988 + </a> 2989 + </li> 2990 + 2991 + <li class="page-item"> 2992 + <a class="page-link" 2993 + href="/doc/html/draft-ietf-httpauth-digest-15" 2994 + rel="nofollow"> 2995 + 15 2996 + </a> 2997 + </li> 2998 + 2999 + <li class="page-item"> 3000 + <a class="page-link" 3001 + href="/doc/html/draft-ietf-httpauth-digest-16" 3002 + rel="nofollow"> 3003 + 16 3004 + </a> 3005 + </li> 3006 + 3007 + <li class="page-item"> 3008 + <a class="page-link" 3009 + href="/doc/html/draft-ietf-httpauth-digest-17" 3010 + rel="nofollow"> 3011 + 17 3012 + </a> 3013 + </li> 3014 + 3015 + <li class="page-item"> 3016 + <a class="page-link" 3017 + href="/doc/html/draft-ietf-httpauth-digest-18" 3018 + rel="nofollow"> 3019 + 18 3020 + </a> 3021 + </li> 3022 + 3023 + <li class="page-item"> 3024 + <a class="page-link" 3025 + href="/doc/html/draft-ietf-httpauth-digest-19" 3026 + rel="nofollow"> 3027 + 19 3028 + </a> 3029 + </li> 3030 + 3031 + 3032 + 3033 + <li class="page-item rfc active"> 3034 + <a class="page-link" 3035 + href="/doc/html/rfc7616"> 3036 + RFC 7616 3037 + </a> 3038 + </li> 3039 + 3040 + </ul> 3041 + 3042 + </td> 3043 + </tr> 3044 + 3045 + <tr> 3046 + <td></td> 3047 + <th scope="row">Compare versions</th> 3048 + <td class="edit"></td> 3049 + <td> 3050 + 3051 + 3052 + 3053 + 3054 + <form class="form-horizontal diff-form" 3055 + action="https://author-tools.ietf.org/iddiff" 3056 + method="get" 3057 + target="_blank"> 3058 + 3059 + <select class="form-select form-select-sm mb-1 select2-field" 3060 + data-max-entries="1" 3061 + data-width="resolve" 3062 + data-allow-clear="false" 3063 + data-minimum-input-length="0" 3064 + aria-label="From revision" 3065 + name="url1"> 3066 + 3067 + <option value="rfc7616"> 3068 + RFC 7616 3069 + 3070 + </option> 3071 + 3072 + <option value="draft-ietf-httpauth-digest-19" selected> 3073 + draft-ietf-httpauth-digest-19 3074 + 3075 + </option> 3076 + 3077 + <option value="draft-ietf-httpauth-digest-18"> 3078 + draft-ietf-httpauth-digest-18 3079 + 3080 + </option> 3081 + 3082 + <option value="draft-ietf-httpauth-digest-17"> 3083 + draft-ietf-httpauth-digest-17 3084 + 3085 + </option> 3086 + 3087 + <option value="draft-ietf-httpauth-digest-16"> 3088 + draft-ietf-httpauth-digest-16 3089 + 3090 + </option> 3091 + 3092 + <option value="draft-ietf-httpauth-digest-15"> 3093 + draft-ietf-httpauth-digest-15 3094 + 3095 + </option> 3096 + 3097 + <option value="draft-ietf-httpauth-digest-14"> 3098 + draft-ietf-httpauth-digest-14 3099 + 3100 + </option> 3101 + 3102 + <option value="draft-ietf-httpauth-digest-13"> 3103 + draft-ietf-httpauth-digest-13 3104 + 3105 + </option> 3106 + 3107 + <option value="draft-ietf-httpauth-digest-12"> 3108 + draft-ietf-httpauth-digest-12 3109 + 3110 + </option> 3111 + 3112 + <option value="draft-ietf-httpauth-digest-11"> 3113 + draft-ietf-httpauth-digest-11 3114 + 3115 + </option> 3116 + 3117 + <option value="draft-ietf-httpauth-digest-10"> 3118 + draft-ietf-httpauth-digest-10 3119 + 3120 + </option> 3121 + 3122 + <option value="draft-ietf-httpauth-digest-09"> 3123 + draft-ietf-httpauth-digest-09 3124 + 3125 + </option> 3126 + 3127 + <option value="draft-ietf-httpauth-digest-08"> 3128 + draft-ietf-httpauth-digest-08 3129 + 3130 + </option> 3131 + 3132 + <option value="draft-ietf-httpauth-digest-07"> 3133 + draft-ietf-httpauth-digest-07 3134 + 3135 + </option> 3136 + 3137 + <option value="draft-ietf-httpauth-digest-06"> 3138 + draft-ietf-httpauth-digest-06 3139 + 3140 + </option> 3141 + 3142 + <option value="draft-ietf-httpauth-digest-05"> 3143 + draft-ietf-httpauth-digest-05 3144 + 3145 + </option> 3146 + 3147 + <option value="draft-ietf-httpauth-digest-04"> 3148 + draft-ietf-httpauth-digest-04 3149 + 3150 + </option> 3151 + 3152 + <option value="draft-ietf-httpauth-digest-03"> 3153 + draft-ietf-httpauth-digest-03 3154 + 3155 + </option> 3156 + 3157 + <option value="draft-ietf-httpauth-digest-02"> 3158 + draft-ietf-httpauth-digest-02 3159 + 3160 + </option> 3161 + 3162 + <option value="draft-ietf-httpauth-digest-01"> 3163 + draft-ietf-httpauth-digest-01 3164 + 3165 + </option> 3166 + 3167 + <option value="draft-ietf-httpauth-digest-00"> 3168 + draft-ietf-httpauth-digest-00 3169 + 3170 + </option> 3171 + 3172 + 3173 + </select> 3174 + 3175 + <select class="form-select form-select-sm mb-1 select2-field" 3176 + data-max-entries="1" 3177 + data-width="resolve" 3178 + data-allow-clear="false" 3179 + data-minimum-input-length="0" 3180 + aria-label="To revision" 3181 + name="url2"> 3182 + 3183 + <option value="rfc7616" selected> 3184 + RFC 7616 3185 + 3186 + </option> 3187 + 3188 + <option value="draft-ietf-httpauth-digest-19"> 3189 + draft-ietf-httpauth-digest-19 3190 + 3191 + </option> 3192 + 3193 + <option value="draft-ietf-httpauth-digest-18"> 3194 + draft-ietf-httpauth-digest-18 3195 + 3196 + </option> 3197 + 3198 + <option value="draft-ietf-httpauth-digest-17"> 3199 + draft-ietf-httpauth-digest-17 3200 + 3201 + </option> 3202 + 3203 + <option value="draft-ietf-httpauth-digest-16"> 3204 + draft-ietf-httpauth-digest-16 3205 + 3206 + </option> 3207 + 3208 + <option value="draft-ietf-httpauth-digest-15"> 3209 + draft-ietf-httpauth-digest-15 3210 + 3211 + </option> 3212 + 3213 + <option value="draft-ietf-httpauth-digest-14"> 3214 + draft-ietf-httpauth-digest-14 3215 + 3216 + </option> 3217 + 3218 + <option value="draft-ietf-httpauth-digest-13"> 3219 + draft-ietf-httpauth-digest-13 3220 + 3221 + </option> 3222 + 3223 + <option value="draft-ietf-httpauth-digest-12"> 3224 + draft-ietf-httpauth-digest-12 3225 + 3226 + </option> 3227 + 3228 + <option value="draft-ietf-httpauth-digest-11"> 3229 + draft-ietf-httpauth-digest-11 3230 + 3231 + </option> 3232 + 3233 + <option value="draft-ietf-httpauth-digest-10"> 3234 + draft-ietf-httpauth-digest-10 3235 + 3236 + </option> 3237 + 3238 + <option value="draft-ietf-httpauth-digest-09"> 3239 + draft-ietf-httpauth-digest-09 3240 + 3241 + </option> 3242 + 3243 + <option value="draft-ietf-httpauth-digest-08"> 3244 + draft-ietf-httpauth-digest-08 3245 + 3246 + </option> 3247 + 3248 + <option value="draft-ietf-httpauth-digest-07"> 3249 + draft-ietf-httpauth-digest-07 3250 + 3251 + </option> 3252 + 3253 + <option value="draft-ietf-httpauth-digest-06"> 3254 + draft-ietf-httpauth-digest-06 3255 + 3256 + </option> 3257 + 3258 + <option value="draft-ietf-httpauth-digest-05"> 3259 + draft-ietf-httpauth-digest-05 3260 + 3261 + </option> 3262 + 3263 + <option value="draft-ietf-httpauth-digest-04"> 3264 + draft-ietf-httpauth-digest-04 3265 + 3266 + </option> 3267 + 3268 + <option value="draft-ietf-httpauth-digest-03"> 3269 + draft-ietf-httpauth-digest-03 3270 + 3271 + </option> 3272 + 3273 + <option value="draft-ietf-httpauth-digest-02"> 3274 + draft-ietf-httpauth-digest-02 3275 + 3276 + </option> 3277 + 3278 + <option value="draft-ietf-httpauth-digest-01"> 3279 + draft-ietf-httpauth-digest-01 3280 + 3281 + </option> 3282 + 3283 + <option value="draft-ietf-httpauth-digest-00"> 3284 + draft-ietf-httpauth-digest-00 3285 + 3286 + </option> 3287 + 3288 + 3289 + </select> 3290 + 3291 + <button type="submit" 3292 + class="btn btn-primary btn-sm" 3293 + value="--html" 3294 + name="difftype"> 3295 + Side-by-side 3296 + </button> 3297 + 3298 + <button type="submit" 3299 + class="btn btn-primary btn-sm" 3300 + value="--hwdiff" 3301 + name="difftype"> 3302 + Inline 3303 + </button> 3304 + 3305 + </form> 3306 + </td> 3307 + </tr> 3308 + 3309 + 3310 + <tr> 3311 + <td></td> 3312 + <th scope="row">Authors</th> 3313 + <td class="edit"> 3314 + 3315 + </td> 3316 + <td> 3317 + 3318 + 3319 + <span ><a 3320 + title="Datatracker profile of Rifaat Shekh-Yusef" 3321 + href="/person/rifaat.s.ietf@gmail.com" >Rifaat Shekh-Yusef</a> <a 3322 + href="mailto:rifaat.s.ietf%40gmail.com" 3323 + aria-label="Compose email to rifaat.s.ietf@gmail.com" 3324 + title="Compose email to rifaat.s.ietf@gmail.com"> 3325 + <i class="bi bi-envelope"></i></a></span>, 3326 + 3327 + <span ><a 3328 + title="Datatracker profile of David Ahrens" 3329 + href="/person/ahrensdc@gmail.com" >David Ahrens</a> <a 3330 + href="mailto:ahrensdc%40gmail.com" 3331 + aria-label="Compose email to ahrensdc@gmail.com" 3332 + title="Compose email to ahrensdc@gmail.com"> 3333 + <i class="bi bi-envelope"></i></a></span>, 3334 + 3335 + <span ><a 3336 + title="Datatracker profile of Sophie Bremer" 3337 + href="/person/ietf@sophiebremer.com" >Sophie Bremer</a> <a 3338 + href="mailto:ietf%40sophiebremer.com" 3339 + aria-label="Compose email to ietf@sophiebremer.com" 3340 + title="Compose email to ietf@sophiebremer.com"> 3341 + <i class="bi bi-envelope"></i></a></span> 3342 + 3343 + 3344 + <br> 3345 + <a class="btn btn-primary btn-sm mt-1" href="mailto:rfc7616@ietf.org?subject=rfc7616" title="Send email to the document authors">Email authors</a> 3346 + 3347 + </td> 3348 + </tr> 3349 + 3350 + 3351 + <tr> 3352 + <td></td> 3353 + <th scope="row"> 3354 + RFC stream 3355 + </th> 3356 + <td class="edit"> 3357 + 3358 + </td> 3359 + <td > 3360 + 3361 + 3362 + 3363 + 3364 + 3365 + 3366 + 3367 + 3368 + <img alt="IETF Logo" 3369 + class="d-lm-none w-25 mt-1" 3370 + 3371 + 3372 + 3373 + src="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-white.svg" 3374 + 3375 + 3376 + > 3377 + 3378 + <img alt="IETF Logo" 3379 + class="d-dm-none w-25 mt-1" 3380 + 3381 + 3382 + 3383 + src="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor.svg" 3384 + 3385 + 3386 + > 3387 + 3388 + 3389 + 3390 + 3391 + </td> 3392 + </tr> 3393 + 3394 + <tr> 3395 + <td></td> 3396 + <th scope="row"> 3397 + Other formats 3398 + </th> 3399 + <td class="edit"> 3400 + </td> 3401 + <td> 3402 + 3403 + 3404 + <div class="buttonlist"> 3405 + 3406 + 3407 + <a class="btn btn-primary btn-sm" 3408 + 3409 + target="_blank" 3410 + href="https://www.rfc-editor.org/rfc/rfc7616.txt"> 3411 + 3412 + <i class="bi bi-file-text"></i> txt 3413 + 3414 + </a> 3415 + 3416 + 3417 + 3418 + <a class="btn btn-primary btn-sm" 3419 + 3420 + target="_blank" 3421 + href="https://www.rfc-editor.org/rfc/rfc7616.html"> 3422 + 3423 + <i class="bi bi-file-code"></i> html 3424 + 3425 + </a> 3426 + 3427 + 3428 + 3429 + <a class="btn btn-primary btn-sm" 3430 + 3431 + download="rfc7616.pdf" 3432 + 3433 + 3434 + target="_blank" 3435 + href="https://www.rfc-editor.org/rfc/pdfrfc/rfc7616.txt.pdf"> 3436 + 3437 + <i class="bi bi-file-pdf"></i> pdf 3438 + 3439 + </a> 3440 + 3441 + 3442 + 3443 + 3444 + 3445 + <a class="btn btn-primary btn-sm" 3446 + 3447 + target="_blank" 3448 + href="https://www.rfc-editor.org/rfc/inline-errata/rfc7616.html"> 3449 + 3450 + <i class="bi bi-file-diff"></i> w/errata 3451 + 3452 + </a> 3453 + 3454 + 3455 + 3456 + <a class="btn btn-primary btn-sm" 3457 + 3458 + target="_blank" 3459 + href="/doc/rfc7616/bibtex/"> 3460 + 3461 + <i class="bi bi-file-ruled"></i> bibtex 3462 + 3463 + </a> 3464 + 3465 + 3466 + </div> 3467 + 3468 + 3469 + </td> 3470 + </tr> 3471 + 3472 + 3473 + 3474 + <tr> 3475 + <td> 3476 + </td> 3477 + <th scope="row"> 3478 + Additional resources 3479 + </th> 3480 + <td class="edit"> 3481 + 3482 + </td> 3483 + <td> 3484 + 3485 + 3486 + 3487 + 3488 + <a href="https://mailarchive.ietf.org/arch/browse/http-auth/?q=rfc7616 OR %22draft-ietf-httpauth-digest%22"> 3489 + Mailing list discussion 3490 + </a> 3491 + 3492 + 3493 + 3494 + </td> 3495 + </tr> 3496 + 3497 + 3498 + </tbody> 3499 + </table> 3500 + <a class="btn btn-sm btn-warning mb-3" 3501 + target="_blank" 3502 + href="https://github.com/ietf-tools/datatracker/issues/new/choose"> 3503 + Report a datatracker bug 3504 + <i class="bi bi-bug"></i> 3505 + </a> 3506 + </div> 3507 + <div class="tab-pane mb-5" 3508 + id="toc-tab-pane" 3509 + role="tabpanel" 3510 + aria-labelledby="toc-tab" 3511 + tabindex="0"> 3512 + <nav class="nav nav-pills flex-column small" id="toc-nav"> 3513 + </nav> 3514 + </div> 3515 + <div class="tab-pane mb-5 small" 3516 + id="pref-tab-pane" 3517 + role="tabpanel" 3518 + aria-labelledby="pref-tab" 3519 + tabindex="0"> 3520 + <label class="form-label fw-bold mb-2">Show sidebar by default</label> 3521 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 3522 + <input type="radio" class="btn-check" name="sidebar" id="on-radio"> 3523 + <label class="btn btn-outline-primary" for="on-radio">Yes</label> 3524 + <input type="radio" class="btn-check" name="sidebar" id="off-radio"> 3525 + <label class="btn btn-outline-primary" for="off-radio">No</label> 3526 + </div> 3527 + <label class="form-label fw-bold mt-4 mb-2">Tab to show by default</label> 3528 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 3529 + <input type="radio" class="btn-check" name="deftab" id="docinfo-radio"> 3530 + <label class="btn btn-outline-primary" for="docinfo-radio"> 3531 + <i class="bi bi-info-circle me-1"></i>Info 3532 + </label> 3533 + <input type="radio" class="btn-check" name="deftab" id="toc-radio"> 3534 + <label class="btn btn-outline-primary" for="toc-radio"> 3535 + <i class="bi bi-list-ol me-1"></i>Contents 3536 + </label> 3537 + </div> 3538 + <label class="form-label fw-bold mt-4 mb-2">HTMLization configuration</label> 3539 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 3540 + <input type="radio" class="btn-check" name="htmlconf" id="txt-radio"> 3541 + <label class="btn btn-outline-primary" for="txt-radio" title="This is the traditional HTMLization method."> 3542 + <i class="bi bi-badge-sd me-1"></i>HTMLize the plaintext 3543 + </label> 3544 + <input type="radio" class="btn-check" name="htmlconf" id="html-radio"> 3545 + <label class="btn btn-outline-primary" for="html-radio" title="This is the modern HTMLization method."> 3546 + <i class="bi bi-badge-hd me-1"></i>Plaintextify the HTML 3547 + </label> 3548 + </div> 3549 + <label class="form-label fw-bold mt-4 mb-2" for="ptsize">Maximum font size</label> 3550 + <input type="range" class="form-range" min="7" max="16" id="ptsize" oninput="ptdemo.value = ptsize.value"> 3551 + <label class="form-label fw-bold mt-4 mb-2">Page dependencies</label> 3552 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 3553 + <input type="radio" class="btn-check" name="pagedeps" id="inline-radio"> 3554 + <label class="btn btn-outline-primary" for="inline-radio" title="Generate larger, standalone web pages that do not require network access to render."> 3555 + <i class="bi bi-box me-1"></i>Inline 3556 + </label> 3557 + <input type="radio" class="btn-check" name="pagedeps" id="reference-radio"> 3558 + <label class="btn btn-outline-primary" for="reference-radio" title="Generate regular web pages that require network access to render."> 3559 + <i class="bi bi-link-45deg me-1"></i>Reference 3560 + </label> 3561 + </div> 3562 + <label class="form-label fw-bold mt-4 mb-2">Citation links</label> 3563 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 3564 + <input type="radio" class="btn-check" name="reflinks" id="refsection-radio"> 3565 + <label class="btn btn-outline-primary" for="refsection-radio" title="Citation links go to the reference section."> 3566 + <i class="bi bi-arrow-clockwise"></i> Go to reference section 3567 + </label> 3568 + <input type="radio" class="btn-check" name="reflinks" id="citation-radio"> 3569 + <label class="btn btn-outline-primary" for="citation-radio" title="Citation links go directly to the cited document."> 3570 + <i class="bi bi-link-45deg me-1"></i>Go to linked document 3571 + </label> 3572 + </div> 3573 + </div> 3574 + </div> 3575 + </div> 3576 + </div> 3577 + </div> 3578 + </div> 3579 + 3580 + <script> 3581 + var _paq = window._paq || []; 3582 + 3583 + _paq.push(['disableCookies']); 3584 + _paq.push(['trackPageView']); 3585 + _paq.push(['enableLinkTracking']); 3586 + (function() { 3587 + var u="//analytics.ietf.org/"; 3588 + _paq.push(['setTrackerUrl', u+'matomo.php']); 3589 + _paq.push(['setSiteId', 7]); 3590 + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 3591 + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); 3592 + })(); 3593 + </script> 3594 + <noscript><p><img src="//analytics.ietf.org/matomo.php?idsite=7" style="border:0;" alt="" /></p></noscript> 3595 + 3596 + </body> 3597 + </html>
+5022
spec/rfc9111.txt
··· 1 + 2 + <!DOCTYPE html> 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + <html data-bs-theme="auto" lang="en"> 11 + <head> 12 + 13 + <meta charset="utf-8"> 14 + <meta http-equiv="X-UA-Compatible" content="IE=edge"> 15 + <title> 16 + 17 + RFC 9111 - HTTP Caching 18 + 19 + </title> 20 + <meta name="viewport" content="width=device-width, initial-scale=1"> 21 + <link href="https://static.ietf.org/fonts/inter/import.css" rel="stylesheet"> 22 + <link href="https://static.ietf.org/fonts/noto-sans-mono/import.css" rel="stylesheet"> 23 + 24 + <link rel="stylesheet" href="https://static.ietf.org/dt/12.54.0/ietf/css/document_html_referenced.css"> 25 + 26 + <link rel="stylesheet" href="https://static.ietf.org/dt/12.54.0/ietf/css/document_html_txt.css"> 27 + 28 + <script type="module" crossorigin="" src="https://static.ietf.org/dt/12.54.0/assets/embedded-055c333d.js"></script> 29 + <link href="https://static.ietf.org/dt/12.54.0/assets/create-pinia-singleton-8312c5df.js" type="text/javascript" crossorigin="anonymous" rel="modulepreload" as="script" /> 30 + <link href="https://static.ietf.org/dt/12.54.0/assets/Scrollbar-ad8c5330.js" type="text/javascript" crossorigin="anonymous" rel="modulepreload" as="script" /> 31 + <script src="https://static.ietf.org/dt/12.54.0/ietf/js/document_html.js"></script> 32 + <script src="https://static.ietf.org/dt/12.54.0/ietf/js/theme.js"></script> 33 + 34 + <link rel="alternate" type="application/atom+xml" title="Document changes" href="/feed/document-changes/rfc9111/"> 35 + <meta name="description" 36 + 37 + content="HTTP Caching (RFC 9111, )" 38 + > 39 + 40 + 41 + <link rel="apple-touch-icon" 42 + sizes="180x180" 43 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-180.png"> 44 + <link rel="icon" 45 + sizes="32x32" 46 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-32.png"> 47 + <link rel="icon" 48 + sizes="16x16" 49 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-16.png"> 50 + <link rel="manifest" href="/site.webmanifest"> 51 + <link rel="mask-icon" 52 + href="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-mask.svg" 53 + color="#ffffff"> 54 + <meta name="msapplication-TileColor" 55 + content="#ffffff"> 56 + <meta name="theme-color" 57 + content="#ffffff"> 58 + 59 + 60 + 61 + 62 + 63 + <meta property="og:title" content="RFC 9111: HTTP Caching"> 64 + <meta property="og:url" content="https://datatracker.ietf.org/doc/html/rfc9111.txt"> 65 + <link rel="canonical" href="https://datatracker.ietf.org/doc/html/rfc9111.txt"> 66 + <meta property="og:site_name" content="IETF Datatracker"> 67 + <meta property="og:description" content="The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document defines HTTP caches and the associated header fields that control cache behavior or indicate cacheable response messages. This document obsoletes RFC 7234."> 68 + <meta property="og:type" content="article"> 69 + 70 + <meta property="og:image" content="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-card.png"> 71 + <meta property="og:image:alt" content="Logo of the IETF"> 72 + <meta property="article:section" content="IETF - Internet Engineering Task Force"> 73 + <meta property="og:image:type" content="image/png"> 74 + <meta property="og:image:width" content="1200"> 75 + <meta property="og:image:height" content="630"> 76 + <meta name="twitter:card" content="summary_large_image"> 77 + 78 + <meta property="article:author" content="Roy T. Fielding"> 79 + <meta property="article:author" content="Mark Nottingham"> 80 + <meta property="article:author" content="Julian Reschke"> 81 + 82 + 83 + 84 + 85 + <style> 86 + 87 + .diff-form .select2-selection__rendered { 88 + direction: rtl; 89 + text-align: left; 90 + } 91 + </style> 92 + </head> 93 + <body> 94 + 95 + <noscript><iframe class="status" title="Site status" src="/status/latest"></iframe></noscript> 96 + <div class="vue-embed" data-component="Status"></div> 97 + <div class="btn-toolbar sidebar-toolbar position-fixed top-0 end-0 m-2 m-lg-3 d-print-none"> 98 + <div class="dropdown"> 99 + <button class="btn btn-outline-secondary btn-sm me-1 dropdown-toggle d-flex align-items-center" 100 + id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" 101 + aria-label="Toggle theme"> 102 + <i class="theme-icon-active bi bi-circle-half"></i> 103 + </button> 104 + 105 + <ul class="dropdown-menu" aria-labelledby="bd-theme"> 106 + <li> 107 + <button type="button" class="dropdown-item d-flex align-items-center" 108 + data-bs-theme-value="light" aria-pressed="false"> 109 + <i class="me-2 opacity-50 theme-icon bi bi-sun-fill"></i> 110 + Light<i class="bi bi-check2 ms-auto d-none"></i> 111 + </button> 112 + </li> 113 + <li> 114 + <button type="button" class="dropdown-item d-flex align-items-center" 115 + data-bs-theme-value="dark" aria-pressed="false"> 116 + <i class="me-2 opacity-50 theme-icon bi bi-moon-stars-fill"></i> 117 + Dark<i class="bi bi-check2 ms-auto d-none"></i> 118 + </button> 119 + </li> 120 + <li> 121 + <button type="button" class="dropdown-item d-flex align-items-center active" 122 + data-bs-theme-value="auto" aria-pressed="true"> 123 + <i class="me-2 opacity-50 theme-icon bi bi-circle-half"></i> 124 + Auto<i class="bi bi-check2 ms-auto d-none"></i> 125 + </button> 126 + </li> 127 + </ul> 128 + </div> 129 + <button class="btn btn-outline-secondary btn-sm sidebar-toggle" 130 + type="button" 131 + data-bs-toggle="collapse" 132 + data-bs-target="#sidebar" 133 + aria-expanded="true" 134 + aria-controls="sidebar" 135 + aria-label="Toggle metadata sidebar" 136 + title="Toggle metadata sidebar"> 137 + <i class="bi bi-arrow-bar-left sidebar-shown"></i> 138 + <i class="bi bi-arrow-bar-right sidebar-collapsed"></i> 139 + </button> 140 + </div> 141 + <nav class="navbar bg-light-subtle px-1 fixed-top d-print-none d-md-none"> 142 + <a class="nav-link ps-1" 143 + href="/doc/rfc9111/"> 144 + 145 + RFC 9111 146 + 147 + <br class="d-sm-none"> 148 + 149 + <span class="ms-sm-3 badge rounded-pill badge-std"> 150 + 151 + Internet Standard 152 + 153 + </span> 154 + </a> 155 + <button class="navbar-toggler p-1" 156 + type="button" 157 + data-bs-toggle="collapse" 158 + data-bs-target="#docinfo-collapse" 159 + aria-controls="docinfo-collapse" 160 + aria-expanded="false" 161 + aria-label="Show document information"> 162 + <span class="navbar-toggler-icon small"></span> 163 + </button> 164 + <div class="navbar-nav navbar-nav-scroll overscroll-none collapse pt-1" id="docinfo-collapse"> 165 + <div class="bg-light-subtle p-0"> 166 + <table class="table table-sm table-borderless small"> 167 + <tbody class="meta align-top"> 168 + <tr> 169 + <th scope="row"></th> 170 + <th scope="row">Title</th> 171 + <td class="edit"></td> 172 + <td>HTTP Caching</td> 173 + </tr> 174 + </tbody> 175 + 176 + 177 + 178 + 179 + 180 + 181 + 182 + 183 + <tbody class="meta align-top "> 184 + <tr> 185 + <th scope="row">Document</th> 186 + <th scope="row">Document type</th> 187 + <td class="edit"></td> 188 + <td> 189 + 190 + 191 + 192 + 193 + 194 + 195 + <span class="text-success">RFC 196 + 197 + - Internet Standard 198 + 199 + </span> 200 + 201 + 202 + 203 + <br>June 2022 204 + 205 + <br> 206 + 207 + 208 + <a class="btn btn-sm btn-warning" 209 + title="Click to report an error in the document." 210 + href="https://www.rfc-editor.org/errata.php#reportnew" 211 + target="_blank"> 212 + Report errata 213 + </a> 214 + 215 + 216 + 217 + 218 + <div>Obsoletes <a href="/doc/html/rfc7234" title="Hypertext Transfer Protocol (HTTP/1.1): Caching">RFC 7234</a></div> 219 + 220 + 221 + 222 + 223 + <div> 224 + Was 225 + <a href="/doc/draft-ietf-httpbis-cache/19/">draft-ietf-httpbis-cache</a> 226 + (<a href="/wg/httpbis/about/">httpbis WG</a>) 227 + </div> 228 + 229 + 230 + 231 + 232 + 233 + 234 + 235 + 236 + 237 + 238 + 239 + 240 + 241 + </td> 242 + </tr> 243 + 244 + <tr> 245 + <td></td> 246 + <th scope="row">Select version</th> 247 + <td class="edit"></td> 248 + <td> 249 + 250 + 251 + 252 + 253 + <ul class="revision-list pagination pagination-sm text-center flex-wrap my-0"> 254 + 255 + 256 + 257 + 258 + <li class="page-item"> 259 + <a class="page-link" 260 + href="/doc/html/draft-ietf-httpbis-cache-00" 261 + rel="nofollow"> 262 + 00 263 + </a> 264 + </li> 265 + 266 + <li class="page-item"> 267 + <a class="page-link" 268 + href="/doc/html/draft-ietf-httpbis-cache-01" 269 + rel="nofollow"> 270 + 01 271 + </a> 272 + </li> 273 + 274 + <li class="page-item"> 275 + <a class="page-link" 276 + href="/doc/html/draft-ietf-httpbis-cache-02" 277 + rel="nofollow"> 278 + 02 279 + </a> 280 + </li> 281 + 282 + <li class="page-item"> 283 + <a class="page-link" 284 + href="/doc/html/draft-ietf-httpbis-cache-03" 285 + rel="nofollow"> 286 + 03 287 + </a> 288 + </li> 289 + 290 + <li class="page-item"> 291 + <a class="page-link" 292 + href="/doc/html/draft-ietf-httpbis-cache-04" 293 + rel="nofollow"> 294 + 04 295 + </a> 296 + </li> 297 + 298 + <li class="page-item"> 299 + <a class="page-link" 300 + href="/doc/html/draft-ietf-httpbis-cache-05" 301 + rel="nofollow"> 302 + 05 303 + </a> 304 + </li> 305 + 306 + <li class="page-item"> 307 + <a class="page-link" 308 + href="/doc/html/draft-ietf-httpbis-cache-06" 309 + rel="nofollow"> 310 + 06 311 + </a> 312 + </li> 313 + 314 + <li class="page-item"> 315 + <a class="page-link" 316 + href="/doc/html/draft-ietf-httpbis-cache-07" 317 + rel="nofollow"> 318 + 07 319 + </a> 320 + </li> 321 + 322 + <li class="page-item"> 323 + <a class="page-link" 324 + href="/doc/html/draft-ietf-httpbis-cache-08" 325 + rel="nofollow"> 326 + 08 327 + </a> 328 + </li> 329 + 330 + <li class="page-item"> 331 + <a class="page-link" 332 + href="/doc/html/draft-ietf-httpbis-cache-09" 333 + rel="nofollow"> 334 + 09 335 + </a> 336 + </li> 337 + 338 + <li class="page-item"> 339 + <a class="page-link" 340 + href="/doc/html/draft-ietf-httpbis-cache-10" 341 + rel="nofollow"> 342 + 10 343 + </a> 344 + </li> 345 + 346 + <li class="page-item"> 347 + <a class="page-link" 348 + href="/doc/html/draft-ietf-httpbis-cache-11" 349 + rel="nofollow"> 350 + 11 351 + </a> 352 + </li> 353 + 354 + <li class="page-item"> 355 + <a class="page-link" 356 + href="/doc/html/draft-ietf-httpbis-cache-12" 357 + rel="nofollow"> 358 + 12 359 + </a> 360 + </li> 361 + 362 + <li class="page-item"> 363 + <a class="page-link" 364 + href="/doc/html/draft-ietf-httpbis-cache-13" 365 + rel="nofollow"> 366 + 13 367 + </a> 368 + </li> 369 + 370 + <li class="page-item"> 371 + <a class="page-link" 372 + href="/doc/html/draft-ietf-httpbis-cache-14" 373 + rel="nofollow"> 374 + 14 375 + </a> 376 + </li> 377 + 378 + <li class="page-item"> 379 + <a class="page-link" 380 + href="/doc/html/draft-ietf-httpbis-cache-15" 381 + rel="nofollow"> 382 + 15 383 + </a> 384 + </li> 385 + 386 + <li class="page-item"> 387 + <a class="page-link" 388 + href="/doc/html/draft-ietf-httpbis-cache-16" 389 + rel="nofollow"> 390 + 16 391 + </a> 392 + </li> 393 + 394 + <li class="page-item"> 395 + <a class="page-link" 396 + href="/doc/html/draft-ietf-httpbis-cache-17" 397 + rel="nofollow"> 398 + 17 399 + </a> 400 + </li> 401 + 402 + <li class="page-item"> 403 + <a class="page-link" 404 + href="/doc/html/draft-ietf-httpbis-cache-18" 405 + rel="nofollow"> 406 + 18 407 + </a> 408 + </li> 409 + 410 + <li class="page-item"> 411 + <a class="page-link" 412 + href="/doc/html/draft-ietf-httpbis-cache-19" 413 + rel="nofollow"> 414 + 19 415 + </a> 416 + </li> 417 + 418 + 419 + 420 + <li class="page-item rfc active"> 421 + <a class="page-link" 422 + href="/doc/html/rfc9111"> 423 + RFC 9111 424 + </a> 425 + </li> 426 + 427 + </ul> 428 + 429 + </td> 430 + </tr> 431 + 432 + <tr> 433 + <td></td> 434 + <th scope="row">Compare versions</th> 435 + <td class="edit"></td> 436 + <td> 437 + 438 + 439 + 440 + 441 + <form class="form-horizontal diff-form" 442 + action="https://author-tools.ietf.org/iddiff" 443 + method="get" 444 + target="_blank"> 445 + 446 + <select class="form-select form-select-sm mb-1 select2-field" 447 + data-max-entries="1" 448 + data-width="resolve" 449 + data-allow-clear="false" 450 + data-minimum-input-length="0" 451 + aria-label="From revision" 452 + name="url1"> 453 + 454 + <option value="rfc9111"> 455 + RFC 9111 456 + 457 + </option> 458 + 459 + <option value="draft-ietf-httpbis-cache-19" selected> 460 + draft-ietf-httpbis-cache-19 461 + 462 + </option> 463 + 464 + <option value="draft-ietf-httpbis-cache-18"> 465 + draft-ietf-httpbis-cache-18 466 + 467 + </option> 468 + 469 + <option value="draft-ietf-httpbis-cache-17"> 470 + draft-ietf-httpbis-cache-17 471 + 472 + </option> 473 + 474 + <option value="draft-ietf-httpbis-cache-16"> 475 + draft-ietf-httpbis-cache-16 476 + 477 + </option> 478 + 479 + <option value="draft-ietf-httpbis-cache-15"> 480 + draft-ietf-httpbis-cache-15 481 + 482 + </option> 483 + 484 + <option value="draft-ietf-httpbis-cache-14"> 485 + draft-ietf-httpbis-cache-14 486 + 487 + </option> 488 + 489 + <option value="draft-ietf-httpbis-cache-13"> 490 + draft-ietf-httpbis-cache-13 491 + 492 + </option> 493 + 494 + <option value="draft-ietf-httpbis-cache-12"> 495 + draft-ietf-httpbis-cache-12 496 + 497 + </option> 498 + 499 + <option value="draft-ietf-httpbis-cache-11"> 500 + draft-ietf-httpbis-cache-11 501 + 502 + </option> 503 + 504 + <option value="draft-ietf-httpbis-cache-10"> 505 + draft-ietf-httpbis-cache-10 506 + 507 + </option> 508 + 509 + <option value="draft-ietf-httpbis-cache-09"> 510 + draft-ietf-httpbis-cache-09 511 + 512 + </option> 513 + 514 + <option value="draft-ietf-httpbis-cache-08"> 515 + draft-ietf-httpbis-cache-08 516 + 517 + </option> 518 + 519 + <option value="draft-ietf-httpbis-cache-07"> 520 + draft-ietf-httpbis-cache-07 521 + 522 + </option> 523 + 524 + <option value="draft-ietf-httpbis-cache-06"> 525 + draft-ietf-httpbis-cache-06 526 + 527 + </option> 528 + 529 + <option value="draft-ietf-httpbis-cache-05"> 530 + draft-ietf-httpbis-cache-05 531 + 532 + </option> 533 + 534 + <option value="draft-ietf-httpbis-cache-04"> 535 + draft-ietf-httpbis-cache-04 536 + 537 + </option> 538 + 539 + <option value="draft-ietf-httpbis-cache-03"> 540 + draft-ietf-httpbis-cache-03 541 + 542 + </option> 543 + 544 + <option value="draft-ietf-httpbis-cache-02"> 545 + draft-ietf-httpbis-cache-02 546 + 547 + </option> 548 + 549 + <option value="draft-ietf-httpbis-cache-01"> 550 + draft-ietf-httpbis-cache-01 551 + 552 + </option> 553 + 554 + <option value="draft-ietf-httpbis-cache-00"> 555 + draft-ietf-httpbis-cache-00 556 + 557 + </option> 558 + 559 + 560 + </select> 561 + 562 + <select class="form-select form-select-sm mb-1 select2-field" 563 + data-max-entries="1" 564 + data-width="resolve" 565 + data-allow-clear="false" 566 + data-minimum-input-length="0" 567 + aria-label="To revision" 568 + name="url2"> 569 + 570 + <option value="rfc9111" selected> 571 + RFC 9111 572 + 573 + </option> 574 + 575 + <option value="draft-ietf-httpbis-cache-19"> 576 + draft-ietf-httpbis-cache-19 577 + 578 + </option> 579 + 580 + <option value="draft-ietf-httpbis-cache-18"> 581 + draft-ietf-httpbis-cache-18 582 + 583 + </option> 584 + 585 + <option value="draft-ietf-httpbis-cache-17"> 586 + draft-ietf-httpbis-cache-17 587 + 588 + </option> 589 + 590 + <option value="draft-ietf-httpbis-cache-16"> 591 + draft-ietf-httpbis-cache-16 592 + 593 + </option> 594 + 595 + <option value="draft-ietf-httpbis-cache-15"> 596 + draft-ietf-httpbis-cache-15 597 + 598 + </option> 599 + 600 + <option value="draft-ietf-httpbis-cache-14"> 601 + draft-ietf-httpbis-cache-14 602 + 603 + </option> 604 + 605 + <option value="draft-ietf-httpbis-cache-13"> 606 + draft-ietf-httpbis-cache-13 607 + 608 + </option> 609 + 610 + <option value="draft-ietf-httpbis-cache-12"> 611 + draft-ietf-httpbis-cache-12 612 + 613 + </option> 614 + 615 + <option value="draft-ietf-httpbis-cache-11"> 616 + draft-ietf-httpbis-cache-11 617 + 618 + </option> 619 + 620 + <option value="draft-ietf-httpbis-cache-10"> 621 + draft-ietf-httpbis-cache-10 622 + 623 + </option> 624 + 625 + <option value="draft-ietf-httpbis-cache-09"> 626 + draft-ietf-httpbis-cache-09 627 + 628 + </option> 629 + 630 + <option value="draft-ietf-httpbis-cache-08"> 631 + draft-ietf-httpbis-cache-08 632 + 633 + </option> 634 + 635 + <option value="draft-ietf-httpbis-cache-07"> 636 + draft-ietf-httpbis-cache-07 637 + 638 + </option> 639 + 640 + <option value="draft-ietf-httpbis-cache-06"> 641 + draft-ietf-httpbis-cache-06 642 + 643 + </option> 644 + 645 + <option value="draft-ietf-httpbis-cache-05"> 646 + draft-ietf-httpbis-cache-05 647 + 648 + </option> 649 + 650 + <option value="draft-ietf-httpbis-cache-04"> 651 + draft-ietf-httpbis-cache-04 652 + 653 + </option> 654 + 655 + <option value="draft-ietf-httpbis-cache-03"> 656 + draft-ietf-httpbis-cache-03 657 + 658 + </option> 659 + 660 + <option value="draft-ietf-httpbis-cache-02"> 661 + draft-ietf-httpbis-cache-02 662 + 663 + </option> 664 + 665 + <option value="draft-ietf-httpbis-cache-01"> 666 + draft-ietf-httpbis-cache-01 667 + 668 + </option> 669 + 670 + <option value="draft-ietf-httpbis-cache-00"> 671 + draft-ietf-httpbis-cache-00 672 + 673 + </option> 674 + 675 + 676 + </select> 677 + 678 + <button type="submit" 679 + class="btn btn-primary btn-sm" 680 + value="--html" 681 + name="difftype"> 682 + Side-by-side 683 + </button> 684 + 685 + <button type="submit" 686 + class="btn btn-primary btn-sm" 687 + value="--hwdiff" 688 + name="difftype"> 689 + Inline 690 + </button> 691 + 692 + </form> 693 + </td> 694 + </tr> 695 + 696 + 697 + <tr> 698 + <td></td> 699 + <th scope="row">Authors</th> 700 + <td class="edit"> 701 + 702 + </td> 703 + <td> 704 + 705 + 706 + <span ><a 707 + title="Datatracker profile of Roy T. Fielding" 708 + href="/person/fielding@gbiv.com" >Roy T. Fielding</a> <a 709 + href="mailto:fielding%40gbiv.com" 710 + aria-label="Compose email to fielding@gbiv.com" 711 + title="Compose email to fielding@gbiv.com"> 712 + <i class="bi bi-envelope"></i></a></span>, 713 + 714 + <span ><a 715 + title="Datatracker profile of Mark Nottingham" 716 + href="/person/mnot@mnot.net" >Mark Nottingham</a> <a 717 + href="mailto:mnot%40mnot.net" 718 + aria-label="Compose email to mnot@mnot.net" 719 + title="Compose email to mnot@mnot.net"> 720 + <i class="bi bi-envelope"></i></a></span>, 721 + 722 + <span ><a 723 + title="Datatracker profile of Julian Reschke" 724 + href="/person/julian.reschke@gmx.de" >Julian Reschke</a> <a 725 + href="mailto:julian.reschke%40gmx.de" 726 + aria-label="Compose email to julian.reschke@gmx.de" 727 + title="Compose email to julian.reschke@gmx.de"> 728 + <i class="bi bi-envelope"></i></a></span> 729 + 730 + 731 + <br> 732 + <a class="btn btn-primary btn-sm mt-1" href="mailto:rfc9111@ietf.org?subject=rfc9111" title="Send email to the document authors">Email authors</a> 733 + 734 + </td> 735 + </tr> 736 + 737 + 738 + <tr> 739 + <td></td> 740 + <th scope="row"> 741 + RFC stream 742 + </th> 743 + <td class="edit"> 744 + 745 + </td> 746 + <td > 747 + 748 + 749 + 750 + 751 + 752 + 753 + 754 + 755 + <img alt="IETF Logo" 756 + class="d-lm-none w-25 mt-1" 757 + 758 + 759 + 760 + src="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-white.svg" 761 + 762 + 763 + > 764 + 765 + <img alt="IETF Logo" 766 + class="d-dm-none w-25 mt-1" 767 + 768 + 769 + 770 + src="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor.svg" 771 + 772 + 773 + > 774 + 775 + 776 + 777 + 778 + </td> 779 + </tr> 780 + 781 + <tr> 782 + <td></td> 783 + <th scope="row"> 784 + Other formats 785 + </th> 786 + <td class="edit"> 787 + </td> 788 + <td> 789 + 790 + 791 + <div class="buttonlist"> 792 + 793 + 794 + <a class="btn btn-primary btn-sm" 795 + 796 + target="_blank" 797 + href="https://www.rfc-editor.org/rfc/rfc9111.txt"> 798 + 799 + <i class="bi bi-file-text"></i> txt 800 + 801 + </a> 802 + 803 + 804 + 805 + <a class="btn btn-primary btn-sm" 806 + 807 + target="_blank" 808 + href="https://www.rfc-editor.org/rfc/rfc9111.html"> 809 + 810 + <i class="bi bi-file-code"></i> html 811 + 812 + </a> 813 + 814 + 815 + 816 + <a class="btn btn-primary btn-sm" 817 + 818 + target="_blank" 819 + href="https://www.rfc-editor.org/rfc/rfc9111.xml"> 820 + 821 + <i class="bi bi-file-code"></i> xml 822 + 823 + </a> 824 + 825 + 826 + 827 + <a class="btn btn-primary btn-sm" 828 + 829 + download="rfc9111.pdf" 830 + 831 + 832 + target="_blank" 833 + href="https://www.rfc-editor.org/rfc/rfc9111.pdf"> 834 + 835 + <i class="bi bi-file-pdf"></i> pdf 836 + 837 + </a> 838 + 839 + 840 + 841 + 842 + 843 + <a class="btn btn-primary btn-sm" 844 + 845 + target="_blank" 846 + href="/doc/rfc9111/bibtex/"> 847 + 848 + <i class="bi bi-file-ruled"></i> bibtex 849 + 850 + </a> 851 + 852 + 853 + </div> 854 + 855 + 856 + </td> 857 + </tr> 858 + 859 + 860 + 861 + <tr> 862 + <td> 863 + </td> 864 + <th scope="row"> 865 + Additional resources 866 + </th> 867 + <td class="edit"> 868 + 869 + </td> 870 + <td> 871 + 872 + 873 + 874 + 875 + <a href="http://lists.w3.org/Archives/Public/ietf-http-wg/"> 876 + Mailing list discussion 877 + </a> 878 + 879 + 880 + 881 + </td> 882 + </tr> 883 + 884 + 885 + </tbody> 886 + <tr> 887 + <th scope="row"></th> 888 + <th scope="row"></th> 889 + <td class="edit"></td> 890 + <td> 891 + <a class="btn btn-sm btn-warning mb-3" 892 + target="_blank" 893 + href="https://github.com/ietf-tools/datatracker/issues/new/choose"> 894 + Report a bug 895 + <i class="bi bi-bug"></i> 896 + </a> 897 + </td> 898 + </tr> 899 + </table> 900 + </div> 901 + </div> 902 + </nav> 903 + <div class="row g-0"> 904 + <div class="col-md-9 d-flex justify-content-center lh-sm" 905 + data-bs-spy="scroll" 906 + data-bs-target="#toc-nav" 907 + data-bs-smooth-scroll="true" 908 + tabindex="0" 909 + id="content"> 910 + 911 + <div class="rfchtml"> 912 + <br class="noprint"> 913 + <div> 914 + <table class="ears"> 915 + <thead><tr> 916 + <td class="left">RFC 9111</td> 917 + <td class="center">HTTP Caching</td> 918 + <td class="right">June 2022</td> 919 + </tr></thead> 920 + <tfoot><tr> 921 + <td class="left">Fielding, et al.</td> 922 + <td class="center">Standards Track</td> 923 + <td class="right">[Page]</td> 924 + </tr></tfoot> 925 + </table> 926 + <div id="external-metadata" class="document-information"></div> 927 + <div id="internal-metadata" class="document-information"> 928 + <dl id="identifiers"> 929 + <dt class="label-stream">Stream:</dt> 930 + <dd class="stream">Internet Engineering Task Force (IETF)</dd> 931 + <dt class="label-rfc">RFC:</dt> 932 + <dd class="rfc"><a href="https://www.rfc-editor.org/rfc/rfc9111" class="eref">9111</a></dd> 933 + <dt class="label-std">STD:</dt> 934 + <dd class="std">98</dd> 935 + <dt class="label-obsoletes">Obsoletes:</dt> 936 + <dd class="obsoletes"> 937 + <a href="https://www.rfc-editor.org/rfc/rfc7234" class="eref">7234</a> </dd> 938 + <dt class="label-category">Category:</dt> 939 + <dd class="category">Standards Track</dd> 940 + <dt class="label-published">Published:</dt> 941 + <dd class="published"> 942 + <time datetime="2022-06" class="published">June 2022</time> 943 + </dd> 944 + <dt class="label-issn">ISSN:</dt> 945 + <dd class="issn">2070-1721</dd> 946 + <dt class="label-authors">Authors:</dt> 947 + <dd class="authors"> 948 + <div class="author"> 949 + <div class="author-name">R. Fielding, <span class="editor">Ed.</span> 950 + </div> 951 + <div class="org">Adobe</div> 952 + </div> 953 + <div class="author"> 954 + <div class="author-name">M. Nottingham, <span class="editor">Ed.</span> 955 + </div> 956 + <div class="org">Fastly</div> 957 + </div> 958 + <div class="author"> 959 + <div class="author-name">J. Reschke, <span class="editor">Ed.</span> 960 + </div> 961 + <div class="org">greenbytes</div> 962 + </div> 963 + </dd> 964 + </dl> 965 + </div> 966 + <h1 id="rfcnum">RFC 9111</h1> 967 + <h1 id="title">HTTP Caching</h1> 968 + <section id="section-abstract"> 969 + <h2 id="abstract"><a href="#abstract" class="selfRef">Abstract</a></h2> 970 + <p id="section-abstract-1"> 971 + The Hypertext Transfer Protocol (HTTP) is a stateless application-level 972 + protocol for distributed, collaborative, hypertext information systems. 973 + This document defines HTTP caches and the associated header fields that 974 + control cache behavior or indicate cacheable response messages.<a href="#section-abstract-1" class="pilcrow">¶</a></p> 975 + <p id="section-abstract-2"> 976 + This document obsoletes RFC 7234.<a href="#section-abstract-2" class="pilcrow">¶</a></p> 977 + </section> 978 + <div id="status-of-memo"> 979 + <section id="section-boilerplate.1"> 980 + <h2 id="name-status-of-this-memo"> 981 + <a href="#name-status-of-this-memo" class="section-name selfRef">Status of This Memo</a> 982 + </h2> 983 + <p id="section-boilerplate.1-1"> 984 + This is an Internet Standards Track document.<a href="#section-boilerplate.1-1" class="pilcrow">¶</a></p> 985 + <p id="section-boilerplate.1-2"> 986 + This document is a product of the Internet Engineering Task Force 987 + (IETF). It represents the consensus of the IETF community. It has 988 + received public review and has been approved for publication by 989 + the Internet Engineering Steering Group (IESG). Further 990 + information on Internet Standards is available in Section 2 of 991 + RFC 7841.<a href="#section-boilerplate.1-2" class="pilcrow">¶</a></p> 992 + <p id="section-boilerplate.1-3"> 993 + Information about the current status of this document, any 994 + errata, and how to provide feedback on it may be obtained at 995 + <span><a href="https://www.rfc-editor.org/info/rfc9111">https://www.rfc-editor.org/info/rfc9111</a></span>.<a href="#section-boilerplate.1-3" class="pilcrow">¶</a></p> 996 + </section> 997 + </div> 998 + <div id="copyright"> 999 + <section id="section-boilerplate.2"> 1000 + <h2 id="name-copyright-notice"> 1001 + <a href="#name-copyright-notice" class="section-name selfRef">Copyright Notice</a> 1002 + </h2> 1003 + <p id="section-boilerplate.2-1"> 1004 + Copyright (c) 2022 IETF Trust and the persons identified as the 1005 + document authors. All rights reserved.<a href="#section-boilerplate.2-1" class="pilcrow">¶</a></p> 1006 + <p id="section-boilerplate.2-2"> 1007 + This document is subject to BCP 78 and the IETF Trust's Legal 1008 + Provisions Relating to IETF Documents 1009 + (<span><a href="https://trustee.ietf.org/license-info">https://trustee.ietf.org/license-info</a></span>) in effect on the date of 1010 + publication of this document. Please review these documents 1011 + carefully, as they describe your rights and restrictions with 1012 + respect to this document. Code Components extracted from this 1013 + document must include Revised BSD License text as described in 1014 + Section 4.e of the Trust Legal Provisions and are provided without 1015 + warranty as described in the Revised BSD License.<a href="#section-boilerplate.2-2" class="pilcrow">¶</a></p> 1016 + <p id="section-boilerplate.2-3"> 1017 + This document may contain material from IETF Documents or IETF 1018 + Contributions published or made publicly available before November 1019 + 10, 2008. The person(s) controlling the copyright in some of this 1020 + material may not have granted the IETF Trust the right to allow 1021 + modifications of such material outside the IETF Standards Process. 1022 + Without obtaining an adequate license from the person(s) 1023 + controlling the copyright in such materials, this document may not 1024 + be modified outside the IETF Standards Process, and derivative 1025 + works of it may not be created outside the IETF Standards Process, 1026 + except to format it for publication as an RFC or to translate it 1027 + into languages other than English.<a href="#section-boilerplate.2-3" class="pilcrow">¶</a></p> 1028 + </section> 1029 + </div> 1030 + <div id="toc"> 1031 + <section id="section-toc.1"> 1032 + <a href="#" onclick="scroll(0,0)" class="toplink">▲</a><h2 id="name-table-of-contents"> 1033 + <a href="#name-table-of-contents" class="section-name selfRef">Table of Contents</a> 1034 + </h2> 1035 + <nav class="toc"><ul class="compact toc ulBare ulEmpty"> 1036 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1"> 1037 + <p id="section-toc.1-1.1.1"><a href="#section-1" class="xref">1</a>.  <a href="#name-introduction" class="xref">Introduction</a></p> 1038 + <ul class="compact toc ulBare ulEmpty"> 1039 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1.2.1"> 1040 + <p id="section-toc.1-1.1.2.1.1" class="keepWithNext"><a href="#section-1.1" class="xref">1.1</a>.  <a href="#name-requirements-notation" class="xref">Requirements Notation</a></p> 1041 + </li> 1042 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1.2.2"> 1043 + <p id="section-toc.1-1.1.2.2.1"><a href="#section-1.2" class="xref">1.2</a>.  <a href="#name-syntax-notation" class="xref">Syntax Notation</a></p> 1044 + <ul class="compact toc ulBare ulEmpty"> 1045 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1.2.2.2.1"> 1046 + <p id="section-toc.1-1.1.2.2.2.1.1" class="keepWithNext"><a href="#section-1.2.1" class="xref">1.2.1</a>.  <a href="#name-imported-rules" class="xref">Imported Rules</a></p> 1047 + </li> 1048 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.1.2.2.2.2"> 1049 + <p id="section-toc.1-1.1.2.2.2.2.1" class="keepWithNext"><a href="#section-1.2.2" class="xref">1.2.2</a>.  <a href="#name-delta-seconds" class="xref">Delta Seconds</a></p> 1050 + </li> 1051 + </ul> 1052 + </li> 1053 + </ul> 1054 + </li> 1055 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.2"> 1056 + <p id="section-toc.1-1.2.1"><a href="#section-2" class="xref">2</a>.  <a href="#name-overview-of-cache-operation" class="xref">Overview of Cache Operation</a></p> 1057 + </li> 1058 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.3"> 1059 + <p id="section-toc.1-1.3.1"><a href="#section-3" class="xref">3</a>.  <a href="#name-storing-responses-in-caches" class="xref">Storing Responses in Caches</a></p> 1060 + <ul class="compact toc ulBare ulEmpty"> 1061 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.3.2.1"> 1062 + <p id="section-toc.1-1.3.2.1.1"><a href="#section-3.1" class="xref">3.1</a>.  <a href="#name-storing-header-and-trailer-" class="xref">Storing Header and Trailer Fields</a></p> 1063 + </li> 1064 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.3.2.2"> 1065 + <p id="section-toc.1-1.3.2.2.1"><a href="#section-3.2" class="xref">3.2</a>.  <a href="#name-updating-stored-header-fiel" class="xref">Updating Stored Header Fields</a></p> 1066 + </li> 1067 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.3.2.3"> 1068 + <p id="section-toc.1-1.3.2.3.1"><a href="#section-3.3" class="xref">3.3</a>.  <a href="#name-storing-incomplete-response" class="xref">Storing Incomplete Responses</a></p> 1069 + </li> 1070 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.3.2.4"> 1071 + <p id="section-toc.1-1.3.2.4.1"><a href="#section-3.4" class="xref">3.4</a>.  <a href="#name-combining-partial-content" class="xref">Combining Partial Content</a></p> 1072 + </li> 1073 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.3.2.5"> 1074 + <p id="section-toc.1-1.3.2.5.1"><a href="#section-3.5" class="xref">3.5</a>.  <a href="#name-storing-responses-to-authen" class="xref">Storing Responses to Authenticated Requests</a></p> 1075 + </li> 1076 + </ul> 1077 + </li> 1078 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4"> 1079 + <p id="section-toc.1-1.4.1"><a href="#section-4" class="xref">4</a>.  <a href="#name-constructing-responses-from" class="xref">Constructing Responses from Caches</a></p> 1080 + <ul class="compact toc ulBare ulEmpty"> 1081 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.1"> 1082 + <p id="section-toc.1-1.4.2.1.1"><a href="#section-4.1" class="xref">4.1</a>.  <a href="#name-calculating-cache-keys-with" class="xref">Calculating Cache Keys with the Vary Header Field</a></p> 1083 + </li> 1084 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2"> 1085 + <p id="section-toc.1-1.4.2.2.1"><a href="#section-4.2" class="xref">4.2</a>.  <a href="#name-freshness" class="xref">Freshness</a></p> 1086 + <ul class="compact toc ulBare ulEmpty"> 1087 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2.2.1"> 1088 + <p id="section-toc.1-1.4.2.2.2.1.1"><a href="#section-4.2.1" class="xref">4.2.1</a>.  <a href="#name-calculating-freshness-lifet" class="xref">Calculating Freshness Lifetime</a></p> 1089 + </li> 1090 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2.2.2"> 1091 + <p id="section-toc.1-1.4.2.2.2.2.1"><a href="#section-4.2.2" class="xref">4.2.2</a>.  <a href="#name-calculating-heuristic-fresh" class="xref">Calculating Heuristic Freshness</a></p> 1092 + </li> 1093 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2.2.3"> 1094 + <p id="section-toc.1-1.4.2.2.2.3.1"><a href="#section-4.2.3" class="xref">4.2.3</a>.  <a href="#name-calculating-age" class="xref">Calculating Age</a></p> 1095 + </li> 1096 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.2.2.4"> 1097 + <p id="section-toc.1-1.4.2.2.2.4.1"><a href="#section-4.2.4" class="xref">4.2.4</a>.  <a href="#name-serving-stale-responses" class="xref">Serving Stale Responses</a></p> 1098 + </li> 1099 + </ul> 1100 + </li> 1101 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.3"> 1102 + <p id="section-toc.1-1.4.2.3.1"><a href="#section-4.3" class="xref">4.3</a>.  <a href="#name-validation" class="xref">Validation</a></p> 1103 + <ul class="compact toc ulBare ulEmpty"> 1104 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.3.2.1"> 1105 + <p id="section-toc.1-1.4.2.3.2.1.1"><a href="#section-4.3.1" class="xref">4.3.1</a>.  <a href="#name-sending-a-validation-reques" class="xref">Sending a Validation Request</a></p> 1106 + </li> 1107 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.3.2.2"> 1108 + <p id="section-toc.1-1.4.2.3.2.2.1"><a href="#section-4.3.2" class="xref">4.3.2</a>.  <a href="#name-handling-a-received-validat" class="xref">Handling a Received Validation Request</a></p> 1109 + </li> 1110 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.3.2.3"> 1111 + <p id="section-toc.1-1.4.2.3.2.3.1"><a href="#section-4.3.3" class="xref">4.3.3</a>.  <a href="#name-handling-a-validation-respo" class="xref">Handling a Validation Response</a></p> 1112 + </li> 1113 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.3.2.4"> 1114 + <p id="section-toc.1-1.4.2.3.2.4.1"><a href="#section-4.3.4" class="xref">4.3.4</a>.  <a href="#name-freshening-stored-responses" class="xref">Freshening Stored Responses upon Validation</a></p> 1115 + </li> 1116 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.3.2.5"> 1117 + <p id="section-toc.1-1.4.2.3.2.5.1"><a href="#section-4.3.5" class="xref">4.3.5</a>.  <a href="#name-freshening-responses-with-h" class="xref">Freshening Responses with HEAD</a></p> 1118 + </li> 1119 + </ul> 1120 + </li> 1121 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.4.2.4"> 1122 + <p id="section-toc.1-1.4.2.4.1"><a href="#section-4.4" class="xref">4.4</a>.  <a href="#name-invalidating-stored-respons" class="xref">Invalidating Stored Responses</a></p> 1123 + </li> 1124 + </ul> 1125 + </li> 1126 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5"> 1127 + <p id="section-toc.1-1.5.1"><a href="#section-5" class="xref">5</a>.  <a href="#name-field-definitions" class="xref">Field Definitions</a></p> 1128 + <ul class="compact toc ulBare ulEmpty"> 1129 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.1"> 1130 + <p id="section-toc.1-1.5.2.1.1"><a href="#section-5.1" class="xref">5.1</a>.  <a href="#name-age" class="xref">Age</a></p> 1131 + </li> 1132 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2"> 1133 + <p id="section-toc.1-1.5.2.2.1"><a href="#section-5.2" class="xref">5.2</a>.  <a href="#name-cache-control" class="xref">Cache-Control</a></p> 1134 + <ul class="compact toc ulBare ulEmpty"> 1135 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.1"> 1136 + <p id="section-toc.1-1.5.2.2.2.1.1"><a href="#section-5.2.1" class="xref">5.2.1</a>.  <a href="#name-request-directives" class="xref">Request Directives</a></p> 1137 + <ul class="compact toc ulBare ulEmpty"> 1138 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.1.2.1"> 1139 + <p id="section-toc.1-1.5.2.2.2.1.2.1.1"><a href="#section-5.2.1.1" class="xref">5.2.1.1</a>.  <a href="#name-max-age" class="xref">max-age</a></p> 1140 + </li> 1141 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.1.2.2"> 1142 + <p id="section-toc.1-1.5.2.2.2.1.2.2.1"><a href="#section-5.2.1.2" class="xref">5.2.1.2</a>.  <a href="#name-max-stale" class="xref">max-stale</a></p> 1143 + </li> 1144 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.1.2.3"> 1145 + <p id="section-toc.1-1.5.2.2.2.1.2.3.1"><a href="#section-5.2.1.3" class="xref">5.2.1.3</a>.  <a href="#name-min-fresh" class="xref">min-fresh</a></p> 1146 + </li> 1147 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.1.2.4"> 1148 + <p id="section-toc.1-1.5.2.2.2.1.2.4.1"><a href="#section-5.2.1.4" class="xref">5.2.1.4</a>.  <a href="#name-no-cache" class="xref">no-cache</a></p> 1149 + </li> 1150 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.1.2.5"> 1151 + <p id="section-toc.1-1.5.2.2.2.1.2.5.1"><a href="#section-5.2.1.5" class="xref">5.2.1.5</a>.  <a href="#name-no-store" class="xref">no-store</a></p> 1152 + </li> 1153 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.1.2.6"> 1154 + <p id="section-toc.1-1.5.2.2.2.1.2.6.1"><a href="#section-5.2.1.6" class="xref">5.2.1.6</a>.  <a href="#name-no-transform" class="xref">no-transform</a></p> 1155 + </li> 1156 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.1.2.7"> 1157 + <p id="section-toc.1-1.5.2.2.2.1.2.7.1"><a href="#section-5.2.1.7" class="xref">5.2.1.7</a>.  <a href="#name-only-if-cached" class="xref">only-if-cached</a></p> 1158 + </li> 1159 + </ul> 1160 + </li> 1161 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2"> 1162 + <p id="section-toc.1-1.5.2.2.2.2.1"><a href="#section-5.2.2" class="xref">5.2.2</a>.  <a href="#name-response-directives" class="xref">Response Directives</a></p> 1163 + <ul class="compact toc ulBare ulEmpty"> 1164 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.1"> 1165 + <p id="section-toc.1-1.5.2.2.2.2.2.1.1"><a href="#section-5.2.2.1" class="xref">5.2.2.1</a>.  <a href="#name-max-age-2" class="xref">max-age</a></p> 1166 + </li> 1167 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.2"> 1168 + <p id="section-toc.1-1.5.2.2.2.2.2.2.1"><a href="#section-5.2.2.2" class="xref">5.2.2.2</a>.  <a href="#name-must-revalidate" class="xref">must-revalidate</a></p> 1169 + </li> 1170 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.3"> 1171 + <p id="section-toc.1-1.5.2.2.2.2.2.3.1"><a href="#section-5.2.2.3" class="xref">5.2.2.3</a>.  <a href="#name-must-understand" class="xref">must-understand</a></p> 1172 + </li> 1173 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.4"> 1174 + <p id="section-toc.1-1.5.2.2.2.2.2.4.1"><a href="#section-5.2.2.4" class="xref">5.2.2.4</a>.  <a href="#name-no-cache-2" class="xref">no-cache</a></p> 1175 + </li> 1176 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.5"> 1177 + <p id="section-toc.1-1.5.2.2.2.2.2.5.1"><a href="#section-5.2.2.5" class="xref">5.2.2.5</a>.  <a href="#name-no-store-2" class="xref">no-store</a></p> 1178 + </li> 1179 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.6"> 1180 + <p id="section-toc.1-1.5.2.2.2.2.2.6.1"><a href="#section-5.2.2.6" class="xref">5.2.2.6</a>.  <a href="#name-no-transform-2" class="xref">no-transform</a></p> 1181 + </li> 1182 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.7"> 1183 + <p id="section-toc.1-1.5.2.2.2.2.2.7.1"><a href="#section-5.2.2.7" class="xref">5.2.2.7</a>.  <a href="#name-private" class="xref">private</a></p> 1184 + </li> 1185 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.8"> 1186 + <p id="section-toc.1-1.5.2.2.2.2.2.8.1"><a href="#section-5.2.2.8" class="xref">5.2.2.8</a>.  <a href="#name-proxy-revalidate" class="xref">proxy-revalidate</a></p> 1187 + </li> 1188 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.9"> 1189 + <p id="section-toc.1-1.5.2.2.2.2.2.9.1"><a href="#section-5.2.2.9" class="xref">5.2.2.9</a>.  <a href="#name-public" class="xref">public</a></p> 1190 + </li> 1191 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.2.2.10"> 1192 + <p id="section-toc.1-1.5.2.2.2.2.2.10.1"><a href="#section-5.2.2.10" class="xref">5.2.2.10</a>. <a href="#name-s-maxage" class="xref">s-maxage</a></p> 1193 + </li> 1194 + </ul> 1195 + </li> 1196 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.3"> 1197 + <p id="section-toc.1-1.5.2.2.2.3.1"><a href="#section-5.2.3" class="xref">5.2.3</a>.  <a href="#name-extension-directives" class="xref">Extension Directives</a></p> 1198 + </li> 1199 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.2.2.4"> 1200 + <p id="section-toc.1-1.5.2.2.2.4.1"><a href="#section-5.2.4" class="xref">5.2.4</a>.  <a href="#name-cache-directive-registry" class="xref">Cache Directive Registry</a></p> 1201 + </li> 1202 + </ul> 1203 + </li> 1204 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.3"> 1205 + <p id="section-toc.1-1.5.2.3.1"><a href="#section-5.3" class="xref">5.3</a>.  <a href="#name-expires" class="xref">Expires</a></p> 1206 + </li> 1207 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.4"> 1208 + <p id="section-toc.1-1.5.2.4.1"><a href="#section-5.4" class="xref">5.4</a>.  <a href="#name-pragma" class="xref">Pragma</a></p> 1209 + </li> 1210 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.5.2.5"> 1211 + <p id="section-toc.1-1.5.2.5.1"><a href="#section-5.5" class="xref">5.5</a>.  <a href="#name-warning" class="xref">Warning</a></p> 1212 + </li> 1213 + </ul> 1214 + </li> 1215 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.6"> 1216 + <p id="section-toc.1-1.6.1"><a href="#section-6" class="xref">6</a>.  <a href="#name-relationship-to-application" class="xref">Relationship to Applications and Other Caches</a></p> 1217 + </li> 1218 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.7"> 1219 + <p id="section-toc.1-1.7.1"><a href="#section-7" class="xref">7</a>.  <a href="#name-security-considerations" class="xref">Security Considerations</a></p> 1220 + <ul class="compact toc ulBare ulEmpty"> 1221 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.7.2.1"> 1222 + <p id="section-toc.1-1.7.2.1.1"><a href="#section-7.1" class="xref">7.1</a>.  <a href="#name-cache-poisoning" class="xref">Cache Poisoning</a></p> 1223 + </li> 1224 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.7.2.2"> 1225 + <p id="section-toc.1-1.7.2.2.1"><a href="#section-7.2" class="xref">7.2</a>.  <a href="#name-timing-attacks" class="xref">Timing Attacks</a></p> 1226 + </li> 1227 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.7.2.3"> 1228 + <p id="section-toc.1-1.7.2.3.1"><a href="#section-7.3" class="xref">7.3</a>.  <a href="#name-caching-of-sensitive-inform" class="xref">Caching of Sensitive Information</a></p> 1229 + </li> 1230 + </ul> 1231 + </li> 1232 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.8"> 1233 + <p id="section-toc.1-1.8.1"><a href="#section-8" class="xref">8</a>.  <a href="#name-iana-considerations" class="xref">IANA Considerations</a></p> 1234 + <ul class="compact toc ulBare ulEmpty"> 1235 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.8.2.1"> 1236 + <p id="section-toc.1-1.8.2.1.1"><a href="#section-8.1" class="xref">8.1</a>.  <a href="#name-field-name-registration" class="xref">Field Name Registration</a></p> 1237 + </li> 1238 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.8.2.2"> 1239 + <p id="section-toc.1-1.8.2.2.1"><a href="#section-8.2" class="xref">8.2</a>.  <a href="#name-cache-directive-registratio" class="xref">Cache Directive Registration</a></p> 1240 + </li> 1241 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.8.2.3"> 1242 + <p id="section-toc.1-1.8.2.3.1"><a href="#section-8.3" class="xref">8.3</a>.  <a href="#name-warn-code-registry" class="xref">Warn Code Registry</a></p> 1243 + </li> 1244 + </ul> 1245 + </li> 1246 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.9"> 1247 + <p id="section-toc.1-1.9.1"><a href="#section-9" class="xref">9</a>.  <a href="#name-references" class="xref">References</a></p> 1248 + <ul class="compact toc ulBare ulEmpty"> 1249 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.9.2.1"> 1250 + <p id="section-toc.1-1.9.2.1.1"><a href="#section-9.1" class="xref">9.1</a>.  <a href="#name-normative-references" class="xref">Normative References</a></p> 1251 + </li> 1252 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.9.2.2"> 1253 + <p id="section-toc.1-1.9.2.2.1"><a href="#section-9.2" class="xref">9.2</a>.  <a href="#name-informative-references" class="xref">Informative References</a></p> 1254 + </li> 1255 + </ul> 1256 + </li> 1257 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.10"> 1258 + <p id="section-toc.1-1.10.1"><a href="#appendix-A" class="xref">Appendix A</a>.  <a href="#name-collected-abnf" class="xref">Collected ABNF</a></p> 1259 + </li> 1260 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.11"> 1261 + <p id="section-toc.1-1.11.1"><a href="#appendix-B" class="xref">Appendix B</a>.  <a href="#name-changes-from-rfc-7234" class="xref">Changes from RFC 7234</a></p> 1262 + </li> 1263 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.12"> 1264 + <p id="section-toc.1-1.12.1"><a href="#appendix-C" class="xref"></a><a href="#name-acknowledgements" class="xref">Acknowledgements</a></p> 1265 + </li> 1266 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.13"> 1267 + <p id="section-toc.1-1.13.1"><a href="#appendix-D" class="xref"></a><a href="#name-index" class="xref">Index</a></p> 1268 + </li> 1269 + <li class="compact toc ulBare ulEmpty" id="section-toc.1-1.14"> 1270 + <p id="section-toc.1-1.14.1"><a href="#appendix-E" class="xref"></a><a href="#name-authors-addresses" class="xref">Authors' Addresses</a></p> 1271 + </li> 1272 + </ul> 1273 + </nav> 1274 + </section> 1275 + </div> 1276 + <div id="caching"> 1277 + <section id="section-1"> 1278 + <h2 id="name-introduction"> 1279 + <a href="#section-1" class="section-number selfRef">1. </a><a href="#name-introduction" class="section-name selfRef">Introduction</a> 1280 + </h2> 1281 + <p id="section-1-1"> 1282 + The Hypertext Transfer Protocol (HTTP) is a stateless application-level 1283 + request/response protocol that uses extensible semantics and 1284 + self-descriptive messages for flexible interaction with network-based 1285 + hypertext information systems. It is typically used for distributed information systems, where 1286 + the use of response caches can improve performance. This document 1287 + defines aspects of HTTP related to caching and reusing response 1288 + messages.<a href="#section-1-1" class="pilcrow">¶</a></p> 1289 + <span id="iref-cache-1" class="iref"></span> 1290 + <p id="section-1-2"> 1291 + An HTTP "cache" is a local store of response messages and the 1292 + subsystem that controls storage, retrieval, and deletion of messages in it. 1293 + A cache stores cacheable responses to reduce the response time and 1294 + network bandwidth consumption on future equivalent requests. Any client or 1295 + server <span class="bcp14">MAY</span> use a cache, though not when acting as a tunnel (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-3.7" class="relref">Section 3.7</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>).<a href="#section-1-2" class="pilcrow">¶</a></p> 1296 + <span id="iref-shared-cache-2" class="iref"></span> 1297 + <span id="iref-private-cache-3" class="iref"></span> 1298 + <div id="shared.and.private.caches"> 1299 + <p id="section-1-3"> 1300 + A "shared cache" is a cache that stores responses for reuse 1301 + by more than one user; shared caches are usually (but not always) deployed 1302 + as a part of an intermediary. A "private cache", in contrast, 1303 + is dedicated to a single user; often, they are deployed as a component of 1304 + a user agent.<a href="#section-1-3" class="pilcrow">¶</a></p> 1305 + </div> 1306 + <p id="section-1-4"> 1307 + The goal of HTTP caching is significantly improving performance 1308 + by reusing a prior response message to satisfy a current request. 1309 + A cache considers a stored response "fresh", as defined in 1310 + <a href="#expiration.model" class="xref">Section 4.2</a>, if it can be reused without 1311 + "validation" (checking with the origin server to see if the cached response 1312 + remains valid for this request). A fresh response can therefore 1313 + reduce both latency and network overhead each time the cache reuses it. 1314 + When a cached response is not fresh, it might still be reusable if validation 1315 + can freshen it (<a href="#validation.model" class="xref">Section 4.3</a>) or if the 1316 + origin is unavailable (<a href="#serving.stale.responses" class="xref">Section 4.2.4</a>).<a href="#section-1-4" class="pilcrow">¶</a></p> 1317 + <p id="section-1-5"> 1318 + This document obsoletes <a href="#RFC7234" class="xref">RFC 7234</a>, 1319 + with the changes being summarized in <a href="#changes.from.rfc.7234" class="xref">Appendix B</a>.<a href="#section-1-5" class="pilcrow">¶</a></p> 1320 + <div id="requirements.notation"> 1321 + <section id="section-1.1"> 1322 + <h3 id="name-requirements-notation"> 1323 + <a href="#section-1.1" class="section-number selfRef">1.1. </a><a href="#name-requirements-notation" class="section-name selfRef">Requirements Notation</a> 1324 + </h3> 1325 + <p id="section-1.1-1"> 1326 + The key words "<span class="bcp14">MUST</span>", "<span class="bcp14">MUST NOT</span>", 1327 + "<span class="bcp14">REQUIRED</span>", "<span class="bcp14">SHALL</span>", "<span class="bcp14">SHALL NOT</span>", "<span class="bcp14">SHOULD</span>", "<span class="bcp14">SHOULD NOT</span>", 1328 + "<span class="bcp14">RECOMMENDED</span>", "<span class="bcp14">NOT RECOMMENDED</span>", 1329 + "<span class="bcp14">MAY</span>", and "<span class="bcp14">OPTIONAL</span>" in this document are 1330 + to be interpreted as described in BCP 14 <span>[<a href="#RFC2119" class="xref">RFC2119</a>]</span> 1331 + <span>[<a href="#RFC8174" class="xref">RFC8174</a>]</span> when, and only when, they appear in all capitals, 1332 + as shown here.<a href="#section-1.1-1" class="pilcrow">¶</a></p> 1333 + <p id="section-1.1-2"> 1334 + <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-2" class="relref">Section 2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span> defines conformance criteria and contains considerations regarding error handling.<a href="#section-1.1-2" class="pilcrow">¶</a></p> 1335 + </section> 1336 + </div> 1337 + <div id="notation"> 1338 + <section id="section-1.2"> 1339 + <h3 id="name-syntax-notation"> 1340 + <a href="#section-1.2" class="section-number selfRef">1.2. </a><a href="#name-syntax-notation" class="section-name selfRef">Syntax Notation</a> 1341 + </h3> 1342 + <span id="iref-grammar-digit-4" class="iref"></span> 1343 + <p id="section-1.2-1"> 1344 + This specification uses the Augmented Backus-Naur Form (ABNF) notation of 1345 + <span>[<a href="#RFC5234" class="xref">RFC5234</a>]</span>, extended with the notation for case-sensitivity 1346 + in strings defined in <span>[<a href="#RFC7405" class="xref">RFC7405</a>]</span>.<a href="#section-1.2-1" class="pilcrow">¶</a></p> 1347 + <p id="section-1.2-2"> 1348 + It also uses a list extension, defined in <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-5.6.1" class="relref">Section 5.6.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>, 1349 + that allows for compact definition of comma-separated lists using a "#" 1350 + operator (similar to how the "*" operator indicates repetition). <a href="#collected.abnf" class="xref">Appendix A</a> shows the collected grammar with all list 1351 + operators expanded to standard ABNF notation.<a href="#section-1.2-2" class="pilcrow">¶</a></p> 1352 + <div id="abnf.imported"> 1353 + <section id="section-1.2.1"> 1354 + <h4 id="name-imported-rules"> 1355 + <a href="#section-1.2.1" class="section-number selfRef">1.2.1. </a><a href="#name-imported-rules" class="section-name selfRef">Imported Rules</a> 1356 + </h4> 1357 + <div id="core.rules"> 1358 + <p id="section-1.2.1-1"> 1359 + 1360 + The following core rule is included by 1361 + reference, as defined in <span>[<a href="#RFC5234" class="xref">RFC5234</a>], <a href="https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1" class="relref">Appendix B.1</a></span>: 1362 + DIGIT (decimal 0-9).<a href="#section-1.2.1-1" class="pilcrow">¶</a></p> 1363 + </div> 1364 + <div id="imported.rules"> 1365 + <p id="section-1.2.1-2"> 1366 + <span>[<a href="#HTTP" class="xref">HTTP</a>]</span> defines the following rules:<a href="#section-1.2.1-2" class="pilcrow">¶</a></p> 1367 + </div> 1368 + <div id="section-1.2.1-3"> 1369 + <pre class="lang-abnf9110 sourcecode"> HTTP-date = &lt;HTTP-date, see [HTTP], Section 5.6.7&gt; 1370 + OWS = &lt;OWS, see [HTTP], Section 5.6.3&gt; 1371 + field-name = &lt;field-name, see [HTTP], Section 5.1&gt; 1372 + quoted-string = &lt;quoted-string, see [HTTP], Section 5.6.4&gt; 1373 + token = &lt;token, see [HTTP], Section 5.6.2&gt; 1374 + </pre><a href="#section-1.2.1-3" class="pilcrow">¶</a> 1375 + </div> 1376 + </section> 1377 + </div> 1378 + <div id="delta-seconds"> 1379 + <section id="section-1.2.2"> 1380 + <h4 id="name-delta-seconds"> 1381 + <a href="#section-1.2.2" class="section-number selfRef">1.2.2. </a><a href="#name-delta-seconds" class="section-name selfRef">Delta Seconds</a> 1382 + </h4> 1383 + <p id="section-1.2.2-1"> 1384 + The delta-seconds rule specifies a non-negative integer, representing time 1385 + in seconds.<a href="#section-1.2.2-1" class="pilcrow">¶</a></p> 1386 + <span id="iref-grammar-delta-seconds-5" class="iref"></span> 1387 + <div id="section-1.2.2-2"> 1388 + <pre class="lang-abnf9110 sourcecode"> delta-seconds = 1*DIGIT 1389 + </pre><a href="#section-1.2.2-2" class="pilcrow">¶</a> 1390 + </div> 1391 + <p id="section-1.2.2-3"> 1392 + A recipient parsing a delta-seconds value and converting it to binary form 1393 + ought to use an arithmetic type of at least 31 bits of non-negative integer 1394 + range. 1395 + If a cache receives a delta-seconds value greater than the greatest integer 1396 + it can represent, or if any of its subsequent calculations overflows, 1397 + the cache <span class="bcp14">MUST</span> consider the value to be 2147483648 1398 + (2<sup>31</sup>) or the greatest positive integer it can conveniently 1399 + represent.<a href="#section-1.2.2-3" class="pilcrow">¶</a></p> 1400 + <aside id="section-1.2.2-4"> 1401 + <p id="section-1.2.2-4.1"> 1402 + <strong>Note:</strong> The value 2147483648 is here for historical reasons, 1403 + represents infinity (over 68 years), and does not need to be stored in 1404 + binary form; an implementation could produce it as a string if 1405 + any overflow occurs, even if the calculations are performed with an 1406 + arithmetic type incapable of directly representing that number. 1407 + What matters here is that an overflow be detected and not treated as a 1408 + negative value in later calculations.<a href="#section-1.2.2-4.1" class="pilcrow">¶</a></p> 1409 + </aside> 1410 + </section> 1411 + </div> 1412 + </section> 1413 + </div> 1414 + </section> 1415 + </div> 1416 + <div id="caching.overview"> 1417 + <section id="section-2"> 1418 + <h2 id="name-overview-of-cache-operation"> 1419 + <a href="#section-2" class="section-number selfRef">2. </a><a href="#name-overview-of-cache-operation" class="section-name selfRef">Overview of Cache Operation</a> 1420 + </h2> 1421 + <span id="iref-cache-key-6" class="iref"></span> 1422 + <p id="section-2-1"> 1423 + Proper cache operation preserves the semantics of HTTP transfers 1424 + while reducing the transmission of information already held in the 1425 + cache. See <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-3" class="relref">Section 3</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span> 1426 + for the general terminology and core concepts of HTTP.<a href="#section-2-1" class="pilcrow">¶</a></p> 1427 + <p id="section-2-2"> 1428 + Although caching is an entirely <span class="bcp14">OPTIONAL</span> feature of HTTP, it can be 1429 + assumed that reusing a cached response is desirable and that such reuse 1430 + is the default behavior when no requirement or local configuration 1431 + prevents it. Therefore, HTTP cache requirements are focused 1432 + on preventing a cache from either storing a non-reusable response or 1433 + reusing a stored response inappropriately, rather than mandating that 1434 + caches always store and reuse particular responses.<a href="#section-2-2" class="pilcrow">¶</a></p> 1435 + <span id="iref-cache-key-7" class="iref"></span> 1436 + <p id="section-2-3"> 1437 + The "cache key" is the information a cache uses to choose a response and 1438 + is composed from, at a minimum, the request method and target 1439 + URI used to retrieve the stored response; the method determines under which 1440 + circumstances that response can be used to satisfy a subsequent request. However, many 1441 + HTTP caches in common use today only cache GET responses and therefore only 1442 + use the URI as the cache key.<a href="#section-2-3" class="pilcrow">¶</a></p> 1443 + <p id="section-2-4"> 1444 + A cache might store multiple responses for a request target that is 1445 + subject to content negotiation. Caches differentiate these responses 1446 + by incorporating some of the original request's header fields 1447 + into the cache key as well, using information in the Vary 1448 + response header field, as per <a href="#caching.negotiated.responses" class="xref">Section 4.1</a>.<a href="#section-2-4" class="pilcrow">¶</a></p> 1449 + <p id="section-2-5"> 1450 + Caches might incorporate additional material into the cache key. 1451 + For example, user agent caches might include the referring site's identity, 1452 + thereby "double keying" the cache to avoid some privacy risks (see <a href="#security.timing" class="xref">Section 7.2</a>).<a href="#section-2-5" class="pilcrow">¶</a></p> 1453 + <p id="section-2-6"> 1454 + Most commonly, caches store the successful result of a retrieval 1455 + request: i.e., a 200 (OK) response to a GET request, which 1456 + contains a representation of the target resource 1457 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-9.3.1" class="relref">Section 9.3.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>). However, it is also possible to store 1458 + redirects, negative results (e.g., 404 (Not Found)), 1459 + incomplete results (e.g., 206 (Partial Content)), and 1460 + responses to methods other than GET if the method's definition allows such 1461 + caching and defines something suitable for use as a cache key.<a href="#section-2-6" class="pilcrow">¶</a></p> 1462 + <p id="section-2-7"> 1463 + A cache is "disconnected" when it cannot contact the origin 1464 + server or otherwise find a forward path for a request. A 1465 + disconnected cache can serve stale responses in some circumstances (<a href="#serving.stale.responses" class="xref">Section 4.2.4</a>).<a href="#section-2-7" class="pilcrow">¶</a></p> 1466 + </section> 1467 + </div> 1468 + <div id="response.cacheability"> 1469 + <section id="section-3"> 1470 + <h2 id="name-storing-responses-in-caches"> 1471 + <a href="#section-3" class="section-number selfRef">3. </a><a href="#name-storing-responses-in-caches" class="section-name selfRef">Storing Responses in Caches</a> 1472 + </h2> 1473 + <p id="section-3-1"> 1474 + A cache <span class="bcp14">MUST NOT</span> store a response to a request unless:<a href="#section-3-1" class="pilcrow">¶</a></p> 1475 + <ul class="normal"> 1476 + <li class="normal" id="section-3-2.1"> 1477 + <p id="section-3-2.1.1">the request method is understood by the cache;<a href="#section-3-2.1.1" class="pilcrow">¶</a></p> 1478 + </li> 1479 + <li class="normal" id="section-3-2.2"> 1480 + <p id="section-3-2.2.1">the response status code is final (see 1481 + <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-15" class="relref">Section 15</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>);<a href="#section-3-2.2.1" class="pilcrow">¶</a></p> 1482 + </li> 1483 + <li class="normal" id="section-3-2.3"> 1484 + <p id="section-3-2.3.1">if the response status code is 206 or 304, or the must-understand cache directive (see <a href="#cache-response-directive.must-understand" class="xref">Section 5.2.2.3</a>) is present: the cache understands the response status code;<a href="#section-3-2.3.1" class="pilcrow">¶</a></p> 1485 + </li> 1486 + <li class="normal" id="section-3-2.4"> 1487 + <p id="section-3-2.4.1">the no-store cache directive is not present in the response 1488 + (see <a href="#cache-response-directive.no-store" class="xref">Section 5.2.2.5</a>);<a href="#section-3-2.4.1" class="pilcrow">¶</a></p> 1489 + </li> 1490 + <li class="normal" id="section-3-2.5"> 1491 + <p id="section-3-2.5.1">if the cache is shared: the private response directive is either not 1492 + present or allows a shared cache to store a modified response; 1493 + see <a href="#cache-response-directive.private" class="xref">Section 5.2.2.7</a>);<a href="#section-3-2.5.1" class="pilcrow">¶</a></p> 1494 + </li> 1495 + <li class="normal" id="section-3-2.6"> 1496 + <p id="section-3-2.6.1">if the cache is shared: the Authorization header field 1497 + is not present in the request 1498 + (see <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-11.6.2" class="relref">Section 11.6.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) or a 1499 + response directive is present that explicitly allows shared caching 1500 + (see <a href="#caching.authenticated.responses" class="xref">Section 3.5</a>); 1501 + and<a href="#section-3-2.6.1" class="pilcrow">¶</a></p> 1502 + </li> 1503 + <li class="normal" id="section-3-2.7"> 1504 + <p id="section-3-2.7.1">the response contains at least one of the following:<a href="#section-3-2.7.1" class="pilcrow">¶</a></p> 1505 + <ul class="normal"> 1506 + <li class="normal" id="section-3-2.7.2.1">a public response directive 1507 + (see <a href="#cache-response-directive.public" class="xref">Section 5.2.2.9</a>);<a href="#section-3-2.7.2.1" class="pilcrow">¶</a> 1508 + </li> 1509 + <li class="normal" id="section-3-2.7.2.2">a private response directive, if the cache is not shared 1510 + (see <a href="#cache-response-directive.private" class="xref">Section 5.2.2.7</a>);<a href="#section-3-2.7.2.2" class="pilcrow">¶</a> 1511 + </li> 1512 + <li class="normal" id="section-3-2.7.2.3">an <a href="#field.expires" class="xref">Expires</a> header field 1513 + (see <a href="#field.expires" class="xref">Section 5.3</a>);<a href="#section-3-2.7.2.3" class="pilcrow">¶</a> 1514 + </li> 1515 + <li class="normal" id="section-3-2.7.2.4">a max-age response directive 1516 + (see <a href="#cache-response-directive.max-age" class="xref">Section 5.2.2.1</a>);<a href="#section-3-2.7.2.4" class="pilcrow">¶</a> 1517 + </li> 1518 + <li class="normal" id="section-3-2.7.2.5">if the cache is shared: an s-maxage response directive 1519 + (see <a href="#cache-response-directive.s-maxage" class="xref">Section 5.2.2.10</a>);<a href="#section-3-2.7.2.5" class="pilcrow">¶</a> 1520 + </li> 1521 + <li class="normal" id="section-3-2.7.2.6">a cache extension that allows it to be cached 1522 + (see <a href="#cache.control.extensions" class="xref">Section 5.2.3</a>); or<a href="#section-3-2.7.2.6" class="pilcrow">¶</a> 1523 + </li> 1524 + <li class="normal" id="section-3-2.7.2.7">a status code that is defined as heuristically cacheable 1525 + (see <a href="#heuristic.freshness" class="xref">Section 4.2.2</a>).<a href="#section-3-2.7.2.7" class="pilcrow">¶</a> 1526 + </li> 1527 + </ul> 1528 + </li> 1529 + </ul> 1530 + <p id="section-3-3"> 1531 + Note that a cache extension can override any of the requirements 1532 + listed; see <a href="#cache.control.extensions" class="xref">Section 5.2.3</a>.<a href="#section-3-3" class="pilcrow">¶</a></p> 1533 + <p id="section-3-4"> 1534 + In this context, a cache has "understood" a request method or a response 1535 + status code if it recognizes it and implements all specified 1536 + caching-related behavior.<a href="#section-3-4" class="pilcrow">¶</a></p> 1537 + <p id="section-3-5"> 1538 + Note that, in normal operation, some caches will not store a response that 1539 + has neither a cache validator nor an explicit expiration time, as such 1540 + responses are not usually useful to store. However, caches are not 1541 + prohibited from storing such responses.<a href="#section-3-5" class="pilcrow">¶</a></p> 1542 + <div id="storing.fields"> 1543 + <section id="section-3.1"> 1544 + <h3 id="name-storing-header-and-trailer-"> 1545 + <a href="#section-3.1" class="section-number selfRef">3.1. </a><a href="#name-storing-header-and-trailer-" class="section-name selfRef">Storing Header and Trailer Fields</a> 1546 + </h3> 1547 + <p id="section-3.1-1"> 1548 + Caches <span class="bcp14">MUST</span> include all received response header fields -- including 1549 + unrecognized ones -- when storing a response; this assures that new HTTP 1550 + header fields can be successfully deployed. However, the following exceptions 1551 + are made:<a href="#section-3.1-1" class="pilcrow">¶</a></p> 1552 + <ul class="normal"> 1553 + <li class="normal" id="section-3.1-2.1">The Connection header field and fields whose names are listed in it are 1554 + required by <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-7.6.1" class="relref">Section 7.6.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span> to be removed before 1555 + forwarding the message. This <span class="bcp14">MAY</span> be implemented by doing so 1556 + before storage.<a href="#section-3.1-2.1" class="pilcrow">¶</a> 1557 + </li> 1558 + <li class="normal" id="section-3.1-2.2">Likewise, some fields' semantics require them to be removed 1559 + before forwarding the message, and this <span class="bcp14">MAY</span> be implemented by doing so 1560 + before storage; see <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-7.6.1" class="relref">Section 7.6.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span> for some 1561 + examples.<a href="#section-3.1-2.2" class="pilcrow">¶</a> 1562 + </li> 1563 + <li class="normal" id="section-3.1-2.3">The no-cache (<a href="#cache-response-directive.no-cache" class="xref">Section 5.2.2.4</a>) and 1564 + private (<a href="#cache-response-directive.private" class="xref">Section 5.2.2.7</a>) cache 1565 + directives can have arguments that prevent storage of header fields by all 1566 + caches and shared caches, respectively.<a href="#section-3.1-2.3" class="pilcrow">¶</a> 1567 + </li> 1568 + <li class="normal" id="section-3.1-2.4">Header fields that are specific to the proxy that a cache uses when forwarding a request 1569 + <span class="bcp14">MUST NOT</span> be stored, unless the cache incorporates the identity of the 1570 + proxy into the cache key. Effectively, this is limited to Proxy-Authenticate 1571 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-11.7.1" class="relref">Section 11.7.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>), Proxy-Authentication-Info 1572 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-11.7.3" class="relref">Section 11.7.3</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>), and Proxy-Authorization 1573 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-11.7.2" class="relref">Section 11.7.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>).<a href="#section-3.1-2.4" class="pilcrow">¶</a> 1574 + </li> 1575 + </ul> 1576 + <p id="section-3.1-3"> 1577 + Caches <span class="bcp14">MAY</span> either store trailer fields separate from header fields or 1578 + discard them. Caches <span class="bcp14">MUST NOT</span> combine trailer fields with header fields.<a href="#section-3.1-3" class="pilcrow">¶</a></p> 1579 + </section> 1580 + </div> 1581 + <div id="update"> 1582 + <section id="section-3.2"> 1583 + <h3 id="name-updating-stored-header-fiel"> 1584 + <a href="#section-3.2" class="section-number selfRef">3.2. </a><a href="#name-updating-stored-header-fiel" class="section-name selfRef">Updating Stored Header Fields</a> 1585 + </h3> 1586 + <p id="section-3.2-1"> 1587 + Caches are required to update a stored response's header fields from another 1588 + (typically newer) response in several situations; for example, see Sections <a href="#combining.responses" class="xref">3.4</a>, <a href="#freshening.responses" class="xref">4.3.4</a>, and 1589 + <a href="#head.effects" class="xref">4.3.5</a>.<a href="#section-3.2-1" class="pilcrow">¶</a></p> 1590 + <p id="section-3.2-2"> 1591 + When doing so, the cache <span class="bcp14">MUST</span> add each header field in the provided response 1592 + to the stored response, replacing field values that are already present, 1593 + with the following exceptions:<a href="#section-3.2-2" class="pilcrow">¶</a></p> 1594 + <ul class="normal"> 1595 + <li class="normal" id="section-3.2-3.1">Header fields excepted from storage in <a href="#storing.fields" class="xref">Section 3.1</a>,<a href="#section-3.2-3.1" class="pilcrow">¶</a> 1596 + </li> 1597 + <li class="normal" id="section-3.2-3.2">Header fields that the cache's stored response depends upon, as described below,<a href="#section-3.2-3.2" class="pilcrow">¶</a> 1598 + </li> 1599 + <li class="normal" id="section-3.2-3.3">Header fields that are automatically processed and removed by the recipient, as described below, and<a href="#section-3.2-3.3" class="pilcrow">¶</a> 1600 + </li> 1601 + <li class="normal" id="section-3.2-3.4">The Content-Length header field.<a href="#section-3.2-3.4" class="pilcrow">¶</a> 1602 + </li> 1603 + </ul> 1604 + <p id="section-3.2-4"> 1605 + In some cases, caches (especially in user agents) store the results of 1606 + processing the received response, rather than the response itself, 1607 + and updating header fields that affect that processing can result in 1608 + inconsistent behavior and security issues. Caches in this situation <span class="bcp14">MAY</span> 1609 + omit these header fields from updating stored responses on an 1610 + exceptional basis but <span class="bcp14">SHOULD</span> limit such omission to those fields 1611 + necessary to assure integrity of the stored response.<a href="#section-3.2-4" class="pilcrow">¶</a></p> 1612 + <p id="section-3.2-5"> 1613 + For example, a browser might decode the content coding of a response 1614 + while it is being received, creating a disconnect between the data it has 1615 + stored and the response's original metadata. 1616 + Updating that stored metadata with a different Content-Encoding 1617 + header field would be problematic. Likewise, a browser might store a 1618 + post-parse HTML tree rather than the content received in 1619 + the response; updating the Content-Type header field would not be workable 1620 + in this case because any assumptions about the format made in parsing would 1621 + now be invalid.<a href="#section-3.2-5" class="pilcrow">¶</a></p> 1622 + <p id="section-3.2-6"> 1623 + Furthermore, some fields are automatically processed and removed by the 1624 + HTTP implementation, such as the Content-Range header field. 1625 + Implementations <span class="bcp14">MAY</span> automatically omit such header fields from updates, 1626 + even when the processing does not actually occur.<a href="#section-3.2-6" class="pilcrow">¶</a></p> 1627 + <p id="section-3.2-7"> 1628 + Note that the Content-* prefix is not a signal that a header field is omitted 1629 + from update; it is a convention for MIME header fields, not HTTP.<a href="#section-3.2-7" class="pilcrow">¶</a></p> 1630 + </section> 1631 + </div> 1632 + <div id="incomplete.responses"> 1633 + <section id="section-3.3"> 1634 + <h3 id="name-storing-incomplete-response"> 1635 + <a href="#section-3.3" class="section-number selfRef">3.3. </a><a href="#name-storing-incomplete-response" class="section-name selfRef">Storing Incomplete Responses</a> 1636 + </h3> 1637 + <p id="section-3.3-1"> 1638 + If the request method is GET, the response status code is 200 1639 + (OK), and the entire response header section has been received, a 1640 + cache <span class="bcp14">MAY</span> store a response that is not complete (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-6.1" class="relref">Section 6.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) provided that the stored response 1641 + is recorded as being incomplete. Likewise, a 206 (Partial 1642 + Content) response <span class="bcp14">MAY</span> be stored as if it were an incomplete 1643 + 200 (OK) response. However, a cache <span class="bcp14">MUST NOT</span> store 1644 + incomplete or partial-content responses if it does not support the 1645 + Range and Content-Range header fields or if 1646 + it does not understand the range units used in those fields.<a href="#section-3.3-1" class="pilcrow">¶</a></p> 1647 + <p id="section-3.3-2"> 1648 + A cache <span class="bcp14">MAY</span> complete a stored incomplete response by making a subsequent 1649 + range request (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-14.2" class="relref">Section 14.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) and combining the successful response with the 1650 + stored response, as defined in <a href="#combining.responses" class="xref">Section 3.4</a>. A cache 1651 + <span class="bcp14">MUST NOT</span> use an incomplete response to answer requests unless the 1652 + response has been made complete, or the request is partial and specifies a 1653 + range wholly within the incomplete response. A cache <span class="bcp14">MUST NOT</span> 1654 + send a partial response to a client without explicitly marking it 1655 + using the 206 (Partial Content) status code.<a href="#section-3.3-2" class="pilcrow">¶</a></p> 1656 + </section> 1657 + </div> 1658 + <div id="combining.responses"> 1659 + <section id="section-3.4"> 1660 + <h3 id="name-combining-partial-content"> 1661 + <a href="#section-3.4" class="section-number selfRef">3.4. </a><a href="#name-combining-partial-content" class="section-name selfRef">Combining Partial Content</a> 1662 + </h3> 1663 + <p id="section-3.4-1"> 1664 + A response might transfer only a partial representation if the 1665 + connection closed prematurely or if the request used one or more Range 1666 + specifiers (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-14.2" class="relref">Section 14.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>). After several such transfers, a cache might have 1667 + received several ranges of the same representation. A cache <span class="bcp14">MAY</span> combine 1668 + these ranges into a single stored response, and reuse that response to 1669 + satisfy later requests, if they all share the same strong validator and 1670 + the cache complies with the client requirements in <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-15.3.7.3" class="relref">Section 15.3.7.3</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>.<a href="#section-3.4-1" class="pilcrow">¶</a></p> 1671 + <p id="section-3.4-2"> 1672 + When combining the new response with one or more stored responses, a cache 1673 + <span class="bcp14">MUST</span> update the stored response header fields using the header fields 1674 + provided in the new response, as per <a href="#update" class="xref">Section 3.2</a>.<a href="#section-3.4-2" class="pilcrow">¶</a></p> 1675 + </section> 1676 + </div> 1677 + <div id="caching.authenticated.responses"> 1678 + <section id="section-3.5"> 1679 + <h3 id="name-storing-responses-to-authen"> 1680 + <a href="#section-3.5" class="section-number selfRef">3.5. </a><a href="#name-storing-responses-to-authen" class="section-name selfRef">Storing Responses to Authenticated Requests</a> 1681 + </h3> 1682 + <p id="section-3.5-1"> 1683 + A shared cache <span class="bcp14">MUST NOT</span> use a cached response to a request with an 1684 + Authorization header field (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-11.6.2" class="relref">Section 11.6.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) to 1685 + satisfy any subsequent request unless the response contains a 1686 + <a href="#field.cache-control" class="xref">Cache-Control</a> field with a response directive 1687 + (<a href="#cache-response-directive" class="xref">Section 5.2.2</a>) that allows it to be stored by 1688 + a shared cache, and the cache conforms to the requirements of that 1689 + directive for that response.<a href="#section-3.5-1" class="pilcrow">¶</a></p> 1690 + <p id="section-3.5-2"> 1691 + In this specification, the following response directives have such an effect: 1692 + must-revalidate (<a href="#cache-response-directive.must-revalidate" class="xref">Section 5.2.2.2</a>), 1693 + public (<a href="#cache-response-directive.public" class="xref">Section 5.2.2.9</a>), and 1694 + s-maxage (<a href="#cache-response-directive.s-maxage" class="xref">Section 5.2.2.10</a>).<a href="#section-3.5-2" class="pilcrow">¶</a></p> 1695 + </section> 1696 + </div> 1697 + </section> 1698 + </div> 1699 + <div id="constructing.responses.from.caches"> 1700 + <section id="section-4"> 1701 + <h2 id="name-constructing-responses-from"> 1702 + <a href="#section-4" class="section-number selfRef">4. </a><a href="#name-constructing-responses-from" class="section-name selfRef">Constructing Responses from Caches</a> 1703 + </h2> 1704 + <p id="section-4-1"> 1705 + When presented with a request, a cache <span class="bcp14">MUST NOT</span> reuse a stored response 1706 + unless:<a href="#section-4-1" class="pilcrow">¶</a></p> 1707 + <ul class="normal"> 1708 + <li class="normal" id="section-4-2.1"> 1709 + <p id="section-4-2.1.1">the presented target URI (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-7.1" class="relref">Section 7.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) and 1710 + that of the stored response match, and<a href="#section-4-2.1.1" class="pilcrow">¶</a></p> 1711 + </li> 1712 + <li class="normal" id="section-4-2.2"> 1713 + <p id="section-4-2.2.1">the request method associated with the stored response allows it to 1714 + be used for the presented request, and<a href="#section-4-2.2.1" class="pilcrow">¶</a></p> 1715 + </li> 1716 + <li class="normal" id="section-4-2.3"> 1717 + <p id="section-4-2.3.1">request header fields nominated by the stored response (if any) 1718 + match those presented (see <a href="#caching.negotiated.responses" class="xref">Section 4.1</a>), and<a href="#section-4-2.3.1" class="pilcrow">¶</a></p> 1719 + </li> 1720 + <li class="normal" id="section-4-2.4"> 1721 + <p id="section-4-2.4.1">the stored response does not contain the no-cache directive 1722 + (<a href="#cache-response-directive.no-cache" class="xref">Section 5.2.2.4</a>), unless it is 1723 + successfully validated (<a href="#validation.model" class="xref">Section 4.3</a>), and<a href="#section-4-2.4.1" class="pilcrow">¶</a></p> 1724 + </li> 1725 + <li class="normal" id="section-4-2.5"> 1726 + <p id="section-4-2.5.1">the stored response is one of the following:<a href="#section-4-2.5.1" class="pilcrow">¶</a></p> 1727 + <ul class="normal"> 1728 + <li class="normal" id="section-4-2.5.2.1">fresh (see <a href="#expiration.model" class="xref">Section 4.2</a>), or<a href="#section-4-2.5.2.1" class="pilcrow">¶</a> 1729 + </li> 1730 + <li class="normal" id="section-4-2.5.2.2">allowed to be served stale (see <a href="#serving.stale.responses" class="xref">Section 4.2.4</a>), or<a href="#section-4-2.5.2.2" class="pilcrow">¶</a> 1731 + </li> 1732 + <li class="normal" id="section-4-2.5.2.3">successfully validated (see <a href="#validation.model" class="xref">Section 4.3</a>).<a href="#section-4-2.5.2.3" class="pilcrow">¶</a> 1733 + </li> 1734 + </ul> 1735 + </li> 1736 + </ul> 1737 + <p id="section-4-3"> 1738 + Note that a cache extension can override any of the requirements 1739 + listed; see <a href="#cache.control.extensions" class="xref">Section 5.2.3</a>.<a href="#section-4-3" class="pilcrow">¶</a></p> 1740 + <p id="section-4-4"> 1741 + When a stored response is used to satisfy a request without validation, a 1742 + cache <span class="bcp14">MUST</span> generate an <a href="#field.age" class="xref">Age</a> header field (<a href="#field.age" class="xref">Section 5.1</a>), replacing any present in the response with a value 1743 + equal to the stored response's current_age; see <a href="#age.calculations" class="xref">Section 4.2.3</a>.<a href="#section-4-4" class="pilcrow">¶</a></p> 1744 + <p id="section-4-5"> 1745 + A cache <span class="bcp14">MUST</span> write through requests with methods that are unsafe 1746 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1" class="relref">Section 9.2.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) to the origin server; i.e., a cache is not allowed to 1747 + generate a reply to such a request before having forwarded the request and 1748 + having received a corresponding response.<a href="#section-4-5" class="pilcrow">¶</a></p> 1749 + <p id="section-4-6"> 1750 + Also, note that unsafe requests might invalidate already-stored responses; 1751 + see <a href="#invalidation" class="xref">Section 4.4</a>.<a href="#section-4-6" class="pilcrow">¶</a></p> 1752 + <span id="iref-collapsed-requests-8" class="iref"></span> 1753 + <p id="section-4-7"> 1754 + A cache can use a response that is stored or storable to satisfy 1755 + multiple requests, provided that it is allowed to reuse that response 1756 + for the requests in question. This enables a cache to "collapse 1757 + requests" -- or combine multiple incoming requests into a single forward 1758 + request upon a cache miss -- thereby reducing load on the origin server 1759 + and network. Note, however, that if the cache cannot use the returned 1760 + response for some or all of the collapsed requests, it will need to 1761 + forward the requests in order to satisfy them, potentially introducing 1762 + additional latency.<a href="#section-4-7" class="pilcrow">¶</a></p> 1763 + <p id="section-4-8"> 1764 + When more than one suitable response is stored, a cache <span class="bcp14">MUST</span> use the 1765 + most recent one (as determined by the Date header 1766 + field). It can also forward the request with "Cache-Control: max-age=0" or 1767 + "Cache-Control: no-cache" to disambiguate which response to use.<a href="#section-4-8" class="pilcrow">¶</a></p> 1768 + <p id="section-4-9"> 1769 + A cache without a clock (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-5.6.7" class="relref">Section 5.6.7</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) <span class="bcp14">MUST</span> revalidate 1770 + stored responses upon every use.<a href="#section-4-9" class="pilcrow">¶</a></p> 1771 + <div id="caching.negotiated.responses"> 1772 + <section id="section-4.1"> 1773 + <h3 id="name-calculating-cache-keys-with"> 1774 + <a href="#section-4.1" class="section-number selfRef">4.1. </a><a href="#name-calculating-cache-keys-with" class="section-name selfRef">Calculating Cache Keys with the Vary Header Field</a> 1775 + </h3> 1776 + <p id="section-4.1-1"> 1777 + When a cache receives a request that can be satisfied by a stored response 1778 + and that stored response contains a Vary header field 1779 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-12.5.5" class="relref">Section 12.5.5</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>), 1780 + the cache <span class="bcp14">MUST NOT</span> use that stored response without revalidation unless 1781 + all the presented request header fields nominated by that Vary field value 1782 + match those fields in the original request (i.e., the 1783 + request that caused the cached response to be stored).<a href="#section-4.1-1" class="pilcrow">¶</a></p> 1784 + <p id="section-4.1-2"> 1785 + The header fields from two requests are defined to match if 1786 + and only if those in the first request can be transformed to those in the 1787 + second request by applying any of the following:<a href="#section-4.1-2" class="pilcrow">¶</a></p> 1788 + <ul class="normal"> 1789 + <li class="normal" id="section-4.1-3.1"> 1790 + adding or removing whitespace, where allowed in the header field's 1791 + syntax<a href="#section-4.1-3.1" class="pilcrow">¶</a> 1792 + </li> 1793 + <li class="normal" id="section-4.1-3.2"> 1794 + combining multiple header field lines with the same field name 1795 + (see <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-5.2" class="relref">Section 5.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>)<a href="#section-4.1-3.2" class="pilcrow">¶</a> 1796 + </li> 1797 + <li class="normal" id="section-4.1-3.3"> 1798 + normalizing both header field values in a way that is known to have 1799 + identical semantics, according to the header field's specification 1800 + (e.g., reordering field values when order is not significant; 1801 + case-normalization, where values are defined to be case-insensitive)<a href="#section-4.1-3.3" class="pilcrow">¶</a> 1802 + </li> 1803 + </ul> 1804 + <p id="section-4.1-4"> 1805 + If (after any normalization that might take place) a header field is absent 1806 + from a request, it can only match another request if it is also absent 1807 + there.<a href="#section-4.1-4" class="pilcrow">¶</a></p> 1808 + <p id="section-4.1-5"> 1809 + A stored response with a Vary header field value containing 1810 + a member "*" always fails to match.<a href="#section-4.1-5" class="pilcrow">¶</a></p> 1811 + <p id="section-4.1-6"> 1812 + If multiple stored responses match, 1813 + the cache will need to choose one to use. 1814 + When a nominated request header field has a known mechanism for ranking preference 1815 + (e.g., qvalues on Accept and similar request header 1816 + fields), that mechanism <span class="bcp14">MAY</span> be used to choose a preferred response. 1817 + If such a mechanism is not available, or leads to equally preferred 1818 + responses, the most recent 1819 + response (as determined by the Date header field) is 1820 + chosen, as 1821 + per <a href="#constructing.responses.from.caches" class="xref">Section 4</a>.<a href="#section-4.1-6" class="pilcrow">¶</a></p> 1822 + <p id="section-4.1-7"> 1823 + Some resources mistakenly omit the Vary header field from their default 1824 + response (i.e., the one sent when the request does not express any preferences), 1825 + with the effect of choosing it for subsequent requests to that resource 1826 + even when more preferable responses are available. When a cache has 1827 + multiple stored responses for a target URI and one or more omits the Vary 1828 + header field, the cache <span class="bcp14">SHOULD</span> choose the most recent 1829 + (see <a href="#age.calculations" class="xref">Section 4.2.3</a>) stored response with a valid Vary 1830 + field value.<a href="#section-4.1-7" class="pilcrow">¶</a></p> 1831 + <p id="section-4.1-8"> 1832 + If no stored response matches, the cache cannot satisfy the presented 1833 + request. Typically, the request is forwarded to the origin server, 1834 + potentially with preconditions added to describe what responses the cache 1835 + has already stored (<a href="#validation.model" class="xref">Section 4.3</a>).<a href="#section-4.1-8" class="pilcrow">¶</a></p> 1836 + </section> 1837 + </div> 1838 + <div id="expiration.model"> 1839 + <section id="section-4.2"> 1840 + <h3 id="name-freshness"> 1841 + <a href="#section-4.2" class="section-number selfRef">4.2. </a><a href="#name-freshness" class="section-name selfRef">Freshness</a> 1842 + </h3> 1843 + <span id="iref-fresh-9" class="iref"></span> 1844 + <span id="iref-stale-10" class="iref"></span> 1845 + <p id="section-4.2-1"> 1846 + A "fresh" response is one whose age has not yet exceeded its 1847 + freshness lifetime. Conversely, a "stale" response is one where it has.<a href="#section-4.2-1" class="pilcrow">¶</a></p> 1848 + <span id="iref-freshness-lifetime-11" class="iref"></span> 1849 + <span id="iref-explicit-expiration-time-12" class="iref"></span> 1850 + <span id="iref-heuristic-expiration-time-1" class="iref"></span> 1851 + <p id="section-4.2-2"> 1852 + A response's "freshness lifetime" is the length of time 1853 + between its generation by the origin server and its expiration time. An 1854 + "explicit expiration time" is the time at which the origin 1855 + server intends that a stored response can no longer be used by a cache 1856 + without further validation, whereas a "heuristic expiration 1857 + time" is assigned by a cache when no explicit expiration time is 1858 + available.<a href="#section-4.2-2" class="pilcrow">¶</a></p> 1859 + <span id="iref-age-14" class="iref"></span> 1860 + <p id="section-4.2-3"> 1861 + A response's "age" is the time that has passed since it was 1862 + generated by, or successfully validated with, the origin server.<a href="#section-4.2-3" class="pilcrow">¶</a></p> 1863 + <p id="section-4.2-4"> 1864 + When a response is fresh, it can be used to satisfy 1865 + subsequent requests without contacting the origin server, thereby improving 1866 + efficiency.<a href="#section-4.2-4" class="pilcrow">¶</a></p> 1867 + <p id="section-4.2-5"> 1868 + The primary mechanism for determining freshness is for an origin server to 1869 + provide an explicit expiration time in the future, using either the 1870 + <a href="#field.expires" class="xref">Expires</a> header field (<a href="#field.expires" class="xref">Section 5.3</a>) or 1871 + the max-age response directive (<a href="#cache-response-directive.max-age" class="xref">Section 5.2.2.1</a>). Generally, origin servers 1872 + will assign future explicit expiration times to responses in the belief 1873 + that the representation is not likely to change in a semantically 1874 + significant way before the expiration time is reached.<a href="#section-4.2-5" class="pilcrow">¶</a></p> 1875 + <p id="section-4.2-6"> 1876 + If an origin server wishes to force a cache to validate every request, it 1877 + can assign an explicit expiration time in the past to indicate that the 1878 + response is already stale. Compliant caches will normally validate a stale 1879 + cached response before reusing it for subsequent requests (see <a href="#serving.stale.responses" class="xref">Section 4.2.4</a>).<a href="#section-4.2-6" class="pilcrow">¶</a></p> 1880 + <p id="section-4.2-7"> 1881 + Since origin servers do not always provide explicit expiration times, 1882 + caches are also allowed to use a heuristic to determine an expiration time 1883 + under certain circumstances (see <a href="#heuristic.freshness" class="xref">Section 4.2.2</a>).<a href="#section-4.2-7" class="pilcrow">¶</a></p> 1884 + <p id="section-4.2-8"> 1885 + The calculation to determine if a response is fresh is:<a href="#section-4.2-8" class="pilcrow">¶</a></p> 1886 + <div id="section-4.2-9"> 1887 + <pre class="lang-pseudocode sourcecode"> 1888 + response_is_fresh = (freshness_lifetime &gt; current_age) 1889 + </pre><a href="#section-4.2-9" class="pilcrow">¶</a> 1890 + </div> 1891 + <p id="section-4.2-10"> 1892 + freshness_lifetime is defined in <a href="#calculating.freshness.lifetime" class="xref">Section 4.2.1</a>; current_age is defined in 1893 + <a href="#age.calculations" class="xref">Section 4.2.3</a>.<a href="#section-4.2-10" class="pilcrow">¶</a></p> 1894 + <p id="section-4.2-11"> 1895 + Clients can send the max-age or min-fresh request directives (<a href="#cache-request-directive" class="xref">Section 5.2.1</a>) to suggest limits on the freshness 1896 + calculations for the corresponding response. However, caches are not 1897 + required to honor them.<a href="#section-4.2-11" class="pilcrow">¶</a></p> 1898 + <p id="section-4.2-12"> 1899 + When calculating freshness, to avoid common problems in date parsing:<a href="#section-4.2-12" class="pilcrow">¶</a></p> 1900 + <ul class="normal"> 1901 + <li class="normal" id="section-4.2-13.1">Although all date formats are specified to be case-sensitive, 1902 + a cache recipient <span class="bcp14">SHOULD</span> match the field value 1903 + case-insensitively.<a href="#section-4.2-13.1" class="pilcrow">¶</a> 1904 + </li> 1905 + <li class="normal" id="section-4.2-13.2">If a cache recipient's internal implementation of time has less 1906 + resolution than the value of an HTTP-date, the recipient <span class="bcp14">MUST</span> 1907 + internally represent a parsed <a href="#field.expires" class="xref">Expires</a> date as the 1908 + nearest time equal to or earlier than the received value.<a href="#section-4.2-13.2" class="pilcrow">¶</a> 1909 + </li> 1910 + <li class="normal" id="section-4.2-13.3">A cache recipient <span class="bcp14">MUST NOT</span> allow local time zones to influence the 1911 + calculation or comparison of an age or expiration time.<a href="#section-4.2-13.3" class="pilcrow">¶</a> 1912 + </li> 1913 + <li class="normal" id="section-4.2-13.4">A cache recipient <span class="bcp14">SHOULD</span> consider a date with a zone abbreviation 1914 + other than "GMT" to be invalid for calculating expiration.<a href="#section-4.2-13.4" class="pilcrow">¶</a> 1915 + </li> 1916 + </ul> 1917 + <p id="section-4.2-14"> 1918 + Note that freshness applies only to cache operation; it cannot be used to 1919 + force a user agent to refresh its display or reload a resource. See <a href="#history.lists" class="xref">Section 6</a> for an explanation of the difference between 1920 + caches and history mechanisms.<a href="#section-4.2-14" class="pilcrow">¶</a></p> 1921 + <div id="calculating.freshness.lifetime"> 1922 + <section id="section-4.2.1"> 1923 + <h4 id="name-calculating-freshness-lifet"> 1924 + <a href="#section-4.2.1" class="section-number selfRef">4.2.1. </a><a href="#name-calculating-freshness-lifet" class="section-name selfRef">Calculating Freshness Lifetime</a> 1925 + </h4> 1926 + <p id="section-4.2.1-1"> 1927 + A cache can calculate the freshness lifetime (denoted as 1928 + freshness_lifetime) of a response by evaluating the following rules and using the first match:<a href="#section-4.2.1-1" class="pilcrow">¶</a></p> 1929 + <ul class="normal"> 1930 + <li class="normal" id="section-4.2.1-2.1">If the cache is shared and the s-maxage response directive 1931 + (<a href="#cache-response-directive.s-maxage" class="xref">Section 5.2.2.10</a>) is present, use its value, 1932 + or<a href="#section-4.2.1-2.1" class="pilcrow">¶</a> 1933 + </li> 1934 + <li class="normal" id="section-4.2.1-2.2">If the max-age response directive (<a href="#cache-response-directive.max-age" class="xref">Section 5.2.2.1</a>) is present, use its value, or<a href="#section-4.2.1-2.2" class="pilcrow">¶</a> 1935 + </li> 1936 + <li class="normal" id="section-4.2.1-2.3">If the <a href="#field.expires" class="xref">Expires</a> response header field 1937 + (<a href="#field.expires" class="xref">Section 5.3</a>) is present, use its value minus the 1938 + value of the Date response header field 1939 + (using the time the message was received if it is not present, as per <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-6.6.1" class="relref">Section 6.6.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>), or<a href="#section-4.2.1-2.3" class="pilcrow">¶</a> 1940 + </li> 1941 + <li class="normal" id="section-4.2.1-2.4">Otherwise, no explicit expiration time is present in the response. A 1942 + heuristic freshness lifetime might be applicable; see <a href="#heuristic.freshness" class="xref">Section 4.2.2</a>.<a href="#section-4.2.1-2.4" class="pilcrow">¶</a> 1943 + </li> 1944 + </ul> 1945 + <p id="section-4.2.1-3"> 1946 + Note that this calculation is intended to reduce clock skew by using the 1947 + clock information provided by the origin server whenever possible.<a href="#section-4.2.1-3" class="pilcrow">¶</a></p> 1948 + <p id="section-4.2.1-4"> 1949 + When there is more than one value present for a given directive (e.g., two 1950 + <a href="#field.expires" class="xref">Expires</a> header field lines or multiple Cache-Control: max-age 1951 + directives), either the first occurrence should be used or the response should 1952 + be considered stale. If directives conflict (e.g., 1953 + both max-age and no-cache are present), the most restrictive directive should 1954 + be honored. Caches are encouraged to consider responses that have 1955 + invalid freshness information (e.g., a max-age directive with non-integer content) to 1956 + be stale.<a href="#section-4.2.1-4" class="pilcrow">¶</a></p> 1957 + </section> 1958 + </div> 1959 + <div id="heuristic.freshness"> 1960 + <section id="section-4.2.2"> 1961 + <h4 id="name-calculating-heuristic-fresh"> 1962 + <a href="#section-4.2.2" class="section-number selfRef">4.2.2. </a><a href="#name-calculating-heuristic-fresh" class="section-name selfRef">Calculating Heuristic Freshness</a> 1963 + </h4> 1964 + <span id="iref-heuristically-cacheable-15" class="iref"></span> 1965 + <p id="section-4.2.2-1"> 1966 + Since origin servers do not always provide explicit expiration times, a 1967 + cache <span class="bcp14">MAY</span> assign a heuristic expiration time when an explicit time is not 1968 + specified, employing algorithms that use other field values (such as 1969 + the Last-Modified time) to estimate a plausible expiration 1970 + time. This specification does not provide specific algorithms, but it does 1971 + impose worst-case constraints on their results.<a href="#section-4.2.2-1" class="pilcrow">¶</a></p> 1972 + <p id="section-4.2.2-2"> 1973 + A cache <span class="bcp14">MUST NOT</span> use heuristics to determine freshness when an explicit 1974 + expiration time is present in the stored response. Because of the 1975 + requirements in <a href="#response.cacheability" class="xref">Section 3</a>, 1976 + heuristics can only be used on responses without explicit 1977 + freshness whose status codes are defined as "heuristically cacheable" (e.g., see 1978 + <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-15.1" class="relref">Section 15.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) and on responses without 1979 + explicit freshness that have been marked as explicitly cacheable (e.g., 1980 + with a public response directive).<a href="#section-4.2.2-2" class="pilcrow">¶</a></p> 1981 + <p id="section-4.2.2-3"> 1982 + Note that in previous specifications, heuristically cacheable response status 1983 + codes were called "cacheable by default".<a href="#section-4.2.2-3" class="pilcrow">¶</a></p> 1984 + <p id="section-4.2.2-4"> 1985 + If the response has a Last-Modified header field 1986 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-8.8.2" class="relref">Section 8.8.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>), caches are encouraged to use a heuristic 1987 + expiration value that is no more than some fraction of the interval since 1988 + that time. A typical setting of this fraction might be 10%.<a href="#section-4.2.2-4" class="pilcrow">¶</a></p> 1989 + <aside id="section-4.2.2-5"> 1990 + <p id="section-4.2.2-5.1"> 1991 + <strong>Note:</strong> 1992 + A previous version of the HTTP specification 1993 + (<span><a href="https://www.rfc-editor.org/rfc/rfc2616#section-13.9" class="relref">Section 13.9</a> of [<a href="#RFC2616" class="xref">RFC2616</a>]</span>) prohibited caches 1994 + from calculating heuristic freshness for URIs with query components 1995 + (i.e., those containing "?"). In practice, this has not been widely 1996 + implemented. Therefore, origin servers are encouraged to send explicit 1997 + directives (e.g., Cache-Control: no-cache) if they wish to prevent 1998 + caching.<a href="#section-4.2.2-5.1" class="pilcrow">¶</a></p> 1999 + </aside> 2000 + </section> 2001 + </div> 2002 + <div id="age.calculations"> 2003 + <section id="section-4.2.3"> 2004 + <h4 id="name-calculating-age"> 2005 + <a href="#section-4.2.3" class="section-number selfRef">4.2.3. </a><a href="#name-calculating-age" class="section-name selfRef">Calculating Age</a> 2006 + </h4> 2007 + <p id="section-4.2.3-1"> 2008 + The <a href="#field.age" class="xref">Age</a> header field is used to convey an estimated 2009 + age of the response message when obtained from a cache. The Age field value 2010 + is the cache's estimate of the number of seconds since the origin server generated 2011 + or validated the response. The Age value is therefore 2012 + the sum of the time that the response has been resident in each of the 2013 + caches along the path from the origin server, plus the time it 2014 + has been in transit along network paths.<a href="#section-4.2.3-1" class="pilcrow">¶</a></p> 2015 + <p id="section-4.2.3-2"> 2016 + Age calculation uses the following data:<a href="#section-4.2.3-2" class="pilcrow">¶</a></p> 2017 + <span class="break"></span><dl class="dlNewline" id="section-4.2.3-3"> 2018 + <dt id="section-4.2.3-3.1"> 2019 + "age_value" 2020 + </dt> 2021 + <dd style="margin-left: 1.5em" id="section-4.2.3-3.2"> 2022 + The term "age_value" denotes the value of the <a href="#field.age" class="xref">Age</a> 2023 + header field (<a href="#field.age" class="xref">Section 5.1</a>), in a form appropriate for 2024 + arithmetic operation; or 0, if not available.<a href="#section-4.2.3-3.2" class="pilcrow">¶</a> 2025 + </dd> 2026 + <dd class="break"></dd> 2027 + <dt id="section-4.2.3-3.3"> 2028 + "date_value" 2029 + </dt> 2030 + <dd style="margin-left: 1.5em" id="section-4.2.3-3.4"> 2031 + The term "date_value" denotes the value of 2032 + the Date header field, in a form appropriate for arithmetic 2033 + operations. See <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-6.6.1" class="relref">Section 6.6.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span> for the definition of the Date header 2034 + field and for requirements regarding responses without it.<a href="#section-4.2.3-3.4" class="pilcrow">¶</a> 2035 + </dd> 2036 + <dd class="break"></dd> 2037 + <dt id="section-4.2.3-3.5"> 2038 + "now" 2039 + </dt> 2040 + <dd style="margin-left: 1.5em" id="section-4.2.3-3.6"> 2041 + The term "now" means the current value of this implementation's clock 2042 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-5.6.7" class="relref">Section 5.6.7</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>).<a href="#section-4.2.3-3.6" class="pilcrow">¶</a> 2043 + </dd> 2044 + <dd class="break"></dd> 2045 + <dt id="section-4.2.3-3.7"> 2046 + "request_time" 2047 + </dt> 2048 + <dd style="margin-left: 1.5em" id="section-4.2.3-3.8"> 2049 + The value of the clock at the time of the request that 2050 + resulted in the stored response.<a href="#section-4.2.3-3.8" class="pilcrow">¶</a> 2051 + </dd> 2052 + <dd class="break"></dd> 2053 + <dt id="section-4.2.3-3.9"> 2054 + "response_time" 2055 + </dt> 2056 + <dd style="margin-left: 1.5em" id="section-4.2.3-3.10"> 2057 + The value of the clock at the time the response 2058 + was received.<a href="#section-4.2.3-3.10" class="pilcrow">¶</a> 2059 + </dd> 2060 + <dd class="break"></dd> 2061 + </dl> 2062 + <p id="section-4.2.3-4"> 2063 + A response's age can be calculated in two entirely independent ways:<a href="#section-4.2.3-4" class="pilcrow">¶</a></p> 2064 + <ol start="1" type="1" class="normal type-1" id="section-4.2.3-5"> 2065 + <li id="section-4.2.3-5.1">the "apparent_age": response_time minus date_value, if the 2066 + implementation's 2067 + clock is reasonably well synchronized to the origin server's clock. If 2068 + the result is negative, the result is replaced by zero.<a href="#section-4.2.3-5.1" class="pilcrow">¶</a> 2069 + </li> 2070 + <li id="section-4.2.3-5.2">the "corrected_age_value", if all of the caches along the response 2071 + path implement HTTP/1.1 or greater. A cache <span class="bcp14">MUST</span> interpret this value 2072 + relative to the time the request was initiated, not the time that the 2073 + response was received.<a href="#section-4.2.3-5.2" class="pilcrow">¶</a> 2074 + </li> 2075 + </ol> 2076 + <div id="section-4.2.3-6"> 2077 + <pre class="lang-pseudocode sourcecode"> 2078 + apparent_age = max(0, response_time - date_value); 2079 + 2080 + response_delay = response_time - request_time; 2081 + corrected_age_value = age_value + response_delay; 2082 + </pre><a href="#section-4.2.3-6" class="pilcrow">¶</a> 2083 + </div> 2084 + <p id="section-4.2.3-7"> 2085 + The corrected_age_value <span class="bcp14">MAY</span> be used as the corrected_initial_age. In 2086 + circumstances where very old cache implementations that might not correctly 2087 + insert <a href="#field.age" class="xref">Age</a> are present, corrected_initial_age can be calculated 2088 + more conservatively as<a href="#section-4.2.3-7" class="pilcrow">¶</a></p> 2089 + <div id="section-4.2.3-8"> 2090 + <pre class="lang-pseudocode sourcecode"> 2091 + corrected_initial_age = max(apparent_age, corrected_age_value); 2092 + </pre><a href="#section-4.2.3-8" class="pilcrow">¶</a> 2093 + </div> 2094 + <p id="section-4.2.3-9"> 2095 + The current_age of a stored response can then be calculated by adding the 2096 + time (in seconds) since the stored response was last validated by 2097 + the origin server to the corrected_initial_age.<a href="#section-4.2.3-9" class="pilcrow">¶</a></p> 2098 + <div id="section-4.2.3-10"> 2099 + <pre class="lang-pseudocode sourcecode"> 2100 + resident_time = now - response_time; 2101 + current_age = corrected_initial_age + resident_time; 2102 + </pre><a href="#section-4.2.3-10" class="pilcrow">¶</a> 2103 + </div> 2104 + </section> 2105 + </div> 2106 + <div id="serving.stale.responses"> 2107 + <section id="section-4.2.4"> 2108 + <h4 id="name-serving-stale-responses"> 2109 + <a href="#section-4.2.4" class="section-number selfRef">4.2.4. </a><a href="#name-serving-stale-responses" class="section-name selfRef">Serving Stale Responses</a> 2110 + </h4> 2111 + <p id="section-4.2.4-1"> 2112 + A "stale" response is one that either has explicit expiry information or is 2113 + allowed to have heuristic expiry calculated, but is not fresh according to 2114 + the calculations in <a href="#expiration.model" class="xref">Section 4.2</a>.<a href="#section-4.2.4-1" class="pilcrow">¶</a></p> 2115 + <p id="section-4.2.4-2"> 2116 + A cache <span class="bcp14">MUST NOT</span> generate a stale response if it is prohibited by an 2117 + explicit in-protocol directive (e.g., by a no-cache response 2118 + directive, a must-revalidate response directive, or an applicable 2119 + s-maxage or proxy-revalidate response directive; see <a href="#cache-response-directive" class="xref">Section 5.2.2</a>).<a href="#section-4.2.4-2" class="pilcrow">¶</a></p> 2120 + <p id="section-4.2.4-3"> 2121 + A cache <span class="bcp14">MUST NOT</span> generate a stale response unless it is disconnected 2122 + or doing so is explicitly permitted by the client or origin server 2123 + (e.g., by the max-stale request directive in <a href="#cache-request-directive" class="xref">Section 5.2.1</a>, extension directives such as those 2124 + defined in <span>[<a href="#RFC5861" class="xref">RFC5861</a>]</span>, or configuration in accordance 2125 + with an out-of-band contract).<a href="#section-4.2.4-3" class="pilcrow">¶</a></p> 2126 + </section> 2127 + </div> 2128 + </section> 2129 + </div> 2130 + <div id="validation.model"> 2131 + <section id="section-4.3"> 2132 + <h3 id="name-validation"> 2133 + <a href="#section-4.3" class="section-number selfRef">4.3. </a><a href="#name-validation" class="section-name selfRef">Validation</a> 2134 + </h3> 2135 + <p id="section-4.3-1"> 2136 + When a cache has one or more stored responses for a requested URI, but 2137 + cannot serve any of them (e.g., because they are not fresh, or one cannot 2138 + be chosen; see <a href="#caching.negotiated.responses" class="xref">Section 4.1</a>), it can use 2139 + the conditional request mechanism (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-13" class="relref">Section 13</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) in the forwarded request to 2140 + give the next inbound server an opportunity to choose a valid stored 2141 + response to use, updating the stored metadata in the process, or to replace 2142 + the stored response(s) with a new response. This process is known as 2143 + "validating" or "revalidating" the stored 2144 + response.<a href="#section-4.3-1" class="pilcrow">¶</a></p> 2145 + <div id="validation.sent"> 2146 + <section id="section-4.3.1"> 2147 + <h4 id="name-sending-a-validation-reques"> 2148 + <a href="#section-4.3.1" class="section-number selfRef">4.3.1. </a><a href="#name-sending-a-validation-reques" class="section-name selfRef">Sending a Validation Request</a> 2149 + </h4> 2150 + <span id="iref-validator-16" class="iref"></span> 2151 + <p id="section-4.3.1-1"> 2152 + When generating a conditional request for validation, a cache either starts with 2153 + a request it is attempting to satisfy or -- if it is initiating 2154 + the request independently -- synthesizes a request using a stored 2155 + response by copying the method, target URI, and request header fields 2156 + identified by the Vary header field (<a href="#caching.negotiated.responses" class="xref">Section 4.1</a>).<a href="#section-4.3.1-1" class="pilcrow">¶</a></p> 2157 + <p id="section-4.3.1-2"> 2158 + It then updates that request with one or more precondition header fields. 2159 + These contain validator metadata sourced from a stored response(s) that has 2160 + the same URI. Typically, this will include only the stored response(s) that 2161 + has the same cache key, although a cache is allowed to validate 2162 + a response that it cannot choose with the request header fields it is sending 2163 + (see <a href="#caching.negotiated.responses" class="xref">Section 4.1</a>).<a href="#section-4.3.1-2" class="pilcrow">¶</a></p> 2164 + <p id="section-4.3.1-3"> 2165 + The precondition header fields are then compared by recipients to 2166 + determine whether any stored response is equivalent to a current 2167 + representation of the resource.<a href="#section-4.3.1-3" class="pilcrow">¶</a></p> 2168 + <p id="section-4.3.1-4"> 2169 + One such validator is the timestamp given in a Last-Modified 2170 + header field (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-8.8.2" class="relref">Section 8.8.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>), which can be used in an 2171 + If-Modified-Since header field for response validation, or 2172 + in an If-Unmodified-Since or If-Range header 2173 + field for representation selection (i.e., the client is referring 2174 + specifically to a previously obtained representation with that timestamp).<a href="#section-4.3.1-4" class="pilcrow">¶</a></p> 2175 + <p id="section-4.3.1-5"> 2176 + Another validator is the entity tag given in an ETag 2177 + field (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-8.8.3" class="relref">Section 8.8.3</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>). One or more entity tags, indicating one or more 2178 + stored responses, can be used in an If-None-Match header 2179 + field for response validation, or in an If-Match or 2180 + If-Range header field for representation selection (i.e., 2181 + the client is referring specifically to one or more previously obtained 2182 + representations with the listed entity tags).<a href="#section-4.3.1-5" class="pilcrow">¶</a></p> 2183 + <p id="section-4.3.1-6"> 2184 + When generating a conditional request for validation, a cache:<a href="#section-4.3.1-6" class="pilcrow">¶</a></p> 2185 + <ul class="normal"> 2186 + <li class="normal" id="section-4.3.1-7.1"> 2187 + <span class="bcp14">MUST</span> send the relevant entity tags 2188 + (using If-Match, If-None-Match, or 2189 + If-Range) if the entity tags were provided in the 2190 + stored response(s) being validated.<a href="#section-4.3.1-7.1" class="pilcrow">¶</a> 2191 + </li> 2192 + <li class="normal" id="section-4.3.1-7.2"> 2193 + <span class="bcp14">SHOULD</span> send the Last-Modified value (using 2194 + If-Modified-Since) if the request is not for a subrange, 2195 + a single stored response is being validated, and that response 2196 + contains a Last-Modified value.<a href="#section-4.3.1-7.2" class="pilcrow">¶</a> 2197 + </li> 2198 + <li class="normal" id="section-4.3.1-7.3"> 2199 + <span class="bcp14">MAY</span> send the Last-Modified value (using 2200 + If-Unmodified-Since or If-Range) if 2201 + the request is for a subrange, a single stored response is being 2202 + validated, and that response contains only a Last-Modified value 2203 + (not an entity tag).<a href="#section-4.3.1-7.3" class="pilcrow">¶</a> 2204 + </li> 2205 + </ul> 2206 + <p id="section-4.3.1-8"> 2207 + In most cases, both validators are generated in cache validation requests, 2208 + even when entity tags are clearly superior, to allow old intermediaries 2209 + that do not understand entity tag preconditions to respond appropriately.<a href="#section-4.3.1-8" class="pilcrow">¶</a></p> 2210 + </section> 2211 + </div> 2212 + <div id="validation.received"> 2213 + <section id="section-4.3.2"> 2214 + <h4 id="name-handling-a-received-validat"> 2215 + <a href="#section-4.3.2" class="section-number selfRef">4.3.2. </a><a href="#name-handling-a-received-validat" class="section-name selfRef">Handling a Received Validation Request</a> 2216 + </h4> 2217 + <p id="section-4.3.2-1"> 2218 + Each client in the request chain may have its own cache, so it is common 2219 + for a cache at an intermediary to receive conditional requests from other 2220 + (outbound) caches. Likewise, some user agents make use of conditional 2221 + requests to limit data transfers to recently modified representations or to 2222 + complete the transfer of a partially retrieved representation.<a href="#section-4.3.2-1" class="pilcrow">¶</a></p> 2223 + <p id="section-4.3.2-2"> 2224 + If a cache receives a request that can be satisfied by reusing a stored 2225 + 200 (OK) or 206 (Partial Content) 2226 + response, as per <a href="#constructing.responses.from.caches" class="xref">Section 4</a>, 2227 + the cache <span class="bcp14">SHOULD</span> evaluate any applicable conditional header 2228 + field preconditions received in that request with respect to the 2229 + corresponding validators contained within the stored response.<a href="#section-4.3.2-2" class="pilcrow">¶</a></p> 2230 + <p id="section-4.3.2-3"> 2231 + A cache <span class="bcp14">MUST NOT</span> evaluate conditional header fields that only 2232 + apply to an origin server, occur in a request with semantics that 2233 + cannot be satisfied with a cached response, or occur in a request with a target resource 2234 + for which it has no stored responses; such preconditions are likely 2235 + intended for some other (inbound) server.<a href="#section-4.3.2-3" class="pilcrow">¶</a></p> 2236 + <p id="section-4.3.2-4"> 2237 + The proper evaluation of conditional requests by a cache depends on the 2238 + received precondition header fields and their precedence. In summary, the If-Match and 2239 + If-Unmodified-Since conditional header fields are not 2240 + applicable to a cache, and If-None-Match takes precedence over 2241 + If-Modified-Since. See <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-13.2.2" class="relref">Section 13.2.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span> for 2242 + a complete specification of precondition precedence.<a href="#section-4.3.2-4" class="pilcrow">¶</a></p> 2243 + <p id="section-4.3.2-5"> 2244 + A request containing an If-None-Match header field (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-13.1.2" class="relref">Section 13.1.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) indicates that the client wants to 2245 + validate one or more of its own stored responses in comparison to the 2246 + stored response chosen by the cache (as per <a href="#constructing.responses.from.caches" class="xref">Section 4</a>).<a href="#section-4.3.2-5" class="pilcrow">¶</a></p> 2247 + <p id="section-4.3.2-6"> 2248 + If an If-None-Match header field is not present, a request 2249 + containing an If-Modified-Since header field 2250 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-13.1.3" class="relref">Section 13.1.3</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) indicates that the client wants to validate 2251 + one or more of its own stored responses by modification date.<a href="#section-4.3.2-6" class="pilcrow">¶</a></p> 2252 + <p id="section-4.3.2-7"> 2253 + If a request contains an If-Modified-Since header field and 2254 + the Last-Modified header field is not present in a 2255 + stored response, a cache <span class="bcp14">SHOULD</span> use the stored response's 2256 + Date field value (or, if no Date field is present, the time 2257 + that the stored response was received) to evaluate the conditional.<a href="#section-4.3.2-7" class="pilcrow">¶</a></p> 2258 + <p id="section-4.3.2-8"> 2259 + A cache that implements partial responses to range requests, as defined in 2260 + <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-14.2" class="relref">Section 14.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>, also needs to evaluate a received 2261 + If-Range header field (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-13.1.5" class="relref">Section 13.1.5</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) 2262 + with respect to the cache's chosen response.<a href="#section-4.3.2-8" class="pilcrow">¶</a></p> 2263 + <p id="section-4.3.2-9"> 2264 + When a cache decides to forward a request to revalidate its own stored 2265 + responses for a 2266 + request that contains an If-None-Match list of entity tags, 2267 + the cache <span class="bcp14">MAY</span> combine the received list with a list of entity tags 2268 + from its own stored set of responses (fresh or stale) and send the union of 2269 + the two lists as a replacement If-None-Match header 2270 + field value in the forwarded request. 2271 + If a stored response contains only partial content, the 2272 + cache <span class="bcp14">MUST NOT</span> include its entity tag in the union unless the request is 2273 + for a range that would be fully satisfied by that partial stored response. 2274 + If the response to the forwarded request is 2275 + 304 (Not Modified) and has an ETag field value with 2276 + an entity tag that is not in the client's list, the cache <span class="bcp14">MUST</span> 2277 + generate a 200 (OK) response for the client by reusing its 2278 + corresponding stored response, as updated by the 304 response metadata 2279 + (<a href="#freshening.responses" class="xref">Section 4.3.4</a>).<a href="#section-4.3.2-9" class="pilcrow">¶</a></p> 2280 + </section> 2281 + </div> 2282 + <div id="validation.response"> 2283 + <section id="section-4.3.3"> 2284 + <h4 id="name-handling-a-validation-respo"> 2285 + <a href="#section-4.3.3" class="section-number selfRef">4.3.3. </a><a href="#name-handling-a-validation-respo" class="section-name selfRef">Handling a Validation Response</a> 2286 + </h4> 2287 + <p id="section-4.3.3-1"> 2288 + Cache handling of a response to a conditional request depends upon its 2289 + status code:<a href="#section-4.3.3-1" class="pilcrow">¶</a></p> 2290 + <ul class="normal"> 2291 + <li class="normal" id="section-4.3.3-2.1"> 2292 + A 304 (Not Modified) response status code indicates 2293 + that the stored response can be updated and reused; see <a href="#freshening.responses" class="xref">Section 4.3.4</a>.<a href="#section-4.3.3-2.1" class="pilcrow">¶</a> 2294 + </li> 2295 + <li class="normal" id="section-4.3.3-2.2"> 2296 + A full response (i.e., one containing content) indicates that none 2297 + of the stored responses nominated in the conditional request are 2298 + suitable. Instead, the cache <span class="bcp14">MUST</span> use the full response to 2299 + satisfy the request. The cache <span class="bcp14">MAY</span> store such a full response, 2300 + subject to its constraints (see <a href="#response.cacheability" class="xref">Section 3</a>).<a href="#section-4.3.3-2.2" class="pilcrow">¶</a> 2301 + </li> 2302 + <li class="normal" id="section-4.3.3-2.3"> 2303 + However, if a cache receives a 5xx (Server Error) 2304 + response while attempting to validate a response, it can either 2305 + forward this response to the requesting client or act as if the 2306 + server failed to respond. In the latter case, the cache can send a 2307 + previously stored response, subject to its constraints on doing so (see <a href="#serving.stale.responses" class="xref">Section 4.2.4</a>), or retry the validation request.<a href="#section-4.3.3-2.3" class="pilcrow">¶</a> 2308 + </li> 2309 + </ul> 2310 + </section> 2311 + </div> 2312 + <div id="freshening.responses"> 2313 + <section id="section-4.3.4"> 2314 + <h4 id="name-freshening-stored-responses"> 2315 + <a href="#section-4.3.4" class="section-number selfRef">4.3.4. </a><a href="#name-freshening-stored-responses" class="section-name selfRef">Freshening Stored Responses upon Validation</a> 2316 + </h4> 2317 + <p id="section-4.3.4-1"> 2318 + When a cache receives a 304 (Not Modified) response, it needs 2319 + to identify stored responses that are suitable for updating with the new information 2320 + provided, and then do so.<a href="#section-4.3.4-1" class="pilcrow">¶</a></p> 2321 + <p id="section-4.3.4-2"> 2322 + The initial set of stored responses to update are those that could have been chosen for 2323 + that request -- i.e., those that meet the requirements in <a href="#constructing.responses.from.caches" class="xref">Section 4</a>, except the last requirement 2324 + to be fresh, able to be served stale, or just validated.<a href="#section-4.3.4-2" class="pilcrow">¶</a></p> 2325 + <p id="section-4.3.4-3"> 2326 + Then, that initial set of stored responses is further filtered by the first match of:<a href="#section-4.3.4-3" class="pilcrow">¶</a></p> 2327 + <ul class="normal"> 2328 + <li class="normal" id="section-4.3.4-4.1"> 2329 + If the new response contains one or more "strong validators" (see 2330 + <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-8.8.1" class="relref">Section 8.8.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>), then each of those strong validators 2331 + identifies a selected representation for update. All the stored 2332 + responses in the initial set with one of those same strong validators are identified for update. If 2333 + none of the initial set contains at least one of the same strong validators, then the 2334 + cache <span class="bcp14">MUST NOT</span> use the new response to update any stored responses.<a href="#section-4.3.4-4.1" class="pilcrow">¶</a> 2335 + </li> 2336 + <li class="normal" id="section-4.3.4-4.2"> 2337 + If the new response contains no strong validators but does contain 2338 + one or more "weak validators", and those 2339 + validators correspond to one of the initial set's stored responses, then the most 2340 + recent of those matching stored responses is identified for update.<a href="#section-4.3.4-4.2" class="pilcrow">¶</a> 2341 + </li> 2342 + <li class="normal" id="section-4.3.4-4.3"> 2343 + If the new response does not include any form of validator (such as 2344 + where a client generates an If-Modified-Since request from 2345 + a source other than the Last-Modified response header 2346 + field), and there is only one stored response in the initial set, and that stored response 2347 + also lacks a validator, then that stored response is identified for update.<a href="#section-4.3.4-4.3" class="pilcrow">¶</a> 2348 + </li> 2349 + </ul> 2350 + <p id="section-4.3.4-5"> 2351 + For each stored response identified, the cache <span class="bcp14">MUST</span> update 2352 + its header fields with the header fields provided in the 304 (Not 2353 + Modified) response, as per <a href="#update" class="xref">Section 3.2</a>.<a href="#section-4.3.4-5" class="pilcrow">¶</a></p> 2354 + </section> 2355 + </div> 2356 + <div id="head.effects"> 2357 + <section id="section-4.3.5"> 2358 + <h4 id="name-freshening-responses-with-h"> 2359 + <a href="#section-4.3.5" class="section-number selfRef">4.3.5. </a><a href="#name-freshening-responses-with-h" class="section-name selfRef">Freshening Responses with HEAD</a> 2360 + </h4> 2361 + <p id="section-4.3.5-1"> 2362 + A response to the HEAD method is identical to what an equivalent request 2363 + made with a GET would have been, without sending the content. This property 2364 + of HEAD responses can be used to invalidate or update a cached GET 2365 + response if the more efficient conditional GET request mechanism is not 2366 + available (due to no validators being present in the stored response) or 2367 + if transmission of the content is not desired even if it has 2368 + changed.<a href="#section-4.3.5-1" class="pilcrow">¶</a></p> 2369 + <p id="section-4.3.5-2"> 2370 + When a cache makes an inbound HEAD request for a target URI and 2371 + receives a 200 (OK) response, the cache <span class="bcp14">SHOULD</span> update or 2372 + invalidate each of its stored GET responses that could have been chosen 2373 + for that request (see <a href="#caching.negotiated.responses" class="xref">Section 4.1</a>).<a href="#section-4.3.5-2" class="pilcrow">¶</a></p> 2374 + <p id="section-4.3.5-3"> 2375 + For each of the stored responses that could have been chosen, if the 2376 + stored response and HEAD response have matching values for any received 2377 + validator fields (ETag and Last-Modified) 2378 + and, if the HEAD response has a Content-Length header field, 2379 + the value of Content-Length matches that of the stored 2380 + response, the cache <span class="bcp14">SHOULD</span> update the stored response as described below; 2381 + otherwise, the cache <span class="bcp14">SHOULD</span> consider the stored response to be stale.<a href="#section-4.3.5-3" class="pilcrow">¶</a></p> 2382 + <p id="section-4.3.5-4"> 2383 + If a cache updates a stored response with the metadata provided in a HEAD 2384 + response, the cache <span class="bcp14">MUST</span> use the header fields provided in the HEAD 2385 + response to update the stored response (see <a href="#update" class="xref">Section 3.2</a>).<a href="#section-4.3.5-4" class="pilcrow">¶</a></p> 2386 + </section> 2387 + </div> 2388 + </section> 2389 + </div> 2390 + <div id="invalidation"> 2391 + <section id="section-4.4"> 2392 + <h3 id="name-invalidating-stored-respons"> 2393 + <a href="#section-4.4" class="section-number selfRef">4.4. </a><a href="#name-invalidating-stored-respons" class="section-name selfRef">Invalidating Stored Responses</a> 2394 + </h3> 2395 + <p id="section-4.4-1"> 2396 + Because unsafe request methods (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1" class="relref">Section 9.2.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) such as PUT, POST, or DELETE 2397 + have the potential for changing state on the origin server, intervening 2398 + caches are required to invalidate stored responses to keep their contents up to date.<a href="#section-4.4-1" class="pilcrow">¶</a></p> 2399 + <p id="section-4.4-2"> 2400 + A cache <span class="bcp14">MUST</span> invalidate the target URI 2401 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-7.1" class="relref">Section 7.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) when it receives a non-error status 2402 + code in response to 2403 + an unsafe request method (including methods whose safety is unknown).<a href="#section-4.4-2" class="pilcrow">¶</a></p> 2404 + <p id="section-4.4-3"> 2405 + A cache <span class="bcp14">MAY</span> invalidate other URIs when it receives a non-error status 2406 + code in response to an unsafe request method (including methods whose 2407 + safety is unknown). 2408 + In particular, the URI(s) in the 2409 + Location and Content-Location response header 2410 + fields (if present) are candidates for invalidation; other URIs might be 2411 + discovered through mechanisms not specified in this document. 2412 + However, a cache <span class="bcp14">MUST NOT</span> trigger an invalidation under these conditions 2413 + if the origin (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-4.3.1" class="relref">Section 4.3.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) of the URI to be invalidated differs from that of the target URI 2414 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-7.1" class="relref">Section 7.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>). This helps prevent denial-of-service attacks.<a href="#section-4.4-3" class="pilcrow">¶</a></p> 2415 + <p id="section-4.4-4"> 2416 + "Invalidate" means that the cache will either remove all 2417 + stored responses whose target URI matches the given URI or mark them 2418 + as "invalid" and in need of a mandatory validation before they can be sent 2419 + in response to a subsequent request.<a href="#section-4.4-4" class="pilcrow">¶</a></p> 2420 + <p id="section-4.4-5"> 2421 + A "non-error response" is one with a 2xx (Successful) 2422 + or 3xx (Redirection) status code.<a href="#section-4.4-5" class="pilcrow">¶</a></p> 2423 + <p id="section-4.4-6"> 2424 + Note that this does not guarantee that all appropriate responses are 2425 + invalidated globally; a state-changing request would only invalidate 2426 + responses in the caches it travels through.<a href="#section-4.4-6" class="pilcrow">¶</a></p> 2427 + </section> 2428 + </div> 2429 + </section> 2430 + </div> 2431 + <div id="header.field.definitions"> 2432 + <section id="section-5"> 2433 + <h2 id="name-field-definitions"> 2434 + <a href="#section-5" class="section-number selfRef">5. </a><a href="#name-field-definitions" class="section-name selfRef">Field Definitions</a> 2435 + </h2> 2436 + <p id="section-5-1"> 2437 + This section defines the syntax and semantics of HTTP fields 2438 + related to caching.<a href="#section-5-1" class="pilcrow">¶</a></p> 2439 + <div id="field.age"> 2440 + <section id="section-5.1"> 2441 + <h3 id="name-age"> 2442 + <a href="#section-5.1" class="section-number selfRef">5.1. </a><a href="#name-age" class="section-name selfRef">Age</a> 2443 + </h3> 2444 + <span id="iref-fields-age-17" class="iref"></span> 2445 + <span id="iref-header-fields-age-18" class="iref"></span> 2446 + <span id="iref-fields-age-19" class="iref"></span> 2447 + <span id="iref-header-fields-age-20" class="iref"></span> 2448 + <span id="iref-age-header-field-21" class="iref"></span> 2449 + <p id="section-5.1-1"> 2450 + The "Age" response header field conveys the sender's estimate of the 2451 + time since the response was generated or successfully validated at the 2452 + origin server. Age values are calculated as specified in <a href="#age.calculations" class="xref">Section 4.2.3</a>.<a href="#section-5.1-1" class="pilcrow">¶</a></p> 2453 + <span id="iref-grammar-age-22" class="iref"></span> 2454 + <div id="section-5.1-2"> 2455 + <pre class="lang-abnf9110 sourcecode"> Age = delta-seconds 2456 + </pre><a href="#section-5.1-2" class="pilcrow">¶</a> 2457 + </div> 2458 + <p id="section-5.1-3"> 2459 + The Age field value is a non-negative integer, representing time in seconds 2460 + (see <a href="#delta-seconds" class="xref">Section 1.2.2</a>).<a href="#section-5.1-3" class="pilcrow">¶</a></p> 2461 + <p id="section-5.1-4"> 2462 + Although it is defined as a singleton header field, a cache encountering a 2463 + message with a list-based Age field value <span class="bcp14">SHOULD</span> use the 2464 + first member of the field value, discarding subsequent ones.<a href="#section-5.1-4" class="pilcrow">¶</a></p> 2465 + <p id="section-5.1-5"> 2466 + If the field value (after discarding additional members, as per above) is invalid 2467 + (e.g., it contains something other than a non-negative integer), 2468 + a cache <span class="bcp14">SHOULD</span> ignore the field.<a href="#section-5.1-5" class="pilcrow">¶</a></p> 2469 + <p id="section-5.1-6"> 2470 + The presence of an Age header field implies that the response was not 2471 + generated or validated by the origin server for this request. However, 2472 + lack of an Age header field does not imply the origin was contacted.<a href="#section-5.1-6" class="pilcrow">¶</a></p> 2473 + </section> 2474 + </div> 2475 + <div id="field.cache-control"> 2476 + <section id="section-5.2"> 2477 + <h3 id="name-cache-control"> 2478 + <a href="#section-5.2" class="section-number selfRef">5.2. </a><a href="#name-cache-control" class="section-name selfRef">Cache-Control</a> 2479 + </h3> 2480 + <span id="iref-fields-cache-control-23" class="iref"></span> 2481 + <span id="iref-header-fields-cache-control" class="iref"></span> 2482 + <span id="iref-cache-control-header-field-" class="iref"></span> 2483 + <p id="section-5.2-1"> 2484 + The "Cache-Control" header field is used to list directives for caches 2485 + along the request/response chain. Cache directives are unidirectional, 2486 + in that the presence of a directive in a request does not imply that the 2487 + same directive is present or copied in the response.<a href="#section-5.2-1" class="pilcrow">¶</a></p> 2488 + <p id="section-5.2-2"> 2489 + See <a href="#cache.control.extensions" class="xref">Section 5.2.3</a> for information about how 2490 + Cache-Control directives defined elsewhere are handled.<a href="#section-5.2-2" class="pilcrow">¶</a></p> 2491 + <p id="section-5.2-3"> 2492 + A proxy, whether or not it implements a cache, <span class="bcp14">MUST</span> pass cache directives 2493 + through in forwarded messages, regardless of their 2494 + significance to that application, since the directives might apply 2495 + to all recipients along the request/response chain. It is not possible to 2496 + target a directive to a specific cache.<a href="#section-5.2-3" class="pilcrow">¶</a></p> 2497 + <p id="section-5.2-4"> 2498 + Cache directives are identified by a token, to be compared case-insensitively, 2499 + and have an optional argument that can use both token and quoted-string 2500 + syntax. For the directives defined below that define arguments, recipients 2501 + ought to accept both forms, even if a specific form is required for generation.<a href="#section-5.2-4" class="pilcrow">¶</a></p> 2502 + <span id="iref-grammar-cache-control-26" class="iref"></span> 2503 + <span id="iref-grammar-cache-directive-27" class="iref"></span> 2504 + <div id="section-5.2-5"> 2505 + <pre class="lang-abnf9110 sourcecode"> Cache-Control = #cache-directive 2506 + 2507 + cache-directive = token [ "=" ( token / quoted-string ) ] 2508 + </pre><a href="#section-5.2-5" class="pilcrow">¶</a> 2509 + </div> 2510 + <p id="section-5.2-6"> 2511 + For the cache directives defined below, no argument is defined (nor allowed) 2512 + unless stated otherwise.<a href="#section-5.2-6" class="pilcrow">¶</a></p> 2513 + <div id="cache-request-directive"> 2514 + <section id="section-5.2.1"> 2515 + <h4 id="name-request-directives"> 2516 + <a href="#section-5.2.1" class="section-number selfRef">5.2.1. </a><a href="#name-request-directives" class="section-name selfRef">Request Directives</a> 2517 + </h4> 2518 + <p id="section-5.2.1-1"> 2519 + This section defines cache request directives. They are advisory; caches 2520 + <span class="bcp14">MAY</span> implement them, but are not required to.<a href="#section-5.2.1-1" class="pilcrow">¶</a></p> 2521 + <div id="cache-request-directive.max-age"> 2522 + <section id="section-5.2.1.1"> 2523 + <h5 id="name-max-age"> 2524 + <a href="#section-5.2.1.1" class="section-number selfRef">5.2.1.1. </a><a href="#name-max-age" class="section-name selfRef">max-age</a> 2525 + </h5> 2526 + <span id="iref-max-age-cache-directive-28" class="iref"></span> 2527 + <p id="section-5.2.1.1-1"> 2528 + Argument syntax:<a href="#section-5.2.1.1-1" class="pilcrow">¶</a></p> 2529 + <ul class="normal ulEmpty"> 2530 + <li class="normal ulEmpty" id="section-5.2.1.1-2.1"> 2531 + <a href="#delta-seconds" class="xref">delta-seconds</a> (see <a href="#delta-seconds" class="xref">Section 1.2.2</a>)<a href="#section-5.2.1.1-2.1" class="pilcrow">¶</a> 2532 + </li> 2533 + </ul> 2534 + <p id="section-5.2.1.1-3"> 2535 + The max-age request directive indicates that the client prefers a 2536 + response whose age is less than or equal to the specified number of 2537 + seconds. Unless the max-stale request directive is also present, the 2538 + client does not wish to receive a stale response.<a href="#section-5.2.1.1-3" class="pilcrow">¶</a></p> 2539 + <p id="section-5.2.1.1-4"> 2540 + This directive uses the token form of the argument syntax: 2541 + e.g., 'max-age=5' not 'max-age="5"'. A sender <span class="bcp14">MUST NOT</span> generate the 2542 + quoted-string form.<a href="#section-5.2.1.1-4" class="pilcrow">¶</a></p> 2543 + </section> 2544 + </div> 2545 + <div id="cache-request-directive.max-stale"> 2546 + <section id="section-5.2.1.2"> 2547 + <h5 id="name-max-stale"> 2548 + <a href="#section-5.2.1.2" class="section-number selfRef">5.2.1.2. </a><a href="#name-max-stale" class="section-name selfRef">max-stale</a> 2549 + </h5> 2550 + <span id="iref-max-stale-cache-directive-2" class="iref"></span> 2551 + <p id="section-5.2.1.2-1"> 2552 + Argument syntax:<a href="#section-5.2.1.2-1" class="pilcrow">¶</a></p> 2553 + <ul class="normal ulEmpty"> 2554 + <li class="normal ulEmpty" id="section-5.2.1.2-2.1"> 2555 + <a href="#delta-seconds" class="xref">delta-seconds</a> (see <a href="#delta-seconds" class="xref">Section 1.2.2</a>)<a href="#section-5.2.1.2-2.1" class="pilcrow">¶</a> 2556 + </li> 2557 + </ul> 2558 + <p id="section-5.2.1.2-3"> 2559 + The max-stale request directive indicates that the client will 2560 + accept a response that has exceeded its freshness lifetime. If a value is 2561 + present, then the client is willing to accept a response that has exceeded 2562 + its freshness lifetime by no more than the specified number of seconds. If 2563 + no value is assigned to max-stale, then the client will accept a 2564 + stale response of any age.<a href="#section-5.2.1.2-3" class="pilcrow">¶</a></p> 2565 + <p id="section-5.2.1.2-4"> 2566 + This directive uses the token form of the argument syntax: 2567 + e.g., 'max-stale=10' not 'max-stale="10"'. A sender <span class="bcp14">MUST NOT</span> generate 2568 + the quoted-string form.<a href="#section-5.2.1.2-4" class="pilcrow">¶</a></p> 2569 + </section> 2570 + </div> 2571 + <div id="cache-request-directive.min-fresh"> 2572 + <section id="section-5.2.1.3"> 2573 + <h5 id="name-min-fresh"> 2574 + <a href="#section-5.2.1.3" class="section-number selfRef">5.2.1.3. </a><a href="#name-min-fresh" class="section-name selfRef">min-fresh</a> 2575 + </h5> 2576 + <span id="iref-min-fresh-cache-directive-3" class="iref"></span> 2577 + <p id="section-5.2.1.3-1"> 2578 + Argument syntax:<a href="#section-5.2.1.3-1" class="pilcrow">¶</a></p> 2579 + <ul class="normal ulEmpty"> 2580 + <li class="normal ulEmpty" id="section-5.2.1.3-2.1"> 2581 + <a href="#delta-seconds" class="xref">delta-seconds</a> (see <a href="#delta-seconds" class="xref">Section 1.2.2</a>)<a href="#section-5.2.1.3-2.1" class="pilcrow">¶</a> 2582 + </li> 2583 + </ul> 2584 + <p id="section-5.2.1.3-3"> 2585 + The min-fresh request directive indicates that the client prefers a 2586 + response whose freshness lifetime is no less than its current age plus the 2587 + specified time in seconds. That is, the client wants a response that will 2588 + still be fresh for at least the specified number of seconds.<a href="#section-5.2.1.3-3" class="pilcrow">¶</a></p> 2589 + <p id="section-5.2.1.3-4"> 2590 + This directive uses the token form of the argument syntax: 2591 + e.g., 'min-fresh=20' not 'min-fresh="20"'. A sender <span class="bcp14">MUST NOT</span> generate 2592 + the quoted-string form.<a href="#section-5.2.1.3-4" class="pilcrow">¶</a></p> 2593 + </section> 2594 + </div> 2595 + <div id="cache-request-directive.no-cache"> 2596 + <section id="section-5.2.1.4"> 2597 + <h5 id="name-no-cache"> 2598 + <a href="#section-5.2.1.4" class="section-number selfRef">5.2.1.4. </a><a href="#name-no-cache" class="section-name selfRef">no-cache</a> 2599 + </h5> 2600 + <span id="iref-no-cache-cache-directive-31" class="iref"></span> 2601 + <p id="section-5.2.1.4-1"> 2602 + The no-cache request directive indicates that the client prefers 2603 + a stored response not be used to satisfy the request without successful 2604 + validation on the origin server.<a href="#section-5.2.1.4-1" class="pilcrow">¶</a></p> 2605 + </section> 2606 + </div> 2607 + <div id="cache-request-directive.no-store"> 2608 + <section id="section-5.2.1.5"> 2609 + <h5 id="name-no-store"> 2610 + <a href="#section-5.2.1.5" class="section-number selfRef">5.2.1.5. </a><a href="#name-no-store" class="section-name selfRef">no-store</a> 2611 + </h5> 2612 + <span id="iref-no-store-cache-directive-32" class="iref"></span> 2613 + <p id="section-5.2.1.5-1"> 2614 + The no-store request directive indicates that a cache <span class="bcp14">MUST NOT</span> 2615 + store any part of either this request or any response to it. This 2616 + directive applies to both private and shared caches. "MUST NOT 2617 + store" in this context means that the cache <span class="bcp14">MUST NOT</span> intentionally 2618 + store the information in non-volatile storage and <span class="bcp14">MUST</span> make a 2619 + best-effort attempt to remove the information from volatile storage as 2620 + promptly as possible after forwarding it.<a href="#section-5.2.1.5-1" class="pilcrow">¶</a></p> 2621 + <p id="section-5.2.1.5-2"> 2622 + This directive is not a reliable or sufficient mechanism for ensuring 2623 + privacy. In particular, malicious or compromised caches might not 2624 + recognize or obey this directive, and communications networks might be 2625 + vulnerable to eavesdropping.<a href="#section-5.2.1.5-2" class="pilcrow">¶</a></p> 2626 + <p id="section-5.2.1.5-3"> 2627 + Note that if a request containing this directive is satisfied from a 2628 + cache, the no-store request directive does not apply to the already 2629 + stored response.<a href="#section-5.2.1.5-3" class="pilcrow">¶</a></p> 2630 + </section> 2631 + </div> 2632 + <div id="cache-request-directive.no-transform"> 2633 + <section id="section-5.2.1.6"> 2634 + <h5 id="name-no-transform"> 2635 + <a href="#section-5.2.1.6" class="section-number selfRef">5.2.1.6. </a><a href="#name-no-transform" class="section-name selfRef">no-transform</a> 2636 + </h5> 2637 + <span id="iref-no-transform-cache-directiv" class="iref"></span> 2638 + <p id="section-5.2.1.6-1"> 2639 + The no-transform request directive indicates that the client is asking 2640 + for intermediaries to avoid 2641 + transforming the content, as defined in <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-7.7" class="relref">Section 7.7</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>.<a href="#section-5.2.1.6-1" class="pilcrow">¶</a></p> 2642 + </section> 2643 + </div> 2644 + <div id="cache-request-directive.only-if-cached"> 2645 + <section id="section-5.2.1.7"> 2646 + <h5 id="name-only-if-cached"> 2647 + <a href="#section-5.2.1.7" class="section-number selfRef">5.2.1.7. </a><a href="#name-only-if-cached" class="section-name selfRef">only-if-cached</a> 2648 + </h5> 2649 + <span id="iref-only-if-cached-cache-direct" class="iref"></span> 2650 + <p id="section-5.2.1.7-1"> 2651 + The only-if-cached request directive indicates that the client only 2652 + wishes to obtain a stored response. Caches that honor this request 2653 + directive <span class="bcp14">SHOULD</span>, upon receiving it, respond with either a stored 2654 + response consistent with the other constraints of the request or 2655 + a 504 (Gateway Timeout) status code.<a href="#section-5.2.1.7-1" class="pilcrow">¶</a></p> 2656 + </section> 2657 + </div> 2658 + </section> 2659 + </div> 2660 + <div id="cache-response-directive"> 2661 + <section id="section-5.2.2"> 2662 + <h4 id="name-response-directives"> 2663 + <a href="#section-5.2.2" class="section-number selfRef">5.2.2. </a><a href="#name-response-directives" class="section-name selfRef">Response Directives</a> 2664 + </h4> 2665 + <p id="section-5.2.2-1"> 2666 + This section defines cache response directives. A cache <span class="bcp14">MUST</span> obey the 2667 + Cache-Control directives defined in this section.<a href="#section-5.2.2-1" class="pilcrow">¶</a></p> 2668 + <div id="cache-response-directive.max-age"> 2669 + <section id="section-5.2.2.1"> 2670 + <h5 id="name-max-age-2"> 2671 + <a href="#section-5.2.2.1" class="section-number selfRef">5.2.2.1. </a><a href="#name-max-age-2" class="section-name selfRef">max-age</a> 2672 + </h5> 2673 + <span id="iref-max-age-cache-directive-35" class="iref"></span> 2674 + <p id="section-5.2.2.1-1"> 2675 + Argument syntax:<a href="#section-5.2.2.1-1" class="pilcrow">¶</a></p> 2676 + <ul class="normal ulEmpty"> 2677 + <li class="normal ulEmpty" id="section-5.2.2.1-2.1"> 2678 + <a href="#delta-seconds" class="xref">delta-seconds</a> (see <a href="#delta-seconds" class="xref">Section 1.2.2</a>)<a href="#section-5.2.2.1-2.1" class="pilcrow">¶</a> 2679 + </li> 2680 + </ul> 2681 + <p id="section-5.2.2.1-3"> 2682 + The max-age response directive indicates that the response is to be 2683 + considered stale after its age is greater than the specified number of 2684 + seconds.<a href="#section-5.2.2.1-3" class="pilcrow">¶</a></p> 2685 + <p id="section-5.2.2.1-4"> 2686 + This directive uses the token form of the argument syntax: 2687 + e.g., 'max-age=5' not 'max-age="5"'. A sender <span class="bcp14">MUST NOT</span> generate the 2688 + quoted-string form.<a href="#section-5.2.2.1-4" class="pilcrow">¶</a></p> 2689 + </section> 2690 + </div> 2691 + <div id="cache-response-directive.must-revalidate"> 2692 + <section id="section-5.2.2.2"> 2693 + <h5 id="name-must-revalidate"> 2694 + <a href="#section-5.2.2.2" class="section-number selfRef">5.2.2.2. </a><a href="#name-must-revalidate" class="section-name selfRef">must-revalidate</a> 2695 + </h5> 2696 + <span id="iref-must-revalidate-cache-direc" class="iref"></span> 2697 + <p id="section-5.2.2.2-1"> 2698 + The must-revalidate response directive indicates that once the response 2699 + has become stale, a cache <span class="bcp14">MUST NOT</span> reuse that response to satisfy 2700 + another request until it has been successfully validated by the origin, as 2701 + defined by <a href="#validation.model" class="xref">Section 4.3</a>.<a href="#section-5.2.2.2-1" class="pilcrow">¶</a></p> 2702 + <p id="section-5.2.2.2-2"> 2703 + The must-revalidate directive is necessary to support reliable operation 2704 + for certain protocol features. In all circumstances, a cache <span class="bcp14">MUST NOT</span> ignore 2705 + the must-revalidate directive; in particular, if a cache is disconnected, 2706 + the cache <span class="bcp14">MUST</span> generate an error response rather than reuse the stale response. 2707 + The generated status code <span class="bcp14">SHOULD</span> be 504 (Gateway Timeout) 2708 + unless another error status code is more applicable.<a href="#section-5.2.2.2-2" class="pilcrow">¶</a></p> 2709 + <p id="section-5.2.2.2-3"> 2710 + The must-revalidate directive ought to be used by servers if and only 2711 + if failure to validate a request could cause 2712 + incorrect operation, such as a silently unexecuted financial 2713 + transaction.<a href="#section-5.2.2.2-3" class="pilcrow">¶</a></p> 2714 + <p id="section-5.2.2.2-4"> 2715 + The must-revalidate directive also permits a shared cache to 2716 + reuse a response to a request containing an Authorization 2717 + header field (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-11.6.2" class="relref">Section 11.6.2</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>), 2718 + subject to the above requirement on revalidation 2719 + (<a href="#caching.authenticated.responses" class="xref">Section 3.5</a>).<a href="#section-5.2.2.2-4" class="pilcrow">¶</a></p> 2720 + </section> 2721 + </div> 2722 + <div id="cache-response-directive.must-understand"> 2723 + <section id="section-5.2.2.3"> 2724 + <h5 id="name-must-understand"> 2725 + <a href="#section-5.2.2.3" class="section-number selfRef">5.2.2.3. </a><a href="#name-must-understand" class="section-name selfRef">must-understand</a> 2726 + </h5> 2727 + <span id="iref-must-understand-cache-direc" class="iref"></span> 2728 + <p id="section-5.2.2.3-1"> 2729 + The must-understand response directive limits caching of the response to 2730 + a cache that understands and conforms to the requirements for that 2731 + response's status code.<a href="#section-5.2.2.3-1" class="pilcrow">¶</a></p> 2732 + <p id="section-5.2.2.3-2"> 2733 + A response that contains the must-understand directive <span class="bcp14">SHOULD</span> 2734 + also contain the no-store directive. When a cache that implements the 2735 + must-understand directive receives a response that includes it, 2736 + the cache <span class="bcp14">SHOULD</span> ignore the no-store directive if it 2737 + understands and implements the status code's caching requirements.<a href="#section-5.2.2.3-2" class="pilcrow">¶</a></p> 2738 + </section> 2739 + </div> 2740 + <div id="cache-response-directive.no-cache"> 2741 + <section id="section-5.2.2.4"> 2742 + <h5 id="name-no-cache-2"> 2743 + <a href="#section-5.2.2.4" class="section-number selfRef">5.2.2.4. </a><a href="#name-no-cache-2" class="section-name selfRef">no-cache</a> 2744 + </h5> 2745 + <span id="iref-no-cache-cache-directive-38" class="iref"></span> 2746 + <p id="section-5.2.2.4-1"> 2747 + Argument syntax:<a href="#section-5.2.2.4-1" class="pilcrow">¶</a></p> 2748 + <ul class="normal ulEmpty"> 2749 + <li class="normal ulEmpty" id="section-5.2.2.4-2.1">#<a href="#imported.rules" class="xref">field-name</a><a href="#section-5.2.2.4-2.1" class="pilcrow">¶</a> 2750 + </li> 2751 + </ul> 2752 + <p id="section-5.2.2.4-3"> 2753 + The no-cache response directive, in its unqualified form (without an 2754 + argument), indicates that the response <span class="bcp14">MUST NOT</span> be used to satisfy any 2755 + other request without forwarding it for validation and receiving a 2756 + successful response; see <a href="#validation.model" class="xref">Section 4.3</a>.<a href="#section-5.2.2.4-3" class="pilcrow">¶</a></p> 2757 + <p id="section-5.2.2.4-4"> 2758 + This allows an origin server to prevent a cache from using 2759 + the response to satisfy a request without contacting it, even by caches that have 2760 + been configured to send stale responses.<a href="#section-5.2.2.4-4" class="pilcrow">¶</a></p> 2761 + <p id="section-5.2.2.4-5"> 2762 + The qualified form of the no-cache response directive, with an argument that 2763 + lists one or more field names, indicates that a cache <span class="bcp14">MAY</span> use the 2764 + response to satisfy a subsequent request, subject to any other restrictions 2765 + on caching, if the listed header fields are excluded from the subsequent 2766 + response or the subsequent response has been successfully revalidated with 2767 + the origin server (updating or removing those fields). 2768 + This allows an origin server to prevent the reuse of certain header 2769 + fields in a response, while still allowing caching of the rest of the 2770 + response.<a href="#section-5.2.2.4-5" class="pilcrow">¶</a></p> 2771 + <p id="section-5.2.2.4-6"> 2772 + The field names given are not limited to the set of header 2773 + fields defined by this specification. Field names are case-insensitive.<a href="#section-5.2.2.4-6" class="pilcrow">¶</a></p> 2774 + <p id="section-5.2.2.4-7"> 2775 + This directive uses the quoted-string form of the argument syntax. 2776 + A sender <span class="bcp14">SHOULD NOT</span> generate the token form (even if quoting appears not 2777 + to be needed for single-entry lists).<a href="#section-5.2.2.4-7" class="pilcrow">¶</a></p> 2778 + <aside id="section-5.2.2.4-8"> 2779 + <p id="section-5.2.2.4-8.1"> 2780 + <strong>Note:</strong> The 2781 + qualified form of the directive is often handled by caches as if an 2782 + unqualified no-cache directive was received; that is, the special handling 2783 + for the qualified form is not widely implemented.<a href="#section-5.2.2.4-8.1" class="pilcrow">¶</a></p> 2784 + </aside> 2785 + </section> 2786 + </div> 2787 + <div id="cache-response-directive.no-store"> 2788 + <section id="section-5.2.2.5"> 2789 + <h5 id="name-no-store-2"> 2790 + <a href="#section-5.2.2.5" class="section-number selfRef">5.2.2.5. </a><a href="#name-no-store-2" class="section-name selfRef">no-store</a> 2791 + </h5> 2792 + <span id="iref-no-store-cache-directive-39" class="iref"></span> 2793 + <p id="section-5.2.2.5-1"> 2794 + The no-store response directive indicates that a cache <span class="bcp14">MUST NOT</span> store 2795 + any part of either the immediate request or the response and <span class="bcp14">MUST NOT</span> use 2796 + the response to satisfy any other request.<a href="#section-5.2.2.5-1" class="pilcrow">¶</a></p> 2797 + <p id="section-5.2.2.5-2"> 2798 + This directive applies to both private and shared caches. "MUST NOT 2799 + store" in this context means that the cache <span class="bcp14">MUST NOT</span> intentionally store 2800 + the information in non-volatile storage and <span class="bcp14">MUST</span> make a best-effort 2801 + attempt to remove the information from volatile storage as promptly as 2802 + possible after forwarding it.<a href="#section-5.2.2.5-2" class="pilcrow">¶</a></p> 2803 + <p id="section-5.2.2.5-3"> 2804 + This directive is not a reliable or sufficient mechanism for ensuring 2805 + privacy. In particular, malicious or compromised caches might not 2806 + recognize or obey this directive, and communications networks might be 2807 + vulnerable to eavesdropping.<a href="#section-5.2.2.5-3" class="pilcrow">¶</a></p> 2808 + <p id="section-5.2.2.5-4"> 2809 + Note that the must-understand cache directive overrides no-store in certain 2810 + circumstances; see <a href="#cache-response-directive.must-understand" class="xref">Section 5.2.2.3</a>.<a href="#section-5.2.2.5-4" class="pilcrow">¶</a></p> 2811 + </section> 2812 + </div> 2813 + <div id="cache-response-directive.no-transform"> 2814 + <section id="section-5.2.2.6"> 2815 + <h5 id="name-no-transform-2"> 2816 + <a href="#section-5.2.2.6" class="section-number selfRef">5.2.2.6. </a><a href="#name-no-transform-2" class="section-name selfRef">no-transform</a> 2817 + </h5> 2818 + <span id="iref-no-transform-cache-directive" class="iref"></span> 2819 + <p id="section-5.2.2.6-1"> 2820 + The no-transform response directive indicates that an intermediary 2821 + (regardless of whether it implements a cache) <span class="bcp14">MUST NOT</span> transform the 2822 + content, as defined in <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-7.7" class="relref">Section 7.7</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>.<a href="#section-5.2.2.6-1" class="pilcrow">¶</a></p> 2823 + </section> 2824 + </div> 2825 + <div id="cache-response-directive.private"> 2826 + <section id="section-5.2.2.7"> 2827 + <h5 id="name-private"> 2828 + <a href="#section-5.2.2.7" class="section-number selfRef">5.2.2.7. </a><a href="#name-private" class="section-name selfRef">private</a> 2829 + </h5> 2830 + <span id="iref-private-cache-directive-41" class="iref"></span> 2831 + <p id="section-5.2.2.7-1"> 2832 + Argument syntax:<a href="#section-5.2.2.7-1" class="pilcrow">¶</a></p> 2833 + <ul class="normal ulEmpty"> 2834 + <li class="normal ulEmpty" id="section-5.2.2.7-2.1">#<a href="#imported.rules" class="xref">field-name</a><a href="#section-5.2.2.7-2.1" class="pilcrow">¶</a> 2835 + </li> 2836 + </ul> 2837 + <p id="section-5.2.2.7-3"> 2838 + The unqualified private response directive indicates that 2839 + a shared cache <span class="bcp14">MUST NOT</span> store the response (i.e., the response is 2840 + intended for a single user). 2841 + It also indicates that a private cache <span class="bcp14">MAY</span> store the response, subject 2842 + to the constraints defined in <a href="#response.cacheability" class="xref">Section 3</a>, even if 2843 + the response would not otherwise be heuristically cacheable by a private 2844 + cache.<a href="#section-5.2.2.7-3" class="pilcrow">¶</a></p> 2845 + <p id="section-5.2.2.7-4"> 2846 + If a qualified private response directive is present, with an argument that 2847 + lists one or more field names, then only the listed header fields are limited to a 2848 + single user: a shared cache <span class="bcp14">MUST NOT</span> store the listed header fields if they 2849 + are present in the original response but <span class="bcp14">MAY</span> store the remainder of the 2850 + response message without those header fields, subject 2851 + the constraints defined in <a href="#response.cacheability" class="xref">Section 3</a>.<a href="#section-5.2.2.7-4" class="pilcrow">¶</a></p> 2852 + <p id="section-5.2.2.7-5"> 2853 + The field names given are not limited to the set of header 2854 + fields defined by this specification. Field names are case-insensitive.<a href="#section-5.2.2.7-5" class="pilcrow">¶</a></p> 2855 + <p id="section-5.2.2.7-6"> 2856 + This directive uses the quoted-string form of the argument syntax. 2857 + A sender <span class="bcp14">SHOULD NOT</span> generate the token form (even if quoting appears not 2858 + to be needed for single-entry lists).<a href="#section-5.2.2.7-6" class="pilcrow">¶</a></p> 2859 + <aside id="section-5.2.2.7-7"> 2860 + <p id="section-5.2.2.7-7.1"> 2861 + <strong>Note:</strong> This usage of the word "private" only controls 2862 + where the response can be stored; it cannot ensure the privacy of the 2863 + message content. Also, the qualified form of the directive is 2864 + often handled by caches as if an unqualified private directive 2865 + was received; that is, the special handling for the qualified form is not 2866 + widely implemented.<a href="#section-5.2.2.7-7.1" class="pilcrow">¶</a></p> 2867 + </aside> 2868 + </section> 2869 + </div> 2870 + <div id="cache-response-directive.proxy-revalidate"> 2871 + <section id="section-5.2.2.8"> 2872 + <h5 id="name-proxy-revalidate"> 2873 + <a href="#section-5.2.2.8" class="section-number selfRef">5.2.2.8. </a><a href="#name-proxy-revalidate" class="section-name selfRef">proxy-revalidate</a> 2874 + </h5> 2875 + <span id="iref-proxy-revalidate-cache-dire" class="iref"></span> 2876 + <p id="section-5.2.2.8-1"> 2877 + The proxy-revalidate response directive indicates that once the response 2878 + has become stale, a shared cache <span class="bcp14">MUST NOT</span> reuse that response to satisfy 2879 + another request until it has been successfully validated by the origin, 2880 + as defined by <a href="#validation.model" class="xref">Section 4.3</a>. This is analogous to 2881 + must-revalidate (<a href="#cache-response-directive.must-revalidate" class="xref">Section 5.2.2.2</a>), 2882 + except that proxy-revalidate does not apply to private caches.<a href="#section-5.2.2.8-1" class="pilcrow">¶</a></p> 2883 + <p id="section-5.2.2.8-2"> 2884 + Note that proxy-revalidate on its own does not imply that a response is 2885 + cacheable. For example, it might be combined with the public directive 2886 + (<a href="#cache-response-directive.public" class="xref">Section 5.2.2.9</a>), allowing the response 2887 + to be cached while requiring only a shared cache to revalidate when stale.<a href="#section-5.2.2.8-2" class="pilcrow">¶</a></p> 2888 + </section> 2889 + </div> 2890 + <div id="cache-response-directive.public"> 2891 + <section id="section-5.2.2.9"> 2892 + <h5 id="name-public"> 2893 + <a href="#section-5.2.2.9" class="section-number selfRef">5.2.2.9. </a><a href="#name-public" class="section-name selfRef">public</a> 2894 + </h5> 2895 + <span id="iref-public-cache-directive-43" class="iref"></span> 2896 + <p id="section-5.2.2.9-1"> 2897 + The public response directive indicates that a cache <span class="bcp14">MAY</span> store the 2898 + response even if it would otherwise be prohibited, subject to the 2899 + constraints defined in <a href="#response.cacheability" class="xref">Section 3</a>. In other words, 2900 + public explicitly marks the response as cacheable. For example, 2901 + public permits a shared cache to reuse a response to a request containing 2902 + an Authorization header field (<a href="#caching.authenticated.responses" class="xref">Section 3.5</a>).<a href="#section-5.2.2.9-1" class="pilcrow">¶</a></p> 2903 + <p id="section-5.2.2.9-2"> 2904 + Note that it is unnecessary to add the public directive to a response that 2905 + is already cacheable according to <a href="#response.cacheability" class="xref">Section 3</a>.<a href="#section-5.2.2.9-2" class="pilcrow">¶</a></p> 2906 + <p id="section-5.2.2.9-3"> 2907 + If a response with the public directive has no explicit freshness information, 2908 + it is heuristically cacheable (<a href="#heuristic.freshness" class="xref">Section 4.2.2</a>).<a href="#section-5.2.2.9-3" class="pilcrow">¶</a></p> 2909 + </section> 2910 + </div> 2911 + <div id="cache-response-directive.s-maxage"> 2912 + <section id="section-5.2.2.10"> 2913 + <h5 id="name-s-maxage"> 2914 + <a href="#section-5.2.2.10" class="section-number selfRef">5.2.2.10. </a><a href="#name-s-maxage" class="section-name selfRef">s-maxage</a> 2915 + </h5> 2916 + <span id="iref-s-maxage-cache-directive-44" class="iref"></span> 2917 + <p id="section-5.2.2.10-1"> 2918 + Argument syntax:<a href="#section-5.2.2.10-1" class="pilcrow">¶</a></p> 2919 + <ul class="normal ulEmpty"> 2920 + <li class="normal ulEmpty" id="section-5.2.2.10-2.1"> 2921 + <a href="#delta-seconds" class="xref">delta-seconds</a> (see <a href="#delta-seconds" class="xref">Section 1.2.2</a>)<a href="#section-5.2.2.10-2.1" class="pilcrow">¶</a> 2922 + </li> 2923 + </ul> 2924 + <p id="section-5.2.2.10-3"> 2925 + The s-maxage response directive indicates that, for a shared cache, the 2926 + maximum age specified by this directive overrides the maximum age 2927 + specified by either the max-age directive or the <a href="#field.expires" class="xref">Expires</a> 2928 + header field.<a href="#section-5.2.2.10-3" class="pilcrow">¶</a></p> 2929 + <p id="section-5.2.2.10-4"> 2930 + The s-maxage directive incorporates the 2931 + semantics of the proxy‑revalidate response directive (<a href="#cache-response-directive.proxy-revalidate" class="xref">Section 5.2.2.8</a>) 2932 + for a shared cache. 2933 + A shared cache <span class="bcp14">MUST NOT</span> reuse a stale response with s-maxage to satisfy 2934 + another request until it has been successfully validated by the origin, as 2935 + defined by <a href="#validation.model" class="xref">Section 4.3</a>. 2936 + This directive also permits a shared cache to reuse a response to a 2937 + request containing an Authorization header field, subject to the above 2938 + requirements on maximum age and revalidation 2939 + (<a href="#caching.authenticated.responses" class="xref">Section 3.5</a>).<a href="#section-5.2.2.10-4" class="pilcrow">¶</a></p> 2940 + <p id="section-5.2.2.10-5"> 2941 + This directive uses the token form of the argument syntax: 2942 + e.g., 's-maxage=10' not 's-maxage="10"'. A sender <span class="bcp14">MUST NOT</span> generate 2943 + the quoted-string form.<a href="#section-5.2.2.10-5" class="pilcrow">¶</a></p> 2944 + </section> 2945 + </div> 2946 + </section> 2947 + </div> 2948 + <div id="cache.control.extensions"> 2949 + <section id="section-5.2.3"> 2950 + <h4 id="name-extension-directives"> 2951 + <a href="#section-5.2.3" class="section-number selfRef">5.2.3. </a><a href="#name-extension-directives" class="section-name selfRef">Extension Directives</a> 2952 + </h4> 2953 + <p id="section-5.2.3-1"> 2954 + The Cache-Control header field can be extended through the use of one or 2955 + more extension cache directives. 2956 + A cache <span class="bcp14">MUST</span> ignore unrecognized cache directives.<a href="#section-5.2.3-1" class="pilcrow">¶</a></p> 2957 + <p id="section-5.2.3-2"> 2958 + Informational extensions (those that do not require a change in cache 2959 + behavior) can be added without changing the semantics of other directives.<a href="#section-5.2.3-2" class="pilcrow">¶</a></p> 2960 + <p id="section-5.2.3-3"> 2961 + Behavioral extensions are designed to work by acting as modifiers to the 2962 + existing base of cache directives. 2963 + Both the new directive and the old directive are supplied, such that 2964 + applications that do not understand the new directive will default to the 2965 + behavior specified by the old directive, and those that understand the 2966 + new directive will recognize it as modifying the requirements associated 2967 + with the old directive. In this way, extensions to the existing 2968 + cache directives can be made without breaking deployed caches.<a href="#section-5.2.3-3" class="pilcrow">¶</a></p> 2969 + <p id="section-5.2.3-4"> 2970 + For example, consider a hypothetical new response directive called 2971 + "community" that acts as a modifier to the private directive: in addition 2972 + to private caches, only a cache that is shared by members of the named 2973 + community is allowed to cache the response. An origin server wishing to 2974 + allow the UCI community to use an otherwise private response in their 2975 + shared cache(s) could do so by including<a href="#section-5.2.3-4" class="pilcrow">¶</a></p> 2976 + <div id="section-5.2.3-5"> 2977 + <pre class="lang-http-message sourcecode">Cache-Control: private, community="UCI" 2978 + </pre><a href="#section-5.2.3-5" class="pilcrow">¶</a> 2979 + </div> 2980 + <p id="section-5.2.3-6"> 2981 + A cache that recognizes such a community cache directive could broaden its 2982 + behavior in accordance with that extension. A cache that does not 2983 + recognize the community cache directive would ignore it and adhere to the 2984 + private directive.<a href="#section-5.2.3-6" class="pilcrow">¶</a></p> 2985 + <p id="section-5.2.3-7"> 2986 + New extension directives ought to consider defining:<a href="#section-5.2.3-7" class="pilcrow">¶</a></p> 2987 + <ul class="normal"> 2988 + <li class="normal" id="section-5.2.3-8.1">What it means for a directive to be specified multiple times,<a href="#section-5.2.3-8.1" class="pilcrow">¶</a> 2989 + </li> 2990 + <li class="normal" id="section-5.2.3-8.2">When the directive does not take an argument, what it means when an 2991 + argument is present,<a href="#section-5.2.3-8.2" class="pilcrow">¶</a> 2992 + </li> 2993 + <li class="normal" id="section-5.2.3-8.3">When the directive requires an argument, what it means when it is 2994 + missing, and<a href="#section-5.2.3-8.3" class="pilcrow">¶</a> 2995 + </li> 2996 + <li class="normal" id="section-5.2.3-8.4">Whether the directive is specific to requests, specific to responses, or able 2997 + to be used in either.<a href="#section-5.2.3-8.4" class="pilcrow">¶</a> 2998 + </li> 2999 + </ul> 3000 + </section> 3001 + </div> 3002 + <div id="cache.directive.registry"> 3003 + <section id="section-5.2.4"> 3004 + <h4 id="name-cache-directive-registry"> 3005 + <a href="#section-5.2.4" class="section-number selfRef">5.2.4. </a><a href="#name-cache-directive-registry" class="section-name selfRef">Cache Directive Registry</a> 3006 + </h4> 3007 + <p id="section-5.2.4-1"> 3008 + The "Hypertext Transfer Protocol (HTTP) Cache Directive Registry" defines the namespace for the 3009 + cache directives. It has been created and is now maintained at 3010 + <span>&lt;<a href="https://www.iana.org/assignments/http-cache-directives">https://www.iana.org/assignments/http-cache-directives</a>&gt;</span>.<a href="#section-5.2.4-1" class="pilcrow">¶</a></p> 3011 + <p id="section-5.2.4-2"> 3012 + A registration <span class="bcp14">MUST</span> include the following fields:<a href="#section-5.2.4-2" class="pilcrow">¶</a></p> 3013 + <ul class="normal"> 3014 + <li class="normal" id="section-5.2.4-3.1">Cache Directive Name<a href="#section-5.2.4-3.1" class="pilcrow">¶</a> 3015 + </li> 3016 + <li class="normal" id="section-5.2.4-3.2">Pointer to specification text<a href="#section-5.2.4-3.2" class="pilcrow">¶</a> 3017 + </li> 3018 + </ul> 3019 + <p id="section-5.2.4-4"> 3020 + Values to be added to this namespace require IETF Review (see <span>[<a href="#RFC8126" class="xref">RFC8126</a>], <a href="https://www.rfc-editor.org/rfc/rfc8126#section-4.8" class="relref">Section 4.8</a></span>).<a href="#section-5.2.4-4" class="pilcrow">¶</a></p> 3021 + </section> 3022 + </div> 3023 + </section> 3024 + </div> 3025 + <div id="field.expires"> 3026 + <section id="section-5.3"> 3027 + <h3 id="name-expires"> 3028 + <a href="#section-5.3" class="section-number selfRef">5.3. </a><a href="#name-expires" class="section-name selfRef">Expires</a> 3029 + </h3> 3030 + <span id="iref-fields-expires-45" class="iref"></span> 3031 + <span id="iref-header-fields-expires-46" class="iref"></span> 3032 + <span id="iref-fields-expires-47" class="iref"></span> 3033 + <span id="iref-header-fields-expires-48" class="iref"></span> 3034 + <span id="iref-expires-header-field-49" class="iref"></span> 3035 + <p id="section-5.3-1"> 3036 + The "Expires" response header field gives the date/time after which the 3037 + response is considered stale. See <a href="#expiration.model" class="xref">Section 4.2</a> for 3038 + further discussion of the freshness model.<a href="#section-5.3-1" class="pilcrow">¶</a></p> 3039 + <p id="section-5.3-2"> 3040 + The presence of an Expires header field does not imply that the original resource 3041 + will change or cease to exist at, before, or after that time.<a href="#section-5.3-2" class="pilcrow">¶</a></p> 3042 + <p id="section-5.3-3"> 3043 + The Expires field value is an HTTP-date timestamp, as defined in <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-5.6.7" class="relref">Section 5.6.7</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>. 3044 + See also <a href="#expiration.model" class="xref">Section 4.2</a> for parsing requirements specific to caches.<a href="#section-5.3-3" class="pilcrow">¶</a></p> 3045 + <span id="iref-grammar-expires-50" class="iref"></span> 3046 + <div id="section-5.3-4"> 3047 + <pre class="lang-abnf9110 sourcecode"> Expires = HTTP-date 3048 + </pre><a href="#section-5.3-4" class="pilcrow">¶</a> 3049 + </div> 3050 + <p id="section-5.3-5"> 3051 + For example<a href="#section-5.3-5" class="pilcrow">¶</a></p> 3052 + <div id="section-5.3-6"> 3053 + <pre class="lang-http-message sourcecode">Expires: Thu, 01 Dec 1994 16:00:00 GMT 3054 + </pre><a href="#section-5.3-6" class="pilcrow">¶</a> 3055 + </div> 3056 + <p id="section-5.3-7"> 3057 + A cache recipient <span class="bcp14">MUST</span> interpret invalid date formats, especially the 3058 + value "0", as representing a time in the past (i.e., "already expired").<a href="#section-5.3-7" class="pilcrow">¶</a></p> 3059 + <p id="section-5.3-8"> 3060 + If a response includes a <a href="#field.cache-control" class="xref">Cache-Control</a> header field with 3061 + the max-age directive (<a href="#cache-response-directive.max-age" class="xref">Section 5.2.2.1</a>), 3062 + a recipient <span class="bcp14">MUST</span> ignore the Expires header field. 3063 + Likewise, if a response includes the s-maxage directive 3064 + (<a href="#cache-response-directive.s-maxage" class="xref">Section 5.2.2.10</a>), a shared cache 3065 + recipient <span class="bcp14">MUST</span> ignore the Expires header field. In both these cases, the value 3066 + in Expires is only intended for recipients that have not yet implemented 3067 + the Cache-Control header field.<a href="#section-5.3-8" class="pilcrow">¶</a></p> 3068 + <p id="section-5.3-9"> 3069 + An origin server without a clock (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-5.6.7" class="relref">Section 5.6.7</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>) 3070 + <span class="bcp14">MUST NOT</span> generate an Expires header field 3071 + unless its value represents a fixed time in the past (always expired) 3072 + or its value has been associated with the resource by a system with 3073 + a clock.<a href="#section-5.3-9" class="pilcrow">¶</a></p> 3074 + <p id="section-5.3-10"> 3075 + Historically, HTTP required the Expires field value to be no more than a 3076 + year in the future. While longer freshness lifetimes are no longer 3077 + prohibited, extremely large values have been demonstrated to cause 3078 + problems (e.g., clock overflows due to use of 32-bit integers for 3079 + time values), and many caches will evict a response far sooner than 3080 + that.<a href="#section-5.3-10" class="pilcrow">¶</a></p> 3081 + </section> 3082 + </div> 3083 + <div id="field.pragma"> 3084 + <section id="section-5.4"> 3085 + <h3 id="name-pragma"> 3086 + <a href="#section-5.4" class="section-number selfRef">5.4. </a><a href="#name-pragma" class="section-name selfRef">Pragma</a> 3087 + </h3> 3088 + <span id="iref-fields-pragma-51" class="iref"></span> 3089 + <span id="iref-header-fields-pragma-52" class="iref"></span> 3090 + <span id="iref-fields-pragma-53" class="iref"></span> 3091 + <span id="iref-header-fields-pragma-54" class="iref"></span> 3092 + <span id="iref-pragma-header-field-55" class="iref"></span> 3093 + <p id="section-5.4-1"> 3094 + The "Pragma" request header field was defined for HTTP/1.0 caches, so that clients 3095 + could specify a "no-cache" request (as <a href="#field.cache-control" class="xref">Cache-Control</a> was 3096 + not defined until HTTP/1.1).<a href="#section-5.4-1" class="pilcrow">¶</a></p> 3097 + <p id="section-5.4-2"> 3098 + However, support for Cache-Control is now widespread. As a result, this 3099 + specification deprecates Pragma.<a href="#section-5.4-2" class="pilcrow">¶</a></p> 3100 + <aside id="section-5.4-3"> 3101 + <p id="section-5.4-3.1"> 3102 + <strong>Note:</strong> Because the meaning of "Pragma: no-cache" in responses was never 3103 + specified, it does not provide a reliable replacement for 3104 + "Cache-Control: no-cache" in them.<a href="#section-5.4-3.1" class="pilcrow">¶</a></p> 3105 + </aside> 3106 + </section> 3107 + </div> 3108 + <div id="field.warning"> 3109 + <section id="section-5.5"> 3110 + <h3 id="name-warning"> 3111 + <a href="#section-5.5" class="section-number selfRef">5.5. </a><a href="#name-warning" class="section-name selfRef">Warning</a> 3112 + </h3> 3113 + <span id="iref-fields-warning-56" class="iref"></span> 3114 + <span id="iref-header-fields-warning-57" class="iref"></span> 3115 + <span id="iref-warning-header-field-58" class="iref"></span> 3116 + <p id="section-5.5-1"> 3117 + The "Warning" header field was used to carry additional information 3118 + about the status or transformation of a message that might not be reflected 3119 + in the status code. This specification obsoletes it, as it is not widely 3120 + generated or surfaced to users. The information it carried can be gleaned 3121 + from examining other header fields, such as <a href="#field.age" class="xref">Age</a>.<a href="#section-5.5-1" class="pilcrow">¶</a></p> 3122 + </section> 3123 + </div> 3124 + </section> 3125 + </div> 3126 + <div id="history.lists"> 3127 + <section id="section-6"> 3128 + <h2 id="name-relationship-to-application"> 3129 + <a href="#section-6" class="section-number selfRef">6. </a><a href="#name-relationship-to-application" class="section-name selfRef">Relationship to Applications and Other Caches</a> 3130 + </h2> 3131 + <p id="section-6-1"> 3132 + Applications using HTTP often specify additional forms of caching. For 3133 + example, Web browsers often have history mechanisms such as "Back" buttons 3134 + that can be used to redisplay a representation retrieved earlier in a 3135 + session.<a href="#section-6-1" class="pilcrow">¶</a></p> 3136 + <p id="section-6-2"> 3137 + Likewise, some Web browsers implement caching of images and other assets 3138 + within a page view; they may or may not honor HTTP caching semantics.<a href="#section-6-2" class="pilcrow">¶</a></p> 3139 + <p id="section-6-3"> 3140 + The requirements in this specification do not necessarily apply to how 3141 + applications use data after it is retrieved from an HTTP cache. For example, a 3142 + history mechanism can display a previous representation even if it has 3143 + expired, and an application can use cached data in other ways beyond its 3144 + freshness lifetime.<a href="#section-6-3" class="pilcrow">¶</a></p> 3145 + <p id="section-6-4"> 3146 + This specification does not prohibit the application from taking HTTP caching into 3147 + account; for example, a history mechanism might tell the user that a view 3148 + is stale, or it might honor cache directives (e.g., Cache-Control: 3149 + no-store).<a href="#section-6-4" class="pilcrow">¶</a></p> 3150 + <p id="section-6-5"> 3151 + However, when an application caches data and does not make this 3152 + apparent to or easily controllable by the user, it is strongly encouraged to 3153 + define its operation with respect to HTTP cache directives so as 3154 + not to surprise authors who expect caching semantics 3155 + to be honored. For example, while it might be reasonable to define an 3156 + application cache "above" HTTP that allows a response containing 3157 + Cache-Control: no-store to be reused for requests that are directly related 3158 + to the request that fetched it (such as those created during the same page 3159 + load), it would likely be surprising and confusing to users and authors if it 3160 + were allowed to be reused for requests unrelated in any way to the one from 3161 + which it was obtained.<a href="#section-6-5" class="pilcrow">¶</a></p> 3162 + </section> 3163 + </div> 3164 + <div id="security.considerations"> 3165 + <section id="section-7"> 3166 + <h2 id="name-security-considerations"> 3167 + <a href="#section-7" class="section-number selfRef">7. </a><a href="#name-security-considerations" class="section-name selfRef">Security Considerations</a> 3168 + </h2> 3169 + <p id="section-7-1"> 3170 + This section is meant to inform developers, information providers, and 3171 + users of known security concerns specific to HTTP caching. 3172 + More general security considerations are addressed in "HTTP/1.1" 3173 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9112#section-11" class="relref">Section 11</a> of [<a href="#HTTP11" class="xref">HTTP/1.1</a>]</span>) 3174 + and "HTTP Semantics" 3175 + (<span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-17" class="relref">Section 17</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>).<a href="#section-7-1" class="pilcrow">¶</a></p> 3176 + <p id="section-7-2"> 3177 + Caches expose an additional attack surface because the contents of 3178 + the cache represent an attractive target for malicious exploitation. 3179 + Since cache contents persist after an HTTP request is complete, an attack 3180 + on the cache can reveal information long after a user believes that the 3181 + information has been removed from the network. Therefore, cache contents 3182 + need to be protected as sensitive information.<a href="#section-7-2" class="pilcrow">¶</a></p> 3183 + <p id="section-7-3"> 3184 + In particular, because private caches are restricted to a single user, 3185 + they can be used to reconstruct a user's activity. As a result, it is 3186 + important for user agents to allow end users to control them, for example, 3187 + by allowing stored responses to be removed for some or all origin servers.<a href="#section-7-3" class="pilcrow">¶</a></p> 3188 + <div id="cache.poisoning"> 3189 + <section id="section-7.1"> 3190 + <h3 id="name-cache-poisoning"> 3191 + <a href="#section-7.1" class="section-number selfRef">7.1. </a><a href="#name-cache-poisoning" class="section-name selfRef">Cache Poisoning</a> 3192 + </h3> 3193 + <p id="section-7.1-1"> 3194 + Storing malicious content in a cache can extend the reach of an attacker 3195 + to affect multiple users. Such 3196 + "cache poisoning" attacks happen when an attacker uses 3197 + implementation flaws, elevated privileges, or other techniques to insert 3198 + a response into a cache. This is especially effective when shared caches 3199 + are used to distribute malicious content to many clients.<a href="#section-7.1-1" class="pilcrow">¶</a></p> 3200 + <p id="section-7.1-2"> 3201 + One common attack vector for cache poisoning is to exploit differences in 3202 + message parsing on proxies and in user agents; see <span><a href="https://www.rfc-editor.org/rfc/rfc9112#section-6.3" class="relref">Section 6.3</a> of [<a href="#HTTP11" class="xref">HTTP/1.1</a>]</span> for the relevant requirements regarding 3203 + HTTP/1.1.<a href="#section-7.1-2" class="pilcrow">¶</a></p> 3204 + </section> 3205 + </div> 3206 + <div id="security.timing"> 3207 + <section id="section-7.2"> 3208 + <h3 id="name-timing-attacks"> 3209 + <a href="#section-7.2" class="section-number selfRef">7.2. </a><a href="#name-timing-attacks" class="section-name selfRef">Timing Attacks</a> 3210 + </h3> 3211 + <p id="section-7.2-1"> 3212 + Because one of the primary uses of a cache is to optimize performance, 3213 + its use can "leak" information about which resources have been previously 3214 + requested.<a href="#section-7.2-1" class="pilcrow">¶</a></p> 3215 + <p id="section-7.2-2"> 3216 + For example, if a user visits a site and their browser caches some of its 3217 + responses and then navigates to a second site, that site can attempt to 3218 + load responses it knows exist on the first site. If they load 3219 + quickly, it can be assumed that the user has visited that site, or even 3220 + a specific page on it.<a href="#section-7.2-2" class="pilcrow">¶</a></p> 3221 + <p id="section-7.2-3"> 3222 + Such "timing attacks" can be mitigated by adding more information to the 3223 + cache key, such as the identity of the referring site (to prevent the 3224 + attack described above). This is sometimes called "double keying".<a href="#section-7.2-3" class="pilcrow">¶</a></p> 3225 + </section> 3226 + </div> 3227 + <div id="caching.of.sensitive.information"> 3228 + <section id="section-7.3"> 3229 + <h3 id="name-caching-of-sensitive-inform"> 3230 + <a href="#section-7.3" class="section-number selfRef">7.3. </a><a href="#name-caching-of-sensitive-inform" class="section-name selfRef">Caching of Sensitive Information</a> 3231 + </h3> 3232 + <p id="section-7.3-1"> 3233 + Implementation and deployment flaws (often led to by the misunderstanding of cache 3234 + operation) might lead to the caching of sensitive information (e.g., 3235 + authentication credentials) that is thought to be private, exposing it to 3236 + unauthorized parties.<a href="#section-7.3-1" class="pilcrow">¶</a></p> 3237 + <p id="section-7.3-2"> 3238 + Note that the Set-Cookie response header field <span>[<a href="#COOKIE" class="xref">COOKIE</a>]</span> 3239 + does not inhibit caching; a cacheable response with a Set-Cookie header 3240 + field can be (and often is) used to satisfy subsequent requests to caches. 3241 + Servers that wish to control caching of these responses are encouraged to 3242 + emit appropriate Cache-Control response header fields.<a href="#section-7.3-2" class="pilcrow">¶</a></p> 3243 + </section> 3244 + </div> 3245 + </section> 3246 + </div> 3247 + <div id="iana.considerations"> 3248 + <section id="section-8"> 3249 + <h2 id="name-iana-considerations"> 3250 + <a href="#section-8" class="section-number selfRef">8. </a><a href="#name-iana-considerations" class="section-name selfRef">IANA Considerations</a> 3251 + </h2> 3252 + <p id="section-8-1"> 3253 + The change controller for the following registrations is: 3254 + "IETF (iesg@ietf.org) - Internet Engineering Task Force".<a href="#section-8-1" class="pilcrow">¶</a></p> 3255 + <div id="field.name.registration"> 3256 + <section id="section-8.1"> 3257 + <h3 id="name-field-name-registration"> 3258 + <a href="#section-8.1" class="section-number selfRef">8.1. </a><a href="#name-field-name-registration" class="section-name selfRef">Field Name Registration</a> 3259 + </h3> 3260 + <p id="section-8.1-1"> 3261 + IANA has updated the "Hypertext Transfer Protocol (HTTP) Field 3262 + Name Registry" at <span>&lt;<a href="https://www.iana.org/assignments/http-fields">https://www.iana.org/assignments/http-fields</a>&gt;</span>, 3263 + as described in <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-18.4" class="relref">Section 18.4</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>, 3264 + with the field names listed in the table below:<a href="#section-8.1-1" class="pilcrow">¶</a></p> 3265 + <div id="iana.header.registration.table"> 3266 + <table class="left" id="table-1"> 3267 + <caption><a href="#table-1" class="selfRef">Table 1</a></caption> 3268 + <thead> 3269 + <tr> 3270 + <th class="text-left" rowspan="1" colspan="1">Field Name</th> 3271 + <th class="text-left" rowspan="1" colspan="1">Status</th> 3272 + <th class="text-left" rowspan="1" colspan="1">Section</th> 3273 + <th class="text-left" rowspan="1" colspan="1">Comments</th> 3274 + </tr> 3275 + </thead> 3276 + <tbody> 3277 + <tr> 3278 + <td class="text-left" rowspan="1" colspan="1">Age</td> 3279 + <td class="text-left" rowspan="1" colspan="1">permanent</td> 3280 + <td class="text-left" rowspan="1" colspan="1"> 3281 + <a href="#field.age" class="xref">5.1</a> 3282 + </td> 3283 + <td class="text-left" rowspan="1" colspan="1"></td> 3284 + </tr> 3285 + <tr> 3286 + <td class="text-left" rowspan="1" colspan="1">Cache-Control</td> 3287 + <td class="text-left" rowspan="1" colspan="1">permanent</td> 3288 + <td class="text-left" rowspan="1" colspan="1"> 3289 + <a href="#field.cache-control" class="xref">5.2</a> 3290 + </td> 3291 + <td class="text-left" rowspan="1" colspan="1"></td> 3292 + </tr> 3293 + <tr> 3294 + <td class="text-left" rowspan="1" colspan="1">Expires</td> 3295 + <td class="text-left" rowspan="1" colspan="1">permanent</td> 3296 + <td class="text-left" rowspan="1" colspan="1"> 3297 + <a href="#field.expires" class="xref">5.3</a> 3298 + </td> 3299 + <td class="text-left" rowspan="1" colspan="1"></td> 3300 + </tr> 3301 + <tr> 3302 + <td class="text-left" rowspan="1" colspan="1">Pragma</td> 3303 + <td class="text-left" rowspan="1" colspan="1">deprecated</td> 3304 + <td class="text-left" rowspan="1" colspan="1"> 3305 + <a href="#field.pragma" class="xref">5.4</a> 3306 + </td> 3307 + <td class="text-left" rowspan="1" colspan="1"></td> 3308 + </tr> 3309 + <tr> 3310 + <td class="text-left" rowspan="1" colspan="1">Warning</td> 3311 + <td class="text-left" rowspan="1" colspan="1">obsoleted</td> 3312 + <td class="text-left" rowspan="1" colspan="1"> 3313 + <a href="#field.warning" class="xref">5.5</a> 3314 + </td> 3315 + <td class="text-left" rowspan="1" colspan="1"></td> 3316 + </tr> 3317 + </tbody> 3318 + </table> 3319 + </div> 3320 + </section> 3321 + </div> 3322 + <div id="cache.directive.registration"> 3323 + <section id="section-8.2"> 3324 + <h3 id="name-cache-directive-registratio"> 3325 + <a href="#section-8.2" class="section-number selfRef">8.2. </a><a href="#name-cache-directive-registratio" class="section-name selfRef">Cache Directive Registration</a> 3326 + </h3> 3327 + <p id="section-8.2-1"> 3328 + IANA has updated the 3329 + "Hypertext Transfer Protocol (HTTP) Cache Directive Registry" 3330 + at <span>&lt;<a href="https://www.iana.org/assignments/http-cache-directives">https://www.iana.org/assignments/http-cache-directives</a>&gt;</span> 3331 + with the registration procedure per <a href="#cache.directive.registry" class="xref">Section 5.2.4</a> 3332 + and the cache directive names summarized in the table below.<a href="#section-8.2-1" class="pilcrow">¶</a></p> 3333 + <div id="iana.cache.directive.registration.table"> 3334 + <table class="left" id="table-2"> 3335 + <caption><a href="#table-2" class="selfRef">Table 2</a></caption> 3336 + <thead> 3337 + <tr> 3338 + <th class="text-left" rowspan="1" colspan="1">Cache Directive</th> 3339 + <th class="text-left" rowspan="1" colspan="1">Section</th> 3340 + </tr> 3341 + </thead> 3342 + <tbody> 3343 + <tr> 3344 + <td class="text-left" rowspan="1" colspan="1">max-age</td> 3345 + <td class="text-left" rowspan="1" colspan="1"> 3346 + <a href="#cache-request-directive.max-age" class="xref">5.2.1.1</a>, <a href="#cache-response-directive.max-age" class="xref">5.2.2.1</a> 3347 + </td> 3348 + </tr> 3349 + <tr> 3350 + <td class="text-left" rowspan="1" colspan="1">max-stale</td> 3351 + <td class="text-left" rowspan="1" colspan="1"> 3352 + <a href="#cache-request-directive.max-stale" class="xref">5.2.1.2</a> 3353 + </td> 3354 + </tr> 3355 + <tr> 3356 + <td class="text-left" rowspan="1" colspan="1">min-fresh</td> 3357 + <td class="text-left" rowspan="1" colspan="1"> 3358 + <a href="#cache-request-directive.min-fresh" class="xref">5.2.1.3</a> 3359 + </td> 3360 + </tr> 3361 + <tr> 3362 + <td class="text-left" rowspan="1" colspan="1">must-revalidate</td> 3363 + <td class="text-left" rowspan="1" colspan="1"> 3364 + <a href="#cache-response-directive.must-revalidate" class="xref">5.2.2.2</a> 3365 + </td> 3366 + </tr> 3367 + <tr> 3368 + <td class="text-left" rowspan="1" colspan="1">must-understand</td> 3369 + <td class="text-left" rowspan="1" colspan="1"> 3370 + <a href="#cache-response-directive.must-understand" class="xref">5.2.2.3</a> 3371 + </td> 3372 + </tr> 3373 + <tr> 3374 + <td class="text-left" rowspan="1" colspan="1">no-cache</td> 3375 + <td class="text-left" rowspan="1" colspan="1"> 3376 + <a href="#cache-request-directive.no-cache" class="xref">5.2.1.4</a>, <a href="#cache-response-directive.no-cache" class="xref">5.2.2.4</a> 3377 + </td> 3378 + </tr> 3379 + <tr> 3380 + <td class="text-left" rowspan="1" colspan="1">no-store</td> 3381 + <td class="text-left" rowspan="1" colspan="1"> 3382 + <a href="#cache-request-directive.no-store" class="xref">5.2.1.5</a>, <a href="#cache-response-directive.no-store" class="xref">5.2.2.5</a> 3383 + </td> 3384 + </tr> 3385 + <tr> 3386 + <td class="text-left" rowspan="1" colspan="1">no-transform</td> 3387 + <td class="text-left" rowspan="1" colspan="1"> 3388 + <a href="#cache-request-directive.no-transform" class="xref">5.2.1.6</a>, <a href="#cache-response-directive.no-transform" class="xref">5.2.2.6</a> 3389 + </td> 3390 + </tr> 3391 + <tr> 3392 + <td class="text-left" rowspan="1" colspan="1">only-if-cached</td> 3393 + <td class="text-left" rowspan="1" colspan="1"> 3394 + <a href="#cache-request-directive.only-if-cached" class="xref">5.2.1.7</a> 3395 + </td> 3396 + </tr> 3397 + <tr> 3398 + <td class="text-left" rowspan="1" colspan="1">private</td> 3399 + <td class="text-left" rowspan="1" colspan="1"> 3400 + <a href="#cache-response-directive.private" class="xref">5.2.2.7</a> 3401 + </td> 3402 + </tr> 3403 + <tr> 3404 + <td class="text-left" rowspan="1" colspan="1">proxy-revalidate</td> 3405 + <td class="text-left" rowspan="1" colspan="1"> 3406 + <a href="#cache-response-directive.proxy-revalidate" class="xref">5.2.2.8</a> 3407 + </td> 3408 + </tr> 3409 + <tr> 3410 + <td class="text-left" rowspan="1" colspan="1">public</td> 3411 + <td class="text-left" rowspan="1" colspan="1"> 3412 + <a href="#cache-response-directive.public" class="xref">5.2.2.9</a> 3413 + </td> 3414 + </tr> 3415 + <tr> 3416 + <td class="text-left" rowspan="1" colspan="1">s-maxage</td> 3417 + <td class="text-left" rowspan="1" colspan="1"> 3418 + <a href="#cache-response-directive.s-maxage" class="xref">5.2.2.10</a> 3419 + </td> 3420 + </tr> 3421 + </tbody> 3422 + </table> 3423 + </div> 3424 + </section> 3425 + </div> 3426 + <div id="warn.code.registration"> 3427 + <section id="section-8.3"> 3428 + <h3 id="name-warn-code-registry"> 3429 + <a href="#section-8.3" class="section-number selfRef">8.3. </a><a href="#name-warn-code-registry" class="section-name selfRef">Warn Code Registry</a> 3430 + </h3> 3431 + <p id="section-8.3-1"> 3432 + IANA has added the following note to the "Hypertext Transfer Protocol (HTTP) Warn Codes" 3433 + registry at <span>&lt;<a href="https://www.iana.org/assignments/http-warn-codes">https://www.iana.org/assignments/http-warn-codes</a>&gt;</span> 3434 + stating that "Warning" has been obsoleted:<a href="#section-8.3-1" class="pilcrow">¶</a></p> 3435 + <blockquote id="section-8.3-2"> 3436 + <p id="section-8.3-2.1"> 3437 + The Warning header field (and the warn codes that it uses) has been obsoleted 3438 + for HTTP per [RFC9111].<a href="#section-8.3-2.1" class="pilcrow">¶</a></p> 3439 + </blockquote> 3440 + </section> 3441 + </div> 3442 + </section> 3443 + </div> 3444 + <section id="section-9"> 3445 + <h2 id="name-references"> 3446 + <a href="#section-9" class="section-number selfRef">9. </a><a href="#name-references" class="section-name selfRef">References</a> 3447 + </h2> 3448 + <section id="section-9.1"> 3449 + <h3 id="name-normative-references"> 3450 + <a href="#section-9.1" class="section-number selfRef">9.1. </a><a href="#name-normative-references" class="section-name selfRef">Normative References</a> 3451 + </h3> 3452 + <dl class="references"> 3453 + <dt id="HTTP">[HTTP]</dt> 3454 + <dd> 3455 + <span class="refAuthor">Fielding, R., Ed.</span>, <span class="refAuthor">Nottingham, M., Ed.</span>, and <span class="refAuthor">J. Reschke, Ed.</span>, <span class="refTitle">"HTTP Semantics"</span>, <span class="seriesInfo">STD 97</span>, <span class="seriesInfo">RFC 9110</span>, <span class="seriesInfo">DOI 10.17487/RFC9110</span>, <time datetime="2022-06" class="refDate">June 2022</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc9110">https://www.rfc-editor.org/info/rfc9110</a>&gt;</span>. </dd> 3456 + <dd class="break"></dd> 3457 + <dt id="RFC2119">[RFC2119]</dt> 3458 + <dd> 3459 + <span class="refAuthor">Bradner, S.</span>, <span class="refTitle">"Key words for use in RFCs to Indicate Requirement Levels"</span>, <span class="seriesInfo">BCP 14</span>, <span class="seriesInfo">RFC 2119</span>, <span class="seriesInfo">DOI 10.17487/RFC2119</span>, <time datetime="1997-03" class="refDate">March 1997</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc2119">https://www.rfc-editor.org/info/rfc2119</a>&gt;</span>. </dd> 3460 + <dd class="break"></dd> 3461 + <dt id="RFC5234">[RFC5234]</dt> 3462 + <dd> 3463 + <span class="refAuthor">Crocker, D., Ed.</span> and <span class="refAuthor">P. Overell</span>, <span class="refTitle">"Augmented BNF for Syntax Specifications: ABNF"</span>, <span class="seriesInfo">STD 68</span>, <span class="seriesInfo">RFC 5234</span>, <span class="seriesInfo">DOI 10.17487/RFC5234</span>, <time datetime="2008-01" class="refDate">January 2008</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc5234">https://www.rfc-editor.org/info/rfc5234</a>&gt;</span>. </dd> 3464 + <dd class="break"></dd> 3465 + <dt id="RFC7405">[RFC7405]</dt> 3466 + <dd> 3467 + <span class="refAuthor">Kyzivat, P.</span>, <span class="refTitle">"Case-Sensitive String Support in ABNF"</span>, <span class="seriesInfo">RFC 7405</span>, <span class="seriesInfo">DOI 10.17487/RFC7405</span>, <time datetime="2014-12" class="refDate">December 2014</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc7405">https://www.rfc-editor.org/info/rfc7405</a>&gt;</span>. </dd> 3468 + <dd class="break"></dd> 3469 + <dt id="RFC8174">[RFC8174]</dt> 3470 + <dd> 3471 + <span class="refAuthor">Leiba, B.</span>, <span class="refTitle">"Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words"</span>, <span class="seriesInfo">BCP 14</span>, <span class="seriesInfo">RFC 8174</span>, <span class="seriesInfo">DOI 10.17487/RFC8174</span>, <time datetime="2017-05" class="refDate">May 2017</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc8174">https://www.rfc-editor.org/info/rfc8174</a>&gt;</span>. </dd> 3472 + <dd class="break"></dd> 3473 + </dl> 3474 + </section> 3475 + <section id="section-9.2"> 3476 + <h3 id="name-informative-references"> 3477 + <a href="#section-9.2" class="section-number selfRef">9.2. </a><a href="#name-informative-references" class="section-name selfRef">Informative References</a> 3478 + </h3> 3479 + <dl class="references"> 3480 + <dt id="COOKIE">[COOKIE]</dt> 3481 + <dd> 3482 + <span class="refAuthor">Barth, A.</span>, <span class="refTitle">"HTTP State Management Mechanism"</span>, <span class="seriesInfo">RFC 6265</span>, <span class="seriesInfo">DOI 10.17487/RFC6265</span>, <time datetime="2011-04" class="refDate">April 2011</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc6265">https://www.rfc-editor.org/info/rfc6265</a>&gt;</span>. </dd> 3483 + <dd class="break"></dd> 3484 + <dt id="HTTP11">[HTTP/1.1]</dt> 3485 + <dd> 3486 + <span class="refAuthor">Fielding, R., Ed.</span>, <span class="refAuthor">Nottingham, M., Ed.</span>, and <span class="refAuthor">J. Reschke, Ed.</span>, <span class="refTitle">"HTTP/1.1"</span>, <span class="seriesInfo">STD 99</span>, <span class="seriesInfo">RFC 9112</span>, <span class="seriesInfo">DOI 10.17487/RFC9112</span>, <time datetime="2022-06" class="refDate">June 2022</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc9112">https://www.rfc-editor.org/info/rfc9112</a>&gt;</span>. </dd> 3487 + <dd class="break"></dd> 3488 + <dt id="RFC2616">[RFC2616]</dt> 3489 + <dd> 3490 + <span class="refAuthor">Fielding, R.</span>, <span class="refAuthor">Gettys, J.</span>, <span class="refAuthor">Mogul, J.</span>, <span class="refAuthor">Frystyk, H.</span>, <span class="refAuthor">Masinter, L.</span>, <span class="refAuthor">Leach, P.</span>, and <span class="refAuthor">T. Berners-Lee</span>, <span class="refTitle">"Hypertext Transfer Protocol -- HTTP/1.1"</span>, <span class="seriesInfo">RFC 2616</span>, <span class="seriesInfo">DOI 10.17487/RFC2616</span>, <time datetime="1999-06" class="refDate">June 1999</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc2616">https://www.rfc-editor.org/info/rfc2616</a>&gt;</span>. </dd> 3491 + <dd class="break"></dd> 3492 + <dt id="RFC5861">[RFC5861]</dt> 3493 + <dd> 3494 + <span class="refAuthor">Nottingham, M.</span>, <span class="refTitle">"HTTP Cache-Control Extensions for Stale Content"</span>, <span class="seriesInfo">RFC 5861</span>, <span class="seriesInfo">DOI 10.17487/RFC5861</span>, <time datetime="2010-05" class="refDate">May 2010</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc5861">https://www.rfc-editor.org/info/rfc5861</a>&gt;</span>. </dd> 3495 + <dd class="break"></dd> 3496 + <dt id="RFC7234">[RFC7234]</dt> 3497 + <dd> 3498 + <span class="refAuthor">Fielding, R., Ed.</span>, <span class="refAuthor">Nottingham, M., Ed.</span>, and <span class="refAuthor">J. Reschke, Ed.</span>, <span class="refTitle">"Hypertext Transfer Protocol (HTTP/1.1): Caching"</span>, <span class="seriesInfo">RFC 7234</span>, <span class="seriesInfo">DOI 10.17487/RFC7234</span>, <time datetime="2014-06" class="refDate">June 2014</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc7234">https://www.rfc-editor.org/info/rfc7234</a>&gt;</span>. </dd> 3499 + <dd class="break"></dd> 3500 + <dt id="RFC8126">[RFC8126]</dt> 3501 + <dd> 3502 + <span class="refAuthor">Cotton, M.</span>, <span class="refAuthor">Leiba, B.</span>, and <span class="refAuthor">T. Narten</span>, <span class="refTitle">"Guidelines for Writing an IANA Considerations Section in RFCs"</span>, <span class="seriesInfo">BCP 26</span>, <span class="seriesInfo">RFC 8126</span>, <span class="seriesInfo">DOI 10.17487/RFC8126</span>, <time datetime="2017-06" class="refDate">June 2017</time>, <span>&lt;<a href="https://www.rfc-editor.org/info/rfc8126">https://www.rfc-editor.org/info/rfc8126</a>&gt;</span>. </dd> 3503 + <dd class="break"></dd> 3504 + </dl> 3505 + </section> 3506 + </section> 3507 + <div id="collected.abnf"> 3508 + <section id="appendix-A"> 3509 + <h2 id="name-collected-abnf"> 3510 + <a href="#appendix-A" class="section-number selfRef">Appendix A. </a><a href="#name-collected-abnf" class="section-name selfRef">Collected ABNF</a> 3511 + </h2> 3512 + <p id="appendix-A-1">In the collected ABNF below, list rules are expanded per <span><a href="https://www.rfc-editor.org/rfc/rfc9110#section-5.6.1" class="relref">Section 5.6.1</a> of [<a href="#HTTP" class="xref">HTTP</a>]</span>.<a href="#appendix-A-1" class="pilcrow">¶</a></p> 3513 + <div id="appendix-A-2"> 3514 + <pre class="lang-abnf sourcecode">Age = delta-seconds 3515 + 3516 + Cache-Control = [ cache-directive *( OWS "," OWS cache-directive ) ] 3517 + 3518 + Expires = HTTP-date 3519 + 3520 + HTTP-date = &lt;HTTP-date, see [HTTP], Section 5.6.7&gt; 3521 + 3522 + OWS = &lt;OWS, see [HTTP], Section 5.6.3&gt; 3523 + 3524 + cache-directive = token [ "=" ( token / quoted-string ) ] 3525 + 3526 + delta-seconds = 1*DIGIT 3527 + 3528 + field-name = &lt;field-name, see [HTTP], Section 5.1&gt; 3529 + 3530 + quoted-string = &lt;quoted-string, see [HTTP], Section 5.6.4&gt; 3531 + 3532 + token = &lt;token, see [HTTP], Section 5.6.2&gt; 3533 + </pre><a href="#appendix-A-2" class="pilcrow">¶</a> 3534 + </div> 3535 + </section> 3536 + </div> 3537 + <div id="changes.from.rfc.7234"> 3538 + <section id="appendix-B"> 3539 + <h2 id="name-changes-from-rfc-7234"> 3540 + <a href="#appendix-B" class="section-number selfRef">Appendix B. </a><a href="#name-changes-from-rfc-7234" class="section-name selfRef">Changes from RFC 7234</a> 3541 + </h2> 3542 + <p id="appendix-B-1"> 3543 + Handling of duplicate and conflicting cache directives has been clarified. 3544 + (<a href="#calculating.freshness.lifetime" class="xref">Section 4.2.1</a>)<a href="#appendix-B-1" class="pilcrow">¶</a></p> 3545 + <p id="appendix-B-2"> 3546 + Cache invalidation of the URIs in the Location and Content-Location 3547 + header fields is no longer required but is still allowed. 3548 + (<a href="#invalidation" class="xref">Section 4.4</a>)<a href="#appendix-B-2" class="pilcrow">¶</a></p> 3549 + <p id="appendix-B-3"> 3550 + Cache invalidation of the URIs in the Location and Content-Location header fields is disallowed 3551 + when the origin is different; previously, it was the host. 3552 + (<a href="#invalidation" class="xref">Section 4.4</a>)<a href="#appendix-B-3" class="pilcrow">¶</a></p> 3553 + <p id="appendix-B-4"> 3554 + Handling invalid and multiple Age header field values has been clarified. 3555 + (<a href="#field.age" class="xref">Section 5.1</a>)<a href="#appendix-B-4" class="pilcrow">¶</a></p> 3556 + <p id="appendix-B-5"> 3557 + Some cache directives defined by this specification now have stronger 3558 + prohibitions against generating the quoted form of their values, since 3559 + this has been found to create interoperability problems. Consumers of 3560 + extension cache directives are no longer required to accept both token and 3561 + quoted-string forms, but they still need to parse them properly for 3562 + unknown extensions. 3563 + (<a href="#field.cache-control" class="xref">Section 5.2</a>)<a href="#appendix-B-5" class="pilcrow">¶</a></p> 3564 + <p id="appendix-B-6"> 3565 + The public and private cache directives were clarified, so that they 3566 + do not make responses reusable under any condition. 3567 + (<a href="#cache-response-directive" class="xref">Section 5.2.2</a>)<a href="#appendix-B-6" class="pilcrow">¶</a></p> 3568 + <p id="appendix-B-7"> 3569 + The must-understand cache directive was introduced; caches are no 3570 + longer required to understand the semantics of new response status codes 3571 + unless it is present. 3572 + (<a href="#cache-response-directive.must-understand" class="xref">Section 5.2.2.3</a>)<a href="#appendix-B-7" class="pilcrow">¶</a></p> 3573 + <p id="appendix-B-8"> 3574 + The Warning response header was obsoleted. Much of the information 3575 + supported by Warning could be gleaned by examining the response, and the 3576 + remaining information -- although potentially useful -- was entirely 3577 + advisory. In practice, Warning was not added by caches or intermediaries. 3578 + (<a href="#field.warning" class="xref">Section 5.5</a>)<a href="#appendix-B-8" class="pilcrow">¶</a></p> 3579 + </section> 3580 + </div> 3581 + <div id="acks"> 3582 + <section id="appendix-C"> 3583 + <h2 id="name-acknowledgements"> 3584 + <a href="#name-acknowledgements" class="section-name selfRef">Acknowledgements</a> 3585 + </h2> 3586 + <p id="appendix-C-1"> 3587 + See Appendix "Acknowledgements" of <span>[<a href="#HTTP" class="xref">HTTP</a>]</span>, which applies to this document as well.<a href="#appendix-C-1" class="pilcrow">¶</a></p> 3588 + </section> 3589 + </div> 3590 + <section id="appendix-D"> 3591 + <h2 id="name-index"> 3592 + <a href="#name-index" class="section-name selfRef">Index</a> 3593 + </h2> 3594 + <div id="rfc.index.index"> 3595 + <p id="appendix-D-1"> 3596 + <a href="#rfc.index.u65" class="xref">A</a> 3597 + <a href="#rfc.index.u67" class="xref">C</a> 3598 + <a href="#rfc.index.u69" class="xref">E</a> 3599 + <a href="#rfc.index.u70" class="xref">F</a> 3600 + <a href="#rfc.index.u71" class="xref">G</a> 3601 + <a href="#rfc.index.u72" class="xref">H</a> 3602 + <a href="#rfc.index.u77" class="xref">M</a> 3603 + <a href="#rfc.index.u78" class="xref">N</a> 3604 + <a href="#rfc.index.u79" class="xref">O</a> 3605 + <a href="#rfc.index.u80" class="xref">P</a> 3606 + <a href="#rfc.index.u83" class="xref">S</a> 3607 + <a href="#rfc.index.u86" class="xref">V</a> 3608 + <a href="#rfc.index.u87" class="xref">W</a><a href="#appendix-D-1" class="pilcrow">¶</a></p> 3609 + </div> 3610 + <ul class="normal ulEmpty"> 3611 + <li class="normal ulEmpty" id="appendix-D-2.1"> 3612 + <div id="rfc.index.u65"> 3613 + <p id="appendix-D-2.1.1" class="keepWithNext"> 3614 + <a href="#rfc.index.u65" class="xref">A</a><a href="#appendix-D-2.1.1" class="pilcrow">¶</a></p> 3615 + </div> 3616 + <ul class="compact normal ulEmpty"> 3617 + <li class="compact normal ulEmpty" id="appendix-D-2.1.2.1"> 3618 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.1.2.1.1"> 3619 + <dt id="appendix-D-2.1.2.1.1.1">age</dt> 3620 + <dd style="margin-left: 1.5em" id="appendix-D-2.1.2.1.1.2"> 3621 + <p id="appendix-D-2.1.2.1.1.2.1"> 3622 + <a href="#expiration.model" class="xref">Section 4.2</a><a href="#appendix-D-2.1.2.1.1.2.1" class="pilcrow">¶</a></p> 3623 + </dd> 3624 + <dd class="break"></dd> 3625 + <dt id="appendix-D-2.1.2.1.1.3">Age header field</dt> 3626 + <dd style="margin-left: 1.5em" id="appendix-D-2.1.2.1.1.4"> 3627 + <p id="appendix-D-2.1.2.1.1.4.1"> 3628 + <strong><em><a href="#field.age" class="xref">Section 5.1</a></em></strong><a href="#appendix-D-2.1.2.1.1.4.1" class="pilcrow">¶</a></p> 3629 + </dd> 3630 + <dd class="break"></dd> 3631 + </dl> 3632 + </li> 3633 + </ul> 3634 + </li> 3635 + <li class="normal ulEmpty" id="appendix-D-2.2"> 3636 + <div id="rfc.index.u67"> 3637 + <p id="appendix-D-2.2.1" class="keepWithNext"> 3638 + <a href="#rfc.index.u67" class="xref">C</a><a href="#appendix-D-2.2.1" class="pilcrow">¶</a></p> 3639 + </div> 3640 + <ul class="compact normal ulEmpty"> 3641 + <li class="compact normal ulEmpty" id="appendix-D-2.2.2.1"> 3642 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.2.2.1.1"> 3643 + <dt id="appendix-D-2.2.2.1.1.1">cache</dt> 3644 + <dd style="margin-left: 1.5em" id="appendix-D-2.2.2.1.1.2"> 3645 + <p id="appendix-D-2.2.2.1.1.2.1"> 3646 + <a href="#caching" class="xref">Section 1</a><a href="#appendix-D-2.2.2.1.1.2.1" class="pilcrow">¶</a></p> 3647 + </dd> 3648 + <dd class="break"></dd> 3649 + <dt id="appendix-D-2.2.2.1.1.3">cache key</dt> 3650 + <dd style="margin-left: 1.5em" id="appendix-D-2.2.2.1.1.4"> 3651 + <p id="appendix-D-2.2.2.1.1.4.1"> 3652 + <a href="#caching.overview" class="xref">Section 2</a>; 3653 + <a href="#caching.overview" class="xref">Section 2</a><a href="#appendix-D-2.2.2.1.1.4.1" class="pilcrow">¶</a></p> 3654 + </dd> 3655 + <dd class="break"></dd> 3656 + <dt id="appendix-D-2.2.2.1.1.5">Cache-Control header field</dt> 3657 + <dd style="margin-left: 1.5em" id="appendix-D-2.2.2.1.1.6"> 3658 + <p id="appendix-D-2.2.2.1.1.6.1"> 3659 + <strong><em><a href="#field.cache-control" class="xref">Section 5.2</a></em></strong><a href="#appendix-D-2.2.2.1.1.6.1" class="pilcrow">¶</a></p> 3660 + </dd> 3661 + <dd class="break"></dd> 3662 + <dt id="appendix-D-2.2.2.1.1.7">collapsed requests</dt> 3663 + <dd style="margin-left: 1.5em" id="appendix-D-2.2.2.1.1.8"> 3664 + <p id="appendix-D-2.2.2.1.1.8.1"> 3665 + <a href="#constructing.responses.from.caches" class="xref">Section 4</a><a href="#appendix-D-2.2.2.1.1.8.1" class="pilcrow">¶</a></p> 3666 + </dd> 3667 + <dd class="break"></dd> 3668 + </dl> 3669 + </li> 3670 + </ul> 3671 + </li> 3672 + <li class="normal ulEmpty" id="appendix-D-2.3"> 3673 + <div id="rfc.index.u69"> 3674 + <p id="appendix-D-2.3.1" class="keepWithNext"> 3675 + <a href="#rfc.index.u69" class="xref">E</a><a href="#appendix-D-2.3.1" class="pilcrow">¶</a></p> 3676 + </div> 3677 + <ul class="compact normal ulEmpty"> 3678 + <li class="compact normal ulEmpty" id="appendix-D-2.3.2.1"> 3679 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.3.2.1.1"> 3680 + <dt id="appendix-D-2.3.2.1.1.1">Expires header field</dt> 3681 + <dd style="margin-left: 1.5em" id="appendix-D-2.3.2.1.1.2"> 3682 + <p id="appendix-D-2.3.2.1.1.2.1"> 3683 + <strong><em><a href="#field.expires" class="xref">Section 5.3</a></em></strong><a href="#appendix-D-2.3.2.1.1.2.1" class="pilcrow">¶</a></p> 3684 + </dd> 3685 + <dd class="break"></dd> 3686 + <dt id="appendix-D-2.3.2.1.1.3">explicit expiration time</dt> 3687 + <dd style="margin-left: 1.5em" id="appendix-D-2.3.2.1.1.4"> 3688 + <p id="appendix-D-2.3.2.1.1.4.1"> 3689 + <a href="#expiration.model" class="xref">Section 4.2</a><a href="#appendix-D-2.3.2.1.1.4.1" class="pilcrow">¶</a></p> 3690 + </dd> 3691 + <dd class="break"></dd> 3692 + </dl> 3693 + </li> 3694 + </ul> 3695 + </li> 3696 + <li class="normal ulEmpty" id="appendix-D-2.4"> 3697 + <div id="rfc.index.u70"> 3698 + <p id="appendix-D-2.4.1" class="keepWithNext"> 3699 + <a href="#rfc.index.u70" class="xref">F</a><a href="#appendix-D-2.4.1" class="pilcrow">¶</a></p> 3700 + </div> 3701 + <ul class="compact normal ulEmpty"> 3702 + <li class="compact normal ulEmpty" id="appendix-D-2.4.2.1"> 3703 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.4.2.1.1"> 3704 + <dt id="appendix-D-2.4.2.1.1.1">Fields</dt> 3705 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.2"></dd> 3706 + <dd class="break"></dd> 3707 + <dt id="appendix-D-2.4.2.1.1.3"></dt> 3708 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.4"> 3709 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.4.2.1.1.4.1"> 3710 + <dt id="appendix-D-2.4.2.1.1.4.1.1">Age</dt> 3711 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.4.1.2"> 3712 + <p id="appendix-D-2.4.2.1.1.4.1.2.1"> 3713 + <strong><em><a href="#field.age" class="xref">Section 5.1</a></em></strong>; 3714 + <strong><em><a href="#field.age" class="xref">Section 5.1</a></em></strong><a href="#appendix-D-2.4.2.1.1.4.1.2.1" class="pilcrow">¶</a></p> 3715 + </dd> 3716 + <dd class="break"></dd> 3717 + <dt id="appendix-D-2.4.2.1.1.4.1.3">Cache-Control</dt> 3718 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.4.1.4"> 3719 + <p id="appendix-D-2.4.2.1.1.4.1.4.1"> 3720 + <strong><em><a href="#field.cache-control" class="xref">Section 5.2</a></em></strong><a href="#appendix-D-2.4.2.1.1.4.1.4.1" class="pilcrow">¶</a></p> 3721 + </dd> 3722 + <dd class="break"></dd> 3723 + <dt id="appendix-D-2.4.2.1.1.4.1.5">Expires</dt> 3724 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.4.1.6"> 3725 + <p id="appendix-D-2.4.2.1.1.4.1.6.1"> 3726 + <strong><em><a href="#field.expires" class="xref">Section 5.3</a></em></strong>; 3727 + <strong><em><a href="#field.expires" class="xref">Section 5.3</a></em></strong><a href="#appendix-D-2.4.2.1.1.4.1.6.1" class="pilcrow">¶</a></p> 3728 + </dd> 3729 + <dd class="break"></dd> 3730 + <dt id="appendix-D-2.4.2.1.1.4.1.7">Pragma</dt> 3731 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.4.1.8"> 3732 + <p id="appendix-D-2.4.2.1.1.4.1.8.1"> 3733 + <strong><em><a href="#field.pragma" class="xref">Section 5.4</a></em></strong>; 3734 + <strong><em><a href="#field.pragma" class="xref">Section 5.4</a></em></strong><a href="#appendix-D-2.4.2.1.1.4.1.8.1" class="pilcrow">¶</a></p> 3735 + </dd> 3736 + <dd class="break"></dd> 3737 + <dt id="appendix-D-2.4.2.1.1.4.1.9">Warning</dt> 3738 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.4.1.10"> 3739 + <p id="appendix-D-2.4.2.1.1.4.1.10.1"> 3740 + <strong><em><a href="#field.warning" class="xref">Section 5.5</a></em></strong><a href="#appendix-D-2.4.2.1.1.4.1.10.1" class="pilcrow">¶</a></p> 3741 + </dd> 3742 + <dd class="break"></dd> 3743 + </dl> 3744 + </dd> 3745 + <dd class="break"></dd> 3746 + <dt id="appendix-D-2.4.2.1.1.5">fresh</dt> 3747 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.6"> 3748 + <p id="appendix-D-2.4.2.1.1.6.1"> 3749 + <a href="#expiration.model" class="xref">Section 4.2</a><a href="#appendix-D-2.4.2.1.1.6.1" class="pilcrow">¶</a></p> 3750 + </dd> 3751 + <dd class="break"></dd> 3752 + <dt id="appendix-D-2.4.2.1.1.7">freshness lifetime</dt> 3753 + <dd style="margin-left: 1.5em" id="appendix-D-2.4.2.1.1.8"> 3754 + <p id="appendix-D-2.4.2.1.1.8.1"> 3755 + <a href="#expiration.model" class="xref">Section 4.2</a><a href="#appendix-D-2.4.2.1.1.8.1" class="pilcrow">¶</a></p> 3756 + </dd> 3757 + <dd class="break"></dd> 3758 + </dl> 3759 + </li> 3760 + </ul> 3761 + </li> 3762 + <li class="normal ulEmpty" id="appendix-D-2.5"> 3763 + <div id="rfc.index.u71"> 3764 + <p id="appendix-D-2.5.1" class="keepWithNext"> 3765 + <a href="#rfc.index.u71" class="xref">G</a><a href="#appendix-D-2.5.1" class="pilcrow">¶</a></p> 3766 + </div> 3767 + <ul class="compact normal ulEmpty"> 3768 + <li class="compact normal ulEmpty" id="appendix-D-2.5.2.1"> 3769 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.5.2.1.1"> 3770 + <dt id="appendix-D-2.5.2.1.1.1">Grammar</dt> 3771 + <dd style="margin-left: 1.5em" id="appendix-D-2.5.2.1.1.2"></dd> 3772 + <dd class="break"></dd> 3773 + <dt id="appendix-D-2.5.2.1.1.3"></dt> 3774 + <dd style="margin-left: 1.5em" id="appendix-D-2.5.2.1.1.4"> 3775 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.5.2.1.1.4.1"> 3776 + <dt id="appendix-D-2.5.2.1.1.4.1.1">Age</dt> 3777 + <dd style="margin-left: 1.5em" id="appendix-D-2.5.2.1.1.4.1.2"> 3778 + <p id="appendix-D-2.5.2.1.1.4.1.2.1"> 3779 + <strong><em><a href="#field.age" class="xref">Section 5.1</a></em></strong><a href="#appendix-D-2.5.2.1.1.4.1.2.1" class="pilcrow">¶</a></p> 3780 + </dd> 3781 + <dd class="break"></dd> 3782 + <dt id="appendix-D-2.5.2.1.1.4.1.3">Cache-Control</dt> 3783 + <dd style="margin-left: 1.5em" id="appendix-D-2.5.2.1.1.4.1.4"> 3784 + <p id="appendix-D-2.5.2.1.1.4.1.4.1"> 3785 + <strong><em><a href="#field.cache-control" class="xref">Section 5.2</a></em></strong><a href="#appendix-D-2.5.2.1.1.4.1.4.1" class="pilcrow">¶</a></p> 3786 + </dd> 3787 + <dd class="break"></dd> 3788 + <dt id="appendix-D-2.5.2.1.1.4.1.5">DIGIT</dt> 3789 + <dd style="margin-left: 1.5em" id="appendix-D-2.5.2.1.1.4.1.6"> 3790 + <p id="appendix-D-2.5.2.1.1.4.1.6.1"> 3791 + <strong><em><a href="#notation" class="xref">Section 1.2</a></em></strong><a href="#appendix-D-2.5.2.1.1.4.1.6.1" class="pilcrow">¶</a></p> 3792 + </dd> 3793 + <dd class="break"></dd> 3794 + <dt id="appendix-D-2.5.2.1.1.4.1.7">Expires</dt> 3795 + <dd style="margin-left: 1.5em" id="appendix-D-2.5.2.1.1.4.1.8"> 3796 + <p id="appendix-D-2.5.2.1.1.4.1.8.1"> 3797 + <strong><em><a href="#field.expires" class="xref">Section 5.3</a></em></strong><a href="#appendix-D-2.5.2.1.1.4.1.8.1" class="pilcrow">¶</a></p> 3798 + </dd> 3799 + <dd class="break"></dd> 3800 + <dt id="appendix-D-2.5.2.1.1.4.1.9">cache-directive</dt> 3801 + <dd style="margin-left: 1.5em" id="appendix-D-2.5.2.1.1.4.1.10"> 3802 + <p id="appendix-D-2.5.2.1.1.4.1.10.1"> 3803 + <strong><em><a href="#field.cache-control" class="xref">Section 5.2</a></em></strong><a href="#appendix-D-2.5.2.1.1.4.1.10.1" class="pilcrow">¶</a></p> 3804 + </dd> 3805 + <dd class="break"></dd> 3806 + <dt id="appendix-D-2.5.2.1.1.4.1.11">delta-seconds</dt> 3807 + <dd style="margin-left: 1.5em" id="appendix-D-2.5.2.1.1.4.1.12"> 3808 + <p id="appendix-D-2.5.2.1.1.4.1.12.1"> 3809 + <strong><em><a href="#delta-seconds" class="xref">Section 1.2.2</a></em></strong><a href="#appendix-D-2.5.2.1.1.4.1.12.1" class="pilcrow">¶</a></p> 3810 + </dd> 3811 + <dd class="break"></dd> 3812 + </dl> 3813 + </dd> 3814 + <dd class="break"></dd> 3815 + </dl> 3816 + </li> 3817 + </ul> 3818 + </li> 3819 + <li class="normal ulEmpty" id="appendix-D-2.6"> 3820 + <div id="rfc.index.u72"> 3821 + <p id="appendix-D-2.6.1" class="keepWithNext"> 3822 + <a href="#rfc.index.u72" class="xref">H</a><a href="#appendix-D-2.6.1" class="pilcrow">¶</a></p> 3823 + </div> 3824 + <ul class="compact normal ulEmpty"> 3825 + <li class="compact normal ulEmpty" id="appendix-D-2.6.2.1"> 3826 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.6.2.1.1"> 3827 + <dt id="appendix-D-2.6.2.1.1.1">Header Fields</dt> 3828 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.2"></dd> 3829 + <dd class="break"></dd> 3830 + <dt id="appendix-D-2.6.2.1.1.3"></dt> 3831 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.4"> 3832 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.6.2.1.1.4.1"> 3833 + <dt id="appendix-D-2.6.2.1.1.4.1.1">Age</dt> 3834 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.4.1.2"> 3835 + <p id="appendix-D-2.6.2.1.1.4.1.2.1"> 3836 + <strong><em><a href="#field.age" class="xref">Section 5.1</a></em></strong>; 3837 + <strong><em><a href="#field.age" class="xref">Section 5.1</a></em></strong><a href="#appendix-D-2.6.2.1.1.4.1.2.1" class="pilcrow">¶</a></p> 3838 + </dd> 3839 + <dd class="break"></dd> 3840 + <dt id="appendix-D-2.6.2.1.1.4.1.3">Cache-Control</dt> 3841 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.4.1.4"> 3842 + <p id="appendix-D-2.6.2.1.1.4.1.4.1"> 3843 + <strong><em><a href="#field.cache-control" class="xref">Section 5.2</a></em></strong><a href="#appendix-D-2.6.2.1.1.4.1.4.1" class="pilcrow">¶</a></p> 3844 + </dd> 3845 + <dd class="break"></dd> 3846 + <dt id="appendix-D-2.6.2.1.1.4.1.5">Expires</dt> 3847 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.4.1.6"> 3848 + <p id="appendix-D-2.6.2.1.1.4.1.6.1"> 3849 + <strong><em><a href="#field.expires" class="xref">Section 5.3</a></em></strong>; 3850 + <strong><em><a href="#field.expires" class="xref">Section 5.3</a></em></strong><a href="#appendix-D-2.6.2.1.1.4.1.6.1" class="pilcrow">¶</a></p> 3851 + </dd> 3852 + <dd class="break"></dd> 3853 + <dt id="appendix-D-2.6.2.1.1.4.1.7">Pragma</dt> 3854 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.4.1.8"> 3855 + <p id="appendix-D-2.6.2.1.1.4.1.8.1"> 3856 + <strong><em><a href="#field.pragma" class="xref">Section 5.4</a></em></strong>; 3857 + <strong><em><a href="#field.pragma" class="xref">Section 5.4</a></em></strong><a href="#appendix-D-2.6.2.1.1.4.1.8.1" class="pilcrow">¶</a></p> 3858 + </dd> 3859 + <dd class="break"></dd> 3860 + <dt id="appendix-D-2.6.2.1.1.4.1.9">Warning</dt> 3861 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.4.1.10"> 3862 + <p id="appendix-D-2.6.2.1.1.4.1.10.1"> 3863 + <strong><em><a href="#field.warning" class="xref">Section 5.5</a></em></strong><a href="#appendix-D-2.6.2.1.1.4.1.10.1" class="pilcrow">¶</a></p> 3864 + </dd> 3865 + <dd class="break"></dd> 3866 + </dl> 3867 + </dd> 3868 + <dd class="break"></dd> 3869 + <dt id="appendix-D-2.6.2.1.1.5">heuristic expiration time</dt> 3870 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.6"> 3871 + <p id="appendix-D-2.6.2.1.1.6.1"> 3872 + <a href="#expiration.model" class="xref">Section 4.2</a><a href="#appendix-D-2.6.2.1.1.6.1" class="pilcrow">¶</a></p> 3873 + </dd> 3874 + <dd class="break"></dd> 3875 + <dt id="appendix-D-2.6.2.1.1.7">heuristically cacheable</dt> 3876 + <dd style="margin-left: 1.5em" id="appendix-D-2.6.2.1.1.8"> 3877 + <p id="appendix-D-2.6.2.1.1.8.1"> 3878 + <a href="#heuristic.freshness" class="xref">Section 4.2.2</a><a href="#appendix-D-2.6.2.1.1.8.1" class="pilcrow">¶</a></p> 3879 + </dd> 3880 + <dd class="break"></dd> 3881 + </dl> 3882 + </li> 3883 + </ul> 3884 + </li> 3885 + <li class="normal ulEmpty" id="appendix-D-2.7"> 3886 + <div id="rfc.index.u77"> 3887 + <p id="appendix-D-2.7.1" class="keepWithNext"> 3888 + <a href="#rfc.index.u77" class="xref">M</a><a href="#appendix-D-2.7.1" class="pilcrow">¶</a></p> 3889 + </div> 3890 + <ul class="compact normal ulEmpty"> 3891 + <li class="compact normal ulEmpty" id="appendix-D-2.7.2.1"> 3892 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.7.2.1.1"> 3893 + <dt id="appendix-D-2.7.2.1.1.1">max-age (cache directive)</dt> 3894 + <dd style="margin-left: 1.5em" id="appendix-D-2.7.2.1.1.2"> 3895 + <p id="appendix-D-2.7.2.1.1.2.1"> 3896 + <strong><em><a href="#cache-request-directive.max-age" class="xref">Section 5.2.1.1</a></em></strong>; 3897 + <strong><em><a href="#cache-response-directive.max-age" class="xref">Section 5.2.2.1</a></em></strong><a href="#appendix-D-2.7.2.1.1.2.1" class="pilcrow">¶</a></p> 3898 + </dd> 3899 + <dd class="break"></dd> 3900 + <dt id="appendix-D-2.7.2.1.1.3">max-stale (cache directive)</dt> 3901 + <dd style="margin-left: 1.5em" id="appendix-D-2.7.2.1.1.4"> 3902 + <p id="appendix-D-2.7.2.1.1.4.1"> 3903 + <strong><em><a href="#cache-request-directive.max-stale" class="xref">Section 5.2.1.2</a></em></strong><a href="#appendix-D-2.7.2.1.1.4.1" class="pilcrow">¶</a></p> 3904 + </dd> 3905 + <dd class="break"></dd> 3906 + <dt id="appendix-D-2.7.2.1.1.5">min-fresh (cache directive)</dt> 3907 + <dd style="margin-left: 1.5em" id="appendix-D-2.7.2.1.1.6"> 3908 + <p id="appendix-D-2.7.2.1.1.6.1"> 3909 + <strong><em><a href="#cache-request-directive.min-fresh" class="xref">Section 5.2.1.3</a></em></strong><a href="#appendix-D-2.7.2.1.1.6.1" class="pilcrow">¶</a></p> 3910 + </dd> 3911 + <dd class="break"></dd> 3912 + <dt id="appendix-D-2.7.2.1.1.7">must-revalidate (cache directive)</dt> 3913 + <dd style="margin-left: 1.5em" id="appendix-D-2.7.2.1.1.8"> 3914 + <p id="appendix-D-2.7.2.1.1.8.1"> 3915 + <strong><em><a href="#cache-response-directive.must-revalidate" class="xref">Section 5.2.2.2</a></em></strong><a href="#appendix-D-2.7.2.1.1.8.1" class="pilcrow">¶</a></p> 3916 + </dd> 3917 + <dd class="break"></dd> 3918 + <dt id="appendix-D-2.7.2.1.1.9">must-understand (cache directive)</dt> 3919 + <dd style="margin-left: 1.5em" id="appendix-D-2.7.2.1.1.10"> 3920 + <p id="appendix-D-2.7.2.1.1.10.1"> 3921 + <strong><em><a href="#cache-response-directive.must-understand" class="xref">Section 5.2.2.3</a></em></strong><a href="#appendix-D-2.7.2.1.1.10.1" class="pilcrow">¶</a></p> 3922 + </dd> 3923 + <dd class="break"></dd> 3924 + </dl> 3925 + </li> 3926 + </ul> 3927 + </li> 3928 + <li class="normal ulEmpty" id="appendix-D-2.8"> 3929 + <div id="rfc.index.u78"> 3930 + <p id="appendix-D-2.8.1" class="keepWithNext"> 3931 + <a href="#rfc.index.u78" class="xref">N</a><a href="#appendix-D-2.8.1" class="pilcrow">¶</a></p> 3932 + </div> 3933 + <ul class="compact normal ulEmpty"> 3934 + <li class="compact normal ulEmpty" id="appendix-D-2.8.2.1"> 3935 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.8.2.1.1"> 3936 + <dt id="appendix-D-2.8.2.1.1.1">no-cache (cache directive)</dt> 3937 + <dd style="margin-left: 1.5em" id="appendix-D-2.8.2.1.1.2"> 3938 + <p id="appendix-D-2.8.2.1.1.2.1"> 3939 + <strong><em><a href="#cache-request-directive.no-cache" class="xref">Section 5.2.1.4</a></em></strong>; 3940 + <strong><em><a href="#cache-response-directive.no-cache" class="xref">Section 5.2.2.4</a></em></strong><a href="#appendix-D-2.8.2.1.1.2.1" class="pilcrow">¶</a></p> 3941 + </dd> 3942 + <dd class="break"></dd> 3943 + <dt id="appendix-D-2.8.2.1.1.3">no-store (cache directive)</dt> 3944 + <dd style="margin-left: 1.5em" id="appendix-D-2.8.2.1.1.4"> 3945 + <p id="appendix-D-2.8.2.1.1.4.1"> 3946 + <strong><em><a href="#cache-request-directive.no-store" class="xref">Section 5.2.1.5</a></em></strong>; 3947 + <strong><em><a href="#cache-response-directive.no-store" class="xref">Section 5.2.2.5</a></em></strong><a href="#appendix-D-2.8.2.1.1.4.1" class="pilcrow">¶</a></p> 3948 + </dd> 3949 + <dd class="break"></dd> 3950 + <dt id="appendix-D-2.8.2.1.1.5">no-transform (cache directive)</dt> 3951 + <dd style="margin-left: 1.5em" id="appendix-D-2.8.2.1.1.6"> 3952 + <p id="appendix-D-2.8.2.1.1.6.1"> 3953 + <strong><em><a href="#cache-request-directive.no-transform" class="xref">Section 5.2.1.6</a></em></strong>; 3954 + <strong><em><a href="#cache-response-directive.no-transform" class="xref">Section 5.2.2.6</a></em></strong><a href="#appendix-D-2.8.2.1.1.6.1" class="pilcrow">¶</a></p> 3955 + </dd> 3956 + <dd class="break"></dd> 3957 + </dl> 3958 + </li> 3959 + </ul> 3960 + </li> 3961 + <li class="normal ulEmpty" id="appendix-D-2.9"> 3962 + <div id="rfc.index.u79"> 3963 + <p id="appendix-D-2.9.1" class="keepWithNext"> 3964 + <a href="#rfc.index.u79" class="xref">O</a><a href="#appendix-D-2.9.1" class="pilcrow">¶</a></p> 3965 + </div> 3966 + <ul class="compact normal ulEmpty"> 3967 + <li class="compact normal ulEmpty" id="appendix-D-2.9.2.1"> 3968 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.9.2.1.1"> 3969 + <dt id="appendix-D-2.9.2.1.1.1">only-if-cached (cache directive)</dt> 3970 + <dd style="margin-left: 1.5em" id="appendix-D-2.9.2.1.1.2"> 3971 + <p id="appendix-D-2.9.2.1.1.2.1"> 3972 + <strong><em><a href="#cache-request-directive.only-if-cached" class="xref">Section 5.2.1.7</a></em></strong><a href="#appendix-D-2.9.2.1.1.2.1" class="pilcrow">¶</a></p> 3973 + </dd> 3974 + <dd class="break"></dd> 3975 + </dl> 3976 + </li> 3977 + </ul> 3978 + </li> 3979 + <li class="normal ulEmpty" id="appendix-D-2.10"> 3980 + <div id="rfc.index.u80"> 3981 + <p id="appendix-D-2.10.1" class="keepWithNext"> 3982 + <a href="#rfc.index.u80" class="xref">P</a><a href="#appendix-D-2.10.1" class="pilcrow">¶</a></p> 3983 + </div> 3984 + <ul class="compact normal ulEmpty"> 3985 + <li class="compact normal ulEmpty" id="appendix-D-2.10.2.1"> 3986 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.10.2.1.1"> 3987 + <dt id="appendix-D-2.10.2.1.1.1">Pragma header field</dt> 3988 + <dd style="margin-left: 1.5em" id="appendix-D-2.10.2.1.1.2"> 3989 + <p id="appendix-D-2.10.2.1.1.2.1"> 3990 + <strong><em><a href="#field.pragma" class="xref">Section 5.4</a></em></strong><a href="#appendix-D-2.10.2.1.1.2.1" class="pilcrow">¶</a></p> 3991 + </dd> 3992 + <dd class="break"></dd> 3993 + <dt id="appendix-D-2.10.2.1.1.3">private (cache directive)</dt> 3994 + <dd style="margin-left: 1.5em" id="appendix-D-2.10.2.1.1.4"> 3995 + <p id="appendix-D-2.10.2.1.1.4.1"> 3996 + <strong><em><a href="#cache-response-directive.private" class="xref">Section 5.2.2.7</a></em></strong><a href="#appendix-D-2.10.2.1.1.4.1" class="pilcrow">¶</a></p> 3997 + </dd> 3998 + <dd class="break"></dd> 3999 + <dt id="appendix-D-2.10.2.1.1.5">private cache</dt> 4000 + <dd style="margin-left: 1.5em" id="appendix-D-2.10.2.1.1.6"> 4001 + <p id="appendix-D-2.10.2.1.1.6.1"> 4002 + <a href="#caching" class="xref">Section 1</a><a href="#appendix-D-2.10.2.1.1.6.1" class="pilcrow">¶</a></p> 4003 + </dd> 4004 + <dd class="break"></dd> 4005 + <dt id="appendix-D-2.10.2.1.1.7">proxy-revalidate (cache directive)</dt> 4006 + <dd style="margin-left: 1.5em" id="appendix-D-2.10.2.1.1.8"> 4007 + <p id="appendix-D-2.10.2.1.1.8.1"> 4008 + <strong><em><a href="#cache-response-directive.proxy-revalidate" class="xref">Section 5.2.2.8</a></em></strong><a href="#appendix-D-2.10.2.1.1.8.1" class="pilcrow">¶</a></p> 4009 + </dd> 4010 + <dd class="break"></dd> 4011 + <dt id="appendix-D-2.10.2.1.1.9">public (cache directive)</dt> 4012 + <dd style="margin-left: 1.5em" id="appendix-D-2.10.2.1.1.10"> 4013 + <p id="appendix-D-2.10.2.1.1.10.1"> 4014 + <strong><em><a href="#cache-response-directive.public" class="xref">Section 5.2.2.9</a></em></strong><a href="#appendix-D-2.10.2.1.1.10.1" class="pilcrow">¶</a></p> 4015 + </dd> 4016 + <dd class="break"></dd> 4017 + </dl> 4018 + </li> 4019 + </ul> 4020 + </li> 4021 + <li class="normal ulEmpty" id="appendix-D-2.11"> 4022 + <div id="rfc.index.u83"> 4023 + <p id="appendix-D-2.11.1" class="keepWithNext"> 4024 + <a href="#rfc.index.u83" class="xref">S</a><a href="#appendix-D-2.11.1" class="pilcrow">¶</a></p> 4025 + </div> 4026 + <ul class="compact normal ulEmpty"> 4027 + <li class="compact normal ulEmpty" id="appendix-D-2.11.2.1"> 4028 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.11.2.1.1"> 4029 + <dt id="appendix-D-2.11.2.1.1.1">s-maxage (cache directive)</dt> 4030 + <dd style="margin-left: 1.5em" id="appendix-D-2.11.2.1.1.2"> 4031 + <p id="appendix-D-2.11.2.1.1.2.1"> 4032 + <strong><em><a href="#cache-response-directive.s-maxage" class="xref">Section 5.2.2.10</a></em></strong><a href="#appendix-D-2.11.2.1.1.2.1" class="pilcrow">¶</a></p> 4033 + </dd> 4034 + <dd class="break"></dd> 4035 + <dt id="appendix-D-2.11.2.1.1.3">shared cache</dt> 4036 + <dd style="margin-left: 1.5em" id="appendix-D-2.11.2.1.1.4"> 4037 + <p id="appendix-D-2.11.2.1.1.4.1"> 4038 + <a href="#caching" class="xref">Section 1</a><a href="#appendix-D-2.11.2.1.1.4.1" class="pilcrow">¶</a></p> 4039 + </dd> 4040 + <dd class="break"></dd> 4041 + <dt id="appendix-D-2.11.2.1.1.5">stale</dt> 4042 + <dd style="margin-left: 1.5em" id="appendix-D-2.11.2.1.1.6"> 4043 + <p id="appendix-D-2.11.2.1.1.6.1"> 4044 + <a href="#expiration.model" class="xref">Section 4.2</a><a href="#appendix-D-2.11.2.1.1.6.1" class="pilcrow">¶</a></p> 4045 + </dd> 4046 + <dd class="break"></dd> 4047 + </dl> 4048 + </li> 4049 + </ul> 4050 + </li> 4051 + <li class="normal ulEmpty" id="appendix-D-2.12"> 4052 + <div id="rfc.index.u86"> 4053 + <p id="appendix-D-2.12.1" class="keepWithNext"> 4054 + <a href="#rfc.index.u86" class="xref">V</a><a href="#appendix-D-2.12.1" class="pilcrow">¶</a></p> 4055 + </div> 4056 + <ul class="compact normal ulEmpty"> 4057 + <li class="compact normal ulEmpty" id="appendix-D-2.12.2.1"> 4058 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.12.2.1.1"> 4059 + <dt id="appendix-D-2.12.2.1.1.1">validator</dt> 4060 + <dd style="margin-left: 1.5em" id="appendix-D-2.12.2.1.1.2"> 4061 + <p id="appendix-D-2.12.2.1.1.2.1"> 4062 + <a href="#validation.sent" class="xref">Section 4.3.1</a><a href="#appendix-D-2.12.2.1.1.2.1" class="pilcrow">¶</a></p> 4063 + </dd> 4064 + <dd class="break"></dd> 4065 + </dl> 4066 + </li> 4067 + </ul> 4068 + </li> 4069 + <li class="normal ulEmpty" id="appendix-D-2.13"> 4070 + <div id="rfc.index.u87"> 4071 + <p id="appendix-D-2.13.1" class="keepWithNext"> 4072 + <a href="#rfc.index.u87" class="xref">W</a><a href="#appendix-D-2.13.1" class="pilcrow">¶</a></p> 4073 + </div> 4074 + <ul class="compact normal ulEmpty"> 4075 + <li class="compact normal ulEmpty" id="appendix-D-2.13.2.1"> 4076 + <span class="break"></span><dl class="dlCompact dlParallel" id="appendix-D-2.13.2.1.1"> 4077 + <dt id="appendix-D-2.13.2.1.1.1">Warning header field</dt> 4078 + <dd style="margin-left: 1.5em" id="appendix-D-2.13.2.1.1.2"> 4079 + <p id="appendix-D-2.13.2.1.1.2.1"> 4080 + <strong><em><a href="#field.warning" class="xref">Section 5.5</a></em></strong><a href="#appendix-D-2.13.2.1.1.2.1" class="pilcrow">¶</a></p> 4081 + </dd> 4082 + <dd class="break"></dd> 4083 + </dl> 4084 + </li> 4085 + </ul> 4086 + </li> 4087 + </ul> 4088 + </section> 4089 + <div id="authors-addresses"> 4090 + <section id="appendix-E"> 4091 + <h2 id="name-authors-addresses"> 4092 + <a href="#name-authors-addresses" class="section-name selfRef">Authors' Addresses</a> 4093 + </h2> 4094 + <address class="vcard"> 4095 + <div dir="auto" class="left"><span class="fn nameRole">Roy T. Fielding (<span class="role">editor</span>)</span></div> 4096 + <div dir="auto" class="left"><span class="org">Adobe</span></div> 4097 + <div dir="auto" class="left"><span class="street-address">345 Park Ave<br>San Jose, CA 95110</span></div> 4098 + <div dir="auto" class="left"><span class="country-name">United States of America</span></div> 4099 + <div class="email"> 4100 + <span>Email:</span> 4101 + <a href="mailto:fielding@gbiv.com" class="email">fielding@gbiv.com</a> 4102 + </div> 4103 + <div class="url"> 4104 + <span>URI:</span> 4105 + <a href="https://roy.gbiv.com/" class="url">https://roy.gbiv.com/</a> 4106 + </div> 4107 + </address> 4108 + <address class="vcard"> 4109 + <div dir="auto" class="left"><span class="fn nameRole">Mark Nottingham (<span class="role">editor</span>)</span></div> 4110 + <div dir="auto" class="left"><span class="org">Fastly</span></div> 4111 + <div dir="auto" class="left"><span class="street-address">Prahran</span></div> 4112 + <div dir="auto" class="left"><span class="country-name">Australia</span></div> 4113 + <div class="email"> 4114 + <span>Email:</span> 4115 + <a href="mailto:mnot@mnot.net" class="email">mnot@mnot.net</a> 4116 + </div> 4117 + <div class="url"> 4118 + <span>URI:</span> 4119 + <a href="https://www.mnot.net/" class="url">https://www.mnot.net/</a> 4120 + </div> 4121 + </address> 4122 + <address class="vcard"> 4123 + <div dir="auto" class="left"><span class="fn nameRole">Julian Reschke (<span class="role">editor</span>)</span></div> 4124 + <div dir="auto" class="left"><span class="org">greenbytes GmbH</span></div> 4125 + <div dir="auto" class="left"><span class="street-address">Hafenweg 16<br>48155 Münster</span></div> 4126 + <div dir="auto" class="left"><span class="country-name">Germany</span></div> 4127 + <div class="email"> 4128 + <span>Email:</span> 4129 + <a href="mailto:julian.reschke@greenbytes.de" class="email">julian.reschke@greenbytes.de</a> 4130 + </div> 4131 + <div class="url"> 4132 + <span>URI:</span> 4133 + <a href="https://greenbytes.de/tech/webdav/" class="url">https://greenbytes.de/tech/webdav/</a> 4134 + </div> 4135 + </address> 4136 + </section> 4137 + </div> 4138 + </div> 4139 + 4140 + </div> 4141 + 4142 + </div> 4143 + <div class="d-print-none col-md-3 bg-light-subtle collapse show" id="sidebar"> 4144 + <div class="position-fixed border-start sidebar overflow-scroll overscroll-none no-scrollbar"> 4145 + <div class="d-flex flex-column vh-100 pt-2 pt-lg-3 ps-3 pl-md-2 pl-lg-3"> 4146 + <div> 4147 + <a class="btn btn-primary btn-sm" href="/doc/rfc9111/">Datatracker</a> 4148 + <p class="fw-bold pt-2"> 4149 + 4150 + RFC 9111 4151 + 4152 + <br> 4153 + 4154 + 4155 + 4156 + 4157 + 4158 + 4159 + <span class="text-success">RFC 4160 + 4161 + - Internet Standard 4162 + 4163 + </span> 4164 + 4165 + </p> 4166 + </div> 4167 + 4168 + <ul class="nav nav-tabs nav-fill small me-2" role="tablist"> 4169 + <li class="nav-item" role="presentation" title="Document information"> 4170 + <button class="nav-link px-2" 4171 + id="docinfo-tab" 4172 + data-bs-toggle="tab" 4173 + data-bs-target="#docinfo-tab-pane" 4174 + type="button" 4175 + role="tab" 4176 + aria-controls="docinfo-tab-pane" 4177 + aria-selected="true"> 4178 + <i class="bi bi-info-circle"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Info</span> 4179 + </button> 4180 + </li> 4181 + <li class="nav-item" role="presentation" title="Table of contents"> 4182 + <button class="nav-link px-2" 4183 + id="toc-tab" 4184 + data-bs-toggle="tab" 4185 + data-bs-target="#toc-tab-pane" 4186 + type="button" 4187 + role="tab" 4188 + aria-controls="toc-tab-pane" 4189 + aria-selected="false"> 4190 + <i class="bi bi-list-ol"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Contents</span> 4191 + </button> 4192 + </li> 4193 + <li class="nav-item" role="presentation" title="Preferences"> 4194 + <button class="nav-link px-2" 4195 + id="pref-tab" 4196 + data-bs-toggle="tab" 4197 + data-bs-target="#pref-tab-pane" 4198 + type="button" 4199 + role="tab" 4200 + aria-controls="pref-tab-pane" 4201 + aria-selected="false"> 4202 + <i class="bi bi-gear"></i><span class="d-none d-md-block d-xl-inline ms-xl-1">Prefs</span> 4203 + </button> 4204 + </li> 4205 + </ul> 4206 + <div class="overflow-auto tab-content pt-2 me-2"> 4207 + <div class="tab-pane" 4208 + id="docinfo-tab-pane" 4209 + role="tabpanel" 4210 + aria-labelledby="docinfo-tab" 4211 + tabindex="0"> 4212 + <table class="table table-sm table-borderless"> 4213 + 4214 + 4215 + 4216 + 4217 + 4218 + 4219 + 4220 + 4221 + <tbody class="meta align-top "> 4222 + <tr> 4223 + <th scope="row">Document</th> 4224 + <th scope="row">Document type</th> 4225 + <td class="edit"></td> 4226 + <td> 4227 + 4228 + 4229 + 4230 + 4231 + 4232 + 4233 + <span class="text-success">RFC 4234 + 4235 + - Internet Standard 4236 + 4237 + </span> 4238 + 4239 + 4240 + 4241 + <br>June 2022 4242 + 4243 + <br> 4244 + 4245 + 4246 + <a class="btn btn-sm btn-warning" 4247 + title="Click to report an error in the document." 4248 + href="https://www.rfc-editor.org/errata.php#reportnew" 4249 + target="_blank"> 4250 + Report errata 4251 + </a> 4252 + 4253 + 4254 + 4255 + 4256 + <div>Obsoletes <a href="/doc/html/rfc7234" title="Hypertext Transfer Protocol (HTTP/1.1): Caching">RFC 7234</a></div> 4257 + 4258 + 4259 + 4260 + 4261 + <div> 4262 + Was 4263 + <a href="/doc/draft-ietf-httpbis-cache/19/">draft-ietf-httpbis-cache</a> 4264 + (<a href="/wg/httpbis/about/">httpbis WG</a>) 4265 + </div> 4266 + 4267 + 4268 + 4269 + 4270 + 4271 + 4272 + 4273 + 4274 + 4275 + 4276 + 4277 + 4278 + 4279 + </td> 4280 + </tr> 4281 + 4282 + <tr> 4283 + <td></td> 4284 + <th scope="row">Select version</th> 4285 + <td class="edit"></td> 4286 + <td> 4287 + 4288 + 4289 + 4290 + 4291 + <ul class="revision-list pagination pagination-sm text-center flex-wrap my-0"> 4292 + 4293 + 4294 + 4295 + 4296 + <li class="page-item"> 4297 + <a class="page-link" 4298 + href="/doc/html/draft-ietf-httpbis-cache-00" 4299 + rel="nofollow"> 4300 + 00 4301 + </a> 4302 + </li> 4303 + 4304 + <li class="page-item"> 4305 + <a class="page-link" 4306 + href="/doc/html/draft-ietf-httpbis-cache-01" 4307 + rel="nofollow"> 4308 + 01 4309 + </a> 4310 + </li> 4311 + 4312 + <li class="page-item"> 4313 + <a class="page-link" 4314 + href="/doc/html/draft-ietf-httpbis-cache-02" 4315 + rel="nofollow"> 4316 + 02 4317 + </a> 4318 + </li> 4319 + 4320 + <li class="page-item"> 4321 + <a class="page-link" 4322 + href="/doc/html/draft-ietf-httpbis-cache-03" 4323 + rel="nofollow"> 4324 + 03 4325 + </a> 4326 + </li> 4327 + 4328 + <li class="page-item"> 4329 + <a class="page-link" 4330 + href="/doc/html/draft-ietf-httpbis-cache-04" 4331 + rel="nofollow"> 4332 + 04 4333 + </a> 4334 + </li> 4335 + 4336 + <li class="page-item"> 4337 + <a class="page-link" 4338 + href="/doc/html/draft-ietf-httpbis-cache-05" 4339 + rel="nofollow"> 4340 + 05 4341 + </a> 4342 + </li> 4343 + 4344 + <li class="page-item"> 4345 + <a class="page-link" 4346 + href="/doc/html/draft-ietf-httpbis-cache-06" 4347 + rel="nofollow"> 4348 + 06 4349 + </a> 4350 + </li> 4351 + 4352 + <li class="page-item"> 4353 + <a class="page-link" 4354 + href="/doc/html/draft-ietf-httpbis-cache-07" 4355 + rel="nofollow"> 4356 + 07 4357 + </a> 4358 + </li> 4359 + 4360 + <li class="page-item"> 4361 + <a class="page-link" 4362 + href="/doc/html/draft-ietf-httpbis-cache-08" 4363 + rel="nofollow"> 4364 + 08 4365 + </a> 4366 + </li> 4367 + 4368 + <li class="page-item"> 4369 + <a class="page-link" 4370 + href="/doc/html/draft-ietf-httpbis-cache-09" 4371 + rel="nofollow"> 4372 + 09 4373 + </a> 4374 + </li> 4375 + 4376 + <li class="page-item"> 4377 + <a class="page-link" 4378 + href="/doc/html/draft-ietf-httpbis-cache-10" 4379 + rel="nofollow"> 4380 + 10 4381 + </a> 4382 + </li> 4383 + 4384 + <li class="page-item"> 4385 + <a class="page-link" 4386 + href="/doc/html/draft-ietf-httpbis-cache-11" 4387 + rel="nofollow"> 4388 + 11 4389 + </a> 4390 + </li> 4391 + 4392 + <li class="page-item"> 4393 + <a class="page-link" 4394 + href="/doc/html/draft-ietf-httpbis-cache-12" 4395 + rel="nofollow"> 4396 + 12 4397 + </a> 4398 + </li> 4399 + 4400 + <li class="page-item"> 4401 + <a class="page-link" 4402 + href="/doc/html/draft-ietf-httpbis-cache-13" 4403 + rel="nofollow"> 4404 + 13 4405 + </a> 4406 + </li> 4407 + 4408 + <li class="page-item"> 4409 + <a class="page-link" 4410 + href="/doc/html/draft-ietf-httpbis-cache-14" 4411 + rel="nofollow"> 4412 + 14 4413 + </a> 4414 + </li> 4415 + 4416 + <li class="page-item"> 4417 + <a class="page-link" 4418 + href="/doc/html/draft-ietf-httpbis-cache-15" 4419 + rel="nofollow"> 4420 + 15 4421 + </a> 4422 + </li> 4423 + 4424 + <li class="page-item"> 4425 + <a class="page-link" 4426 + href="/doc/html/draft-ietf-httpbis-cache-16" 4427 + rel="nofollow"> 4428 + 16 4429 + </a> 4430 + </li> 4431 + 4432 + <li class="page-item"> 4433 + <a class="page-link" 4434 + href="/doc/html/draft-ietf-httpbis-cache-17" 4435 + rel="nofollow"> 4436 + 17 4437 + </a> 4438 + </li> 4439 + 4440 + <li class="page-item"> 4441 + <a class="page-link" 4442 + href="/doc/html/draft-ietf-httpbis-cache-18" 4443 + rel="nofollow"> 4444 + 18 4445 + </a> 4446 + </li> 4447 + 4448 + <li class="page-item"> 4449 + <a class="page-link" 4450 + href="/doc/html/draft-ietf-httpbis-cache-19" 4451 + rel="nofollow"> 4452 + 19 4453 + </a> 4454 + </li> 4455 + 4456 + 4457 + 4458 + <li class="page-item rfc active"> 4459 + <a class="page-link" 4460 + href="/doc/html/rfc9111"> 4461 + RFC 9111 4462 + </a> 4463 + </li> 4464 + 4465 + </ul> 4466 + 4467 + </td> 4468 + </tr> 4469 + 4470 + <tr> 4471 + <td></td> 4472 + <th scope="row">Compare versions</th> 4473 + <td class="edit"></td> 4474 + <td> 4475 + 4476 + 4477 + 4478 + 4479 + <form class="form-horizontal diff-form" 4480 + action="https://author-tools.ietf.org/iddiff" 4481 + method="get" 4482 + target="_blank"> 4483 + 4484 + <select class="form-select form-select-sm mb-1 select2-field" 4485 + data-max-entries="1" 4486 + data-width="resolve" 4487 + data-allow-clear="false" 4488 + data-minimum-input-length="0" 4489 + aria-label="From revision" 4490 + name="url1"> 4491 + 4492 + <option value="rfc9111"> 4493 + RFC 9111 4494 + 4495 + </option> 4496 + 4497 + <option value="draft-ietf-httpbis-cache-19" selected> 4498 + draft-ietf-httpbis-cache-19 4499 + 4500 + </option> 4501 + 4502 + <option value="draft-ietf-httpbis-cache-18"> 4503 + draft-ietf-httpbis-cache-18 4504 + 4505 + </option> 4506 + 4507 + <option value="draft-ietf-httpbis-cache-17"> 4508 + draft-ietf-httpbis-cache-17 4509 + 4510 + </option> 4511 + 4512 + <option value="draft-ietf-httpbis-cache-16"> 4513 + draft-ietf-httpbis-cache-16 4514 + 4515 + </option> 4516 + 4517 + <option value="draft-ietf-httpbis-cache-15"> 4518 + draft-ietf-httpbis-cache-15 4519 + 4520 + </option> 4521 + 4522 + <option value="draft-ietf-httpbis-cache-14"> 4523 + draft-ietf-httpbis-cache-14 4524 + 4525 + </option> 4526 + 4527 + <option value="draft-ietf-httpbis-cache-13"> 4528 + draft-ietf-httpbis-cache-13 4529 + 4530 + </option> 4531 + 4532 + <option value="draft-ietf-httpbis-cache-12"> 4533 + draft-ietf-httpbis-cache-12 4534 + 4535 + </option> 4536 + 4537 + <option value="draft-ietf-httpbis-cache-11"> 4538 + draft-ietf-httpbis-cache-11 4539 + 4540 + </option> 4541 + 4542 + <option value="draft-ietf-httpbis-cache-10"> 4543 + draft-ietf-httpbis-cache-10 4544 + 4545 + </option> 4546 + 4547 + <option value="draft-ietf-httpbis-cache-09"> 4548 + draft-ietf-httpbis-cache-09 4549 + 4550 + </option> 4551 + 4552 + <option value="draft-ietf-httpbis-cache-08"> 4553 + draft-ietf-httpbis-cache-08 4554 + 4555 + </option> 4556 + 4557 + <option value="draft-ietf-httpbis-cache-07"> 4558 + draft-ietf-httpbis-cache-07 4559 + 4560 + </option> 4561 + 4562 + <option value="draft-ietf-httpbis-cache-06"> 4563 + draft-ietf-httpbis-cache-06 4564 + 4565 + </option> 4566 + 4567 + <option value="draft-ietf-httpbis-cache-05"> 4568 + draft-ietf-httpbis-cache-05 4569 + 4570 + </option> 4571 + 4572 + <option value="draft-ietf-httpbis-cache-04"> 4573 + draft-ietf-httpbis-cache-04 4574 + 4575 + </option> 4576 + 4577 + <option value="draft-ietf-httpbis-cache-03"> 4578 + draft-ietf-httpbis-cache-03 4579 + 4580 + </option> 4581 + 4582 + <option value="draft-ietf-httpbis-cache-02"> 4583 + draft-ietf-httpbis-cache-02 4584 + 4585 + </option> 4586 + 4587 + <option value="draft-ietf-httpbis-cache-01"> 4588 + draft-ietf-httpbis-cache-01 4589 + 4590 + </option> 4591 + 4592 + <option value="draft-ietf-httpbis-cache-00"> 4593 + draft-ietf-httpbis-cache-00 4594 + 4595 + </option> 4596 + 4597 + 4598 + </select> 4599 + 4600 + <select class="form-select form-select-sm mb-1 select2-field" 4601 + data-max-entries="1" 4602 + data-width="resolve" 4603 + data-allow-clear="false" 4604 + data-minimum-input-length="0" 4605 + aria-label="To revision" 4606 + name="url2"> 4607 + 4608 + <option value="rfc9111" selected> 4609 + RFC 9111 4610 + 4611 + </option> 4612 + 4613 + <option value="draft-ietf-httpbis-cache-19"> 4614 + draft-ietf-httpbis-cache-19 4615 + 4616 + </option> 4617 + 4618 + <option value="draft-ietf-httpbis-cache-18"> 4619 + draft-ietf-httpbis-cache-18 4620 + 4621 + </option> 4622 + 4623 + <option value="draft-ietf-httpbis-cache-17"> 4624 + draft-ietf-httpbis-cache-17 4625 + 4626 + </option> 4627 + 4628 + <option value="draft-ietf-httpbis-cache-16"> 4629 + draft-ietf-httpbis-cache-16 4630 + 4631 + </option> 4632 + 4633 + <option value="draft-ietf-httpbis-cache-15"> 4634 + draft-ietf-httpbis-cache-15 4635 + 4636 + </option> 4637 + 4638 + <option value="draft-ietf-httpbis-cache-14"> 4639 + draft-ietf-httpbis-cache-14 4640 + 4641 + </option> 4642 + 4643 + <option value="draft-ietf-httpbis-cache-13"> 4644 + draft-ietf-httpbis-cache-13 4645 + 4646 + </option> 4647 + 4648 + <option value="draft-ietf-httpbis-cache-12"> 4649 + draft-ietf-httpbis-cache-12 4650 + 4651 + </option> 4652 + 4653 + <option value="draft-ietf-httpbis-cache-11"> 4654 + draft-ietf-httpbis-cache-11 4655 + 4656 + </option> 4657 + 4658 + <option value="draft-ietf-httpbis-cache-10"> 4659 + draft-ietf-httpbis-cache-10 4660 + 4661 + </option> 4662 + 4663 + <option value="draft-ietf-httpbis-cache-09"> 4664 + draft-ietf-httpbis-cache-09 4665 + 4666 + </option> 4667 + 4668 + <option value="draft-ietf-httpbis-cache-08"> 4669 + draft-ietf-httpbis-cache-08 4670 + 4671 + </option> 4672 + 4673 + <option value="draft-ietf-httpbis-cache-07"> 4674 + draft-ietf-httpbis-cache-07 4675 + 4676 + </option> 4677 + 4678 + <option value="draft-ietf-httpbis-cache-06"> 4679 + draft-ietf-httpbis-cache-06 4680 + 4681 + </option> 4682 + 4683 + <option value="draft-ietf-httpbis-cache-05"> 4684 + draft-ietf-httpbis-cache-05 4685 + 4686 + </option> 4687 + 4688 + <option value="draft-ietf-httpbis-cache-04"> 4689 + draft-ietf-httpbis-cache-04 4690 + 4691 + </option> 4692 + 4693 + <option value="draft-ietf-httpbis-cache-03"> 4694 + draft-ietf-httpbis-cache-03 4695 + 4696 + </option> 4697 + 4698 + <option value="draft-ietf-httpbis-cache-02"> 4699 + draft-ietf-httpbis-cache-02 4700 + 4701 + </option> 4702 + 4703 + <option value="draft-ietf-httpbis-cache-01"> 4704 + draft-ietf-httpbis-cache-01 4705 + 4706 + </option> 4707 + 4708 + <option value="draft-ietf-httpbis-cache-00"> 4709 + draft-ietf-httpbis-cache-00 4710 + 4711 + </option> 4712 + 4713 + 4714 + </select> 4715 + 4716 + <button type="submit" 4717 + class="btn btn-primary btn-sm" 4718 + value="--html" 4719 + name="difftype"> 4720 + Side-by-side 4721 + </button> 4722 + 4723 + <button type="submit" 4724 + class="btn btn-primary btn-sm" 4725 + value="--hwdiff" 4726 + name="difftype"> 4727 + Inline 4728 + </button> 4729 + 4730 + </form> 4731 + </td> 4732 + </tr> 4733 + 4734 + 4735 + <tr> 4736 + <td></td> 4737 + <th scope="row">Authors</th> 4738 + <td class="edit"> 4739 + 4740 + </td> 4741 + <td> 4742 + 4743 + 4744 + <span ><a 4745 + title="Datatracker profile of Roy T. Fielding" 4746 + href="/person/fielding@gbiv.com" >Roy T. Fielding</a> <a 4747 + href="mailto:fielding%40gbiv.com" 4748 + aria-label="Compose email to fielding@gbiv.com" 4749 + title="Compose email to fielding@gbiv.com"> 4750 + <i class="bi bi-envelope"></i></a></span>, 4751 + 4752 + <span ><a 4753 + title="Datatracker profile of Mark Nottingham" 4754 + href="/person/mnot@mnot.net" >Mark Nottingham</a> <a 4755 + href="mailto:mnot%40mnot.net" 4756 + aria-label="Compose email to mnot@mnot.net" 4757 + title="Compose email to mnot@mnot.net"> 4758 + <i class="bi bi-envelope"></i></a></span>, 4759 + 4760 + <span ><a 4761 + title="Datatracker profile of Julian Reschke" 4762 + href="/person/julian.reschke@gmx.de" >Julian Reschke</a> <a 4763 + href="mailto:julian.reschke%40gmx.de" 4764 + aria-label="Compose email to julian.reschke@gmx.de" 4765 + title="Compose email to julian.reschke@gmx.de"> 4766 + <i class="bi bi-envelope"></i></a></span> 4767 + 4768 + 4769 + <br> 4770 + <a class="btn btn-primary btn-sm mt-1" href="mailto:rfc9111@ietf.org?subject=rfc9111" title="Send email to the document authors">Email authors</a> 4771 + 4772 + </td> 4773 + </tr> 4774 + 4775 + 4776 + <tr> 4777 + <td></td> 4778 + <th scope="row"> 4779 + RFC stream 4780 + </th> 4781 + <td class="edit"> 4782 + 4783 + </td> 4784 + <td > 4785 + 4786 + 4787 + 4788 + 4789 + 4790 + 4791 + 4792 + 4793 + <img alt="IETF Logo" 4794 + class="d-lm-none w-25 mt-1" 4795 + 4796 + 4797 + 4798 + src="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor-white.svg" 4799 + 4800 + 4801 + > 4802 + 4803 + <img alt="IETF Logo" 4804 + class="d-dm-none w-25 mt-1" 4805 + 4806 + 4807 + 4808 + src="https://static.ietf.org/dt/12.54.0/ietf/images/ietf-logo-nor.svg" 4809 + 4810 + 4811 + > 4812 + 4813 + 4814 + 4815 + 4816 + </td> 4817 + </tr> 4818 + 4819 + <tr> 4820 + <td></td> 4821 + <th scope="row"> 4822 + Other formats 4823 + </th> 4824 + <td class="edit"> 4825 + </td> 4826 + <td> 4827 + 4828 + 4829 + <div class="buttonlist"> 4830 + 4831 + 4832 + <a class="btn btn-primary btn-sm" 4833 + 4834 + target="_blank" 4835 + href="https://www.rfc-editor.org/rfc/rfc9111.txt"> 4836 + 4837 + <i class="bi bi-file-text"></i> txt 4838 + 4839 + </a> 4840 + 4841 + 4842 + 4843 + <a class="btn btn-primary btn-sm" 4844 + 4845 + target="_blank" 4846 + href="https://www.rfc-editor.org/rfc/rfc9111.html"> 4847 + 4848 + <i class="bi bi-file-code"></i> html 4849 + 4850 + </a> 4851 + 4852 + 4853 + 4854 + <a class="btn btn-primary btn-sm" 4855 + 4856 + target="_blank" 4857 + href="https://www.rfc-editor.org/rfc/rfc9111.xml"> 4858 + 4859 + <i class="bi bi-file-code"></i> xml 4860 + 4861 + </a> 4862 + 4863 + 4864 + 4865 + <a class="btn btn-primary btn-sm" 4866 + 4867 + download="rfc9111.pdf" 4868 + 4869 + 4870 + target="_blank" 4871 + href="https://www.rfc-editor.org/rfc/rfc9111.pdf"> 4872 + 4873 + <i class="bi bi-file-pdf"></i> pdf 4874 + 4875 + </a> 4876 + 4877 + 4878 + 4879 + 4880 + 4881 + <a class="btn btn-primary btn-sm" 4882 + 4883 + target="_blank" 4884 + href="/doc/rfc9111/bibtex/"> 4885 + 4886 + <i class="bi bi-file-ruled"></i> bibtex 4887 + 4888 + </a> 4889 + 4890 + 4891 + </div> 4892 + 4893 + 4894 + </td> 4895 + </tr> 4896 + 4897 + 4898 + 4899 + <tr> 4900 + <td> 4901 + </td> 4902 + <th scope="row"> 4903 + Additional resources 4904 + </th> 4905 + <td class="edit"> 4906 + 4907 + </td> 4908 + <td> 4909 + 4910 + 4911 + 4912 + 4913 + <a href="http://lists.w3.org/Archives/Public/ietf-http-wg/"> 4914 + Mailing list discussion 4915 + </a> 4916 + 4917 + 4918 + 4919 + </td> 4920 + </tr> 4921 + 4922 + 4923 + </tbody> 4924 + </table> 4925 + <a class="btn btn-sm btn-warning mb-3" 4926 + target="_blank" 4927 + href="https://github.com/ietf-tools/datatracker/issues/new/choose"> 4928 + Report a datatracker bug 4929 + <i class="bi bi-bug"></i> 4930 + </a> 4931 + </div> 4932 + <div class="tab-pane mb-5" 4933 + id="toc-tab-pane" 4934 + role="tabpanel" 4935 + aria-labelledby="toc-tab" 4936 + tabindex="0"> 4937 + <nav class="nav nav-pills flex-column small" id="toc-nav"> 4938 + </nav> 4939 + </div> 4940 + <div class="tab-pane mb-5 small" 4941 + id="pref-tab-pane" 4942 + role="tabpanel" 4943 + aria-labelledby="pref-tab" 4944 + tabindex="0"> 4945 + <label class="form-label fw-bold mb-2">Show sidebar by default</label> 4946 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 4947 + <input type="radio" class="btn-check" name="sidebar" id="on-radio"> 4948 + <label class="btn btn-outline-primary" for="on-radio">Yes</label> 4949 + <input type="radio" class="btn-check" name="sidebar" id="off-radio"> 4950 + <label class="btn btn-outline-primary" for="off-radio">No</label> 4951 + </div> 4952 + <label class="form-label fw-bold mt-4 mb-2">Tab to show by default</label> 4953 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 4954 + <input type="radio" class="btn-check" name="deftab" id="docinfo-radio"> 4955 + <label class="btn btn-outline-primary" for="docinfo-radio"> 4956 + <i class="bi bi-info-circle me-1"></i>Info 4957 + </label> 4958 + <input type="radio" class="btn-check" name="deftab" id="toc-radio"> 4959 + <label class="btn btn-outline-primary" for="toc-radio"> 4960 + <i class="bi bi-list-ol me-1"></i>Contents 4961 + </label> 4962 + </div> 4963 + <label class="form-label fw-bold mt-4 mb-2">HTMLization configuration</label> 4964 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 4965 + <input type="radio" class="btn-check" name="htmlconf" id="txt-radio"> 4966 + <label class="btn btn-outline-primary" for="txt-radio" title="This is the traditional HTMLization method."> 4967 + <i class="bi bi-badge-sd me-1"></i>HTMLize the plaintext 4968 + </label> 4969 + <input type="radio" class="btn-check" name="htmlconf" id="html-radio"> 4970 + <label class="btn btn-outline-primary" for="html-radio" title="This is the modern HTMLization method."> 4971 + <i class="bi bi-badge-hd me-1"></i>Plaintextify the HTML 4972 + </label> 4973 + </div> 4974 + <label class="form-label fw-bold mt-4 mb-2" for="ptsize">Maximum font size</label> 4975 + <input type="range" class="form-range" min="7" max="16" id="ptsize" oninput="ptdemo.value = ptsize.value"> 4976 + <label class="form-label fw-bold mt-4 mb-2">Page dependencies</label> 4977 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 4978 + <input type="radio" class="btn-check" name="pagedeps" id="inline-radio"> 4979 + <label class="btn btn-outline-primary" for="inline-radio" title="Generate larger, standalone web pages that do not require network access to render."> 4980 + <i class="bi bi-box me-1"></i>Inline 4981 + </label> 4982 + <input type="radio" class="btn-check" name="pagedeps" id="reference-radio"> 4983 + <label class="btn btn-outline-primary" for="reference-radio" title="Generate regular web pages that require network access to render."> 4984 + <i class="bi bi-link-45deg me-1"></i>Reference 4985 + </label> 4986 + </div> 4987 + <label class="form-label fw-bold mt-4 mb-2">Citation links</label> 4988 + <div class="btn-group-vertical btn-group-sm d-flex" role="group"> 4989 + <input type="radio" class="btn-check" name="reflinks" id="refsection-radio"> 4990 + <label class="btn btn-outline-primary" for="refsection-radio" title="Citation links go to the reference section."> 4991 + <i class="bi bi-arrow-clockwise"></i> Go to reference section 4992 + </label> 4993 + <input type="radio" class="btn-check" name="reflinks" id="citation-radio"> 4994 + <label class="btn btn-outline-primary" for="citation-radio" title="Citation links go directly to the cited document."> 4995 + <i class="bi bi-link-45deg me-1"></i>Go to linked document 4996 + </label> 4997 + </div> 4998 + </div> 4999 + </div> 5000 + </div> 5001 + </div> 5002 + </div> 5003 + </div> 5004 + 5005 + <script> 5006 + var _paq = window._paq || []; 5007 + 5008 + _paq.push(['disableCookies']); 5009 + _paq.push(['trackPageView']); 5010 + _paq.push(['enableLinkTracking']); 5011 + (function() { 5012 + var u="//analytics.ietf.org/"; 5013 + _paq.push(['setTrackerUrl', u+'matomo.php']); 5014 + _paq.push(['setSiteId', 7]); 5015 + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 5016 + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); 5017 + })(); 5018 + </script> 5019 + <noscript><p><img src="//analytics.ietf.org/matomo.php?idsite=7" style="border:0;" alt="" /></p></noscript> 5020 + 5021 + </body> 5022 + </html>
+237
test/test_http_date.ml
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Comprehensive tests for HTTP-date parsing per RFC 9110 Section 5.6.7 *) 7 + 8 + open Requests 9 + 10 + (** Alcotest testable for Ptime.t *) 11 + module Alcotest_ptime = struct 12 + let pp = Ptime.pp_rfc3339 () 13 + let equal = Ptime.equal 14 + let testable = Alcotest.testable pp equal 15 + end 16 + 17 + (** Helper to create expected Ptime.t values *) 18 + let make_time year month day hour min sec = 19 + match Ptime.of_date_time ((year, month, day), ((hour, min, sec), 0)) with 20 + | Some t -> t 21 + | None -> failwith (Printf.sprintf "Invalid test time: %d-%02d-%02d %02d:%02d:%02d" 22 + year month day hour min sec) 23 + 24 + (** {1 RFC 1123 Format Tests} *) 25 + 26 + let test_rfc1123_basic () = 27 + (* RFC 9110 Section 5.6.7: preferred format "Sun, 06 Nov 1994 08:49:37 GMT" *) 28 + let result = Http_date.parse "Sun, 06 Nov 1994 08:49:37 GMT" in 29 + let expected = Some (make_time 1994 11 6 8 49 37) in 30 + Alcotest.(check (option Alcotest_ptime.testable)) 31 + "RFC 1123 basic parsing" expected result 32 + 33 + let test_rfc1123_all_months () = 34 + (* Test all month names *) 35 + let months = [ 36 + ("Jan", 1); ("Feb", 2); ("Mar", 3); ("Apr", 4); 37 + ("May", 5); ("Jun", 6); ("Jul", 7); ("Aug", 8); 38 + ("Sep", 9); ("Oct", 10); ("Nov", 11); ("Dec", 12); 39 + ] in 40 + List.iter (fun (month_str, month_num) -> 41 + let date_str = Printf.sprintf "Mon, 01 %s 2020 00:00:00 GMT" month_str in 42 + let result = Http_date.parse date_str in 43 + let expected = Some (make_time 2020 month_num 1 0 0 0) in 44 + Alcotest.(check (option Alcotest_ptime.testable)) 45 + (Printf.sprintf "RFC 1123 month %s" month_str) expected result 46 + ) months 47 + 48 + let test_rfc1123_all_weekdays () = 49 + (* Test all weekday names - the weekday is not validated, just skipped *) 50 + let weekdays = ["Sun"; "Mon"; "Tue"; "Wed"; "Thu"; "Fri"; "Sat"] in 51 + List.iter (fun wday -> 52 + let date_str = Printf.sprintf "%s, 06 Nov 1994 08:49:37 GMT" wday in 53 + let result = Http_date.parse date_str in 54 + let expected = Some (make_time 1994 11 6 8 49 37) in 55 + Alcotest.(check (option Alcotest_ptime.testable)) 56 + (Printf.sprintf "RFC 1123 weekday %s" wday) expected result 57 + ) weekdays 58 + 59 + let test_rfc1123_edge_dates () = 60 + (* Test edge cases for dates *) 61 + let test_cases = [ 62 + ("Thu, 01 Jan 1970 00:00:00 GMT", 1970, 1, 1, 0, 0, 0, "Unix epoch"); 63 + ("Fri, 31 Dec 1999 23:59:59 GMT", 1999, 12, 31, 23, 59, 59, "Y2K eve"); 64 + ("Sat, 01 Jan 2000 00:00:00 GMT", 2000, 1, 1, 0, 0, 0, "Y2K"); 65 + ("Tue, 29 Feb 2000 12:00:00 GMT", 2000, 2, 29, 12, 0, 0, "Leap year"); 66 + ("Fri, 13 Dec 2024 23:59:59 GMT", 2024, 12, 13, 23, 59, 59, "Near current"); 67 + ] in 68 + List.iter (fun (date_str, y, m, d, h, min, s, desc) -> 69 + let result = Http_date.parse date_str in 70 + let expected = Some (make_time y m d h min s) in 71 + Alcotest.(check (option Alcotest_ptime.testable)) 72 + (Printf.sprintf "RFC 1123 edge: %s" desc) expected result 73 + ) test_cases 74 + 75 + (** {1 RFC 850 Format Tests (Obsolete)} *) 76 + 77 + let test_rfc850_basic () = 78 + (* RFC 850 format: "Sunday, 06-Nov-94 08:49:37 GMT" *) 79 + let result = Http_date.parse "Sunday, 06-Nov-94 08:49:37 GMT" in 80 + let expected = Some (make_time 1994 11 6 8 49 37) in 81 + Alcotest.(check (option Alcotest_ptime.testable)) 82 + "RFC 850 basic parsing (2-digit year)" expected result 83 + 84 + let test_rfc850_year_interpretation () = 85 + (* Test Y2K two-digit year interpretation: 70-99 -> 1970-1999, 00-69 -> 2000-2069 *) 86 + let test_cases = [ 87 + ("Monday, 01-Jan-70 00:00:00 GMT", 1970, "Year 70 -> 1970"); 88 + ("Tuesday, 01-Jan-99 00:00:00 GMT", 1999, "Year 99 -> 1999"); 89 + ("Saturday, 01-Jan-00 00:00:00 GMT", 2000, "Year 00 -> 2000"); 90 + ("Sunday, 01-Jan-25 00:00:00 GMT", 2025, "Year 25 -> 2025"); 91 + ("Thursday, 01-Jan-69 00:00:00 GMT", 2069, "Year 69 -> 2069"); 92 + ] in 93 + List.iter (fun (date_str, expected_year, desc) -> 94 + let result = Http_date.parse date_str in 95 + let expected = Some (make_time expected_year 1 1 0 0 0) in 96 + Alcotest.(check (option Alcotest_ptime.testable)) 97 + (Printf.sprintf "RFC 850 %s" desc) expected result 98 + ) test_cases 99 + 100 + (** {1 ANSI C asctime() Format Tests (Obsolete)} *) 101 + 102 + let test_asctime_basic () = 103 + (* asctime() format: "Sun Nov 6 08:49:37 1994" *) 104 + let result = Http_date.parse "Sun Nov 6 08:49:37 1994" in 105 + let expected = Some (make_time 1994 11 6 8 49 37) in 106 + Alcotest.(check (option Alcotest_ptime.testable)) 107 + "asctime basic parsing" expected result 108 + 109 + let test_asctime_single_digit_day () = 110 + (* asctime has space-padded day for single digits *) 111 + let test_cases = [ 112 + ("Sun Nov 1 08:49:37 1994", 1, "Day 1"); 113 + ("Sun Nov 9 08:49:37 1994", 9, "Day 9"); 114 + ] in 115 + List.iter (fun (date_str, day, desc) -> 116 + let result = Http_date.parse date_str in 117 + let expected = Some (make_time 1994 11 day 8 49 37) in 118 + Alcotest.(check (option Alcotest_ptime.testable)) 119 + (Printf.sprintf "asctime %s" desc) expected result 120 + ) test_cases 121 + 122 + (** {1 Invalid Input Tests} *) 123 + 124 + let test_invalid_completely_wrong () = 125 + (* Completely invalid strings *) 126 + let invalid_inputs = [ 127 + ""; 128 + "not a date"; 129 + "2024-12-13"; (* ISO 8601 not supported *) 130 + "12/13/2024"; (* US format not supported *) 131 + "13-Dec-2024"; (* No day name *) 132 + ] in 133 + List.iter (fun input -> 134 + let result = Http_date.parse input in 135 + Alcotest.(check (option Alcotest_ptime.testable)) 136 + (Printf.sprintf "Invalid input: %S" input) None result 137 + ) invalid_inputs 138 + 139 + let test_invalid_month_names () = 140 + (* Invalid month names *) 141 + let invalid_months = [ 142 + "Sun, 06 Foo 1994 08:49:37 GMT"; 143 + "Sun, 06 13 1994 08:49:37 GMT"; (* Numeric month *) 144 + "Sun, 06 November 1994 08:49:37 GMT"; (* Full month name *) 145 + ] in 146 + List.iter (fun input -> 147 + let result = Http_date.parse input in 148 + Alcotest.(check (option Alcotest_ptime.testable)) 149 + (Printf.sprintf "Invalid month: %S" input) None result 150 + ) invalid_months 151 + 152 + let test_invalid_dates () = 153 + (* Dates that are syntactically correct but semantically invalid *) 154 + let invalid_dates = [ 155 + "Sun, 32 Jan 2020 00:00:00 GMT"; (* Day 32 *) 156 + "Sun, 00 Jan 2020 00:00:00 GMT"; (* Day 0 *) 157 + "Sun, 29 Feb 2021 00:00:00 GMT"; (* Feb 29 in non-leap year *) 158 + "Sun, 31 Apr 2020 00:00:00 GMT"; (* April has 30 days *) 159 + ] in 160 + List.iter (fun input -> 161 + let result = Http_date.parse input in 162 + Alcotest.(check (option Alcotest_ptime.testable)) 163 + (Printf.sprintf "Invalid date: %S" input) None result 164 + ) invalid_dates 165 + 166 + let test_invalid_times () = 167 + (* Invalid time components *) 168 + let invalid_times = [ 169 + "Sun, 06 Nov 1994 25:00:00 GMT"; (* Hour 25 *) 170 + "Sun, 06 Nov 1994 00:60:00 GMT"; (* Minute 60 *) 171 + "Sun, 06 Nov 1994 00:00:60 GMT"; (* Second 60 (no leap second support) *) 172 + ] in 173 + List.iter (fun input -> 174 + let result = Http_date.parse input in 175 + Alcotest.(check (option Alcotest_ptime.testable)) 176 + (Printf.sprintf "Invalid time: %S" input) None result 177 + ) invalid_times 178 + 179 + (** {1 Whitespace and Case Tests} *) 180 + 181 + let test_trimming_whitespace () = 182 + (* Should handle leading/trailing whitespace *) 183 + let test_cases = [ 184 + " Sun, 06 Nov 1994 08:49:37 GMT "; 185 + "\tSun, 06 Nov 1994 08:49:37 GMT\t"; 186 + "\n Sun, 06 Nov 1994 08:49:37 GMT \n"; 187 + ] in 188 + let expected = Some (make_time 1994 11 6 8 49 37) in 189 + List.iter (fun input -> 190 + let result = Http_date.parse input in 191 + Alcotest.(check (option Alcotest_ptime.testable)) 192 + "Whitespace trimming" expected result 193 + ) test_cases 194 + 195 + let test_case_insensitive_months () = 196 + (* Month names should be case-insensitive *) 197 + let test_cases = [ 198 + ("Sun, 06 nov 1994 08:49:37 GMT", "lowercase"); 199 + ("Sun, 06 NOV 1994 08:49:37 GMT", "uppercase"); 200 + ("Sun, 06 NoV 1994 08:49:37 GMT", "mixed case"); 201 + ] in 202 + let expected = Some (make_time 1994 11 6 8 49 37) in 203 + List.iter (fun (input, desc) -> 204 + let result = Http_date.parse input in 205 + Alcotest.(check (option Alcotest_ptime.testable)) 206 + (Printf.sprintf "Case insensitive: %s" desc) expected result 207 + ) test_cases 208 + 209 + (** {1 Test Suite} *) 210 + 211 + let () = 212 + Alcotest.run "HTTP Date Parsing (RFC 9110 Section 5.6.7)" [ 213 + ("RFC 1123 format", [ 214 + Alcotest.test_case "Basic parsing" `Quick test_rfc1123_basic; 215 + Alcotest.test_case "All months" `Quick test_rfc1123_all_months; 216 + Alcotest.test_case "All weekdays" `Quick test_rfc1123_all_weekdays; 217 + Alcotest.test_case "Edge dates" `Quick test_rfc1123_edge_dates; 218 + ]); 219 + ("RFC 850 format (obsolete)", [ 220 + Alcotest.test_case "Basic parsing" `Quick test_rfc850_basic; 221 + Alcotest.test_case "Y2K year interpretation" `Quick test_rfc850_year_interpretation; 222 + ]); 223 + ("asctime format (obsolete)", [ 224 + Alcotest.test_case "Basic parsing" `Quick test_asctime_basic; 225 + Alcotest.test_case "Single digit day" `Quick test_asctime_single_digit_day; 226 + ]); 227 + ("Invalid inputs", [ 228 + Alcotest.test_case "Completely wrong format" `Quick test_invalid_completely_wrong; 229 + Alcotest.test_case "Invalid month names" `Quick test_invalid_month_names; 230 + Alcotest.test_case "Invalid dates" `Quick test_invalid_dates; 231 + Alcotest.test_case "Invalid times" `Quick test_invalid_times; 232 + ]); 233 + ("Whitespace and case", [ 234 + Alcotest.test_case "Trimming whitespace" `Quick test_trimming_whitespace; 235 + Alcotest.test_case "Case insensitive months" `Quick test_case_insensitive_months; 236 + ]); 237 + ]
+6
test/test_http_date.mli
··· 1 + (*--------------------------------------------------------------------------- 2 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 + SPDX-License-Identifier: ISC 4 + ---------------------------------------------------------------------------*) 5 + 6 + (** Comprehensive tests for HTTP-date parsing per RFC 9110 Section 5.6.7 *)