def test_servlet(): req_mock = RequestMock() resp_mock = ResponseMock() bridge = RequestBridge(req_mock, AdaptedInputStream(), AdaptedErrLog()) bridge_map = dict_builder(bridge.asMap)() req_wrapper = bridge.asWrapper() servlet = WSGIServlet() servlet.init( ServletConfigMock({"wsgi.handler": "servlet_support.simple_app"})) servlet.service(req_wrapper, resp_mock) assert next(resp_mock.outputStream) == b"Hello world!\n" assert resp_mock.getHeader('Content-Type') == 'text/plain' assert resp_mock.getStatus() == 200
def test_servlet(): req_mock = RequestMock() resp_mock = ResponseMock() bridge = RequestBridge(req_mock, AdaptedInputStream(), AdaptedErrLog()) bridge_map = dict_builder(bridge.asMap)() req_wrapper = bridge.asWrapper() servlet = WSGIServlet() servlet.init(ServletConfigMock( { "wsgi.handler": "servlet_support.simple_app" })) servlet.service(req_wrapper, resp_mock) assert next(resp_mock.outputStream) == b"Hello world!\n" assert resp_mock.getHeader('Content-Type') == 'text/plain' assert resp_mock.getStatus() == 200
def filter_wsgi_call(self, req, resp, chain): bridge = RequestBridge(req, self.err_log, AdaptedInputStream(req.getInputStream())) environ = dict_builder(bridge.asMap)() # Can only set up the actual wrapped response once the filter coroutine is set up wrapped_req = bridge.asWrapper() call = WSGICall(environ, req, resp) progress = [ ] # FIXME currently we are using three states - [], [False], [True] - which is pretty awful # FIXME instead something like [PROBING], [INCREMENTAL], [BATCH] probably would work better call_filter = None def setup_coupler(): (yield) # @validator def null_app(environ, start_response): # print "null_app environ=%s start_response=%s" % (environ, start_response) #for name in call.wrapped_resp.getHeaders(): # ... response_headers = [] for name in call.wrapped_resp.getHeaderNames(): for value in call.wrapped_resp.getHeaders(name): response_headers.append( (str(name), value.encode("latin1"))) # Is it possible to get the underlying status from the response? status = "%s FIXME" % (call.wrapped_resp.getStatus(), ) # Reset the underlying response so we can re-write headers/status; # otherwise we will get duplicated headers call.wrapped_resp.reset() start_response(status, response_headers) output_stream = call.wrapped_resp.getOutputStream() for i, chunk in enumerate(output_stream): # print >> sys.stderr, "Got this chunk %d %r (%r)" % (i, chunk, progress) # check if stalled (is there no progress in the below while loop?) # if stalled, we have to wait until the filter chain is complete before # we can return another chunk yield chunk if not progress: progress[:] = [False] # need three states! FIXME def f(s): pass # print "null_app stalled value %r" % (s,) output_stream.callback = f call_filter() # print >> sys.stderr, "Filter chain completed" for chunk in output_stream.getChunks(): yield chunk return if i > 100: raise AssertionError( "Stopping, obviously we are broken!!!!!") wsgi_filter = self.application(null_app) result = wsgi_filter(call.environ, call.start_response) # print >> sys.stderr, "got result from wsgi_filter %s" % (result,) it = iter(result) while True: try: # print >> sys.stderr, "waiting on yield" if not progress or progress[0] != False: data = (yield) else: data = None # print >> sys.stderr, "completed yield, waiting on next of %s" % (it,) filtered = next(it) progress[:] = [True] # print >> sys.stderr, "%r -> %r" % (data, filtered) # print >> sys.stderr, "call %r" % (call,) call.write(filtered) except StopIteration: break if not call.headers_sent: call.write("") # send headers now if body was empty coupler = setup_coupler() # fill in the wrapping servlet response call.wrapped_resp = CaptureHttpServletResponse(resp, coupler.send) call_filter = lambda: chain.doFilter( wrapped_req, call.wrapped_resp ) # FIXME maybe name "complete_filter_chain"? coupler.send(None) # advance the coroutine to before filtering coupler.send( None) # advance one more time to after sending the response if not progress or progress[0] != False: # print >> sys.stderr, "Calling filter" call_filter() else: pass # print >> sys.stderr, "Not calling filter, should be done in null_app" # print >> sys.stderr, "Closing coupler" coupler.close() # put in a try-finally context
def get_bridge(self, req): return RequestBridge(req, self.err_log, AdaptedInputStream(req.getInputStream()))
def filter_wsgi_call(self, req, resp, chain): bridge = RequestBridge(req, self.err_log, AdaptedInputStream(req.getInputStream())) environ = dict_builder(bridge.asMap)() # Can only set up the actual wrapped response once the filter coroutine is set up wrapped_req = bridge.asWrapper() call = WSGICall(environ, req, resp) progress = [] # FIXME currently we are using three states - [], [False], [True] - which is pretty awful # FIXME instead something like [PROBING], [INCREMENTAL], [BATCH] probably would work better call_filter = None def setup_coupler(): (yield) # @validator def null_app(environ, start_response): # print "null_app environ=%s start_response=%s" % (environ, start_response) #for name in call.wrapped_resp.getHeaders(): # ... response_headers = [] for name in call.wrapped_resp.getHeaderNames(): for value in call.wrapped_resp.getHeaders(name): response_headers.append((str(name), value.encode("latin1"))) # Is it possible to get the underlying status from the response? status = "%s FIXME" % (call.wrapped_resp.getStatus(),) # Reset the underlying response so we can re-write headers/status; # otherwise we will get duplicated headers call.wrapped_resp.reset() start_response(status, response_headers) output_stream = call.wrapped_resp.getOutputStream() for i, chunk in enumerate(output_stream): # print >> sys.stderr, "Got this chunk %d %r (%r)" % (i, chunk, progress) # check if stalled (is there no progress in the below while loop?) # if stalled, we have to wait until the filter chain is complete before # we can return another chunk yield chunk if not progress: progress[:] = [False] # need three states! FIXME def f(s): pass # print "null_app stalled value %r" % (s,) output_stream.callback = f call_filter() # print >> sys.stderr, "Filter chain completed" for chunk in output_stream.getChunks(): yield chunk return if i > 100: raise AssertionError("Stopping, obviously we are broken!!!!!") wsgi_filter = self.application(null_app) result = wsgi_filter(call.environ, call.start_response) # print >> sys.stderr, "got result from wsgi_filter %s" % (result,) it = iter(result) while True: try: # print >> sys.stderr, "waiting on yield" if not progress or progress[0] != False: data = (yield) else: data = None # print >> sys.stderr, "completed yield, waiting on next of %s" % (it,) filtered = next(it) progress[:] = [True] # print >> sys.stderr, "%r -> %r" % (data, filtered) # print >> sys.stderr, "call %r" % (call,) call.write(filtered) except StopIteration: break if not call.headers_sent: call.write("") # send headers now if body was empty coupler = setup_coupler() # fill in the wrapping servlet response call.wrapped_resp = CaptureHttpServletResponse(resp, coupler.send) call_filter = lambda: chain.doFilter(wrapped_req, call.wrapped_resp) # FIXME maybe name "complete_filter_chain"? coupler.send(None) # advance the coroutine to before filtering coupler.send(None) # advance one more time to after sending the response if not progress or progress[0] != False: # print >> sys.stderr, "Calling filter" call_filter() else: pass # print >> sys.stderr, "Not calling filter, should be done in null_app" # print >> sys.stderr, "Closing coupler" coupler.close() # put in a try-finally context