#############################
#2006-1-8
#############################
from django.core.handlers.base import BaseHandler
from django.core import signals
from django.dispatch import dispatcher
from django.utils import datastructures
from django import http
from pprint import pformat
import os,sys
STATUS_CODE_TEXT = {
	100: 'CONTINUE',
	101: 'SWITCHING PROTOCOLS',
	200: 'OK',
	201: 'CREATED',
	202: 'ACCEPTED',
	203: 'NON-AUTHORITATIVE INFORMATION',
	204: 'NO CONTENT',
	205: 'RESET CONTENT',
	206: 'PARTIAL CONTENT',
	300: 'MULTIPLE CHOICES',
	301: 'MOVED PERMANENTLY',
	302: 'FOUND',
	303: 'SEE OTHER',
	304: 'NOT MODIFIED',
	305: 'USE PROXY',
	306: 'RESERVED',
	307: 'TEMPORARY REDIRECT',
	400: 'BAD REQUEST',
	401: 'UNAUTHORIZED',
	402: 'PAYMENT REQUIRED',
	403: 'FORBIDDEN',
	404: 'NOT FOUND',
	405: 'METHOD NOT ALLOWED',
	406: 'NOT ACCEPTABLE',
	407: 'PROXY AUTHENTICATION REQUIRED',
	408: 'REQUEST TIMEOUT',
	409: 'CONFLICT',
	410: 'GONE',
	411: 'LENGTH REQUIRED',
	412: 'PRECONDITION FAILED',
	413: 'REQUEST ENTITY TOO LARGE',
	414: 'REQUEST-URI TOO LONG',
	415: 'UNSUPPORTED MEDIA TYPE',
	416: 'REQUESTED RANGE NOT SATISFIABLE',
	417: 'EXPECTATION FAILED',
	500: 'INTERNAL SERVER ERROR',
	501: 'NOT IMPLEMENTED',
	502: 'BAD GATEWAY',
	503: 'SERVICE UNAVAILABLE',
	504: 'GATEWAY TIMEOUT',
	505: 'HTTP VERSION NOT SUPPORTED',
}
META_NAMES=(
	'ALL_HTTP',
	'ALL_RAW',
	'APPL_MD_PATH',
	'APPL_PHYSICAL_PATH',
	'AUTH_PASSWORD',
	'AUTH_TYPE',
	'AUTH_USER',
	'CERT_COOKIE',
	'CERT_FLAGS',
	'CERT_ISSUER',
	'CERT_KEYSIZE',
	'CERT_SECRETKEYSIZE',
	'CERT_SERIALNUMBER',
	'CERT_SERVER_ISSUER',
	'CERT_SERVER_SUBJECT',
	'CERT_SUBJECT',
	'CONTENT_LENGTH',
	'CONTENT_TYPE',
	'GATEWAY_INTERFACE',
	'HTTPS',
	'HTTPS_KEYSIZE',
	'HTTPS_SECRETKEYSIZE',
	'HTTPS_SERVER_ISSUER',
	'HTTPS_SERVER_SUBJECT',
	'INSTANCE_ID',
	'INSTANCE_META_PATH',
	'LOCAL_ADDR',
	'LOGON_USER',
	'PATH_INFO',
	'PATH_TRANSLATED',
	'QUERY_STRING',
	'REMOTE_ADDR',
	'REMOTE_HOST',
	'REMOTE_USER',
	'REQUEST_METHOD',
	'SERVER_NAME',
	'SERVER_NAME',
	'SERVER_PORT',
	'SERVER_PORT_SECURE',
	'SERVER_PROTOCOL',
	'SERVER_SOFTWARE',
	'URL',
	'HTTP_CONNECTION',
	'HTTP_ACCEPT',
	'HTTP_ACCEPT_ENCODING',
	'HTTP_ACCEPT_LANGUAGE',
	'HTTP_COOKIE',
	'HTTP_HOST',
	'HTTP_USER_AGENT',
	'HTTP_UA_CPU',
)
bsetenv=True
class D4IRequest(http.HttpRequest):
	def __init__(self,ecb):
		self._ecb=ecb
		self.method=ecb.Method
		self.path=ecb.PathInfo

	def __repr__(self):
		return '<D4IRequest\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % (self.path, pformat(self.GET), pformat(self.POST), pformat(self.COOKIES),pformat(self.META))

	def get_full_path(self):
		return '%s%s' % (self.path,self._ecb.QueryString and ('?' + self._ecb.QueryString) or '')

	def is_secure(self):
		return self._ecb.GetServerVariable('HTTPS')=='on'

	def _load_post_and_files(self):
		if self.method=='POST':
			if self._ecb.ContentType.startswith('multipart'):
				all_raw =dict([x.split(':',1) for x in self._ecb.GetServerVariable('ALL_RAW').split('\r\n') if (x.find(':')>-1 and x[0] !=':')])
				self._post, self._files = http.parse_file_upload(all_raw, self.raw_post_data)
			else:
				self._post, self._files = http.QueryDict(self.raw_post_data), datastructures.MultiValueDict()
		else:
			self._post, self._files = http.QueryDict(''), datastructures.MultiValueDict()

	def _get_request(self):
		if not hasattr(self,'_request'):
			self._request = datastructures.MergeDict(self.POST, self.GET)
		return self._request

	def _get_get(self):
		if not hasattr(self,'_get'):
			self._get=http.QueryDict(self._ecb.QueryString)
		return self._get

	def _set_get(self,get):
		self._get=get

	def _get_post(self):
		if not hasattr(self,'_post'):
			self._load_post_and_files()
		return self._post

	def _set_post(self,post):
		self._post=post

	def _get_cookies(self):
		if not hasattr(self,'_cookies'):
			try:
				http_cookie=self._ecb.GetServerVariable('HTTP_COOKIE')
			except:
				http_cookie=''
			self._cookies=http.parse_cookie(http_cookie)
		return self._cookies

	def _set_cookies(self,cookies):
		self._cookies=cookies

	def _get_files(self):
		if not hasattr(self,'_files'):
			self._load_post_and_files()
		return self._files

	def _get_meta(self):
		if not hasattr(self,'_meta'):
			#self._meta=dict([[key.upper(),self._ecb.GetServerVariable(key)] for key in META_NAMES])
			self._meta={}
			for key in META_NAMES:
				try:
					self._meta[key]=self._ecb.GetServerVariable(key)
				except:
					self._meta[key]=''
		return self._meta

	def _get_raw_post_data(self):
		if not hasattr(self,'_raw_post_data'):
			self._raw_post_data=self._ecb.AvailableData
		return self._raw_post_data

	GET=property(_get_get,_set_get)
	POST=property(_get_post,_set_post)
	COOKIES=property(_get_cookies,_set_cookies)
	FILES=property(_get_files)
	META=property(_get_meta)
	REQUEST=property(_get_request)
	raw_post_data=property(_get_raw_post_data)

