javascript - Issue With Python Sockets: How To Get Reliably POSTed data whatever the browser? -
i wrote small python+ajax programs (listed @ end) socket module study comet concept of asynchronous communications.
the idea allow browsers send messages real time each others via python program.
the trick let "get messages/..." connection opened waiting message answer back.
my problem on reliability of have via socket.recv...
when post firefox, working well.
when post chrome or ie, "data" in python empty.
does know problem between browsers?
are browsers injecting eof or else characters killing receiving of "recv"?
is there solution known problem?
the server.py in python:
import socket connected={} def inrequest(text): content='' if text[0:3]=='get': method='get' else: method='post' k=len(text)-1 while k>0 , text[k]!='\n' , text[k]!='\r': k=k-1 content=text[k+1:] text=text[text.index(' ')+1:] url=text[:text.index(' ')] return {"method":method,"url":url,"content":content} mysocket = socket.socket ( socket.af_inet, socket.sock_stream ) mysocket.bind ( ( '', 80 ) ) mysocket.listen ( 10 ) while true: channel, details = mysocket.accept() data=channel.recv(4096) req=inrequest(data) url=req["url"] if url=="/client.html" or url=="/clientie.html": f=open('c:\\async\\'+url) channel.send ('http/1.1 200 ok\n\n'+f.read()) f.close() channel.close() elif '/messages' in url: if req["method"]=='post': target=url[10:] if target in connected: connected[target].send("http/1.1 200 ok\n\n"+req["content"]) print req["content"]+" sent "+target connected[target].close() channel.close() elif req["method"]=='get': user=url[10:] connected[user]=channel print user+' connected'
the client.html in html+javascript:
<html> <head> <script> var user='' function post(el) { if (window.xmlhttprequest) { var text=el.value; var req=new xmlhttprequest(); el.value=''; var target=document.getelementbyid('to').value } else if (window.activexobject) { var text=el.content; var req=new activexobject("microsoft.xmlhttp"); el.content=''; } else return; req.open('post','messages/'+target,true) req.send(text); } function get(u) { if (user=='') user=u.value var req=new xmlhttprequest() req.open('get','messages/'+user,true) req.onload=function() { var message=document.createelement('p'); message.innerhtml=req.responsetext; document.getelementbyid('messages').appendchild(message); get(user); } req.send(null) } </script> </head> <body> <span>from</span> <input id="user"/> <input type="button" value="sign in" onclick="get(document.getelementbyid('user'))"/> <span>to</span> <input id="to"/> <span>:</span> <input id="message"/> <input type="button" value="post" onclick="post(document.getelementbyid('message'))"/> <div id="messages"> </div> </body> </html>
the problem have that
- your tcp socket handling isn't reading as should
- your http handling not complete
i recommend following lectures:
- rfc2616
- the sockets networking api stevens
see example below working http server can process posts
index = ''' <html> <head> </head> <body> <form action="/" method="post"> <textarea name="foo"></textarea> <button type="submit">post</button> </form> <h3>data posted</h3> <div> %s </div> </body> </html> ''' bufsize = 4048 import socket import re urlparse import urlparse class headers(object): def __init__(self, headers): self.__dict__.update(headers) def __getitem__(self, name): return getattr(self, name) def get(self, name, default=none): return getattr(self, name, default) class request(object): header_re = re.compile(r'([a-za-z-]+):? ([^\r]+)', re.m) def __init__(self, sock): header_off = -1 data = '' while header_off == -1: data += sock.recv(bufsize) header_off = data.find('\r\n\r\n') header_string = data[:header_off] self.content = data[header_off+4:] lines = self.header_re.findall(header_string) self.method, path = lines.pop(0) path, protocol = path.split(' ') self.headers = headers( (name.lower().replace('-', '_'), value) name, value in lines ) if self.method in ['post', 'put']: content_length = int(self.headers.get('content_length', 0)) while len(self.content) < content_length: self.content += sock.recv(bufsize) self.query = urlparse(path)[4] acceptor = socket.socket(socket.af_inet, socket.sock_stream) acceptor.setsockopt( socket.sol_socket, socket.so_reuseaddr, 1, ) acceptor.bind(('', 2501 )) acceptor.listen(10) if __name__ == '__main__': while true: sock, info = acceptor.accept() request = request(sock) sock.send('http/1.1 200 ok\n\n' + (index % request.content) ) sock.close()
Comments
Post a Comment