# -*- coding: utf-8 -*- import socket import asyncore import time import os import os.path import re import urllib import string import mimetools globalTCPIP=None from win32com.client import Dispatch GlobalPVersion='1.05' global pdx command = path = version = rqbody = None rqbuf="" oparam="" # Default error message DEFAULT_ERROR_MESSAGE = """\ Error response

Error response

Error code %(code)d.

Message: %(message)s.

Error code explanation: %(code)s = %(explain)s. """ error_message_format = DEFAULT_ERROR_MESSAGE weekdayname = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'] monthname = [None, 'Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Jui', 'Jul', 'Aou', 'Sep', 'Oct', 'Nov', 'Dec'] protocol_version = "HTTP/1.0" MessageClass = mimetools.Message responses = { 200: ('OK', 'Request fulfilled, document follows'), 201: ('Created', 'Document created, URL follows'), 202: ('Accepted', 'Request accepted, processing continues off-line'), 203: ('Partial information', 'Request fulfilled from cache'), 204: ('No response', 'Request fulfilled, nothing follows'), 301: ('Moved', 'Object moved permanently -- see URI list'), 302: ('Found', 'Object moved temporarily -- see URI list'), 303: ('Method', 'Object moved -- see Method and URL list'), 304: ('Not modified', 'Document has not changed singe given time'), 400: ('Bad request', 'Erreur de syntaxe ou requete non supportee'), 401: ('Unauthorized', 'Permission(s) insuffisante(s)'), 402: ('Payment required', 'No payment -- see charging schemes'), 403: ('Forbidden', 'Request forbidden -- authorization will not help'), 404: ('Not found', 'Fichier ou page inexistant'), 500: ('Internal error', 'Server got itself in trouble'), 501: ('Non implemente', 'Non supporte par le serveur'), 502: ('Service temporarily overloaded', 'The server cannot process the request due to a high load'), 503: ('Gateway timeout', 'The gateway server did not receive a timely response'), } def remplacerdansfichiertxt(file, listeremplacement, filout): # remplacement dans un fichier texte data = open(file, "rb").read() newdata=data for chaine,remplacement in listeremplacement: print chaine,' --> ',remplacement newdata = newdata.replace(chaine, remplacement) if newdata != data: f = open(filout, "wb") f.write(newdata) f.close() def paradoxopen(): global pdx pdx = Dispatch('Paradox.Application') bof = pdx.ScriptOpen("c:\\nscrite.ssl") pdx.visible = 1 def paradoxcall(): global pdx #print "Paradox ==> Post.ssl" bof = pdx.ScriptOpen("Post.ssl") #print"bof",bof def paradoxquit(): global pdx pdx.Quit() def prepare_send_post(): global command, path, version,rqbody htmlretour="" f = None httpmethod=command action=path[1:] bouton='' champs=[] for item in rqbody: print"\t=>",item if item[:3]=="BT_": bouton=item[3:-1] bouton=bouton[:string.find(bouton,"=")] else: chnom=item[:string.find(item,"=")] chval=item[string.find(item,"=")+1:] if len(chnom)>1: champs.append([chnom,chval]) print httpmethod,action,bouton #print champs if action<>"": paradoxcall() lstremplac=[['%CREATEUR%','Michel Claveau Informatique']] ff=open('Ppost.txt','r') st=ff.read() ff.close() if st[-1]=='\x00': st=st[:-1] lstemp=string.split(st,'\n') #print lstemp if lstemp[0]=="ERREUR": lstremplac=[["%ERREUR%",lstemp[1]]] # print lstremplac remplacerdansfichiertxt('ERREUR.htm', lstremplac, 'ERREUR_send.htm') path = os.getcwd()+'\\ERREUR_send.htm' else: for i in lstemp[1:]: if i[:4]=='PAGE': pagesuivante=list(string.split(i,"\t"))[1] print "Page suivante : ",pagesuivante, " ==> ", else: lstremplac.append(list(string.split(i,"\t"))) # print"bouton",bouton # print lstremplac if bouton<>"": # print"remplacement en cours" if len(lstremplac)>0: #print '-'*55 #print lstremplac #print '-'*55 remplacerdansfichiertxt(pagesuivante, lstremplac, 'X-'+pagesuivante) path = os.getcwd()+'\\X-'+pagesuivante else : path = os.getcwd()+pagesuivante # print"Envoi ",path # print"-- " return path,htmlretour def send_response(code, message=None): """Send the response header and log the response code. Also send two standard headers with the server software version and the current date. """ log_request(code) if message is None: if responses.has_key(code): message = responses[code][0] else: message = '' if request_version != 'HTTP/0.9': txt=("%s %s %s\r\n" % (protocol_version, str(code), message)) txt+=send_header('Server', version_string()) txt+=send_header('Date', self.date_time_string()) time.sleep(0.1) def send_header(keyword, value): """Prepare a MIME header.""" if request_version != 'HTTP/0.9': return("%s: %s\r\n" % (keyword, value)) def end_headers(): """Send the blank line ending the MIME headers.""" if request_version != 'HTTP/0.9': return("\r\n") def log_request(code='-', size='-'): """Log an accepted request. This is called by send_reponse(). """ txt=log_message('"%s" %s %s',requestline, str(code), str(size)) def log_error(*args): """Log an error. This is called when a request cannot be fulfilled. By default it passes the message on to log_message(). Arguments are the same as for log_message(). XXX This should go to the separate error log. """ return(apply(log_message, args)) def log_message(format, *args): return("%s [%s] %s\n" % (address_string(), log_date_time_string(), format%args)) def version_string(): return server_version + ' ' + sys_version def date_time_string(): now = time.time() year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now) s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( weekdayname[wd], day, monthname[month], year, hh, mm, ss) return s def log_date_time_string(): now = time.time() year, month, day, hh, mm, ss, x, y, z = time.localtime(now) s = "%02d/%3s/%04d %02d:%02d:%02d" % ( day, monthname[month], year, hh, mm, ss) return s def maintenant(): now = time.time() year, month, day, hh, mm, ss, x, y, z = time.localtime(now) s = "%02d.%3s %02d:%02d" % ( day, monthname[month], hh, mm) return s def send_error(code, message): try: short, long = responses[code] except KeyError: short, long = '???', '???' if not message: message = long txt="HTTP/1.0 "+str(code)+" "+short+" "+message+""" Content-Type: text/html """ print "Erreur",code,message return(txt) def parse_request(txtparam): global command, path, version,rqbody,oparam request_version = version = "HTTP/0.9" # Defaut heure=maintenant() stmp=txtparam.replace('\r\n\r\n','\r\n') stmp=stmp.replace('\r\n','\n') stmp=stmp.replace('\r\r','\r') stmp=stmp.replace('\n\n','\n') stmp=stmp.replace('\r\r','\r') stmp=stmp.replace('\n\n','\n') stmp=stmp.replace('\r\r','\r') stmp=stmp.replace('\n\n','\n') stmp=stmp.replace('\r\r','\n') stmp=stmp.replace('\n\n','\n') print "*"*77 print stmp print "*"*77 f=open("RQ0.txt","aw") f.write('\r\n'+'-'*110+heure+" "+str(globalTCPIP)+'\n'+stmp+'-'*70+'\n') f.close() blocparam=txtparam.split('\r\n\r\n') lparam=blocparam[0].split('\n') requestline = lparam[0] htmlretour="" # print "requestline : ",requestline # i=0 # for it in blocparam: # i+=1 # print "\n",i,"\n",it if requestline[-2:] == '\r\n': requestline = requestline[:-2] elif requestline[-1:] == '\n': requestline = requestline[:-1] requestline = requestline words = requestline.split() if len(words) == 3: [command, path, version] = words if version[:5] != 'HTTP/': htmlretour,send_error(400, "Bad request version (%s)" % `version`) return 0,htmlretour elif len(words) == 2: [command, path] = words if command != 'GET': htmlretour=send_error(400, "Bad HTTP/0.9 request type (%s)" % `command`) return 0,htmlretour else: htmlretour=send_error(400, "Bad request syntax (%s)" % `requestline`) return 0,htmlretour command, path, request_version = command, path, version # headers = blocparam[1] print "RQ :",command,path,version if command=='POST' : ff=open('paramPOST','wb') ff.write(command+'\n') ff.write(path+'\n') ff.write('OPARAM='+oparam+'\n') lparam=blocparam[1].split('\n') # print"lparam0:",lparam[0] rqbody=[] for i in lparam[0].split('&'): i=re.sub('\+', ' ', i) ii=urllib.unquote(i) # print "***",ii rqbody.append(ii) ff.write(ii+'\n') ff.close() return 1,'' class http_server(asyncore.dispatcher): def __init__(self, ip, port): self.ip= ip self.port = port self.count = 0 self.sessions={"NEXT":0L} asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.bind((ip, port)) self.listen(2) def writable(self): return 0 def handle_read(self): pass def readable(self): return self.accepting def handle_connect(self): #print"Connect" pass def handle_accept(self): global globalTCPIP try: conn, addr = self.accept() except socket.error: # rare Linux error print "Socket error on server accept()" return except TypeError: # rare FreeBSD3 error print "EWOULDBLOCK exception on server accept()" return self.count+=1 print "\nTCP/IP: "+addr[0]+" /:"+str(addr[1])+" Nb.conn."+str(self.count)," ",maintenant() globalTCPIP=addr[0] print '-'*55 handler = http_handler(conn, addr, self, self.count, self.sessions) def decrement(self): self.count -= 1 #print"Decrementation ; nb connexions :",self.count class http_handler(asyncore.dispatcher): def __init__(self, conn, addr, server, count, sessions): asyncore.dispatcher.__init__(self, sock=conn) self.addr = addr self.buffer = "" self.time = time.time() self.count = count self.sessions = sessions self.server = server def handle_read(self): global command, path, version, rqbuf, oparam if len(rqbuf)>0: rq = rqbuf+self.recv(2048) rqbuf='' else: rq = self.recv(2048) tai=0 oparam="" i=string.find(rq,"Content-Length:") if i>0: j=string.find(rq,"\n",i+1) tai=int(rq[i+16:j]) print "tai",tai #print "rq.tai",len(rq) k=string.find(rq,'Connection')+23 flagpost=string.find(rq,"POST") flaglong=string.find(rq,"Content-Length") #print "flagpost, flaglong",flagpost, flaglong if flagpost>-1 and flaglong<0: rqbuf=rq print"Attente suite" return if tai>len(rq[k:]) : rqbuf=rq print"Attente suite" return #print "Longueur requete :",len(rq) #print '- rq','-'*30,'\r\n',rq #print '-'*34,'\r\n' html="" flag=0 try: flag,html=parse_request(rq) except: pass if flag!=1 : return if command=="POST": #print "*"*55 #print html #print "*"*55 path,html=prepare_send_post() oparam='' pos=path.find('?') if pos>-1: oparam=path[pos+1:] path=path[:pos] f=path if command=="GET": if len(path)<=1: path='\index.htm' oparam='' pos=path.find('?') if pos>-1: oparam=path[pos+1:] path=path[:pos] f=os.getcwd()+'\\'+path[1:] if not os.path.isfile(f): f=os.getcwd()+'\\index.htm' print"Page:",f," ==> ", if os.path.exists(f): pagesuivante=f else: pagesuivante="erreur.htm" # suivant pagesuivante="" # le cas html=html+send_error(404, "Fichier inexistant") if pagesuivante!="": if oparam!="": remplacerdansfichiertxt(pagesuivante, [["%IDENTIFIANT%",oparam],["%INVARIANT%",oparam]], os.getcwd()+'\\ptemp.htm') f=open(os.getcwd()+'\\ptemp.htm',"rb") else: f=open(pagesuivante,"rb") pagehtml=f.read() f.close() html = """HTTP/1.0 200 OK Canned Response Follows Content-Type: text/html """ html=html+pagehtml self.buffer=html def writable(self): #print time.time()-self.time if time.time()-self.time > 0: return len(self.buffer) >0 else: return 0 def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:] if len(self.buffer) == 0: self.close() self.server.decrement() if __name__ == '__main__': paradoxopen() server = http_server('', 80) print'P.W.Serveur sur port 80\n' asyncore.loop(timeout=3.0) paradoxquit()