Changeset 4ec7caa for server


Ignore:
Timestamp:
Nov 6, 2010, 4:27:10 PM (13 years ago)
Author:
Jessica B. Hamrick <jhamrick@…>
Branches:
no-cups
Children:
d56a0bc
Parents:
84e8137
git-author:
Jessica B. Hamrick <jhamrick@…> (11/06/10 16:27:10)
git-committer:
Jessica B. Hamrick <jhamrick@…> (11/06/10 16:27:10)
Message:

Add some comments to ipp.py; use struct module in ipprequest.py

Location:
server/lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • server/lib/ipp.py

    rc216863 r4ec7caa  
    1313import ipplib
    1414
    15 from ipplib import IPPRequest
     15from ipprequest import IPPRequest
    1616from tempfile import mkstemp
    1717from shutil import move
     
    3939    # nothing to do in the init
    4040    def __init__(self):
     41        """
     42        This function doesn't actually do anything.
     43        """
    4144        pass
    4245
    4346    # this function processes an IPP request and sends a response
    4447    def process(self, request_in, response_out):
     48        """
     49        Processes an IPP request and sends a response.
    4550
     51        Arguments:
    4652
     53            request_in -- a file handle to read in the request
     54
     55            request_out -- a file handle to print the response
     56        """
     57       
     58        # parse the request from request_in
     59        request = IPPRequest(request=request_in)
     60
     61        # create the response, copying the version, operation-id, and
     62        # request-id from the request
    4763        response = IPPRequest(version=request.version,
    4864                              operation_id=request.operation_id,
    4965                              request_id=request.request_id)
    50         #file('/mit/gutenbach/tmp/requests/'+str(request.operation_id)).write()
     66       
    5167        handler = getattr(self, "_operation_%d" % request.operation_id, None)
    5268
  • server/lib/ipprequest.py

    r84e8137 r4ec7caa  
    11#!/usr/bin/python
    22
    3 import sys
    4 
    5 # various tags
    6 zero_name_length                  = 0x00
    7 operation_attributes_tag          = 0x01
    8 job_attributes_tag                = 0x02
    9 end_of_attributes_tag             = 0x03
    10 printer_attributes_tag            = 0x04
    11 unsupported_attributes_tag        = 0x05
    12 
    13 # "out of band" value tags
    14 oob_unsupported_value_tag         = 0x10
    15 oob_default_value_tag             = 0x11
    16 oob_unknown_value_tag             = 0x12
    17 oob_no_value_tag                  = 0x13
    18 
    19 # integer value tags
    20 generic_integer_value_tag         = 0x20
    21 integer_value_tag                 = 0x21
    22 boolean_value_tag                 = 0x22
    23 enum_value_tag                    = 0x23
    24                  
    25 # octetString value tags
    26 unspecified_octetString_value_tag = 0x30
    27 dateTime_value_tag                = 0x31
    28 resolution_value_tag              = 0x32
    29 rangeOfInteger_value_tag          = 0x33
    30 collection_value_tag              = 0x34
    31 textWithLanguage_value_tag        = 0x35
    32 nameWithLanguage_value_tag        = 0x36
    33 
    34 # character-string value tags
    35 generic_char_string_value_tag     = 0x40
    36 textWithoutLanguage_value_tag     = 0x41
    37 nameWithoutLanguage_value_tag     = 0x42
    38 keyword_value_tag                 = 0x44
    39 uri_value_tag                     = 0x45
    40 uriScheme_value_tag               = 0x46
    41 charset_value_tag                 = 0x47
    42 naturalLanguage_value_tag         = 0x48
    43 mimeMediaType_value_tag           = 0x49                                   
     3import sys, struct
     4
     5class IPPTags():
     6    """
     7    Contains constants for the various IPP tags, as defined by RFC
     8    2565.
     9    """
     10   
     11    # various tags
     12    ZERO_NAME_LENGTH                  = 0X00
     13    OPERATION_ATTRIBUTES_TAG          = 0X01
     14    JOB_ATTRIBUTES_TAG                = 0X02
     15    END_OF_ATTRIBUTES_TAG             = 0X03
     16    PRINTER_ATTRIBUTES_TAG            = 0X04
     17    UNSUPPORTED_ATTRIBUTES_TAG        = 0X05
     18   
     19    # "out of band" value tags
     20    UNSUPPORTED                       = 0X10
     21    DEFAULT                           = 0X11
     22    UNKNOWN                           = 0X12
     23    NO_VALUE                          = 0X13
     24   
     25    # integer value tags
     26    GENERIC_INTEGER                   = 0X20
     27    INTEGER                           = 0X21
     28    BOOLEAN                           = 0X22
     29    ENUM                              = 0X23
     30
     31    # octetstring value tags
     32    UNSPECIFIED_OCTETSTRING           = 0X30
     33    DATETIME                          = 0X31
     34    RESOLUTION                        = 0X32
     35    RANGEOFINTEGER                    = 0X33
     36    COLLECTION                        = 0X34
     37    TEXTWITHLANGUAGE                  = 0X35
     38    NAMEWITHLANGUAGE                  = 0X36
     39
     40    # character-string value tags
     41    GENERIC_CHAR_STRING               = 0X40
     42    TEXTWITHOUTLANGUAGE               = 0X41
     43    NAMEWITHOUTLANGUAGE               = 0X42
     44    KEYWORD                           = 0X44
     45    URI                               = 0X45
     46    URISCHEME                         = 0X46
     47    CHARSET                           = 0X47
     48    NATURALLANGUAGE                   = 0X48
     49    MIMEMEDIATYPE                     = 0X49                                   
    4450
    4551class IPPValue():
     
    6975        assert value is not None
    7076
    71         self.value_tag = value_tag
    72         self.name = name
    73         self.value = value
     77        self.value_tag = hex(value_tag)
     78        self.name = str(name)
     79        self.value = str(value)
    7480
    7581class IPPAttribute():
    7682     """
     83     In addition to what the RFC reports, an attribute has an
     84     'attribute tag', which specifies what type of attribute it is.
     85     It is 1 bytes long, and comes before the list of values.
     86
    7787     From RFC 2565:
    7888
     
    123133         for value in values: assert isinstance(value, IPPValue)
    124134       
    125          self.attribute_tag = attribute_tag
     135         self.attribute_tag = hex(attribute_tag)
    126136         self.values = values
    127137
     
    162172        Keyword arguments for passing in the segments of the request:
    163173       
    164             version -- two bytes, identifying the version number of
    165                        the request
     174            version -- a tuple of two signed chars, identifying the
     175                       major version and minor version numbers of the
     176                       request
    166177                           
    167             operation_id -- two bytes, identifying the id of the
     178            operation_id -- a signed short, identifying the id of the
    168179                            requested operation
    169180
    170             request_id -- four bytes, identifying the id of the
     181            request_id -- a signed int, identifying the id of the
    171182                          request itself.
    172183
    173             attributes -- a list of IPPAttributes.  May be empty.
     184            attributes -- (optional) a list of IPPAttributes
    174185
    175186            data -- (optional) variable length, containing the actual
     
    185196            # make sure the version number isn't empty
    186197            assert version is not None
    187             # make sure the version number is two bytes long
    188             assert sys.getsizeof(version) == 2
     198            # make sure verison is a tuple of length 2
     199            assert isinstance(version, tuple)
     200            assert len(version) == 2
     201            # make sure the major version number is one byte long
     202            assert sys.getsizeof(version[0]) == 1
     203            # make sure the minor version number is one byte long
     204            assert sys.getsizeof(version[1]) == 1
    189205            # make sure the operation id isn't empty
    190206            assert operation_id is not None
     
    199215        # that file handle
    200216        if request is not None:
    201             # read the version-number (two bytes)
    202             self.version        = request.read(2)
     217            # read the version-number (two signed chars)
     218            self.version        = struct.unpack('bb', request.read(2))
    203219
    204220            # read the operation-id (or status-code, but that's only
    205             # for a response) (two bytes)
    206             self.operation_id   = request.read(2)
    207 
    208             # read the request-id (4 bytes)
    209             self.request_id     = request.read(4)
     221            # for a response) (signed short)
     222            self.operation_id   = struct.unpack('h', request.read(2))
     223
     224            # read the request-id (signed int)
     225            self.request_id     = struct.unpack('i', request.read(4))
    210226
    211227            # now we have to read in the attributes.  Each attribute
     
    214230
    215231            # read in the next byte
    216             next_byte = request.read(1)
     232            next_byte = struct.unpack('b', request.read(1))
    217233
    218234            # as long as the next byte isn't signaling the end of the
    219235            # attributes, keep looping and parsing attributes
    220             while next_byte != end_of_attributes_tag:
     236            while next_byte != IPPTags.END_OF_ATTRIBUTES_TAG:
    221237               
    222238                # if the next byte is an attribute tag, then we're at
     
    225241
    226242                    attribute_tag = next_byte
    227                     # read in the value tag (one byte)
    228                     value_tag     = request.read(1)
    229                     # read in the length of the name (two bytes)
    230                     name_length   = request.read(2)
    231                     # read the name (name_length bytes)
    232                     name          = request.read(name_length)
    233                     # read in the length of the value (two bytes)
    234                     value_length  = request.read(2)
    235                     # read in the value (value_length bytes)
    236                     value         = request.read(value_length)
     243                    # read in the value tag (signed char)
     244                    value_tag     = struct.unpack('b', request.read(1))
     245                    # read in the length of the name (signed short)
     246                    name_length   = struct.unpack('h', request.read(2))
     247                    # read the name (a string of name_length bytes)
     248                    name          = struct.unpack('s', request.read(name_length))
     249                    # read in the length of the value (signed short)
     250                    value_length  = struct.unpack('h', request.read(2))
     251                    # read in the value (string of value_length bytes)
     252                    value         = struct.unpack('b'*value_length, request.read(value_length))
    237253
    238254                    # create a new IPPAttribute from the data we just
     
    249265                    # read in the length of the name (two bytes) --
    250266                    # this should be 0x0
    251                     name_length   = request.read(2)
     267                    name_length   = struct.unpack('h', request.read(2))
    252268                    assert name_length == zero_name_length
    253269                    # name should be empty
    254                     name          = None
     270                    name          = ''
    255271                    # read in the length of the value (two bytes)
    256                     value_length  = request.read(2)
     272                    value_length  = struct.unpack('h', request.read(2))
    257273                    # read in the value (value_length bytes)
    258                     value         = request.read(value_length)
     274                    value         = struct.unpack('b'*value_length, request.read(value_length))
    259275
    260276                    # add another value to the last attribute
     
    262278
    263279                # read another byte
    264                 next_byte = request.read(1)
     280                next_byte = struct.unpack('b', request.read(1))
    265281
    266282            # once we hit the end-of-attributes tag, the only thing
    267283            # left is the data, so go ahead and read all of it
    268             self.data = request.read()
     284            buff = request.read()
     285            self.data = struct.unpack('b'*len(buff), sys.getsizeof(buff))
    269286
    270287        # otherwise, just set the class variables to the keyword
    271288        # arguments passed in
    272289        else:
    273             self.version = version
    274             self.operation_id = operation_id
    275             self.request_id = request_id
     290            self.version = int(version)
     291            self.operation_id = int(operation_id)
     292            self.request_id = int(request_id)
    276293            self.attributes = attributes
    277294            self.data = data
Note: See TracChangeset for help on using the changeset viewer.