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

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

Clean up core ipp code a bit

  • Property mode set to 100644
File size: 3.4 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 traceback
11import tempfile
12import threading
13import time
14
15# initialize logger
16logger = logging.getLogger(__name__)
17
18class GutenbachServer(threading.Thread):
19
20    def run(self):
21        self.printer = GutenbachPrinter(name="test")
22        self.request_stop = False
23
24        while not self.request_stop:
25            job = self.printer.next_job
26            if job is not None:
27                try:
28                    self.printer.start_job(job)
29                except InvalidPrinterStateException:
30                    pass
31                except:
32                    logger.fatal(traceback.format_exc())
33                    sys.exit(1)
34            time.sleep(0.1)
35
36class IPPServer(BaseHTTPServer.BaseHTTPRequestHandler):
37   
38    def send_continue(self):
39        self.send_response(100, "continue")
40        self.send_header("Content-Type", "application/ipp")
41        self.end_headers()
42
43    def send_ok(self, response):
44        logger.debug(repr(response))
45        binary, data_file = response.packed_value
46           
47        self.send_response(200, "ok")
48        self.send_header("Content-Type", "application/ipp")
49        self.send_header("Connection", "close")
50        self.end_headers()
51       
52        self.wfile.write(binary)
53        if data_file is not None:
54            data = data_file.read(1024)
55            while data != '':
56                self.wfile.write(data)
57                data = data_file.read(1024)
58
59    def log_request(self, code=0, size=0):
60        logger.info("response (%s)" % code)
61
62    def log_message(self, fmt, *args):
63        logger.info(fmt % args)
64
65    def read_chunks(self):
66        size = sys.maxint
67        totalsize = 0
68
69        with tempfile.SpooledTemporaryFile() as tmp:
70            while size > 0:
71                a, b = self.rfile.read(2)
72                size = a + b
73                while not (a == "\r" and b == "\n"):
74                    a = b
75                    b = self.rfile.read(1)
76                    size += b
77                size = int(size[:-2], base=16)
78                totalsize += size
79                chunk = self.rfile.read(size)
80                clrf = self.rfile.read(2)
81                if clrf != "\r\n":
82                    raise ipp.errors.ServerErrorInternalError(
83                        "clrf != \\r\\n (is '%s')" % clrf)
84                tmp.write(chunk)
85
86            tmp.seek(0)
87            request = ipp.Request(request=tmp, length=totalsize)
88
89        return request
90               
91    def do_POST(self):
92        length = int(self.headers.getheader('content-length', 0))
93        expect = self.headers.getheader('expect', None)
94        encoding = self.headers.getheader('transfer-encoding', None)
95
96        logger.info("request %s (%d bytes)" % (self.command, length))
97        logger.debug(str(self.headers))
98
99        # Parse the request
100        if length == 0 and encoding == "chunked":
101            request = self.read_chunks()
102        else:
103            request = ipp.Request(request=self.rfile, length=length)
104
105        # Get the handler and pass it the request and response
106        # objects.  It will fill in values for the response object or
107        # throw a fatal error.
108        logger.debug("request: %s" % repr(request))
109        response = GutenbachRequestHandler(self.server.gutenbach_server).handle(request)
110        self.send_ok(response)
Note: See TracBrowser for help on using the repository browser.