OpenFlax Design Goal #2: Conformancy

Conformancy should, unsurprisingly, be a concern of every web server.

OpenFlax hopes to one day be "conditionally compliant" with RFC 2616; that is, to honestly be able to call itself an HTTP/1.1 web server.

Overview

Some of the things OpenFlax "MUST" support but currently does not support include:

It may also be worth noting that OpenFlax has been tested with the following packages, and has demonstrated adequate functioning:

And the webserver has been tried on the following operating systems, serving files with no obvious problems:

Lastly, the reasoning behind this design goal being ranked second is that in the unlikely event that OpenFlax must choose between being either conformant or secure, it would prefer to be secure.

Detail - MUSTs checklist

These are excerpts of the MUST clauses from RFC 2616.

All MUSTs not listed apply to clients or proxies, and not to servers.

Some SHOULDs and other notes which seem important are also listed.

PageMUSTComments
15 "where at least one element is required, at least one non-null element MUST be present." Done. OpenFlax currently neither generates nor parses any of the headers which mention 1# in their grammar, with the following exceptions:
  • Connection: close
  • Cache-Control: no-cache
  • Transfer-Encoding: identity
  • Transfer-Encoding: chunked

15 "At least one delimiter (LWS and/or seperators) MUST exist between any two tokens" Done. All tokens generated by OpenFlax are seperated with whitespace.
16 "header field values can be folded onto multiple lines" Done. OpenFlax checks to see if a header field is split onto multiple lines before collecting it.
17 "These special characters MUST be in a quoted string" Todo. Look for this in grammar.
18 "major and minor numbers MUST be treated as seperate integers" Done. OpenFlax treats them as seperate integers.
18 "leading zeroes MUST be ignored by recipients and MUST NOT be sent." Done. OpenFlax ignores leading zeroes.
18 "application ... that includes "HTTP/1.1" MUST be conditionally compliant." Todo. This comes last.
18 "Applications ... MUST [use ... "HTTP/1.1"] for any message not compatible with HTTP/1.0" Done. OpenFlax uses HTTP/1.1 for all messages.
19 "Servers MUST be able to handle the URI of any resource they serve" Done. OpenFlax places no restriction on length of a URI.
20 "servers which parse the date value MUST accept all three formats" Done. OpenFlax does not parse the date value.
20 "though they MUST only generate the RFC 1123 format for representing..." Done. OpenFlax generates only RFC 1123 dates.
20 "though they MUST only generate the RFC 1123 format for representing..." Done. OpenFlax generates only RFC 1123 dates.
21 "date/time stamps MUST be represented in GMT" Done. OpenFlax generates GMT dates.
21 "date is case-sensitive and MUST not include additional LWS" Done. OpenFlax generates strict RFC 1123 dates.
22 "the definition associated with a MIME character set name MUST fully specify the mapping" Done. OpenFlax does not use character sets.
22 "any token that has a predefined value within... IANA... MUST represent the character set defined by that registry" Done. OpenFlax does not use character sets.
22 "any token that has a predefined value within... IANA... MUST represent the character set defined by that registry" Done. OpenFlax does not use character sets.
24 "Whenever a transfer-coding is applied... the set of transfer-coding MUST include "chunked"" Done. OpenFlax does not apply transfer-codings.
24 "When the "chunked" transfer-coding is used, it MUST be the last transfer-coding" Done. OpenFlax does not apply transfer-codings.
24 "The "chunked" transfer-coding MUST NOT be applied more than once" Done. OpenFlax does not apply transfer-codings.
25 "A server which receives an entity-body with a transfer-coding it does not understand SHOULD return 501 (Unimplemented) ..." Done. 501 is sent for any incoming Transfer-Encoding which is not absent, "identity", or "chunked"..
25 "A server MUST NOT send transfer-codings to an HTTP/1.0 client" Done. OpenFlax does not apply transfer-codings.
26 "A server using chunked transfer-coding in a response MUST NOT use the trailer for any header fields" Done. OpenFlax does not apply transfer-codings.
26 "applications MUST be able to recieve and decode the "chunked" transfer-coding" Done. OpenFlax understands "chunked" bodies (ignoring extensions and trailers.)
26 "and MUST ignore chunk-extension extensions they do not understand." Done. OpenFlax ignores all chunk-extensions.
26 "LWS MUST NOT be used between the type and the subtype." Done. OpenFlax treats type/subtype as a unit.
27 "An entity-body transferred via HTTP messages MUST be represented in the appropriate canonical form prior to its transmission" Assumed. It's up to the webmaster to ensure that their resources are in canonical form.
27 "HTTP applications MUST accept CRLF, bare CR, and bare LF as being representative of a line break in text media received via HTTP." Todo, check.
27 "a bare CR or LF MUST NOT be substituted for CRLF within any of the HTTP control structures (such as header fields and multipart boundaries)." Done. OpenFlax uses CRLF exclusively within HTTP control structures.
27 "If an entity-body is encoded with a content-coding, the underlying data MUST be in a form defined above prior to being encoded." Done. OpenFlax does not apply content-codings.
27 "Data in character sets other than "ISO-8859-1" or its subsets MUST be labeled with an appropriate charset value." Done. OpenFlax does not use character sets.
28 "All multipart types ... MUST include a boundary parameter as part of the media type value." Done. OpenFlax doesn't transmit multiparts.
28 "The message body is itself a protocol element and MUST therefore use only CRLF to represent line breaks between body-parts." Done. OpenFlax doesn't transmit multiparts.
28 "the epilogue of any multipart message MUST be empty; HTTP applications MUST NOT transmit the epilogue" Done. OpenFlax doesn't transmit multiparts.
28 "If an application receives an unrecognized multipart subtype, the application MUST treat it as being equivalent to "multipart/mixed"." Todo, check this.
29 "[Product tokens] MUST NOT be used for advertising ot other non-essential information" Done. OpenFlax sends only its name and version.
29 "applications MUST NOT generate more than 3 digits after the decimal point" Done. OpenFlax does not generate quality values.
30 "an entity tag MUST be unique across all versions of all entities associated with a particular resource" Done. OpenFlax does not use entity tags.
32 "It MUST be possible to combine the multiple header fields into one... pair" Todo. Double-check this.
32 "Transfer-Encoding MUST be used to indicate any transfer-codings applied" Done. OpenFlax does not apply transfer-codings.
33 "A message-body MUST NOT be included in a request if ... method ... does not allow" Done. OpenFlax does not send message-body in response to HEAD method.
33 "All responses to the HEAD request method MUST NOT include a message-body" Done. OpenFlax does not send message-body in response to HEAD method.
33 "1xx, 204, and 304 responses MUST NOT include a message-body" Done. OpenFlax does not send 1xx, 204. or 304 responses.
33 "The Content-Length header field MUST NOT be sent if [entity-length and transfer-length] are different" Done. OpenFlax does not apply transfer-codings, therefore entity-length and transfer-length will never differ.
34 "If a message is received with both ... Transfer-Encoding ... and a Content-Length header field, the latter MUST be ignored" Done. When Transfer-Encoding is not identity, OpenFlax throws out Content-Length.
34 "[Multipart/byte-ranges] MUST NOT be used unless the sender knows that the recipient can parse it" Done. OpenFlax does not send multipart/byte-ranges.
34 "the server MUST delimit the message using methods defined in items 1,3 or 5" Done. OpenFlax does not send multipart/byte-ranges.
34 "All HTTP/1.1 applications that receive entities MUST accept the "chunked" transfer-coding" Done. OpenFlax understands "chunked" bodies.
34 "Messages MUST NOT include both a Content-Length header field and a non-identity transfer-coding" Done. OpenFlax does not apply transfer-codings.
34 "If the message does include a non- identity transfer-coding, the Content-Length MUST be ignored." Done. When Transfer-Encoding is not identity, OpenFlax throws out Content-Length.
34 "When a Content-Length is given in a message where a message-body is allowed, its field value MUST exactly match the number of OCTETs in the message-body." Done. OpenFlax sends the exact Content-Length of the body.
36 "The methods GET and HEAD MUST be supported by all general-purpose servers" Done. OpenFlax supports GET and HEAD.
36 "methods ... MUST be implemented with the same semantics as those specified in section 9" Todo. Double-check this.
37 "HTTP/1.1 servers MUST accept the absoluteURI form in requests" Done. OpenFlax accepts the absoluteURI form.
37 "the origin server MUST decode ["% HEX HEX" encodings in] the Request-URI" Done. OpenFlax decodes these.
38 "virtual hosts ... MUST use the following rules" Done. OpenFlax treats the given hostname this way.
38 "If Request-URI is an absoluteURI, the host is part of the Request-URI. Any Host header field value in the request MUST be ignored." Done. OpenFlax extracts the host from the absoluteURI form.
38 "If the host ... is not a valid host on the server, the response MUST be a 400" Done. OpenFlax 400's any hostname not in its config file.
45 "In order to remain persistent, all messages on the connection MUST have a self-defined message length" Done. All responses have a Content-Length, except for streaming responses (which can only be enabled with "Connection: close")
46 "A server MUST send its responses ... in the same order that the requests were received." Done. Openflax relies on Erlang's semantics of retainment of order of messages.
47 "servers... MUST be able to recover from asynchronous close events." Done. Openflax will timeout after an unexpected client close.
48 "Upon receiving ... "100-continue" expectation, an origin server MUST either respond with 100 (Continue) ..., or respond with a final status code." Done. OpenFlax will always send the 417 response to any expectation.
48 "The origin server MUST NOT wait for the request body before sending the 100 (Continue) response" Done. OpenFlax does not send 100 Continue responses.
49 "It MUST NOT perform the requested method if it returns a final status code." Done. OpenFlax sends only the 417 response.
49 "An origin server ... MUST NOT send a 100 (Continue) response [to] an HTTP/1.0 (or earlier) client" Done. OpenFlax does not send 100 Continue responses.
49 "An origin server that sends a 100 (Continue) response MUST ultimately send a final status code" Done. OpenFlax does not send 100 Continue responses.
53 "If no response body is included, the response MUST include a Content-Length ... of "0"." Done. OpenFlax sends a 0 Content-Length in all bodiless responses.
54 "The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response." Done. OpenFlax implements HEAD correctly.
55 "POST requests MUST obey the message transmission requirements set out in section 8.2." Todo. Double-check this.
55 (PUT and TRACE MUSTS) Done. OpenFlax implements neither PUT nor TRACE (nor is it required to.)
57 "servers MUST NOT send a 1xx response to an HTTP/1.0 client" Done. OpenFlax does not currently send 1xx responses.
58 "The server MUST send a final response after the request has been completed." Done. OpenFlax does not currently send 1xx responses.
59 "The origin server MUST create the resource before returning the 201 status code." Done. 201 responses are not sent.
60 "The 204 response MUST NOT include a message-body" Done. 204 responses are not sent.
60 "The [205] response MUST NOT include an entity." Done. 205 responses are not sent.
60 "The [partial GET] request MUST have included a Range header field" Todo. Double-check this.
60 "The [206] response MUST include the following header fields" Done. 206 responses are not sent.
60 "If a Content-Length header field is present in the response, its value MUST match the actual number of OCTETs transmitted in the message-body" Done. OpenFlax sends the exact Content-Length of the body.
61 "If the response is the result of an If-Range request that used a weak validator, the response MUST NOT include other entity-headers" Todo. Double-check this.
61 "Otherwise, the response MUST include all of the entity-headers that would have been returned with a 200 (OK) response to the same request." Todo. Double-check this.
63 "The 304 response MUST NOT contain a message-body" Done. 304 responses are not sent.
63 "The [304] response MUST include the following header fields: Date, ETag and/or Content-Location, Expires Cache-Control and/or Vary" Done. 304 responses are not sent.
64 "If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. Otherwise (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers" Todo. Double-check this.
66 "The [401] response MUST include a WWW-Authenticate header field" Done. 401 responses are not sent.
66 "The [405] response MUST include an Allow header containing a list of valid methods " Done. 405 responses always include an Allow header.
69 "This [416] response MUST NOT use the multipart/byteranges content-type." Done. 416 responses are not sent.
85 "Servers MUST NOT depend on clients being able to choose deterministically between responses generated during the same second, if their expiration times overlap." Done. OpenFlax does not send expiration times.
87 "The strong comparison function: in order to be considered equal, both validators MUST be identical in every way, and both MUST NOT be weak." Todo. OpenFlax does not yet generate validators.
87 "The weak comparison function: in order to be considered equal, both validators MUST be identical in every way, but either or both of them MAY be tagged as "weak" without affecting the result." Todo. OpenFlax does not yet generate validators.
88 "A cache or origin server receiving a conditional request, other than a full-body GET request, MUST use the strong comparison function to evaluate the condition." Todo. OpenFlax does not yet grok conditional requests.
89 "In order to be legal, a strong entity tag MUST change whenever the associated entity value changes in any way." Todo. OpenFlax does not yet generate entity tags.
89 "In order to be legal, a strong entity tag MUST change whenever the associated entity value changes in any way." Todo. OpenFlax does not yet generate entity tags.
90 "An HTTP/1.1 origin server, upon receiving a conditional request that includes both a Last-Modified date ... and one or more entity tags ..., MUST NOT return a response status of 304 (Not Modified) unless doing so is consistent with all of the conditional header fields in the request." Done. 304 responses are never sent.
106 "An Allow header field MUST be present in a 405 (Method Not Allowed) response." Done. Every 405 response has an Allow header.
113 "The server MUST NOT use a cached copy when responding to [a 'no-cache'] request." Done. OpenFlax never caches responses.
117 "Message headers listed in the Connection header MUST NOT include end-to-end headers, such as Cache-Control." Done. Only "Connection: close" is ever sent.
117 "HTTP/1.1 applications that do not support persistent connections MUST include the "close" connection option in every message." Done. With persistency disabled, "Connection: close" is always sent.
117 "A system receiving an HTTP/1.0 (or lower-version) message that includes a Connection header MUST ... remove and ignore any header field(s) from the message with the same name as the connection-token." Todo. Implement this.
118 "If the content-coding of an entity is not "identity", then the response MUST include a Content-Encoding entity-header ... that lists the non-identity content-coding(s) used." Done. Content-encoding of responses is always "identity".
118 "If multiple encodings have been applied to an entity, the content codings MUST be listed in the order in which they were applied." Done. Content-encoding of responses is always "identity".
121 "If the message is received with a transfer-encoding, that encoding MUST be removed prior to checking the Content-MD5 value against the received entity." Done. OpenFlax doesn't check incoming MD5's.
121 "Conversion of all line breaks to CRLF MUST NOT be done before computing or checking the digest: the line break convention used in the text actually transmitted MUST be left unaltered when computing the digest." Done. OpenFlax doesn't check incoming MD5's.
122 "a byte-range-resp-spec MUST only specify one range, and MUST contain absolute byte positions for both the first and last byte of the range." Done. OpenFlax ignores ranges in requests.
122 "The recipient of an invalid byte-content-range-spec MUST ignore it and any content transferred along with it." Done. OpenFlax ignores ranges in requests.
123 "A response with status code 206 (Partial Content) MUST NOT include a Content-Range field with a byte-range- resp-spec of "*"." Done. 206 responses are never sent.
123 "A response to a request for a single range MUST NOT be sent using the multipart/byteranges media type." Done. multipart/byteranges responses are never sent.
124 "The field value is an HTTP-date ...; it MUST be sent in RFC 1123 [8]-date format." Done. All dates are sent in RFC 1123 format.
124 "Origin servers MUST include a Date header field ..." Done. OpenFlax always sends a Date.
125 "If the server does not have a clock that can provide a reasonable approximation of the current time, its responses MUST NOT include a Date header field. In this case, the rules in section 14.18.1 MUST be followed." Done. OpenFlax does not (yet) support clockless operation.
126 "A server that does not understand or is unable to comply with any of the expectation values in the Expect field of a request MUST respond ... with a 417 (Expectation Failed) status ..." Done. OpenFlax always sends a 417 in response to Expect.
126 "If a server receives a request containing an Expect field that includes an expectation-extension that it does not support, it MUST respond with a 417 (Expectation Failed) status." Done. OpenFlax always sends a 417 in response to Expect.
127 "The format is an absolute date and time as defined by HTTP-date in section 3.3.1; it MUST be in RFC 1123 date format" Done. Expires is not sent. All dates are RFC 1123.
129 "Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request) status code to any HTTP/1.1 request message which lacks a Host header field." Done. OpenFlax sends a 400 response in this case.
130 "A server MUST use the strong comparison function (see section 13.3.3) to compare the entity tags in If-Match." Todo. Double-check.
130 "If none of the entity tags match, or if "*" is given and no current entity exists, the server MUST NOT perform the requested method, and MUST return a 412 (Precondition Failed) response." Todo. Double-check.
130 "If the request would, without the If-Match header field, result in anything other than a 2xx or 412 status, then the If-Match header MUST be ignored." Todo. Double-check.
130 "The meaning of "If-Match: *" is that the method SHOULD be performed if the representation selected by the origin server (or by a cache, possibly using the Vary mechanism, see section 14.44) exists, and MUST NOT be performed if the representation does not exist." Todo. Double-check.
130 "A request intended to update a resource (e.g., a PUT) MAY include an If-Match header field to signal that the request method MUST NOT be applied if the entity corresponding to the If-Match value (a single entity tag) is no longer a representation of that resource." Todo. Double-check.
132 "If any of the entity tags match the entity tag of the entity that would have been returned in the response to a similar GET request (without the If-None-Match header) on that resource, or if "*" is given and any current entity exists for that resource, then the server MUST NOT perform the requested method, unless required to do so because the resource's modification date fails to match that supplied in an If-Modified-Since header field in the request." Todo. Double-check.
132 "For all other request methods, the server MUST respond with a status of 412 (Precondition Failed)." Todo. Double-check.
133 "If none of the entity tags match, then the server ... MUST also ignore any If-Modified-Since header field(s) in the request. That is, if no entity tags match, then the server MUST NOT return a 304 (Not Modified) response." Todo. Double-check.
133 "If the request would, without the If-None-Match header field, result in anything other than a 2xx or 304 status, then the If-None-Match header MUST be ignored." Todo. Double-check.
133 "The meaning of "If-None-Match: *" is that the method MUST NOT be performed if the representation selected by the origin server ... exists..." Todo. Double-check.
134 "The If-Range header ... MUST be ignored if the request does not include a Range header, or if the server does not support the sub-range operation." Done. OpenFlax ignores If-Range headers.
134 "If the requested variant has been modified since the specified time, the server MUST NOT perform the requested operation, and MUST return a 412 (Precondition Failed)." Todo. Double-check.
135 "An origin server MUST NOT send a Last-Modified date which is later than the server's time of message origination ... the server MUST replace that date with the message origination date." Todo. Double-check.
137 "The Proxy-Authenticate response-header field MUST be included as part of a 407 (Proxy Authentication Required) response." Done. OpenFlax never sends 407 responses.
138 "The recipient of a byte-range-set that includes one or more syntactically invalid byte-range-spec values MUST ignore the header field that includes that byte-range-set." Done. OpenFlax ignores range headers in requests.
143 "Message header fields listed in the Trailer header field MUST NOT include the following header fields: Transfer-Encoding, Content-Length, and Trailer" Done. OpenFlax never sends trailers.
144 "If multiple encodings have been applied to an entity, the transfer- codings MUST be listed in the order in which they were applied." Done. OpenFlax does not apply transfer-codings.
144 "The server MUST use the Upgrade header field within a 101 (Switching Protocols) response ..." Done. OpenFlax never sends 101 responses.
144 "... the first action after changing the protocol MUST be a response to the initial HTTP request containing the Upgrade header field. " Done. OpenFlax does not (yet) support switching protocols.
148 "If a character set other than ISO-8859-1 is used, it MUST be encoded in the warn-text using the method described in RFC 2047 [14]." Done. OpenFlax never sends Warning headers.
149 "A system receiving [a 199] warning MUST NOT take any automated action, besides presenting the warning to the user." Done. OpenFlax ignores Warning headers.
150 "A system receiving [a 299] warning MUST NOT take any automated action." Done. OpenFlax ignores Warning headers.
150 "If an implementation sends a message with one or more Warning headers whose version is HTTP/1.0 or lower, then the sender MUST include in each warning-value a warn-date that matches the date in the response." Done. OpenFlax does not send Warning headers.
150 "If an implementation receives a message with a warning-value that includes a warn-date, and that warn-date is different from the Date value in the response, then that warning-value MUST be deleted from the message before storing, forwarding, or using it. ... If all of the warning-values are deleted for this reason, the Warning header MUST be deleted as well." Done. OpenFlax ignores Warning headers.
150 "The WWW-Authenticate response-header field MUST be included in 401 (Unauthorized) response messages." Done. OpenFlax never sends 401 responses.
153 "If an HTTP server translates HTTP URIs directly into file system calls, the server MUST take special care not to serve files that were not intended to be delivered to HTTP clients." Done. Several measures are taken.
153 "On such a system, an HTTP server MUST disallow any such construct in the Request-URI if it would otherwise allow access to a resource outside those intended to be accessible via the HTTP server." Done. URI's containing ".." are rejected.
153 "Similarly, files intended for reference only internally to the server (such as access control files, configuration files, and script code) MUST be protected from inappropriate retrieval ..." Done. Such resources can, and should, be protected by measures in the configuration file.
154 "If a single server supports multiple organizations that do not trust one another, then it MUST check the values of Location and Content- Location headers in responses that are generated under control of said organizations to make sure that they do not attempt to invalidate resources over which they have no authority." Done. OpenFlax does not yet support multiple organizations that do not trust one another.
166 "An HTTP/1.1 implementation ... MUST NOT internally represent a parsed Expires date as later than the proper value." Done. OpenFlax does not parse Expires.
166 "All expiration-related calculations MUST be done in GMT. The local time zone MUST NOT influence the calculation or comparison of an age or expiration time." Done. OpenFlax does not do expiration calculations.
167 "If an HTTP header incorrectly carries a date value with a time zone other than GMT, it MUST be converted into GMT using the most conservative possible conversion." Done. OpenFlax does not (yet) parse incoming dates.
172 "Both [HTTP/1.1] clients and servers MUST support the Host request-header." Done. OpenFlax supports Host.
172 "[HTTP/1.1] Servers MUST report a 400 (Bad Request) error if an HTTP/1.1 request does not include a Host request-header." Done. (It also gripes about HTTP/1.0, but maybe shouldn't.)
172 "[HTTP/1.1] Servers MUST accept absolute URIs." Done. OpenFlax accepts absolute URI's.