我正在尝试运行SSL服务器,因此它可以接受JSON对象并使用其他JSON对象进行回复。但是,在做JSON对象之前,我决定做一个简化版本,我遇到了这个奇怪的错误,我找不到任何关于SSL的错误。除非我做错了,否则证书生成的解决方案似乎不起作用。所以这就是我所做的一切:
Python服务器
import socket
import re
import ssl
# Standard socket stuff:
host = '' # do we need socket.gethostname() ?
port = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))
sock.listen(1) # don't queue up any requests
# Loop forever, listening for requests:
while True:
csock, caddr = sock.accept()
connstream = ssl.wrap_socket(csock,
server_side=True,
certfile="cert.pem",
keyfile="cert.pem",
ssl_version=ssl.PROTOCOL_SSLv23)
print "Connection from: " + `caddr`
dataBuf = connstream.recv(4096) # read what is there to read
extraData = connstream.recv(4096) #see if there is more
while len(extraData) != 0: #if something extra was read
dataBuf += extraData
extraData = connstream.recv(4096) #check again
print '--------'
print len(dataBuf), dataBuf
# Look in the first line of the request for a move command
# A move command should be e.g. 'http://server/move?a=90'
match = re.match('GET /move\?a=(\d+)\sHTTP/1', dataBuf)
if match:
angle = match.group(1)
print "ANGLE: " + angle + "\n"
connstream.sendall("HTTP/1.0 200 OK\r\n"+
"Content-Type: text/html\r\n"+
"Connection: close\r\n"+
"\r\n"+
"""<!DOCTYPE html>
<head>
<title>Success</title>
</head>
<body>
Boo!
</body>
</html>\r\n
""")
else:
# If there was no recognised command then return a 404 (page not found)
print "Returning 404"
connstream.sendall("HTTP/1.0 404 Not Found\r\n")
#connstream.shutdown(socket.SHUT_RDWR)
connstream.close()
密钥和证书的生成:我不确定我在“公共名称”部分是否做错了,因为我在帖子Python SSL example from docs gives "Connection reset by peer" error后面给了localhost.localdomain
openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
我如何填写字段:
Country Name (2 letter code) [AU]:UK
State or Province Name (full name) [Some-State]:C
Locality Name (eg, city) []:C
Organization Name (eg, company) [Internet Widgits Pty Ltd]:U of C
Organizational Unit Name (eg, section) []:CL
Common Name (e.g. server FQDN or YOUR name) []:localhost.localdomain
Email Address []:unis
Errors: after going to https://localhost:8080/move?a=77 on a browser (Firefox and Chrome)
Connection from: ('127.0.0.1', 39107)
Traceback (most recent call last):
File "ser.py", line 29, in <module>
dataBuf = connstream.recv(44096) # read what is there to read
File "/usr/lib/python2.7/ssl.py", line 241, in recv
return self.read(buflen)
File "/usr/lib/python2.7/ssl.py", line 160, in read
return self._sslobj.read(len)
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
帮助表示感谢!谢谢!
ps:我尝试过TLSv1和PROTOCOL_SSLv23,同样的错误......
///关注:
我上了Firefox并手动添加了证书。
现在我明白了:
Connection from: ('127.0.0.1', 39220)
Traceback (most recent call last):
File "ser.py", line 29, in <module>
dataBuf = connstream.recv(44096) # read what is there to read
File "/usr/lib/python2.7/ssl.py", line 241, in recv
return self.read(buflen)
File "/usr/lib/python2.7/ssl.py", line 160, in read
return self._sslobj.read(len)
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094419:SSL routines:SSL3_READ_BYTES:tlsv1 alert access denied
任何想法?
//再试一次:
我告诉Firefox相信证书,现在我得到了
Connection from: ('127.0.0.1', 39248)
Traceback (most recent call last):
File "ser.py", line 29, in <module>
dataBuf = connstream.recv(44096) # read what is there to read
File "/usr/lib/python2.7/ssl.py", line 241, in recv
return self.read(buflen)
File "/usr/lib/python2.7/ssl.py", line 160, in read
return self._sslobj.read(len)
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
搜索这个什么都没有!
//跟进:
使用http://devsec.org/info/ssl-cert.html重新生成密钥和证书,也作为公用名localhost
。我得到连接,但服务器卡住了,从不回复......读取部分有问题吗?
答案 0 :(得分:1)
关于后续问题,我怀疑问题出在这个代码上......
dataBuf = connstream.recv(4096) # read what is there to read
extraData = connstream.recv(4096) #see if there is more
while len(extraData) != 0: #if something extra was read
dataBuf += extraData
extraData = connstream.recv(4096) #check again
...将尝试从套接字读取,直到它到达EOF。
但是,大多数浏览器默认使用persistent HTTP connection,这意味着它们在发送请求后不会关闭其套接字的出站一半,因此EOF不会发生,并且您的代码将被阻止其中一个recv()
来电。
如果要实现符合要求的HTTP服务器,则需要熟悉the protocol。你必须逐行阅读HTTP标题,注意Connection
和Content-Length
标题,一旦你到达标题的末尾,你应该只尝试阅读如果请求标头包含Content-Length
,则Connection: keep-alive
个字节。
协议可能会变得更复杂,因此使用内置的Python HTTP服务器并包装套接字可能更简单。 python https server
的快速Google会产生fairly simple example作为第一个结果。