![命令行中的“curl”如何确定正在上传的文件的MIME类型?](https://linux22.com/image/119154/%E5%91%BD%E4%BB%A4%E8%A1%8C%E4%B8%AD%E7%9A%84%E2%80%9Ccurl%E2%80%9D%E5%A6%82%E4%BD%95%E7%A1%AE%E5%AE%9A%E6%AD%A3%E5%9C%A8%E4%B8%8A%E4%BC%A0%E7%9A%84%E6%96%87%E4%BB%B6%E7%9A%84MIME%E7%B1%BB%E5%9E%8B%EF%BC%9F.png)
当将文件作为表单字段上传curl
(例如curl -F 'file=@path/to/file' https://example.org/upload
)时,curl
有时会设置MIME类型与确定 MIME 类型的其他实用程序返回的内容不同。
例如,在位.bmp
图文件上,file -i path/to/file.bmp
表示它是image/x-ms-bmp
,但curl
将 MIME 类型设置为 ,application/octet-stream
除非我明确覆盖它。
但是,它适用于某些文件类型,例如.png
和.jpg
。
我想知道它如何确定 MIME 类型以及在什么条件下它会按预期工作。
答案1
从一些源代码中,spelunking forContent-Type
curl
似乎会进行一些文件扩展名匹配,否则默认为HTTPPOST_CONTENTTYPE_DEFAULT
which is application/octet-stream
,在奇怪的命名ContentTypeForFilename
函数中:
https://github.com/curl/curl/blob/ee56fdb6910f6bf215eecede9e2e9bfc83cb5f29/lib/formdata.c#L166
static const char *ContentTypeForFilename(const char *filename,
const char *prevtype)
{
const char *contenttype = NULL;
unsigned int i;
/*
* No type was specified, we scan through a few well-known
* extensions and pick the first we match!
*/
struct ContentType {
const char *extension;
const char *type;
};
static const struct ContentType ctts[]={
{".gif", "image/gif"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".txt", "text/plain"},
{".html", "text/html"},
{".xml", "application/xml"}
};
if(prevtype)
/* default to the previously set/used! */
contenttype = prevtype;
else
contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
if(filename) { /* in case a NULL was passed in */
for(i = 0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
if(strlen(filename) >= strlen(ctts[i].extension)) {
if(strcasecompare(filename +
strlen(filename) - strlen(ctts[i].extension),
ctts[i].extension)) {
contenttype = ctts[i].type;
break;
}
}
}
}
/* we have a contenttype by now */
return contenttype;
}
file(1)
(虽然我认为将来可以修改源代码以进行类型魔术检查,也许......)