Message-Id: Date: Mon, 11 Mar 1996 07:30:44 -0800 To: luotonen@netscape.com, mogul@pa.dec.com, fielding@avron.ICS.UCI.EDU From: Steve Zilles Subject: Comments on Accepts-Range and Conditional Range requests Cc: szilles@mv.us.adobe.com below are the comments that I promised you all when we spoke at the IETF meeting in Los Angeles on Thursday. I was not able to propose a re-write of Section 3.2 of the Byte Range proposal because I needed feedback on my interpretation of how partial GETs and conditional GETs should interact. If these notes make sense to you, then distribute them to the whole list. I will be travelling most of this week and will only be able to check mail overnight Steve Z. The following revision of section 2 attempts to do the following: (1) provide something like replacement text, (2) changes the name from "Accepts-Ranges" to "Ranges-Supported" (or any other name) to respond to concerns that "Accepts-Ranges" is too similar to Request "Accepts" headers, (3) provides an overview of the generic value in knowing (when a resource arrives at a client) whether or not that resource can be obtained with partical GETs using the Range header. 2. RANGES-SUPPORTED HTTP RESPONSE HEADER The Ranges-Supported response [entity?] header defines which range types are supported for partial GETs using the Range header. The only range type currently supported is "byte". Ranges-Supported = 1#range-type range-type = "byte" An example is Ranges-Supported: bytes The server will send this header only for resources for which it will be able to satisfy the byte Range request, e.g. for PDF documents, or images, which can be partially reloaded Knowledge of support for Range requests allows the client to better adapt its caching and reloading strategies. For example, some clients, such as those on a so called "Network Computer" or "Surfboard", may have limited caching space. Such a client may be displaying a page with a number of image resources some of which are only partially on screen. If the client needs space for a new image,perhaps due to scrolling the page, it may need to reuse existing cache space. If the client knows a resource supports Range requests, then the client may reuse part of the cache space for that resource, that part that is currently off screen, knowing that a partial Get with a Range header can issued to reload the reused part if the user scrolls back to lost part of the image. Without range support the whole image would need to be reloaded wasting net bandwidth. Partial reloading can also be used to more efficiently retrieve uncached parts of a resource when loading the resource was interrupted for any reason. Because of the architecture of the byte range request and response, the client is not limited to attempting to use byte ranges only when this header is present. The Request-Range header is simply ignored by a server that does not support it, and it will send the entire document as a response. The following comments on section 3.2 of the Byte Range I_D attempts to clarify the interaction of conditional and partial GETs without taking sides on how conditional GETs are represented. That is, there is the exiting IMS conditional and several other proposed conditionals; which of these is chosen for 1.1 should be independent of the description of the interaction of partial and conditional GETs. For consistency with the existing draft, the "if-valid" request-validator is used in this revision. In attempting to work out a simple, consistent solution, I considered the following (somewhat independent) questions: 1. Is the GET Unconditional or Conditional? 2. Is the GET Full or Partial? This determines what data is requested. 3. Does the Server implement Ranges (Partial GETs)? 4. Is the Condition Tentative or Insertional? 5. Is the Condition variable IMS or Other I then tried to establish some simplifying assumptions. These are a. Tentative and Insertional conditions apply to both Full and Partial requests. With this view, a Tentative conditional is one in which the requested data is sent when the tested condition is satisfied and an Insertional condition is the negation of the Tentative condition so the requested data is sent if the tested (Tentative) condition is not satisfied. What happens when the requested data is not sent depends on the answers to the other questions. For example, the tested condition in an "if-modified-since" (IMS) is whether the data on the server has been modified since the given date. The corresponding Insertional condition would be "unless-modified-since" or "if-not-modified-since". b. The existing IMS condition is a Tentative condition c. The response to a Partial request from a Server that does not implement Partial requests is *always* the same as a full request; that is, only when the server implements Ranges does its response take into account Range information. This assumption means that most conditional processing is simple and only when both ranges and conditions are present do things get complicated The result of these simplifications is captured in the table below where the first five columns hold answers to the questions 1. - 5.above and the last four columns hold a description of the response, both when the condition (if any) is satisfied and when it is not. To fit on the page, the table is split into two parts. The first part defines the different Request cases and gives each a case number. The second part specifies the response, both status code and resource, to each of the cases, as numbered in part one. Where the answers to the question in earlier columns make the answers to questions in later columns moot, "NA" is used to mark the later columns. In the table, the condition being tested is always the same, whether the Tentative or the Insertional case; for example, with IMS the test is always whether the resource has changed since the given date. The syntactic convention that distinguishes the cases ("if" means Tentative and "unless" means Insertion) is not expressed in the table. For Insertion conditions, this results in the requested data being returned in response to the test not being satisfied. If this is confusing, then simply interchange columns 2 and 3 with 4 and 5 of the response table for the Insertion cases. What is important about this is that the syntactic distinction between Tentative and Insertion cases must be more than just the negation of the tested condition (e.g., changing "if" to "unless") because the tested condition may itself be negative (as is the case with the request-validator where the Tentative condition is "if-not-valid"). Also, the table does not show Other conditions, but their behavior is basically the same as IMS provided that the sense of the condition is the same as IMS; that is, if the condition is satisfied it corresponds to the Tentative condition. (This would mean that the Tentative form of "if-valid" would be "if-not-valid" so that data would be sent if the request validator were not valid.) In addition, the Other conditions would replace the 304 status code with a suitable status code for that condition (412?) Request Cases Cond Cond Case Cond Request Range direction kind number Uncond/ Full/ Impl/ Tentative/ IMS/ Cond Part NotImpl Insertion Other Uncond Full NA NA NA 1 Uncond Part NotImpl NA NA 2 Uncond Part Impl NA NA 3 Cond Full NA Tentative IMS 4 Cond Part NotImpl Tentative IMS 5 Cond Part Impl Tentative IMS 6 Cond Full NA Insertion IMS 7 Cond Part NotImpl Insertion IMS 8 Cond Part Impl Insertion IMS 9 Response Cases Case number Satisfied Satisfied Not Satisfied Not Satisfied Status Response Status Response 1 200 Full Resource Failure Status No Resource 2 206 Part Resource Failure Status No Resource 3 200 Full Resource Failure Status No Resource 4 200 Full Resource 304 No Resource 5 200 Full Resource 304 No Resource 6 206 Part Resource 304 No Resource 7 304 No Resource 200 Full Resource 8 304 No Resource 200 Full Resource 9 200? Full Resource 206 Part Resource Most entries in the table are explained by the above assumptions or existing HTTP 1.0 rules. The set of entries that bear some explanation are the ones for Insertion conditions. The entry for a "Partial, Insertion (conditional) request that is satisfied and the server implements ranges" is not symetric with the case of a "Partial, Tentative (conditional) request that is not satisfied and the server implements ranges". This is intentional. The presumption for a "Partial, Insertion (conditional) request that is satisfied" (e.g. the data has been modified) is that the client wants (all) the updated data. The presumption for a "Partial, Tentative (conditional) request that is not satisfied" is that the client (or cache) already has the relevant data and does not need data that has not changed. The case of a Partial, Insertion (conditional) request that is satisfied and the server does not implement ranges is handled somewhat arbitrarily. It seemed better to keep the consistency of responding as if the request was a full request when the server does not handle ranges than to try to do something clever. Thus, only when the server implements Range requests is the response to an Insertion conditional different from the negation of a Tentative conditional. This difference lies in the presumed intent of the request: for a Tentative request, do nothing if the condition is not satisfied and for the Insertion request (on the same test) update/replace the complete local copy if that condition is satisfied.