Como o 'curl' na linha de comando determina o tipo MIME de um arquivo sendo carregado?

3

Ao fazer o upload de um arquivo como um campo de formulário em curl (por exemplo, curl -F 'file=@path/to/file' https://example.org/upload ), curl às vezes define o Tipo MIME diferentemente do que é retornado por outros utilitários que determinam o tipo MIME.

Por exemplo, nos arquivos de bitmap .bmp , file -i path/to/file.bmp diz que é image/x-ms-bmp , mas curl define o tipo MIME como application/octet-stream , a menos que eu o substitua explicitamente.

No entanto, funciona corretamente para alguns tipos de arquivo, como .png e .jpg .

Eu gostaria de saber como ele determina o tipo MIME e sob quais condições ele funcionará como esperado.

    
por markasoftware 06.10.2017 / 01:25

1 resposta

3

De alguns spelunking de código-fonte para Content-Type curl parece fazer alguma correspondência de extensão de arquivo, caso contrário, usar como padrão HTTPPOST_CONTENTTYPE_DEFAULT , que é application/octet-stream , na estranha função ContentTypeForFilename :

link

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;
}

(Embora eu suponha que a fonte possa ser modificada para fazer verificações de magia do tipo file(1) no futuro, talvez ...)

    
por 06.10.2017 / 01:50