source: server/lib/gutenbach/server/server.py @ 7c143c9

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

Add support for chunking, i.e. receiving file data

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