Command-Line

命令行上的 curl 如何確定上傳文件的 MIME 類型?

  • February 28, 2018

將文件作為表單欄位上傳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 類型以及在什麼條件下它將按預期工作。

從一些原始碼中尋找Content-Type curl似乎做了一些文件副檔名匹配,否則預設為HTTPPOST_CONTENTTYPE_DEFAULTis 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)類型魔術檢查,也許……)

引用自:https://unix.stackexchange.com/questions/396385