# -*- Mode: Text; tab-width: 4 -*-

[note, a better solution is now available, see the various modules in
 the 'thread' directory (SMR 990105)]

		  A Workable Approach to Mixing Threads and Medusa.
---------------------------------------------------------------------------

When Medusa receives a request that needs to be handled by a separate
thread, have the thread remove the socket from Medusa's control, by
calling the 'del_channel()' method, and put the socket into
blocking-mode:

    request.channel.del_channel()
    request.channel.socket.setblocking (0)

Now your thread is responsible for managing the rest of the HTTP
'session'.  In particular, you need to send the HTTP response, followed
by any headers, followed by the response body.

Since the most common need for mixing threads and Medusa is to support
CGI, there's one final hurdle that should be pointed out: CGI scripts
sometimes make use of a 'Status:' hack (oops, I meant to say 'header')
in order to tell the server to return a reply other than '200 OK'.  To
support this it is necessary to scan the output _before_ it is sent.
Here is a sample 'write' method for a file-like object that performs
this scan:

HEADER_LINE = regex.compile ('\([A-Za-z0-9-]+\): \(.*\)')

	def write (self, data):
		if self.got_header:
			self._write (data)
		else:
			# CGI scripts may optionally provide extra headers.
			# 
			# If they do not, then the output is assumed to be
			# text/html, with an HTTP reply code of '200 OK'.
			# 
			# If they do, we need to scan those headers for one in
			# particular: the 'Status:' header, which will tell us
			# to use a different HTTP reply code [like '302 Moved']
			#
			self.buffer = self.buffer + data
			lines = string.split (self.buffer, '\n')
			# look for something un-header-like
			for i in range(len(lines)):
				if i == (len(lines)-1):
					if lines[i] == '':
						break
				elif HEADER_LINE.match (lines[i]) == -1:
					# this is not a header line.
					self.got_header = 1
					self.buffer = self.build_header (lines[:i])
					# rejoin the rest of the data
					self._write (string.join (lines[i:], '\n'))
					break
