RFC 8010
Internet Printing Protocol/1.1: Encoding and Transport
RFC 8010: Internet Printing Protocol/1.1: Encoding and Transport π¨οΈβ¨
- Authors: M. Sweet (Apple Inc.) and I. McDonald (High North, Inc.) π§βπ»
- Category: Standards Track π
- Date: January 2017 π
- ISSN: 2070-1721
- Obsoletes: RFC 2910 and RFC 3382 π
- Updates: none listed in the header
Abstract
Okay bestie, so IPP (the Internet Printing Protocol) is an application-level protocol for distributed printing that runs on Internet tools and technologies. π¨οΈ This doc lays out the rules for encoding IPP operations, attributes, and values into the Internet MIME media type called "application/ipp". It also covers the rules for transporting a message body whose Content-Type is "application/ipp" over HTTP and/or HTTPS. π¦ The data model and operation semantics live in "Internet Printing Protocol/1.1: Model and Semantics" (RFC 8011), so go check that one for the what-it-means part.
This document obsoletes RFCs 2910 and 3382. π
Status of This Memo β¨
This is an Internet Standards Track document. πΈ
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has gotten public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check Section 2 of RFC 7841. π
Want the current status of this document, any errata, or a way to send feedback? Head to http://www.rfc-editor.org/info/rfc8010. π
Copyright Notice π
Copyright (c) 2017 IETF Trust and the persons identified as the document authors. All rights reserved. Β©οΈ
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the date of publication. Please review these carefully, because they spell out your rights and restrictions for this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Simplified BSD License. π«Ά
Table of Contents πΊοΈ
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
2. Conventions Used in This Document . . . . . . . . . . . . . . 5
2.1. Requirements Language . . . . . . . . . . . . . . . . . . 5
2.2. Printing Terminology . . . . . . . . . . . . . . . . . . 5
2.3. Abbreviations . . . . . . . . . . . . . . . . . . . . . . 6
3. Encoding of the Operation Layer . . . . . . . . . . . . . . . 6
3.1. Picture of the Encoding . . . . . . . . . . . . . . . . . 8
3.1.1. Request and Response . . . . . . . . . . . . . . . . 8
3.1.2. Attribute Group . . . . . . . . . . . . . . . . . . . 9
3.1.3. Attribute . . . . . . . . . . . . . . . . . . . . . . 9
3.1.4. Attribute-with-one-value . . . . . . . . . . . . . . 10
3.1.5. Additional-value . . . . . . . . . . . . . . . . . . 11
3.1.6. Collection Attribute . . . . . . . . . . . . . . . . 12
3.1.7. Member Attributes . . . . . . . . . . . . . . . . . . 13
3.1.8. Alternative Picture of the Encoding of a Request or a
Response . . . . . . . . . . . . . . . . . . . . . . 14
3.2. Syntax of Encoding . . . . . . . . . . . . . . . . . . . 15
3.3. Attribute-group . . . . . . . . . . . . . . . . . . . . . 16
3.4. Required Parameters . . . . . . . . . . . . . . . . . . . 18
3.4.1. "version-number" . . . . . . . . . . . . . . . . . . 18
3.4.2. "operation-id" . . . . . . . . . . . . . . . . . . . 18
3.4.3. "status-code" . . . . . . . . . . . . . . . . . . . . 19
3.4.4. "request-id" . . . . . . . . . . . . . . . . . . . . 19
3.5. Tags . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.5.1. "delimiter-tag" Values . . . . . . . . . . . . . . . 19
3.5.2. "value-tag" Values . . . . . . . . . . . . . . . . . 20
3.6. "name-length" . . . . . . . . . . . . . . . . . . . . . . 23
3.7. (Attribute) "name" . . . . . . . . . . . . . . . . . . . 23
3.8. "value-length" . . . . . . . . . . . . . . . . . . . . . 23
3.9. (Attribute) "value" . . . . . . . . . . . . . . . . . . . 24
3.10. Data . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4. Encoding of Transport Layer . . . . . . . . . . . . . . . . . 26
4.1. Printer URI, Job URI, and Job ID . . . . . . . . . . . . 26
5. IPP URI Schemes . . . . . . . . . . . . . . . . . . . . . . . 28
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 29
7. Internationalization Considerations . . . . . . . . . . . . . 31
8. Security Considerations . . . . . . . . . . . . . . . . . . . 31
8.1. Security Conformance Requirements . . . . . . . . . . . . 31
8.1.1. Digest Authentication . . . . . . . . . . . . . . . . 32
8.1.2. Transport Layer Security (TLS) . . . . . . . . . . . 32
8.2. Using IPP with TLS . . . . . . . . . . . . . . . . . . . 33
9. Interoperability with Other IPP Versions . . . . . . . . . . 33
9.1. The "version-number" Parameter . . . . . . . . . . . . . 34
9.2. Security and URI Schemes . . . . . . . . . . . . . . . . 34
10. Changes since RFC 2910 . . . . . . . . . . . . . . . . . . . 35
11. References . . . . . . . . . . . . . . . . . . . . . . . . . 36
11.1. Normative References . . . . . . . . . . . . . . . . . . 36
11.2. Informative References . . . . . . . . . . . . . . . . . 38
Appendix A. Protocol Examples . . . . . . . . . . . . . . . . . 40
A.1. Print-Job Request . . . . . . . . . . . . . . . . . . . . 40
A.2. Print-Job Response (Successful) . . . . . . . . . . . . . 41
A.3. Print-Job Response (Failure) . . . . . . . . . . . . . . 42
A.4. Print-Job Response (Success with Attributes Ignored) . . 43
A.5. Print-URI Request . . . . . . . . . . . . . . . . . . . . 45
A.6. Create-Job Request . . . . . . . . . . . . . . . . . . . 46
A.7. Create-Job Request with Collection Attributes . . . . . . 46
A.8. Get-Jobs Request . . . . . . . . . . . . . . . . . . . . 48
A.9. Get-Jobs Response . . . . . . . . . . . . . . . . . . . . 49
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 51
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 51
1. Introduction π·
Okay so this doc has the rules for encoding IPP operations, and it describes two layers: the transport layer and the operation layer. π
The transport layer is an HTTP request and response. Every IPP implementation supports HTTP/1.1, and the relevant parts of it are described in these RFCs:
- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing [RFC7230]
- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content [RFC7231]
- Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests [RFC7232]
- Hypertext Transfer Protocol (HTTP/1.1): Caching [RFC7234]
- Hypertext Transfer Protocol (HTTP/1.1): Authentication [RFC7235]
- The 'Basic' HTTP Authentication Scheme [RFC7617]
- HTTP Digest Access Authentication [RFC7616]
IPP implementations can also support HTTP/2, which is described in these RFCs:
- Hypertext Transfer Protocol Version 2 (HTTP/2) [RFC7540]
- HPACK - Header Compression for HTTP/2 [RFC7541]
This document specifies the HTTP headers that an IPP implementation supports. π§
The operation layer is a message body inside an HTTP request or response. The "Internet Printing Protocol/1.1: Model and Semantics" document [RFC8011] and its later extensions (collectively called the IPP Model) define what that message body means and which values are supported. π This document is the one that specifies how an IPP request and response message gets encoded. π¦
2. Conventions Used in This Document π
2.1. Requirements Language π
Okay, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. Read those carefully, they're the whole vibe check for what's mandatory and what's optional. π
2.2. Printing Terminology π¨οΈ
Here's the cast of characters:
- Client: The initiator of outgoing IPP session requests and the sender of outgoing IPP operation requests (Hypertext Transfer Protocol -- HTTP/1.1 [RFC7230] User Agent). π€
- Document: An object that a Printer creates and manages, holding description, processing, and status information. A Document object can have attached data, and it's bound to a single Job. π
- 'ipp' URI: An IPP URI as defined in [RFC3510]. π
- 'ipps' URI: An IPPS URI as defined in [RFC7472]. π
- Job: An object that a Printer creates and manages, holding description, processing, and status information. A Job also contains zero or more Document objects. π§Ύ
- Logical Device: A print server, software service, or gateway that processes Jobs and either forwards or stores the processed Job, or uses one or more Physical Devices to render output. π’
- Model: The semantics of operations, attributes, values, and status-codes used in the Internet Printing Protocol, as defined in the Internet Printing Protocol/1.1: Model and Semantics document [RFC8011] and its later extensions. π§
- Output Device: A single Logical or Physical Device. β¨
- Physical Device: A hardware implementation of an endpoint device, for example a marking engine, a fax modem, and so on. π¨οΈ
- Printer: The listener for incoming IPP session requests and the receiver of incoming IPP operation requests (Hypertext Transfer Protocol -- HTTP/1.1 [RFC7230] Server). It represents one or more Physical Devices or a Logical Device. π
2.3. Abbreviations π€
Here's the alphabet soup, bestie:
- ABNF: Augmented Backus-Naur Form [RFC5234] π§©
- ASCII: American Standard Code for Information Interchange [RFC20] π
- HTTP: Hypertext Transfer Protocol [RFC7230] π
- HTTPS: HTTP over TLS [RFC2818] π
- IANA: Internet Assigned Numbers Authority ποΈ
- IEEE: Institute of Electrical and Electronics Engineers β‘
- IESG: Internet Engineering Steering Group π
- IPP: Internet Printing Protocol (this document and [PWG5100.12]) π¨οΈπ
- ISTO: IEEE Industry Standards and Technology Organization ποΈ
- LPD: Line Printer Daemon Protocol [RFC1179] π¦
- PWG: IEEE-ISTO Printer Working Group π§βπ€βπ§
- RFC: Request for Comments π
- TCP: Transmission Control Protocol [RFC793] π
- TLS: Transport Layer Security [RFC5246] π‘οΈ
- URI: Uniform Resource Identifier [RFC3986] π
- URL: Uniform Resource Locator [RFC3986] πΊοΈ
- UTF-8: Unicode Transformation Format - 8-bit [RFC3629] π
3. Encoding of the Operation Layer β¨
okay so the operation layer is the message body part of the HTTP request or response, and it MUST contain a single IPP operation request or IPP operation response π. Each request or response is a sequence of values and attribute groups. Attribute groups are sequences of attributes, and each attribute is a name and a value. Names and values are ultimately sequences of octets π§.
The whole encoding is built out of octets, which are the most primitive type π. Three important types sit on top of octets: integers, character strings, and octet strings, and most of the other data types are built from those three πΈ.
Every character string in this encoding MUST be a sequence of characters where the characters are associated with some charset [RFC2978] and some natural language π. A character string MUST be in "reading order", so the first character in the value (according to reading order) is the first character in the encoding π. A character string whose charset is US-ASCII and whose natural language is US English is from now on called a US-ASCII-STRING πΊπΈ. A character string whose charset and natural language are specified in a request or response, as described in the Model, is from now on called a LOCALIZED-STRING π.
An octet string MUST be in "Model order", so the first octet in the value (according to the Model order) is the first octet in the encoding π¦. Every integer in this encoding MUST be encoded as a signed integer using two's-complement binary encoding with big-endian format. This is also known as "network order" or "most significant byte first" π₯. The number of octets for an integer MUST be 1, 2, or 4, depending on how it's used in the protocol π.
Here's how the integer sizes shake out:
- A one-octet integer, called a SIGNED-BYTE, is used for the version-number and tag fields π¬.
- A two-byte integer, called a SIGNED-SHORT, is used for the operation-id, status-code, and length fields β¨.
- A four-byte integer, called a SIGNED-INTEGER, is used for value fields and the request-id π .
The next two sections explain the encoding of the operation layer in two different ways:
- informally, through pictures and description πΌοΈ
- formally, through Augmented Backus-Naur Form (ABNF), as specified by RFC 5234 [RFC5234] π§
An operation request or response MUST use the encoding described in these two sections. No skipping, bestie π«Ά.
3.1. Picture of the Encoding
3.1.1. Request and Response
An operation request or response is encoded like this π:
-----------------------------------------------
| version-number | 2 bytes - required
-----------------------------------------------
| operation-id (request) |
| or | 2 bytes - required
| status-code (response) |
-----------------------------------------------
| request-id | 4 bytes - required
-----------------------------------------------
| attribute-group | n bytes - 0 or more
-----------------------------------------------
| end-of-attributes-tag | 1 byte - required
-----------------------------------------------
| data | q bytes - optional
-----------------------------------------------
Figure 1: IPP Message Format
The first three fields in that diagram hold the values of attributes described in Section 4.1.1 of the Model and Semantics document [RFC8011]. Cute, right? They're like the VIP section of the message π.
The fourth field is the "attribute-group" field, and it can show up 0 or more times π·. Each "attribute-group" field represents one group of attributes, like an Operation Attributes group or a Job Attributes group (see the Model) π°. The Model is the one that says which attribute groups are required, and what order they go in, for each operation request and response π.
The "end-of-attributes-tag" field is always present, even when the "data" field isn't π. The Model is the source of truth for whether the "data" field is present for each operation request and response π.
3.1.2. Attribute Group
Each "attribute-group" field is encoded like this β¨:
-----------------------------------------------
| begin-attribute-group-tag | 1 byte
----------------------------------------------------------
| attribute | p bytes |- 0 or more
----------------------------------------------------------
Figure 2: Attribute Group Encoding
An "attribute-group" field contains zero or more "attribute" fields π§Ί.
Also, fun fact: the "begin-attribute-group-tag" field and the "end-of-attributes-tag" field are both called "delimiter-tags" π§.
3.1.3. Attribute
An "attribute" field is encoded like this π¦:
-----------------------------------------------
| attribute-with-one-value | q bytes
----------------------------------------------------------
| additional-value | r bytes |- 0 or more
----------------------------------------------------------
Figure 3: Attribute Encoding
So here's the deal. When an attribute is single valued (like "copies" with a value of 10), or multi-valued with just one value (like "sides-supported" with only the value 'one-sided'), it's encoded with just an "attribute-with-one-value" field π . When an attribute is multi-valued with n values (like "sides-supported" with the values 'one-sided' and 'two-sided-long-edge'), it's encoded with an "attribute-with-one-value" field followed by n-1 "additional-value" fields π. Main character energy for the first value, supporting cast for the rest π.
3.1.4. Attribute-with-one-value
Each "attribute-with-one-value" field is encoded like this π¦:
-----------------------------------------------
| value-tag | 1 byte
-----------------------------------------------
| name-length (value is u) | 2 bytes
-----------------------------------------------
| name | u bytes
-----------------------------------------------
| value-length (value is v) | 2 bytes
-----------------------------------------------
| value | v bytes
-----------------------------------------------
Figure 4: Single Value Attribute Encoding
An "attribute-with-one-value" field has five subfields, and I'm obsessed with how neatly they line up π:
- The "value-tag" field specifies the attribute syntax. For example, 0x44 is the attribute syntax 'keyword' π.
- The "name-length" field specifies the length of the "name" field in bytes. That's u in the diagram above, or 15 for the name "sides-supported" π.
- The "name" field contains the textual name of the attribute, like "sides-supported" π·οΈ.
- The "value-length" field specifies the length of the "value" field in bytes. That's v in the diagram, or 9 for the (keyword) value 'one-sided' π.
- The "value" field contains the value of the attribute, like the textual value 'one-sided' π.
3.1.5. Additional-value
Each "additional-value" field is encoded like this π:
-----------------------------------------------
| value-tag | 1 byte
-----------------------------------------------
| name-length (value is 0x0000) | 2 bytes
-----------------------------------------------
| value-length (value is w) | 2 bytes
-----------------------------------------------
| value | w bytes
-----------------------------------------------
Figure 5: Additional Attribute Value Encoding
An "additional-value" has four subfields π«§:
- The "value-tag" field specifies the attribute syntax. For example, 0x44 is the attribute syntax 'keyword' π.
- The "name-length" field is always 0, and that's how it signals that this is an "additional-value". So here's the trick: a "name-length" of 0 means "additional-value", and a "name-length" that isn't 0 means "attribute-with-one-value" π΅οΈββοΈ.
- The "value-length" field specifies the length of the "value" field in bytes. That's w in the diagram, or 19 for the (keyword) value 'two-sided-long-edge' π.
- The "value" field contains the value of the attribute, like the textual value 'two-sided-long-edge' π.
3.1.6. Collection Attribute
Collection attributes create a named group that holds related "member" attributes ποΈ. The "attribute-with-one-value" field for a collection attribute is encoded like this π§©:
-----------------------------------------------
| value-tag (value is 0x34) | 1 byte
-----------------------------------------------
| name-length (value is u) | 2 bytes
-----------------------------------------------
| name | u bytes
-----------------------------------------------
| value-length (value is 0x0000) | 2 bytes
-----------------------------------------------------------
| member-attribute | q bytes |-0 or more
-----------------------------------------------------------
| end-value-tag (value is 0x37) | 1 byte
-----------------------------------------------
| end-name-length (value is 0x0000) | 2 bytes
-----------------------------------------------
| end-value-length (value is 0x0000) | 2 bytes
-----------------------------------------------
Figure 6: Collection Attribute Encoding
A collection attribute has eight subfields, and honestly, the bookends are giving π:
- The "value-tag" field specifies the start attribute syntax: 0x34 is the attribute syntax 'begCollection' πΈ.
- The "name-length" field specifies the length of the "name" field in bytes. That's u in the diagram, or 9 for the name "media-col". Additional collection attribute values use a name length of 0x0000 π.
- The "name" field contains the textual name of the attribute, like "media-col" π.
- The "value-length" field specifies a length of 0x0000 π«₯.
- The "member-attribute" field contains member attributes, encoded as defined in Section 3.1.7 π§ββοΈ.
- The "end-value-tag" field specifies the end attribute syntax: 0x37 is the attribute syntax 'endCollection' π.
- The "end-name-length" field specifies a length of 0x0000 π.
- The "end-value-length" field specifies a length of 0x0000 β¨.
3.1.7. Member Attributes π
okay so member attributes are the little pieces that live inside a collection π§ each one gets encoded like this, no cap:
-----------------------------------------------
| value-tag (value is 0x4a) | 1 byte
-----------------------------------------------
| name-length (value is 0x0000) | 2 bytes
-----------------------------------------------
| value-length (value is w) | 2 bytes
-----------------------------------------------
| value (member-name) | w bytes
-----------------------------------------------
| member-value-tag | 1 byte
-----------------------------------------------
| name-length (value is 0x0000) | 2 bytes
-----------------------------------------------
| member-value-length (value is x) | 2 bytes
-----------------------------------------------
| member-value | x bytes
-----------------------------------------------
Figure 7: Member Attribute Encoding
A member-attribute is made of eight subfields π
here's the tea on each one:
- The
value-tagfield specifies 0x4a for the attribute syntaxmemberAttrName. - The
name-lengthfield has the value of 0 in order to signify that it is amember-attributecontained in the collection. - The
value-lengthfield specifies the length of thevaluefield in bytes, e.g.,win the above diagram or 10 for the member attribute name'media-type'. Additional member attribute values are specified using a value length of 0. - The
valuefield contains the name of the member attribute, e.g., the textual value'media-type'. - The
member-value-tagfield specifies the attribute syntax for the member attribute, e.g., 0x44 for the attribute syntaxkeyword. - The second
name-lengthfield has the value of 0 in order to signify that it is amember-attributecontained in the collection. - The
member-value-lengthfield specifies the length of the member attribute value, e.g.,xin the above diagram or 10 for the value'stationery'. - The
member-valuefield contains the value of the attribute, e.g., the textual value'stationery'.
3.1.8. Alternative Picture of the Encoding of a Request or a Response π¦
ok this one is for the parser girlies π€ if you're reading the message based on each tag value, the encoding looks like this:
-----------------------------------------------
| version-number | 2 bytes - required
-----------------------------------------------
| operation-id (request) |
| or | 2 bytes - required
| status-code (response) |
-----------------------------------------------
| request-id | 4 bytes - required
-----------------------------------------------------------
| tag (delimiter-tag or value-tag) | 1 byte |
----------------------------------------------- |-0 or more
| empty or rest of attribute | x bytes |
-----------------------------------------------------------
| end-of-attributes-tag | 1 byte - required
-----------------------------------------------
| data | y bytes - optional
-----------------------------------------------
Figure 8: Encoding Based on Value Tags
And here's what the parser should expect to see after each type of tag π:
begin-attribute-group-tag: expect zero or moreattributefieldsvalue-tag: expect the remainder of anattribute-with-one-valueor anadditional-valueend-of-attributes-tag: expect thatattributefields are complete and there is optionaldata
3.2. Syntax of Encoding π
the ABNF [RFC5234] syntax for an IPP message is shown in Figure 9, and it's giving very precise π§
ipp-message = ipp-request / ipp-response
ipp-request = version-number operation-id request-id
*attribute-group end-of-attributes-tag data
ipp-response = version-number status-code request-id
*attribute-group end-of-attributes-tag data
version-number = major-version-number minor-version-number
major-version-number = SIGNED-BYTE
minor-version-number = SIGNED-BYTE
operation-id = SIGNED-SHORT ; mapping from model
status-code = SIGNED-SHORT ; mapping from model
request-id = SIGNED-INTEGER ; whose value is > 0
attribute-group = begin-attribute-group-tag *attribute
attribute = attribute-with-one-value *additional-value
attribute-with-one-value = value-tag name-length name
value-length value
additional-value = value-tag zero-name-length
value-length value
name-length = SIGNED-SHORT ; number of octets of 'name'
name = LALPHA *( LALPHA / DIGIT / "-" / "_" / "." )
value-length = SIGNED-SHORT ; number of octets of 'value'
value = OCTET-STRING
data = OCTET-STRING
zero-name-length = %x00.00 ; name-length of 0
value-tag = %x10-ff ; see Section 3.5.2
begin-attribute-group-tag = %x00-02 / %x04-0f ; see Section 3.5.1
end-of-attributes-tag = %x03 ; tag of 3
; see Section 3.5.1
SIGNED-BYTE = BYTE
SIGNED-SHORT = 2BYTE
SIGNED-INTEGER = 4BYTE
DIGIT = %x30-39 ; "0" to "9"
LALPHA = %x61-7A ; "a" to "z"
BYTE = %x00-ff
OCTET-STRING = *BYTE
Figure 9: ABNF of IPP Message Format
Figure 10 defines some extra terms that get referenced in this doc, and it also gives us an alternate way of grouping the delimiter tags β¨
delimiter-tag = begin-attribute-group-tag / ; see Section 3.5.1
end-of-attributes-tag
begin-attribute-group-tag = %x00 / operation-attributes-tag /
job-attributes-tag / printer-attributes-tag /
unsupported-attributes-tag / future-group-tags
operation-attributes-tag = %x01 ; tag of 1
job-attributes-tag = %x02 ; tag of 2
end-of-attributes-tag = %x03 ; tag of 3
printer-attributes-tag = %x04 ; tag of 4
unsupported-attributes-tag = %x05 ; tag of 5
future-group-tags = %x06-0f ; future extensions
Figure 10: ABNF for Attribute Group Tags
3.3. Attribute-group π
each attribute-group field MUST be encoded with the begin-attribute-group-tag field, followed by zero or more attribute subfields. no skipping that step, bestie π«Ά
Table 1 maps the Model group name to the value of the begin-attribute-group-tag field π
+----------------+--------------------------------------------------+
| Model Document | "begin-attribute-group-tag" field values |
| Group | |
+----------------+--------------------------------------------------+
| Operation | "operations-attributes-tag" |
| Attributes | |
+----------------+--------------------------------------------------+
| Job Template | "job-attributes-tag" |
| Attributes | |
+----------------+--------------------------------------------------+
| Job Object | "job-attributes-tag" |
| Attributes | |
+----------------+--------------------------------------------------+
| Unsupported | "unsupported-attributes-tag" |
| Attributes | |
+----------------+--------------------------------------------------+
| Requested | (Get-Job-Attributes) "job-attributes-tag" |
| Attributes | |
+----------------+--------------------------------------------------+
| Requested | (Get-Printer-Attributes)"printer-attributes-tag" |
| Attributes | |
+----------------+--------------------------------------------------+
| Document | in a special position at the end of the message |
| Content | as described in Section 3.1.1. |
+----------------+--------------------------------------------------+
Table 1: Group Values
For every operation request and response, the Model decides which attribute groups are required and which are optional, plus the order they go in π same goes for attributes inside each group: the Model says which are required and which are optional, and in what order.
okay now the empty group situation π when the Model requires an attribute group and that group has zero attributes, a request or response SHOULD still encode the group with its begin-attribute-group-tag field followed by zero attribute fields. example: if the Client asks for a single unsupported attribute with Get-Printer-Attributes, the Printer MUST return no attribute fields, and it SHOULD return a begin-attribute-group-tag field for the Printer Attributes group. the Unsupported Attributes group is NOT like that, though π
ββοΈ according to the Model, the Unsupported Attributes group SHOULD be present only if it contains at least one attribute.
a receiver of a request MUST be able to treat the following as equivalent empty attribute groups, so don't panic π
a. A begin-attribute-group-tag field with zero following attribute fields.
b. A missing, but expected, begin-attribute-group-tag field.
and when the Model needs a sequence of an unknown number of attribute groups, all of the same type, the encoding MUST contain one begin-attribute-group-tag field for each attribute group, even if an attribute-group field has zero attribute subfields. for example, Get-Jobs might return zero attributes for some Jobs and not others π§ a begin-attribute-group-tag followed by zero attribute fields tells the recipient "yep, there's a Job in the queue, we just don't have any info on it except that it's queued" ποΈ
3.4. Required Parameters π
some operation elements are called parameters in the Model π«§ they MUST be encoded in a special position, and they MUST NOT show up as operation attributes. the subsections below cover them.
3.4.1. "version-number" πΈ
the version-number field is a major and minor version-number, and each one is a SIGNED-BYTE π
the major version-number is the first byte of the encoding, and the minor version-number is the second byte. the protocol described in [RFC8011] has a major version-number of 1 (0x01) and a minor version-number of 1 (0x01), so the ABNF for these two bytes is %x01.01, periodt β¨
Note: check out Section 9 for more on the version-number field and IPP version numbers π¦
3.4.2. "operation-id" π
the operation-id field holds an operation-id value as defined in the Model π§ it's encoded as a SIGNED-SHORT and lives in the third and fourth bytes of the encoding of an operation request π
3.4.3. "status-code" π
Okay bestie, the "status-code" field holds the status-code value from the Model β¨ It's encoded as a SIGNED-SHORT and lives in the third and fourth bytes of an operation response encoding π
If an IPP status-code is returned, then the HTTP status-code MUST be 200 (OK). π With any other HTTP status-code value, the HTTP response MUST NOT contain an IPP message body, so no IPP status-code comes back at all π
3.4.4. "request-id" π¦
The "request-id" field is the request-id value from the Model π It's encoded as a SIGNED-INTEGER and sits in the fifth through eighth bytes of the encoding πΈ
3.5. Tags π
Tags come in two flavours, and I'm obsessed with how they split the work π
- delimiter tags: delimit major sections of the protocol, namely attribute groups and data
- value tags: specify the type of each attribute value
Tags are part of the IANA IPP registry [IANA-IPP] π
3.5.1. "delimiter-tag" Values π
Table 2 lists the values for the delimiter tags defined in this document. These are registered, along with tags from other documents, in the "Attribute Group Tags" registry π§
+-----------------+------------------------------+
| Tag Value (Hex) | Meaning |
+-----------------+------------------------------+
| 0x00 | Reserved |
| 0x01 | "operation-attributes-tag" |
| 0x02 | "job-attributes-tag" |
| 0x03 | "end-of-attributes-tag" |
| 0x04 | "printer-attributes-tag" |
| 0x05 | "unsupported-attributes-tag" |
+-----------------+------------------------------+
Table 2: "delimiter-tag" Values
When a "begin-attribute-group-tag" field shows up, it means that zero or more of the following attributes, up to the next group tag, belong to the attribute group named by that tag's value β¨ For example, if "begin-attribute-group-tag" is 0x01, the attributes that follow are members of the Operations Attributes group π
The "end-of-attributes-tag" (value 0x03) MUST occur exactly once in an operation and MUST be the last "delimiter-tag" π€ If the operation has a document-data group, the Document data in that group follows the "end-of-attributes-tag" π«Ά
The order and presence of "attribute-group" fields (whose beginning is marked by the "begin-attribute-group-tag" subfield) for each operation request and each operation response MUST be that defined in the Model π
A Printer MUST treat a "delimiter-tag" (values from 0x00 through 0x0f) differently from a "value-tag" (values from 0x10 through 0xff), so the Printer knows there's a whole attribute group instead of a single value π₯
3.5.2. "value-tag" Values π
The remaining tables cover the "value-tag" field, which is the first octet of an attribute π The "value-tag" field tells you the type of the attribute's value, and that's the whole plot π
Table 3 lists the "out-of-band" values for the "value-tag" field defined in this document. These are registered, along with tags from other documents, in the "Out-of-Band Attribute Value Tags" registry π¦
+-----------------+-------------+
| Tag Value (Hex) | Meaning |
+-----------------+-------------+
| 0x10 | unsupported |
| 0x12 | unknown |
| 0x13 | no-value |
+-----------------+-------------+
Table 3: Out-of-Band Values
Table 4 lists the integer values defined here for the "value-tag" field. They're registered in the "Attribute Syntaxes" registry πΈ
+----------------+--------------------------------------------------+
| Tag Value | Meaning |
| (Hex) | |
+----------------+--------------------------------------------------+
| 0x20 | Unassigned integer data type (see IANA IPP |
| | registry) |
| 0x21 | integer |
| 0x22 | boolean |
| 0x23 | enum |
| 0x24-0x2f | Unassigned integer data types (see IANA IPP |
| | registry) |
+----------------+--------------------------------------------------+
Table 4: Integer Tags
Table 5 lists the octetString values defined here for the "value-tag" field, also registered in the "Attribute Syntaxes" registry π§
+---------------+---------------------------------------------------+
| Tag Value | Meaning |
| (Hex) | |
+---------------+---------------------------------------------------+
| 0x30 | octetString with an unspecified format |
| 0x31 | dateTime |
| 0x32 | resolution |
| 0x33 | rangeOfInteger |
| 0x34 | begCollection |
| 0x35 | textWithLanguage |
| 0x36 | nameWithLanguage |
| 0x37 | endCollection |
| 0x38-0x3f | Unassigned octetString data types (see IANA IPP |
| | registry) |
+---------------+---------------------------------------------------+
Table 5: octetString Tags
Table 6 lists the character-string values defined here for the "value-tag" field, registered in the "Attribute Syntaxes" registry too π
+---------------+---------------------------------------------------+
| Tag Value | Meaning |
| (Hex) | |
+---------------+---------------------------------------------------+
| 0x40 | Unassigned character-string data type (see IANA |
| | IPP registry) |
| 0x41 | textWithoutLanguage |
| 0x42 | nameWithoutLanguage |
| 0x43 | Unassigned character-string data type (see IANA |
| | IPP registry) |
| 0x44 | keyword |
| 0x45 | uri |
| 0x46 | uriScheme |
| 0x47 | charset |
| 0x48 | naturalLanguage |
| 0x49 | mimeMediaType |
| 0x4a | memberAttrName |
| 0x4b-0x5f | Unassigned character-string data types (see IANA |
| | IPP registry) |
+---------------+---------------------------------------------------+
Table 6: String Tags
Note: An attribute value always has a type, and that type is explicitly specified by its tag. One such tag value is "nameWithoutLanguage". An attribute's name has an implicit type, which is keyword. π₯
The values 0x60-0xff are reserved for future type definitions in Standards Track documents π
The tag 0x7f is reserved for extending types beyond the 255 values a single byte can hold π A tag value of 0x7f MUST signify that the first four bytes of the value field are interpreted as the tag value. Bonus: this future extension doesn't affect parsers that don't know about it, because the tag is treated like any other unknown tag π«Ά The value length says how long the value is, and the parser handles that value atomically. Values from 0x00000000 to 0x3fffffff are reserved for definition in future Standards Track documents. The values 0x40000000 to 0x7fffffff are reserved for vendor extensions π¦
3.6. "name-length" π
The "name-length" field is a SIGNED-SHORT that gives the number of octets in the immediately following "name" field. The value of this field doesn't count the two bytes of the "name-length" field itself π For example, if the "name" field contains 'sides', the value of this field is 5 β¨
If a "name-length" field has a value of zero, the following "name" field is empty, and the following value is treated as an additional value for the attribute encoded in the nearest preceding "attribute-with-one-value" field π Within an attribute group, if two or more attributes have the same name, the attribute group is malformed (see [RFC8011]) π The zero-length name is the only mechanism for multi-valued attributes π
3.7. (Attribute) "name" πΈ
The "name" field holds the name of an attribute, and the Model is the one that specifies those names π§
3.8. "value-length" π
The "value-length" field is a SIGNED-SHORT that specifies the number of octets in the immediately following "value" field. The value of this field doesn't count the two bytes of the "value-length" field π¦ For example, if the "value" field contains the keyword (string) value 'one-sided', the value of this field is 9 π
For any of the types represented by binary signed integers, the sender MUST encode the value in exactly four octets π₯
For any of the types represented by binary signed bytes, e.g., the boolean type, the sender MUST encode the value in exactly one octet π
For any of the types represented by character strings, the sender MUST encode the value with all the characters of the string and without any padding characters π«Ά
For "out-of-band" values for the "value-tag" field defined in this document, such as 'unsupported', the "value-length" MUST be 0 and the "value" empty π The "value" has no meaning when the "value-tag" has one of these "out-of-band" values. For future "out-of-band" "value-tag" fields, the same rule holds unless the definition explicitly states that the "value-length" MAY be non-zero and the "value" non-empty π
3.9. (Attribute) "value" π
okay so the syntax types (the ones the "value-tag" field points at) and most of the nitty-gritty about how attribute values get represented are all defined in the Model π§. Table 7 is like a cheat sheet that adds to the Model and defines every Model syntax type using the five basic types from Section 3 β¨. The five types are US-ASCII-STRING, LOCALIZED-STRING, SIGNED-INTEGER, SIGNED-SHORT, SIGNED-BYTE, and OCTET-STRING.
+----------------------+--------------------------------------------+
| Syntax of Attribute | Encoding |
| Value | |
+----------------------+--------------------------------------------+
| textWithoutLanguage, | LOCALIZED-STRING |
| nameWithoutLanguage | |
+----------------------+--------------------------------------------+
| textWithLanguage | OCTET-STRING consisting of four fields: a |
| | SIGNED-SHORT, which is the number of |
| | octets in the following field; a value of |
| | type natural-language; a SIGNED-SHORT, |
| | which is the number of octets in the |
| | following field; and a value of type |
| | textWithoutLanguage. The length of a |
| | textWithLanguage value MUST be 4 + the |
| | value of field a + the value of field c. |
+----------------------+--------------------------------------------+
| nameWithLanguage | OCTET-STRING consisting of four fields: a |
| | SIGNED-SHORT, which is the number of |
| | octets in the following field; a value of |
| | type natural-language; a SIGNED-SHORT, |
| | which is the number of octets in the |
| | following field; and a value of type |
| | nameWithoutLanguage. The length of a |
| | nameWithLanguage value MUST be 4 + the |
| | value of field a + the value of field c. |
+----------------------+--------------------------------------------+
| charset, | US-ASCII-STRING |
| naturalLanguage, | |
| mimeMediaType, | |
| keyword, uri, and | |
| uriScheme | |
+----------------------+--------------------------------------------+
| boolean | SIGNED-BYTE where 0x00 is 'false' and 0x01 |
| | is 'true' |
+----------------------+--------------------------------------------+
| integer and enum | a SIGNED-INTEGER |
+----------------------+--------------------------------------------+
| dateTime | OCTET-STRING consisting of eleven octets |
| | whose contents are defined by |
| | "DateAndTime" in RFC 2579 [RFC2579] |
+----------------------+--------------------------------------------+
| resolution | OCTET-STRING consisting of nine octets of |
| | two SIGNED-INTEGERs followed by a SIGNED- |
| | BYTE. The first SIGNED-INTEGER contains |
| | the value of cross-feed direction |
| | resolution. The second SIGNED-INTEGER |
| | contains the value of feed direction |
| | resolution. The SIGNED-BYTE contains the |
| | units value. |
+----------------------+--------------------------------------------+
| rangeOfInteger | Eight octets consisting of two SIGNED- |
| | INTEGERs. The first SIGNED-INTEGER |
| | contains the lower bound and the second |
| | SIGNED-INTEGER contains the upper bound. |
+----------------------+--------------------------------------------+
| 1setOf X | Encoding according to the rules for an |
| | attribute with more than one value. Each |
| | value X is encoded according to the rules |
| | for encoding its type. |
+----------------------+--------------------------------------------+
| octetString | OCTET-STRING |
+----------------------+--------------------------------------------+
| collection | Encoding as defined in Section 3.1.6. |
+----------------------+--------------------------------------------+
Table 7: Attribute Value Encoding
whatever syntax type an attribute value has is what decides its encoding, and it's also what sets the value of its "value-tag" π ngl, it's the whole chain reaction π¦
3.10. Data π
the "data" field MUST include any data required by the operation. no skipping it, bestie π«Ά
4. Encoding of Transport Layer π
okay the transport layer is where things get real π₯ HTTP/1.1 [RFC7230] is the REQUIRED transport layer for this protocol, full stop π HTTP/2 [RFC7540] is an OPTIONAL transport layer for this protocol, so it's a bonus, not a must β¨
the operation layer was designed assuming the transport layer is carrying these two things:
- the target URI for the operation; and
- the total length of the data in the operation layer, either as a single length or as a sequence of chunks each with a length.
Printer implementations MUST support HTTP over the IANA-assigned well-known port 631 (the IPP default port), although a Printer implementation can support HTTP over some other port as well πΈ
each HTTP operation MUST use the POST method, where the request-target is the object target of the operation. and the "Content-Type" of the message body in each request and response MUST be "application/ipp" π the message body MUST contain the operation layer and MUST have the syntax described in Section 3.2, "Syntax of Encoding". A Client implementation MUST adhere to the rules for a Client described for HTTP [RFC7230]. A Printer (server) implementation MUST adhere to the rules for an origin server described for HTTP [RFC7230]. main character energy, the rules are super clear π
An IPP server sends a response for each request that it receives. If an IPP server detects an error, it MAY send a response before it has read the entire request. If the HTTP layer of the IPP server completes processing the HTTP headers successfully, it MAY send an intermediate response, such as "100 Continue", with no IPP data before sending the IPP response. A Client MUST expect such a variety of responses from an IPP server π¦ for further info on HTTP, go check the HTTP documents [RFC7230], iykyk π§
An HTTP/1.1 server MUST support chunking for IPP requests, and an IPP Client MUST support chunking for IPP responses according to HTTP/1.1 [RFC7230] π
4.1. Printer URI, Job URI, and Job ID πͺͺ
All Printer and Job objects are identified by a Uniform Resource Identifier (URI) [RFC3986] so that they can be persistently and unambiguously referenced. Jobs can also be identified by a combination of Printer URI and Job ID β¨
some operation elements are encoded twice: once as the request-target on the HTTP request-line, and a second time as a REQUIRED operation attribute in the application/ipp entity. these attributes are the target for the operation and are called "printer-uri" and "job-uri" π
Note: The target URI is included twice in an operation referencing the same IPP object, but the two URIs can be different. For example, the HTTP request-target can be relative while the IPP request URI is absolute. π
HTTP allows Clients to generate and send a relative URI rather than an absolute URI. A relative URI identifies a resource with the scope of the HTTP server but does not include scheme, host, or port. the following statements characterize how URIs are used in the mapping of IPP onto HTTP π
- Although potentially redundant, a Client MUST supply the target of the operation both as an operation attribute and as a URI at the HTTP layer. The rationale for this decision is to maintain a consistent set of rules for mapping
"application/ipp"to possibly many communication layers, even where URIs are not used as the addressing mechanism in the transport layer. - Even though these two URIs might not be literally identical (one being relative and the other being absolute), they MUST both reference the same IPP object.
- The URI in the HTTP layer is either relative or absolute and is used by the HTTP server to route the HTTP request to the correct resource relative to that HTTP server.
- Once the HTTP server resource begins to process the HTTP request, it can get the reference to the appropriate IPP Printer object from either the HTTP URI (using to the context of the HTTP server for relative URIs) or from the URI within the operation request; the choice is up to the implementation. π§
- HTTP URIs can be relative or absolute, but the target URI in the IPP operation attribute MUST be an absolute URI. π
5. IPP URI Schemes β¨
okay so the IPP URI schemes are 'ipp' [RFC3510] and 'ipps' [RFC7472] π¦ and bestie, Clients and Printers MUST support the ipp-URI value in these IPP attributes:
- Job attributes:
job-urijob-printer-uri
- Printer attributes:
printer-uri-supported
- Operation attributes:
job-uriprinter-uri
each of these attributes identifies a Printer or Job π¨οΈ the ipp-URI and ipps-URI are meant to be the value of the attributes in this list. all of them have a syntax type of 'uri', BUT there are other 'uri' attributes that don't use the 'ipp' scheme, like "job-more-info" π so don't assume every URI is an ipp one, periodt.
If a Printer registers its URI with a directory service, the Printer MUST register an ipp-URI or ipps-URI. no exceptions, it's giving rule π
When a Client sends a request, it MUST convert a target ipp-URI to a target http-URL (or ipps-URI to a target https-URI) for the HTTP layer. the steps are:
- change the 'ipp' scheme to 'http' or 'ipps' scheme to 'https'; and
- add an explicit port 631 if the ipp-URL or ipps-URL does not contain an explicit port. note that port 631 is the IANA-assigned well-known port for the 'ipp' and 'ipps' schemes πΈ
the Client MUST use the target http-URL or https-URL in both the HTTP request-line and HTTP headers, as specified by HTTP [RFC7230]. but the Client MUST use the target ipp-URI or ipps-URI for the value of the "printer-uri" or "job-uri" operation attribute within the application/ipp body of the request. the server MUST use the ipp-URI or ipps-URI for the value of the "printer-uri", "job-uri", or "printer-uri-supported" attributes within the application/ipp body of the response. so the HTTP part gets the http vibes, and the IPP body keeps the ipp vibes π
here's an example. when an IPP Client sends a request directly (no proxy) to the ipp-URI ipp://printer.example.com/ipp/print/myqueue, it opens a TCP connection to port 631 (the IPP implicit port) on the host printer.example.com and sends this:
POST /ipp/print/myqueue HTTP/1.1
Host: printer.example.com:631
Content-type: application/ipp
Transfer-Encoding: chunked
...
"printer-uri" 'ipp://printer.example.com/ipp/print/myqueue'
(encoded in application/ipp message body)
...
Figure 11: Direct IPP Request
and now the proxy version π§ same request, but this time it goes through myproxy.example.com. the Client opens a TCP connection to the proxy port 8080 on the proxy host myproxy.example.com and sends this:
POST http://printer.example.com:631/ipp/print/myqueue HTTP/1.1
Host: printer.example.com:631
Content-type: application/ipp
Transfer-Encoding: chunked
...
"printer-uri" 'ipp://printer.example.com/ipp/print/myqueue'
(encoded in application/ipp message body)
...
Figure 12: Proxied IPP Request
the proxy then connects to the IPP origin server with headers that are the same as the "no-proxy" example above. it's the same energy, just with a middleman π
6. IANA Considerations
okay the IANA-PRINTER-MIB [RFC3805] has been updated to reference this document. the current version is available from <http://www.iana.org> π
see the IANA Considerations in the document "Internet Printing Protocol/1.1: Model and Semantics" [RFC8011] for info on IANA considerations for IPP extensions. IANA has also updated the existing 'application/ipp' media type registration (whose contents are defined in Section 3 "Encoding of the Operation Layer") with the following info:
Type name: application
Subtype name: ipp
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: IPP requests/responses MAY contain long
lines and ALWAYS contain binary data (for example, attribute value
lengths).
Security considerations: IPP requests/responses do not introduce any
security risks not already inherent in the underlying transport
protocols. Protocol mixed-version interworking rules in [RFC8011] as
well as protocol-encoding rules in this document are complete and
unambiguous. See also the security considerations in this document
and [RFC8011].
Interoperability considerations: IPP requests (generated by Clients)
and responses (generated by servers) MUST comply with all conformance
requirements imposed by the normative specifications [RFC8011] and
this document. Protocol-encoding rules specified in RFC 8010 are
comprehensive so that interoperability between conforming
implementations is guaranteed (although support for specific optional
features is not ensured). Both the "charset" and "natural-language"
of all IPP attribute values that are a LOCALIZED-STRING are explicit
within IPP requests/responses (without recourse to any external
information in HTTP, SMTP, or other message transport headers).
Published specifications: RFCs 8010 and 8011
Applications that use this media type: Internet Printing Protocol
(IPP) print clients and print servers that communicate using HTTP/
HTTPS or other transport protocols. Messages of type "application/
ipp" are self-contained and transport independent, including
"charset" and "natural-language" context for any LOCALIZED-STRING
value.
Fragment identifier considerations: N/A
Additional information:
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person & email address to contact for further information:
ISTO PWG IPP Workgroup <ipp@pwg.org>
Intended usage: COMMON
Restrictions on usage: N/A
Author: ISTO PWG IPP Workgroup <ipp@pwg.org>
Change controller: ISTO PWG IPP Workgroup <ipp@pwg.org>
Provisional registration? (standards tree only): No
7. Internationalization Considerations
see the section on "Internationalization Considerations" in the document "Internet Printing Protocol/1.1: Model and Semantics" [RFC8011] for the i18n details. this document adds no additional issues πβ¨
8. Security Considerations π
okay this one is SERIOUS bestie, so grab your snacks π the IPP Model and Semantics document [RFC8011] talks about the high-level security requirements: Client Authentication, Server Authentication, and Operation Privacy.
- Client Authentication is how the Client proves its identity to the server in a secure way.
- Server Authentication is how the server proves its identity to the Client in a secure way.
- Operation Privacy is a mechanism for protecting operations from eavesdropping. no snooping allowed π
Message Integrity is covered in the document "Internet Printing Protocol (IPP) over HTTPS Transport Binding and the 'ipps' URI Scheme" [RFC7472] π«Ά
8.1. Security Conformance Requirements
this section defines the security requirements for IPP Clients and IPP objects. the rules are lowkey strict, so read carefully π
8.1.1. Digest Authentication
IPP Clients and Printers SHOULD support Digest Authentication [RFC7616]. Use of the Message Integrity feature (qop="auth-int") is OPTIONAL.
Note: previous versions of this spec required support for the MD5 algorithms. however, [RFC7616] makes SHA2-256 mandatory to implement and deprecates MD5, only allowing its use for backwards compatibility reasons. so IPP implementations that support Digest Authentication MUST support SHA2-256 and SHOULD support MD5 for backwards compatibility. the glow-up is real πΈ
Note: the reason that IPP Clients and Printers SHOULD (rather than MUST) support Digest Authentication is that there's a certain class of Output Devices where it doesn't make sense. specifically, a low-end device with limited ROM space and low paper throughput may not need Client Authentication. this class of device typically forces firmware designers to make trade-offs between protocols and functionality to land on the lowest-cost solution possible. the designer has to weigh not just the size of the code, but also the testing, maintenance, usefulness, and time-to-market impact for each feature delivered to the customer. forcing these low-end devices to provide security just to claim IPP/1.1 conformance wouldn't make business sense π§Ύ print devices with high-volume throughput and available ROM space will typically support Client Authentication that safeguards the device from unauthorized access, because these devices are prone to a high loss of consumables and paper if unauthorized access happens πΈ
8.1.2. Transport Layer Security (TLS)
IPP Clients and Printers SHOULD support Transport Layer Security (TLS) [RFC5246] [RFC7525] for Server Authentication and Operation Privacy. IPP Printers MAY also support TLS for Client Authentication. IPP Clients and Printers MAY support Basic Authentication [RFC7617] for User Authentication if the channel is secure, e.g., IPP over HTTPS [RFC7472]. but IPP Clients and Printers SHOULD NOT support Basic Authentication over insecure channels. yikes, no cap π ββοΈ
the IPP Model and Semantics document [RFC8011] defines two Printer attributes ("uri-authentication-supported" and "uri-security-supported") that the Client can use to discover a Printer's security policy. that document also outlines IPP-specific security considerations and is the primary reference for security implications with regard to IPP itself π
Note: because previous versions of this spec did not require TLS support, this version can't require it for IPP/1.1. however, printing often involves a great deal of sensitive or private info (medical reports, performance reviews, banking information, etc.), and network monitoring is pervasive ([RFC7258]). so implementors are strongly encouraged to include TLS support. this is literally the main character moment ππ
Note: because IPP Printers typically use self-signed X.509 certificates, IPP Clients SHOULD support Trust On First Use (defined in [RFC7435]) in addition to traditional X.509 certificate validation π¦
8.2. Using IPP with TLS
IPP uses the "Upgrading to TLS Within HTTP/1.1" mechanism [RFC2817] for 'ipp' URIs. the Client requests a secure TLS connection by using the HTTP Upgrade header, and the server agrees in the HTTP response. the switch to TLS happens either because the server grants the Client's request to upgrade, or because a server asks to switch to TLS in its response. secure communication begins with a server's response to switch to TLS πβ¨
IPP uses the "HTTPS: HTTP over TLS" mechanism [RFC2818] for 'ipps' URIs. the Client and server negotiate a secure TLS connection immediately and unconditionally. no waiting, no maybe π
9. Interoperability with Other IPP Versions π
it's beyond the scope of this specification to mandate conformance with versions of IPP other than 1.1. BUT IPP was deliberately designed to make supporting other versions easy, which is so smart π§ IPP objects (Printers, Jobs, etc.) SHOULD:
- understand any valid request whose major
version-numberis greater than 0; and - respond appropriately with a response containing the same
version-numberparameter value the Client used in the request (if the Client-suppliedversion-numberis supported), or the highestversion-numbersupported by the Printer (if the Client-suppliedversion-numberis not supported).
IPP Clients SHOULD:
- understand any valid response whose major
version-numberis greater than 0.
9.1. The "version-number" Parameter β¨
okay so this one is all about the "version-number" parameter π (peep Section 3.3 if you want the backstory). here are the rules:
- Clients MUST send requests with the highest supported value, like
1.1,2.0, etc. π₯ If they get aserver-error-version-not-supportederror back, they SHOULD try supplying alternate version numbers. For example, if a Client sends an IPP/2.0 request that gets rejected withserver-error-version-not-supportedand an IPP/1.1"version-number", it SHOULD retry by sending an IPP/1.1 request π¦ - IPP objects (Printers, Jobs, etc.) MUST accept requests with a
'1.1'value π (or reject the request for reasons other than'server-error-version-not-supported') π - IPP objects SHOULD either accept requests whose major version is greater than
0or reject them with the'server-error-version-not-supported'status-code πΈ See Section 4.1.8 of [RFC8011]. - In any case, security MUST NOT be compromised when a Client supplies a lower
"version-number"parameter in a request π«Ά For example, if an IPP/2.0 conforming Printer accepts version'1.1'requests and is set up to enforce Digest Authentication, it MUST do the same for a version'1.1'request. no shortcuts, bestie π
9.2. Security and URI Schemes π
this section is about how security, the "version-number" parameter, and the URI scheme in target attributes and responses all vibe together β¨
- When a Client supplies a request, the
"printer-uri"or"job-uri"target operation attribute MUST have the same scheme as one of the values of the"printer-uri-supported"Printer attribute π - When the Printer returns the
"job-printer-uri"or"job-uri"Job Description attributes, it SHOULD return the same scheme ('ipp','ipps', etc.) that the Client supplied in the"printer-uri"or"job-uri"target operation attributes in the Get-Job-Attributes or Get-Jobs request π§ It's the one the Client used in that query, not the scheme from when the Job was created. However, when a Client asks for Job attributes with Get-Job-Attributes or Get-Jobs, what the Printer hands back depends on: (1) the security in effect when the Job was created, (2) the security in effect in the query request, and (3) the security policy in force. it's giving layers π - The Printer MUST enforce its security and privacy policies based on the owner of the IPP object and on the URI scheme and/or credentials the Client supplies in the current request π
10. Changes since RFC 2910 π
okay here's the glow-up list. these are all the changes since RFC 2910 was published:
- Added references to current IPP extension specifications π
- Added optional support for HTTP/2 π¦
- Added collection attribute syntax from RFC 3382 π
- Fixed typographical errors π
- Now reference TLS/1.2 and no longer mandate the TLS/1.0 MTI ciphersuites π₯
- Updated all references πΈ
- Updated document organization to follow current style β¨
- Updated example
ipp:URIs to follow guidelines in RFC 7472 π§ - Updated version compatibility for all versions of IPP π
- Updated HTTP Digest Authentication to optional for Clients π«Ά
- Removed references to (Experimental) IPP/1.0 and usage of
http:/https:URLs π
11. References π
11.1. Normative References
- [PWG5100.12] Sweet, M. and I. McDonald, "IPP Version 2.0, 2.1, and 2.2", October 2015,
http://ftp.pwg.org/pub/pwg/standards/std-ipp20-20151030-5100.12.pdf. - [RFC20] Cerf, V., "ASCII format for network interchange", STD 80, RFC 20, DOI 10.17487/RFC0020, October 1969,
http://www.rfc-editor.org/info/rfc20. - [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, DOI 10.17487/RFC0793, September 1981,
http://www.rfc-editor.org/info/rfc793. - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997,
http://www.rfc-editor.org/info/rfc2119. - [RFC2579] McCloghrie, K., Ed., Perkins, D., Ed., and J. Schoenwaelder, Ed., "Textual Conventions for SMIv2", STD 58, RFC 2579, DOI 10.17487/RFC2579, April 1999,
http://www.rfc-editor.org/info/rfc2579. - [RFC2817] Khare, R. and S. Lawrence, "Upgrading to TLS Within HTTP/1.1", RFC 2817, DOI 10.17487/RFC2817, May 2000,
http://www.rfc-editor.org/info/rfc2817. - [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, DOI 10.17487/RFC2818, May 2000,
http://www.rfc-editor.org/info/rfc2818. - [RFC2978] Freed, N. and J. Postel, "IANA Charset Registration Procedures", BCP 19, RFC 2978, DOI 10.17487/RFC2978, October 2000,
http://www.rfc-editor.org/info/rfc2978. - [RFC3510] Herriot, R. and I. McDonald, "Internet Printing Protocol/1.1: IPP URL Scheme", RFC 3510, DOI 10.17487/RFC3510, April 2003,
http://www.rfc-editor.org/info/rfc3510. - [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003,
http://www.rfc-editor.org/info/rfc3629. - [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005,
http://www.rfc-editor.org/info/rfc3986. - [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008,
http://www.rfc-editor.org/info/rfc5234. - [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, DOI 10.17487/RFC5246, August 2008,
http://www.rfc-editor.org/info/rfc5246. - [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing", RFC 7230, DOI 10.17487/RFC7230, June 2014,
http://www.rfc-editor.org/info/rfc7230. - [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, DOI 10.17487/RFC7231, June 2014,
http://www.rfc-editor.org/info/rfc7231. - [RFC7232] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests", RFC 7232, DOI 10.17487/RFC7232, June 2014,
http://www.rfc-editor.org/info/rfc7232. - [RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching", RFC 7234, DOI 10.17487/RFC7234, June 2014,
http://www.rfc-editor.org/info/rfc7234. - [RFC7235] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Authentication", RFC 7235, DOI 10.17487/RFC7235, June 2014,
http://www.rfc-editor.org/info/rfc7235. - [RFC7472] McDonald, I. and M. Sweet, "Internet Printing Protocol (IPP) over HTTPS Transport Binding and the 'ipps' URI Scheme", RFC 7472, DOI 10.17487/RFC7472, March 2015,
http://www.rfc-editor.org/info/rfc7472. - [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext Transfer Protocol Version 2 (HTTP/2)", RFC 7540, DOI 10.17487/RFC7540, May 2015,
http://www.rfc-editor.org/info/rfc7540. - [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015,
http://www.rfc-editor.org/info/rfc7541. - [RFC7616] Shekh-Yusef, R., Ed., Ahrens, D., and S. Bremer, "HTTP Digest Access Authentication", RFC 7616, DOI 10.17487/RFC7616, September 2015,
http://www.rfc-editor.org/info/rfc7616. - [RFC7617] Reschke, J., "The 'Basic' HTTP Authentication Scheme", RFC 7617, DOI 10.17487/RFC7617, September 2015,
http://www.rfc-editor.org/info/rfc7617. - [RFC8011] Sweet, M. and I. McDonald, "Internet Printing Protocol/1.1: Model and Semantics", RFC 8011, DOI 10.17487/RFC8011, January 2017,
http://www.rfc-editor.org/info/rfc8011.
11.2. Informative References
- [IANA-IPP] IANA, "Internet Printing Protocol (IPP) Registry",
http://www.iana.org/assignments/ipp-registrations/. - [PWG5100.3] Ocke, K. and T. Hastings, "Internet Printing Protocol (IPP): Production Printing Attributes - Set1", Candidate Standard 5100.3-2001, February 2001,
http://ftp.pwg.org/pub/pwg/candidates/cs-ippprodprint10-20010212-5100.3.pdf. - [RFC1179] McLaughlin, L., "Line printer daemon protocol", RFC 1179, DOI 10.17487/RFC1179, August 1990,
http://www.rfc-editor.org/info/rfc1179. - [RFC7258] Farrell, S. and H. Tschofenig, "Pervasive Monitoring Is an Attack", BCP 188, RFC 7258, DOI 10.17487/RFC7258, May 2014,
http://www.rfc-editor.org/info/rfc7258. - [RFC7435] Dukhovni, V., "Opportunistic Security: Some Protection Most of the Time", RFC 7435, DOI 10.17487/RFC7435, December 2014,
http://www.rfc-editor.org/info/rfc7435. - [RFC7525] Sheffer, Y., Holz, R., and P. Saint-Andre, "Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May 2015,
http://www.rfc-editor.org/info/rfc7525.
Appendix A. Protocol Examples π§
A.1. Print-Job Request β¨
okay so this is a Print-Job request with "job-name", "copies", and "sides" all specified π¨οΈ. The ipp-attribute-fidelity attribute is set to 'true', which means the whole print request fails if "copies" or "sides" isn't supported, or if their values aren't supported. it's giving strict bestie energy π
Octets Symbolic Value Protocol field
0x0101 1.1 version-number
0x0002 Print-Job operation-id
0x00000001 1 request-id
0x01 start operation- operation-
attributes attributes-tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language value-tag
type
0x001b name-length
attributes-natural-language attributes-natural- name
language
0x0005 value-length
en-us en-US value
0x45 uri type value-tag
0x000b name-length
printer-uri printer-uri name
0x002c value-length
ipp://printer.example.com/ipp/ printer pinetree value
print/pinetree
0x42 nameWithoutLanguage value-tag
type
0x0008 name-length
job-name job-name name
0x0006 value-length
foobar foobar value
0x22 boolean type value-tag
0x0016 name-length
ipp-attribute-fidelity ipp-attribute- name
fidelity
0x0001 value-length
0x01 true value
0x02 start job-attributes job-attributes-
tag
0x21 integer type value-tag
0x0006 name-length
copies copies name
0x0004 value-length
0x00000014 20 value
0x44 keyword type value-tag
0x0005 name-length
sides sides name
0x0013 value-length
two-sided-long-edge two-sided-long-edge value
0x03 end-of-attributes end-of-
attributes-tag
%!PDF... <PDF Document> data
A.2. Print-Job Response (Successful) π
here's the successful Print-Job response to that previous request π₯³. the Printer supported both "copies" and "sides" along with their supplied values, so the status-code comes back as 'successful-ok' β¨
Octets Symbolic Value Protocol field
0x0101 1.1 version-number
0x0000 successful-ok status-code
0x00000001 1 request-id
0x01 start operation- operation-
attributes attributes-tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language value-tag
type
0x001b name-length
attributes-natural-language attributes- name
natural-language
0x0005 value-length
en-us en-US value
0x41 textWithoutLanguag value-tag
e type
0x000e name-length
status-message status-message name
0x000d value-length
successful-ok successful-ok value
0x02 start job- job-attributes-
attributes tag
0x21 integer value-tag
0x0006 name-length
job-id job-id name
0x0004 value-length
147 147 value
0x45 uri type value-tag
0x0007 name-length
job-uri job-uri name
0x0030 value-length
ipp://printer.example.com/ipp/pr job 147 on value
int/pinetree/147 pinetree
0x23 enum type value-tag
0x0009 name-length
job-state job-state name
0x0004 value-length
0x0003 pending value
0x03 end-of-attributes end-of-
attributes-tag
A.3. Print-Job Response (Failure) π
and now the flop era π. this is the unsuccessful Print-Job response to that same request. it fails because the Printer doesn't support the "sides" attribute, and because the value '20' for "copies" isn't supported either. so no Job gets created, and neither a "job-id" nor a "job-uri" operation attribute comes back π. the error code is 'client-error-attributes-or-values-not-supported' (0x040b) π
Octets Symbolic Value Protocol
field
0x0101 1.1 version-
number
0x040b client-error-attributes-or- status-code
values-not-supported
0x00000001 1 request-id
0x01 start operation-attributes operation-
attributes
tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language type value-tag
0x001b name-length
attributes-natural-language attributes-natural-language name
0x0005 value-length
en-us en-US value
0x41 textWithoutLanguage type value-tag
0x000e name-length
status-message status-message name
0x002f value-length
client-error-attributes-or- client-error-attributes-or- value
values-not-supported values-not-supported
0x05 start unsupported- unsupported-
attributes attributes
tag
0x21 integer type value-tag
0x0006 name-length
copies copies name
0x0004 value-length
0x00000014 20 value
0x10 unsupported (type) value-tag
0x0005 name-length
sides sides name
0x0000 value-length
0x03 end-of-attributes end-of-
attributes-
tag
A.4. Print-Job Response (Success with Attributes Ignored) π
okay so this one is giving "it worked, but not exactly how you asked" π It's a successful Print-Job response to a request like the last one, except this time "ipp-attribute-fidelity" is 'false' π«Ά The print request still succeeds even though the Printer supports neither the "sides" attribute nor the value '20' for "copies" π So a Job gets created, and you get back both a "job-id" and a "job-uri" operation attribute π¦ The unsupported attributes show up in an Unsupported Attributes group too. The error code is 'successful-ok-ignored-or-substituted-attributes' (0x0001) β¨
Octets Symbolic Value Protocol field
0x0101 1.1 version-number
0x0001 successful-ok-ignored-or- status-code
substituted-attributes
0x00000001 1 request-id
0x01 start operation-attributes operation-
attributes-tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language type value-tag
0x001b name-length
attributes-natural- attributes-natural-language name
language
0x0005 value-length
en-us en-US value
0x41 textWithoutLanguage type value-tag
0x000e name-length
status-message status-message name
0x002f value-length
successful-ok-ignored-or- successful-ok-ignored-or- value
substituted-attributes substituted-attributes
0x05 start unsupported- unsupported-
attributes attributes tag
0x21 integer type value-tag
0x0006 name-length
copies copies name
0x0004 value-length
0x00000014 20 value
0x10 unsupported (type) value-tag
0x0005 name-length
sides sides name
0x0000 value-length
0x02 start job-attributes job-
attributes-tag
0x21 integer value-tag
0x0006 name-length
job-id job-id name
0x0004 value-length
147 147 value
0x45 uri type value-tag
0x0007 name-length
job-uri job-uri name
0x0030 value-length
ipp://printer.example.com/ job 147 on pinetree value
ipp/print/pinetree/147
0x23 enum type value-tag
0x0009 name-length
job-state job-state name
0x0004 value-length
0x0003 pending value
0x03 end-of-attributes end-of-
attributes-tag
A.5. Print-URI Request π
okay, the Print-URI request is so cute π§ This example sends the "copies" and "job-name" parameters along with the request β¨
Octets Symbolic Value Protocol field
0x0101 1.1 version-number
0x0003 Print-URI operation-id
0x00000001 1 request-id
0x01 start operation- operation-
attributes attributes-tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language value-tag
type
0x001b name-length
attributes-natural-language attributes-natural- name
language
0x0005 value-length
en-us en-US value
0x45 uri type value-tag
0x000b name-length
printer-uri printer-uri name
0x002c value-length
ipp://printer.example.com/ipp/ printer pinetree value
print/pinetree
0x45 uri type value-tag
0x000c name-length
document-uri document-uri name
0x0019 value-length
ftp://foo.example.com/foo ftp://foo.example.co value
m/foo
0x42 nameWithoutLanguage value-tag
type
0x0008 name-length
job-name job-name name
0x0006 value-length
foobar foobar value
0x02 start job-attributes job-attributes-
tag
0x21 integer type value-tag
0x0006 name-length
copies copies name
0x0004 value-length
0x00000001 1 value
0x03 end-of-attributes end-of-
attributes-tag
A.6. Create-Job Request π¦
this one is the minimalist era π«Ά It's a Create-Job request with no parameters and no attributes, just the bare minimum π
Octets Symbolic Value Protocol field
0x0101 1.1 version-number
0x0005 Create-Job operation-id
0x00000001 1 request-id
0x01 start operation- operation-
attributes attributes-tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language value-tag
type
0x001b name-length
attributes-natural-language attributes-natural- name
language
0x0005 value-length
en-us en-US value
0x45 uri type value-tag
0x000b name-length
printer-uri printer-uri name
0x002c value-length
ipp://printer.example.com/ipp/ printer pinetree value
print/pinetree
0x03 end-of-attributes end-of-
attributes-tag
A.7. Create-Job Request with Collection Attributes β¨
okay so this one is where things get spicy πΆοΈ we're sending a Create-Job request that carries the media-col collection attribute [PWG5100.3], and its value is media-size={x-dimension=21000 y-dimension=29700} media-type='stationery' π the collection is basically a little box of named members sitting inside one attribute, and the bytes show exactly how that box gets packed up π
Octets Symbolic Value Protocol field
0x0101 1.1 version-number
0x0005 Create-Job operation-id
0x00000001 1 request-id
0x01 start operation- operation-
attributes attributes-tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language value-tag
type
0x001b name-length
attributes-natural-language attributes-natural- name
language
0x0005 value-length
en-us en-US value
0x45 uri type value-tag
0x000b name-length
printer-uri printer-uri name
0x002c value-length
ipp://printer.example.com/ipp/ printer pinetree value
print/pinetree
0x34 begCollection value-tag
0x0009 9 name-length
media-col media-col name
0x0000 0 value-length
0x4a memberAttrName value-tag
0x0000 0 name-length
0x000a 10 value-length
media-size media-size value (member-
name)
0x34 begCollection member-value-tag
0x0000 0 name-length
0x0000 0 member-value-
length
0x4a memberAttrName value-tag
0x0000 0 name-length
0x000b 11 value-length
x-dimension x-dimension value (member-
name)
0x21 integer member-value-tag
0x0000 0 name-length
0x0004 4 member-value-
length
0x00005208 21000 member-value
0x4a memberAttrName value-tag
0x0000 0 name-length
0x000b 11 value-length
y-dimension y-dimension value (member-
name)
0x21 integer member-value-tag
0x0000 0 name-length
0x0004 4 member-value-
length
0x00007404 29700 member-value
0x37 endCollection end-value-tag
0x0000 0 end-name-length
0x0000 0 end-value-length
0x4a memberAttrName value-tag
0x0000 0 name-length
0x000a 10 value-length
media-type media-type value (member-
name)
0x44 keyword member-value-tag
0x0000 0 name-length
0x000a 10 member-value-
length
stationery stationery member-value
0x37 endCollection end-value-tag
0x0000 0 end-name-length
0x0000 0 end-value-length
0x03 end-of-attributes end-of-
attributes-tag
A.8. Get-Jobs Request π§
this one is a chill vibe πΈ it's a Get-Jobs request that has parameters but no attributes, so there's no collection drama here, just a clean little ask π
the limit is 50, and we're requesting job-id, job-name, and document-format back
Octets Symbolic Value Protocol field
0x0101 1.1 version-number
0x000a Get-Jobs operation-id
0x0000007b 123 request-id
0x01 start operation- operation-
attributes attributes-tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language value-tag
type
0x001b name-length
attributes-natural-language attributes-natural- name
language
0x0005 value-length
en-us en-US value
0x45 uri type value-tag
0x000b name-length
printer-uri printer-uri name
0x002c value-length
ipp://printer.example.com/ipp/ printer pinetree value
print/pinetree
0x21 integer type value-tag
0x0005 name-length
limit limit name
0x0004 value-length
0x00000032 50 value
0x44 keyword type value-tag
0x0014 name-length
requested-attributes requested-attributes name
0x0006 value-length
job-id job-id value
0x44 keyword type value-tag
0x0000 additional value name-length
0x0008 value-length
job-name job-name value
0x44 keyword type value-tag
0x0000 additional value name-length
0x000f value-length
document-format document-format value
0x03 end-of-attributes end-of-
attributes-tag
A.9. Get-Jobs Response π
ok the response to that last request is where we get to see the Printer's answer π this one comes back with three Jobs, but the Printer keeps the second Job's details to itself (because of security reasons π) so you'll notice that object is just an empty start with no details inside
Octets Symbolic Value Protocol field
0x0101 1.1 version-number
0x0000 successful-ok status-code
0x0000007b 123 request-id (echoed
back)
0x01 start operation- operation-attributes-
attributes tag
0x47 charset type value-tag
0x0012 name-length
attributes-charset attributes-charset name
0x0005 value-length
utf-8 UTF-8 value
0x48 natural-language type value-tag
0x001b name-length
attributes-natural- attributes-natural- name
language language
0x0005 value-length
en-us en-US value
0x41 textWithoutLanguage value-tag
type
0x000e name-length
status-message status-message name
0x000d value-length
successful-ok successful-ok value
0x02 start job-attributes job-attributes-tag
(1st object)
0x21 integer type value-tag
0x0006 name-length
job-id job-id name
0x0004 value-length
147 147 value
0x36 nameWithLanguage value-tag
0x0008 name-length
job-name job-name name
0x000c value-length
0x0005 sub-value-length
fr-ca fr-CA value
0x0003 sub-value-length
fou fou name
0x02 start job-attributes job-attributes-tag
(2nd object)
0x02 start job-attributes job-attributes-tag
(3rd object)
0x21 integer type value-tag
0x0006 name-length
job-id job-id name
0x0004 value-length
148 149 value
0x36 nameWithLanguage value-tag
0x0008 name-length
job-name job-name name
0x0012 value-length
0x0005 sub-value-length
de-CH de-CH value
0x0009 sub-value-length
isch guet isch guet name
0x03 end-of-attributes end-of-attributes-tag
Acknowledgements π«Ά
okay bestie, the authors wanted to give a massive shoutout to the people who helped build the original IPP/1.1 specs π that's Sylvan Butler, Roger deBry, Tom Hastings, Robert Herriot (the original editor of RFC 2910 π), Paul Moore, Kirk Ocke, Randy Turner, John Wenn, and Peter Zehler. the whole squad deserves flowers πβ¨
Authors' Addresses π¦
these are the two authors who wrote this one, so here's where you can find them π
Michael Sweet Apple Inc. 1 Infinite Loop MS 111-HOMC Cupertino, CA 95014 United States of America
Email: msweet@apple.com
Ira McDonald High North, Inc. PO Box 221 Grand Marais, MI 49839 United States of America
Phone: +1 906-494-2434 Email: blueroofmusic@gmail.com
that's the whole doc, babe πβ¨ you made it through all 11 parts π
π¦ where this page comes from
- ietf: rfc8010 2017-01
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms