如何通过telnet或原始套接字上传文件?
我正在尝试通过一个原始套接字发送一个文件,我看过相关的标准文档,也测试了很多选项,但现在遇到瓶颈了。
顺便说一下,我知道可以使用像pycurl、httplib这样的库,但我真的想手动实现这个功能。
这是我的请求:
POST /upload.php?foo=bar HTTP/1.0
Host: localhost
User-Agent: Mozilla/5.0
Content-Type: multipart/form-data; boundary=9afb0c26-7adf-11e0-b167-1c6f65955350
--9afb0c26-7adf-11e0-b167-1c6f65955350
Content-Disposition: form-data; name="files[]"; filename="image.png"
Content-Type: image/png
#PNG
IHD&# )IDA##x## D
[##
###b######j
5#r#`IEND#B`#
--9afb0c26-7adf-11e0-b167-1c6f65955350--
这些行都是从一个数组中拼接而来的:
"\n".join(lines)
我尝试过用\n和\r\n这两种方式。
并且在最后我发送了CRLF。
我这样读取我的图片:
f = open(file, 'rb')
file_content = ''
while True:
chunck = f.read(1024)
file_content += chunck
if len(chunck) == 0:
break;
lines.append(file_content)
有什么想法吗?
3 个回答
0
每一行的头部信息都必须以CRLF结束。想了解更多,可以查看这里:https://www.rfc-editor.org/rfc/rfc2616#section-5
1
既然你已经找到了要用的头部信息,我建议把它放进一个多行字符串里,像这样:
# An infinitely clever way to make \r\n\r\n at end of header, although technically
# inferior to just going rnrn = '\r\n\r\n' tho. Shut up...
rnrn = '\n'.join('\r\r\r')[:4]
# remember that each line in an http header must be terminated with \r\n.
# Since multiline strings already add a \n terminator at the end of each line,
# all that is needed is \r at the end of each line.
header = """POST /upload.php?foo=bar HTTP/1.0\r
Host: localhost\r
User-Agent: Mozilla/5.0\r
Content-Type: multipart/form-data; boundary=9afb0c26-7adf-11e0-b167-1c6f65955350\r
--9afb0c26-7adf-11e0-b167-1c6f65955350\r
Content-Disposition: form-data; name="files[]"; filename="image.png"\r
Content-Type: image/png\r
#PNG\r
IHD&# )IDA##x## D\r
[##\r
###b######j\r
5#r#`IEND#B`#\r
--9afb0c26-7adf-11e0-b167-1c6f65955350--"""+rnrn
HOST = '' #your hostname here
PORT = 0 #your port here
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
s.send(header)
return_data = s.recv(1024)
s.close()
print('Got back: ', return_data)
就这样,差不多就完成了。Python的真正精髓在于,实际的编码部分其实很简单,真正的挑战在于你用它来做什么。
我自己正在写一个使用原始套接字的HTTP程序。这将是一个xchat脚本,利用babelfish.yahoo.com来翻译来自外语使用者的IRC消息。
1
难道在部分头信息里不应该有一个'Content-Length'吗?