有些时候,不只需要提交表单,还需要上传附件。本篇针对上传文件,对上篇curl提交表单进行补充。
注:本篇只针对HTTP上传文件部分。
PHP程序
同前,所有服务端代码通过php实现。
- file.php,显示文件上传表单:
<html>
<head>
<title>
PHP FileUpload Demo for curl basic usage By Adeploy
</title>
</head>
<body>
This is a PHP File Upload Demo.<br />
Select a file and Submit.<br /><br />
<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br /><br />
<input type="submit" name="submit" value="Submit" />
</form>
<br /><br /><br />
<a href="http://www.adeploy.com" target="_blank">Adeploy's Blog</a>
</body>
</html>
upload_file.php,处理上传的文件。
上传文件后,文件先缓存在临时目录中,脚本结束时临时文件被删除。upload_file.php只是简单输出上传文件的信息,而不做实际场景中将临时文件保存至永久目录等进一步处理。但此差异对我们进行curl实验没有任何影响。<html>
<head>
<title>
PHP FileUpload Demo for curl basic usage By Adeploy
</title>
</head>
<body>
This is a File Upload Process Demo.<br />
It only shows the information of the file you uploaded.<br />
The file you uploaded remains temporary,<br />
and is deleted when this script is finished.<br /><br />
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Stored in: " . $_FILES["file"]["tmp_name"];
}
<br><br><br>
<a href="http://www.adeploy.com" target="_blank">Adeploy's Blog</a>
</body>
</html>put.php,处理通过HTTP PUT方法上传的文件。
同上,为了安全只输出上传文件信息,不做实际转存处理。<html>
<head>
<title>
PHP Form Demo for curl basic usage By Adeploy
</title>
</head>
<body>
This is a PHP PUT Demo.<br>
It reads the file you upload using PUT,<br>
and prints the content out.<br><br>
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
/* Read the data 1 KB at a time
and print the content out */
echo "The contents of the file you upload:<br><br>\n";
while ($data = fread($putdata, 1024))
echo $data;
echo "<br>";
/* Close the streams */
fclose($putdata);
<br /><br /><br />
<a href="http://www.adeploy.com" target="_blank">Adeploy's Blog</a>
</body>
</html>
主要参数
-F/–form
-F/--form <name=content>
使用Content-Type multi‐part/form-data
的方式提交数据,可用于上传二进制文件。
@的使用
一般使用-F file=@filename
的形式,其中file为文件表单的name,filename为文件名。@后面的文件作为文件上传处理。<的使用
对于<后的文件,curl会读取其内容,而不会作为文件上传。类似-d选项中@的作用。
如curl -F name=<foobar.txt -Fage=100 http://127.0.0.1/welcome.php
foobar.txt内容为Adeploy,则此命令与以下命令等价:curl -F name=Adeploy -Fage=100 http://127.0.0.1/welcome.php
而-F @foobar.txt表示将foobar.txt作为文件上传。-F不进行url编码
-F与-d类似,都是不对数据进行urlencode编码,而且-F不能与-d或–data-urlencode共用。
因此如果上传文件的同时还需要提交其他需要urlencode编码的字段(如中文用户名),就会出现问题。
除手动编码外,实用的解决办法是自己编写urlencode函数(网上可以找到Linux脚本实现的urlencode函数或C语言版本、Perl版本、Python),调用即可。使用”type=”指定Content-Type
如curl -F "web=@index.html;type=text/html" url.com
将index.html以text/html的Content-Type上传。使用”filename=”修改上传文件的名字
如curl -F "file=@localfile;filename=nameinpost" url.com
上传localfile并修改文件名字为nameinpost。
–form-string
--form-string <name=string>
基本同-F,但是此参数后面跟”@”、”<”、”;type=”时,不做特殊含义解析。
-T/–upload-file
-T/--upload-file <file>
使用HTTP的PUT方法上传文件,需要目标URL支持HTTP的PUT方法。
可以与-d、–data-urlencode、-F同时使用。
参数使用实例
-F文件上传
打开file.php选择文件后submit,Developer Tools抓包截图如下:
注意此时的Content-Type字段是multipart/form-data
,主要用于上传文件,具体可参考RFC1867。
分析file.php的源代码可知,表单中file类型的input元素name=file,所以命令如下:
curl -s -o file.html -F file=@a.txt http://127.0.0.1/upload_file.php |
-T文件上传
没有找到正确的PUT表单,因此无法使用Developer Tools跟踪实际提交过程。
命令:
curl -s -o put.html -T a.txt http://127.0.0.1/put.php |
总结
本篇主要为使用curl上传文件的操作方法。