source: server/lib/gutenbach/server/server.py @ eee389a

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

Better threading model

  • Property mode set to 100644
File size: 2.9 KB
Line 
1import gutenbach.ipp as ipp
2
3from . import InvalidPrinterStateException, InvalidJobException
4from . import GutenbachPrinter
5from . import GutenbachRequestHandler
6
7import BaseHTTPServer
8import logging
9import sys
10import tempfile
11
12# initialize logger
13logger = logging.getLogger(__name__)
14
15class IPPServer(BaseHTTPServer.BaseHTTPRequestHandler):
16   
17    def send_continue(self):
18        self.send_response(100, "continue")
19        self.send_header("Content-Type", "application/ipp")
20        self.end_headers()
21
22    def send_ok(self, response):
23        logger.debug(repr(response))
24        binary, data_file = response.packed_value
25           
26        self.send_response(200, "ok")
27        self.send_header("Content-Type", "application/ipp")
28        self.send_header("Connection", "close")
29        self.end_headers()
30       
31        self.wfile.write(binary)
32        if data_file is not None:
33            data = data_file.read(1024)
34            while data != '':
35                self.wfile.write(data)
36                data = data_file.read(1024)
37
38    def log_request(self, code=0, size=0):
39        logger.info("response (%s)" % code)
40
41    def log_message(self, fmt, *args):
42        logger.info(fmt % args)
43
44    def read_chunks(self):
45        size = sys.maxint
46        totalsize = 0
47
48        with tempfile.SpooledTemporaryFile() as tmp:
49            while size > 0:
50                a, b = self.rfile.read(2)
51                size = a + b
52                while not (a == "\r" and b == "\n"):
53                    a = b
54                    b = self.rfile.read(1)
55                    size += b
56                size = int(size[:-2], base=16)
57                totalsize += size
58                chunk = self.rfile.read(size)
59                clrf = self.rfile.read(2)
60                if clrf != "\r\n":
61                    raise ipp.errors.ServerErrorInternalError(
62                        "clrf != \\r\\n (is '%s')" % clrf)
63                tmp.write(chunk)
64
65            tmp.seek(0)
66            request = ipp.Request(request=tmp, length=totalsize)
67
68        return request
69               
70    def do_POST(self):
71        length = int(self.headers.getheader('content-length', 0))
72        expect = self.headers.getheader('expect', None)
73        encoding = self.headers.getheader('transfer-encoding', None)
74
75        logger.info("request %s (%d bytes)" % (self.command, length))
76        logger.debug(str(self.headers))
77
78        # Parse the request
79        if length == 0 and encoding == "chunked":
80            request = self.read_chunks()
81        else:
82            request = ipp.Request(request=self.rfile, length=length)
83
84        # Get the handler and pass it the request and response
85        # objects.  It will fill in values for the response object or
86        # throw a fatal error.
87        logger.debug("request: %s" % repr(request))
88        response = GutenbachRequestHandler(self.server.gutenbach_printer).handle(request)
89        self.send_ok(response)
Note: See TracBrowser for help on using the repository browser.