source: server/lib/ipprequest.py @ c216863

no-cups
Last change on this file since c216863 was c216863, checked in by Jessica B. Hamrick <jhamrick@…>, 14 years ago

Add an IPPRequest class/module to deal with storing and parsing IPP
requests.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1#!/usr/bin/python
2
3class IPPValue():
4    def __init__(self, value_tag, name, value):
5        assert value_tag is not None and \
6               value is not None
7
8        self.value_tag = value_tag
9        self.name = name
10        self.value = value
11
12class IPPAttribute():
13    # From RFC 2565:
14
15    # Each attribute consists of:
16    # -----------------------------------------------
17    # |                   value-tag                 |   1 byte
18    # -----------------------------------------------
19    # |               name-length  (value is u)     |   2 bytes
20    # -----------------------------------------------
21    # |                     name                    |   u bytes
22    # -----------------------------------------------
23    # |              value-length  (value is v)     |   2 bytes
24    # -----------------------------------------------
25    # |                     value                   |   v bytes
26    # -----------------------------------------------
27
28    # An additional value consists of:
29    # -----------------------------------------------------------
30    # |                   value-tag                 |   1 byte  |
31    # -----------------------------------------------           |
32    # |            name-length  (value is 0x0000)   |   2 bytes |
33    # -----------------------------------------------           |-0 or more
34    # |              value-length (value is w)      |   2 bytes |
35    # -----------------------------------------------           |
36    # |                     value                   |   w bytes |
37    # -----------------------------------------------------------
38
39    def __init__(self, attribute_tag, values):
40        assert attribute_tag is not None
41        for value in values: assert isinstance(value, IPPValue)
42       
43        self.attribute_tag = attribute_tag
44        self.values = values
45
46class IPPRequest():
47    # From RFC 2565:
48   
49    # The encoding for an operation request or response consists of:
50    # -----------------------------------------------
51    # |                  version-number             |   2 bytes  - required
52    # -----------------------------------------------
53    # |               operation-id (request)        |
54    # |                      or                     |   2 bytes  - required
55    # |               status-code (response)        |
56    # -----------------------------------------------
57    # |                   request-id                |   4 bytes  - required
58    # -----------------------------------------------------------
59    # |               xxx-attributes-tag            |   1 byte  |
60    # -----------------------------------------------           |-0 or more
61    # |             xxx-attribute-sequence          |   n bytes |
62    # -----------------------------------------------------------
63    # |              end-of-attributes-tag          |   1 byte   - required
64    # -----------------------------------------------
65    # |                     data                    |   q bytes  - optional
66    # -----------------------------------------------
67
68    # either give the version, operation_id, request_id,
69    # attribute_sequence, and data, or a file handler (request) which
70    # can be read from to get the request
71    def __init__(self, version=None, operation_id=None, request_id=None, attributes=[], data=None, request=None):
72        assert (version is not None and \
73                operation_id is not None and \
74                request_id is not None) or request is not None
75
76        if request is not None:
77            self.version        = request.read(2)
78            self.operation_id   = request.read(2)
79            self.request_id     = request.read(4)
80            self.attributes     = []
81           
82            next_byte = request.read(1)
83            while next_byte != 0x03:
84                if next_byte <= 0x0F:
85                    attribute_tag = next_byte
86                    value_tag     = request.read(1)
87                    name_length   = request.read(2)
88                    name          = request.read(name_length)
89                    value_length  = request.read(2)
90                    value         = request.read(value_length)
91                   
92                    self.attributes.append(IPPAttribute(
93                        attribute_tag,
94                        [IPPValue(value_tag, name, value)]))
95                else:
96                    value_tag     = next_byte
97                    name_length   = request.read(2)
98                    name          = None
99                    value_length  = request.read(2)
100                    value         = request.read(value_length)
101                   
102                    self.attributes[-1].values.append(IPPValue(value_tag, name, value))
103                   
104                next_byte = request.read(1)
105
106            self.data = request.read()
107
108        else:
109            self.version = version
110            self.operation_id = operation_id
111            self.request_id = request_id
112            self.attributes = attributes
113            self.data = data
Note: See TracBrowser for help on using the repository browser.