使用原始HTTP(PuTTY)通过POST发送文件

9
如果我设置一个带有以下表单的HTML页面:
<html>

    <body>
        <form action="upload_file.php"
              method="post"
              enctype="multipart/form-data">

            <label for="file">Filename:</label>
            <input type="file" name="file" id="file" />
            <br />
            <input type="submit" name="submit" value="Submit" />
        </form>
    </body>

</html>

我可以上传文件到upload_file.php,并使用PHP脚本处理它。
为了测试目的,我需要通过PuTTY会话使用原始HTTP进行相同的操作。
我可以通过常规POST方式(只发送文本数据)来执行此操作:
POST /test_post.php HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

name=myname

我怎样才能以这种方式发送文件?

2个回答

17

你需要使用multipart内容类型,并将文件数据编码为十六进制/二进制。

在telnet中尝试以下内容:

POST /the_url HTTP/1.1
User-Agent: Mozilla
Host: www.example.com
Content-Length: xxxx
Content-Type: multipart/form-data; boundary=--------------------31063722920652
------------------------------31063722920652
Content-Disposition: form-data; name="a"

value_for_a
------------------------------31063722920652
Content-Disposition: form-data; name="b"

value_for_b
------------------------------31063722920652
Content-Disposition: form-data; name="c"; filename="myfile.txt"
Content-Type: text/plain

            This is a test 
            and more

-----------------------------31063722920652
Content-Disposition: form-data; name="submit"

Submit
-----------------------------31063722920652--

记得在字段名称和其数据之间需要添加额外的换行符。另外,更新Content-Length的值。


我该如何调整文件的新内容长度?它会是文件大小(以字节为单位)吗? - Ayush
1
我已经完成了我的答案中的原始数据。现在它包含一个文本文件负载。Content-Length将是负载的完整大小(包括文件)以字节为单位。 - Aziz Shaikh
Content-Length 是从第一个“boundary”开始发送的数据字节数,直到最后一个“boundary”的大小。 - Aziz Shaikh
请问您能告诉我请求中的数字31063722920652代表什么吗? - Hemal Chevli
@HemalChevli 这是一个任意值,你可以将其设置为任何值。我认为限制是70个字节。这个分隔符值不应该出现在请求数据中,否则它将被视为边界。 - Aziz Shaikh

5

使用netcat打开一个端口并保存传入的请求:

nc -l -p 1090 > income-http.txt

然后修改你的表单,将数据发送到netcat:
<form action="http://localhost:1090/upload_file.php" 
    method="post" enctype="multipart/form-data">

从您的浏览器提交表单。您可以在income-http.txt文件中找到完整的原始请求和文件内容。

保存income-http.txt是一次性活动。之后,您可以多次发送保存的请求。请注意,您应编辑保存的txt中的Host:标头。


我非常喜欢能够分析传入请求的想法。但不幸的是,对我来说打开端口不是一个选项。有没有其他选择? - Ayush
1
你只需要在本地机器上执行一次即可。获取了income-http.txt文件后,你可以随时发送它。 - palacsint
哦,你的意思是我在本地机器上打开端口,而不必在路由器上进行转发吗?我无法访问路由器。我会尝试使用netcat。 - Ayush
顺便问一句,我能在我的Linux Web托管服务器上安装netcat吗? - Ayush
2
是的,只需要在本地机器上操作,无需将其路由到任何地方。它只是将传入的请求保存到文本文件中,在保存后您就不再需要它了。在Debian上安装Netcat:aptitude install netcat。其他发行版通常也有Netcat包。 - palacsint

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接