选择怪异 [英] Select weirdness

查看:57
本文介绍了选择怪异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码。它是一个小小的微弱的HTTP服务器。 (我不是真的想要在这里重新发明轮子。我正在做的是写一个

调度代理服务器,但这是最短的方式来说明我正在讨论的

问题:

来自SocketServer导入的
*来自套接字导入的
*

来自精选导入选择


class myHandler(StreamRequestHandler):

def handle(self):

打印''>>>>>>>>>>>''

而1:

sl = select([ self.rfile],[],[])[0]

如果sl:

l = self.rfile.readline()

if len(l)< 3:break

print l,

pass

pass

print>> self.wfile,''HTTP / 1.0 200 OK''

print>> self.wfile,''Content-type:text / plain''

print> > self.wfile

print>> self.wfile,''foo''

self.rfile.close()

self .wfile.close()

print''<<<<<<<<<<<<<''

pass

pass


def main():

server = TCPServer(('''',8080),myHandler)

服务器。 serve_forever()

传递


if __name__ ==''__ main__'':main()

如果我telnet到这服务器并手动输入HTTP请求

工作正常。但是,当我尝试使用浏览器访问它时(我已经尝试了

Firefox和Safari - 两者都做同样的事情)它会立即挂起

读取第一个请求中的行(即在读取第一个

标题之前)。


当我点击停止时浏览器中的按钮打破了logjam和服务器读取标题的
(但当然它会因为写入

对现在关闭的套接字的响应而死)。


我能辨别的唯一区别是浏览器发送\\\\ n为

行结束,而telnet只发送\ n 。但是我不明白为什么要这样做会产生任何不同。所以我很难过。任何线索都会很多赞赏。


谢谢,

rg

解决方案

Ron Garret写道:


print>> self.wfile,''HTTP / 1.0 200 OK''

print>> self.wfile,''Content-type:text / plain''

print>> self.wfile

print>> self.wfile,''foo''

[...]

如果我telnet到这个服务器并手动输入HTTP请求

它工作正常。但是当我尝试使用浏览器访问它时(我已经尝试使用Firefox和Safari进行了
- 两者都做了同样的事情)它在读完第一个后立即挂起

请求中的行(即在读取第一个标题之前

)。



问题可能是打印结束了带有\\\\ n的行。不是所有的

平台?尝试明确地做。


我能辨别的唯一区别是浏览器发送\\\\ n

为end-of -line而telnet只发送\ n。



然后,我认为,你的telnet客户端坏了。我似乎有多个

应用程序依赖于telnet或类似协议

required\\\ n作为终点。 E. g。我需要破解

twisted.protocols.basic.LineReceiverFactory,因为它显示了你为浏览器描述的确切行为。它出现了因为

busybox''telnet只发送\ n作为EOL。


但是我不明白为什么要这样做有所作为。



简单。如果您只接受\\\\ n作为EOL,你会永远等待,除非

你真的收到它。


问候,

Bj?rn


-

BOFH借口#81:


请原谅,我必须通过我的电路连接一条交流线路前往

让这个数据库工作。


Ron Garret写道:


这是我的代码。它是一个小小的微弱的HTTP服务器。 (我不是真的想要在这里重新发明轮子。我正在做的是写一个

调度代理服务器,但这是最短的方式来说明我正在讨论的

问题:

来自SocketServer导入的
*来自套接字导入的
*

来自精选导入选择


class myHandler(StreamRequestHandler):

def handle(self):

打印''>>>>>>>>>>>''

而1:

sl = select([ self.rfile],[],[])[0]

如果sl:

l = self.rfile.readline()

if len(l)< 3:break

print l,

pass

pass

print>> self.wfile,''HTTP / 1.0 200 OK''

print>> self.wfile,''Content-type:text / plain''

print> > self.wfile

print>> self.wfile,''foo ''

self.rfile.close()

self.wfile.close()

print''<<<< ;<<<<<<<<''

通过

通过



你不应该在句柄方法中使用你自己的select()。

socketserver会为你处理。


您需要做的是从插座读取输入,直到您输入结束标记为
。在处理HTTP GET请求时,该标记是一个空行,只包含\\\\ n和/或



任何理由都不要想要使用Python附带的BasicHTTPServer吗?


无论如何,请尝试以下代码:

来自SocketServer导入的
*
$来自套接字导入的b $ b *
来自select import的
选择


class myHandler(StreamRequestHandler):

def handle(self) :

打印''>>>>>>>>>>>>''

而True:

l = self.rfile.readline()

print repr(l)

如果不是l或l ==''\\\\ n ':

休息

打印>> self.wfile,''HTTP / 1.0 200 OK''

打印>> self。 wfile,''Content-type:text / plain''

print>> self.wfile

print>> self.wfile,''foo''

self.rfile.close()

self.wfile.close()

打印''<<<<<<<<<<<<<<''


def main():

server = TCPServer(('''',8080),myHandler)

server.serve_forever()


if __name__ ==''__ main__ '':main()


- 图片


文章< 46 ********* ************@news.xs4all.nl>,

Irmen de Jong< ir ********** @ xs4all.nlwrote:< br>


Ron Garret写道:


这是我的代码。它是一个小小的微弱的HTTP服务器。 (我不是真的想要在这里重新发明轮子。我正在做的是写一个

调度代理服务器,但这是最短的方式来说明我正在讨论的

问题:

来自SocketServer导入的
*来自套接字导入的
*

来自精选导入选择


class myHandler(StreamRequestHandler):

def handle(self):

打印''>>>>>>>>>>>''

而1:

sl = select([ self.rfile],[],[])[0]

如果sl:

l = self.rfile.readline()

if len(l)< 3:break

print l,

pass

pass

print>> self.wfile,''HTTP / 1.0 200 OK''

print>> self.wfile,''Content-type:text / plain''

print> > self.wfile

print>&g t; self.wfile,''foo''

self.rfile.close()

self.wfile.close()

打印''<<<<<<<<<<<<<''

pass

pass




你不应该在handle方法中使用你自己的select()。

socketserver会为你处理。



我不明白为什么socketserver调用select应该很重要。 (并且

BTW,在SocketServer.py中没有要求选择。我正在使用

Python2.5。)


你需要做的是从套接字读取输入,直到你输入结束标记为
。在处理HTTP GET请求时,该标记是一个空行,只包含\\\\ n和/或



任何理由都不要想使用Python附带的BasicHTTPServer?



是的,但这是一个很长的故事。我真正在做的是写一个

调度代理。它读取HTTP请求,然后根据URL将其重定向到

个不同的服务器。这些服务器都是本地的,并且是由unix套接字服务的,而不是TCP套接字(这就是为什么我不能让b $ b配置Apache来执行此操作)。 />

我运行这个奇怪配置的原因(如果你想要b / b
)是因为这是一台开发机器和多个副本
同一网站的
同时运行。该网站的每个副本

运行一个定制服务器来有效地处理AJAX请求。


>

无论如何,请尝试以下方法:



这对POST请求不起作用。


rg


Here''s my code. It''s a teeny weeny little HTTP server. (I''m not really
trying to reinvent the wheel here. What I''m really doing is writing a
dispatching proxy server, but this is the shortest way to illustrate the
problem I''m having):

from SocketServer import *
from socket import *
from select import select

class myHandler(StreamRequestHandler):
def handle(self):
print ''>>>>>>>>>>>''
while 1:
sl = select([self.rfile],[],[])[0]
if sl:
l = self.rfile.readline()
if len(l)<3: break
print l,
pass
pass
print>>self.wfile, ''HTTP/1.0 200 OK''
print>>self.wfile, ''Content-type: text/plain''
print>>self.wfile
print>>self.wfile, ''foo''
self.rfile.close()
self.wfile.close()
print ''<<<<<<<<<<<<''
pass
pass

def main():
server = TCPServer(('''',8080), myHandler)
server.serve_forever()
pass

if __name__ == ''__main__'': main()
If I telnet into this server and type in an HTTP request manually it
works fine. But when I try to access this with a browser (I''ve tried
Firefox and Safari -- both do the same thing) it hangs immediately after
reading the first line in the request (i.e. before reading the first
header).

When I click the "stop" button in the browser it breaks the logjam and
the server reads the headers (but then of course it dies trying to write
the response to a now-closed socket).

The only difference I can discern is that the browser send \r\n for
end-of-line while telnet just sends \n. But I don''t see why that should
make any difference. So I''m stumped. Any clues would be much
appreciated.

Thanks,
rg

解决方案

Ron Garret wrote:

print>>self.wfile, ''HTTP/1.0 200 OK''
print>>self.wfile, ''Content-type: text/plain''
print>>self.wfile
print>>self.wfile, ''foo''
[...]
If I telnet into this server and type in an HTTP request manually
it works fine. But when I try to access this with a browser (I''ve
tried Firefox and Safari -- both do the same thing) it hangs
immediately after reading the first line in the request (i.e.
before reading the first header).

Could the problem be that print ends lines with "\r\n" not on all
platforms? Try doing it explicitly.

The only difference I can discern is that the browser send \r\n
for end-of-line while telnet just sends \n.

Then, I think, your telnet client is broken. I''ve seem multiple
applications relying on telnet or similar protocols which
required "\r\n" as end-of-line. E. g. I needed to hack
twisted.protocols.basic.LineReceiverFactory since it showed the
exact behaviour you described for browsers. It showed up because
busybox'' telnet only sends \n as EOL.

But I don''t see why that should make any difference.

Easy. If you only accept "\r\n" as EOL, you''ll wait forever unless
you really receive it.

Regards,
Bj?rn

--
BOFH excuse #81:

Please excuse me, I have to circuit an AC line through my head to
get this database working.


Ron Garret wrote:

Here''s my code. It''s a teeny weeny little HTTP server. (I''m not really
trying to reinvent the wheel here. What I''m really doing is writing a
dispatching proxy server, but this is the shortest way to illustrate the
problem I''m having):

from SocketServer import *
from socket import *
from select import select

class myHandler(StreamRequestHandler):
def handle(self):
print ''>>>>>>>>>>>''
while 1:
sl = select([self.rfile],[],[])[0]
if sl:
l = self.rfile.readline()
if len(l)<3: break
print l,
pass
pass
print>>self.wfile, ''HTTP/1.0 200 OK''
print>>self.wfile, ''Content-type: text/plain''
print>>self.wfile
print>>self.wfile, ''foo''
self.rfile.close()
self.wfile.close()
print ''<<<<<<<<<<<<''
pass
pass


You shouldn''t use a select() of your own inside the handle method.
The socketserver takes care of that for you.

What you need to do is read the input from the socket until you''ve reached
the end-of-input marker. That marker is an empty line containing just "\r\n"
when dealing with HTTP GET requests.

Any reason don''t want to use the BasicHTTPServer that comes with Python?

Anyway, try the following instead:

from SocketServer import *
from socket import *
from select import select

class myHandler(StreamRequestHandler):
def handle(self):
print ''>>>>>>>>>>>''
while True:
l = self.rfile.readline()
print repr(l)
if not l or l==''\r\n'':
break
print>>self.wfile, ''HTTP/1.0 200 OK''
print>>self.wfile, ''Content-type: text/plain''
print>>self.wfile
print>>self.wfile, ''foo''
self.rfile.close()
self.wfile.close()
print ''<<<<<<<<<<<<''

def main():
server = TCPServer(('''',8080), myHandler)
server.serve_forever()

if __name__ == ''__main__'': main()

--Irmen


In article <46*********************@news.xs4all.nl>,
Irmen de Jong <ir**********@xs4all.nlwrote:

Ron Garret wrote:

Here''s my code. It''s a teeny weeny little HTTP server. (I''m not really
trying to reinvent the wheel here. What I''m really doing is writing a
dispatching proxy server, but this is the shortest way to illustrate the
problem I''m having):

from SocketServer import *
from socket import *
from select import select

class myHandler(StreamRequestHandler):
def handle(self):
print ''>>>>>>>>>>>''
while 1:
sl = select([self.rfile],[],[])[0]
if sl:
l = self.rfile.readline()
if len(l)<3: break
print l,
pass
pass
print>>self.wfile, ''HTTP/1.0 200 OK''
print>>self.wfile, ''Content-type: text/plain''
print>>self.wfile
print>>self.wfile, ''foo''
self.rfile.close()
self.wfile.close()
print ''<<<<<<<<<<<<''
pass
pass



You shouldn''t use a select() of your own inside the handle method.
The socketserver takes care of that for you.

I don''t understand why socketserver calling select should matter. (And
BTW, there are no calls to select in SocketServer.py. I''m using
Python2.5.)

What you need to do is read the input from the socket until you''ve reached
the end-of-input marker. That marker is an empty line containing just "\r\n"
when dealing with HTTP GET requests.

Any reason don''t want to use the BasicHTTPServer that comes with Python?

Yes, but it''s a long story. What I''m really doing is writing a
dispatching proxy. It reads the HTTP request and then redirects it to a
number of different servers depending on the URL. The servers are all
local and served off of unix sockets, not TCP sockets (which is why I
can''t just configure Apache to do this).

The reason I''m running this weird configuration (in case you''re
wondering) is because this is a development machine and multiple copies
of the same website run on it simultaneously. Each copy of the site
runs a customized server to handle AJAX requests efficiently.

>
Anyway, try the following instead:

That won''t work for POST requests.

rg


这篇关于选择怪异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