如何通过telnet或原始套接字上传文件?

0 投票
3 回答
2323 浏览
提问于 2025-04-16 17:20

我正在尝试通过一个原始套接字发送一个文件,我看过相关的标准文档,也测试了很多选项,但现在遇到瓶颈了。

顺便说一下,我知道可以使用像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'吗?

撰写回答