class D4IHandler(BaseHandler):
	def __call__(self,ecb):
		global bsetenv
		if bsetenv :
			appl_physical_path=os.path.dirname(ecb.GetServerVariable('APPL_PHYSICAL_PATH'))
			strPath=os.path.dirname(appl_physical_path)
			strModule=os.path.basename(appl_physical_path)
			sys.path=[strPath] + sys.path
			os.environ['DJANGO_SETTINGS_MODULE']= '%s.%s' % (strModule,'settings')
			bsetenv=False
		from django.conf import settings
		if self._request_middleware is None:
			self.load_middleware()
		dispatcher.send(signal=signals.request_started)
		try:
			request=D4IRequest(ecb)
			response=self.get_response(request)
			for middleware_method in self._response_middleware:
				response=middleware_method(request,response)
		finally:
			dispatcher.send(signal=signals.request_finished)
		populate_iis_request(response, ecb)
def populate_iis_request(http_response,ecb):
	vbnewline='\r\n'
	headers=vbnewline.join([vbnewline.join([': '.join(x) for x in http_response.headers.items()]) ,vbnewline.join(['Set-Cookie: %s' % c.output(header='') for c in http_response.cookies.values()]) ,''])
	try:
		status_text=STATUS_CODE_TEXT[http_response.status_code]
	except KeyError:
		status_text='UNKNOWN STATUS CODE'
	status = '%s %s' % (http_response.status_code,status_text)
	ecb.SendResponseHeaders(status,headers,False)
	for chunk in http_response:
		print >> ecb,chunk
	ecb.DoneWithSession()

def handler(ecb):
	D4IHandler()(ecb)

