【问题标题】:Content-disposition filename "suggestion" is always ignored. Why?内容处置文件名“建议”总是被忽略。为什么?
【发布时间】:2016-07-23 02:07:23
【问题描述】:

这是用 C 编写的 CGI 程序的一部分。当客户端单击链接时,我希望文件开始下载,并使用建议的默认文件名。

我知道规范明确指出 Content-disposition 标头中指定的文件名只是建议的,但似乎无论我使用什么浏览器,它总是被忽略。我将这种行为解释为我做错了什么。

这是重现我的问题的精简代码 sn-p。当编译为 test.cgi 时,程序可以工作,但浏览器将数据保存为文件名“test.cgi”,而不是建议的“archive.tar.gz”。

(文件 i/o 错误检查和其他安全位被删除以保持清晰和简洁。)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#define CHUNK_SIZE 1024

int main( int argc, char *argv[] ) {
  int fd;
  long bytes_remaining, bytes_to_get, bytes_read, bytes_sent, retval;
  int chunksize;
  unsigned char data_buffer[CHUNK_SIZE];
  char header_str[200];

  fd = open( "archive.tar.gz", O_RDONLY );
  if( fd == -1 ) {
    printf( "Content-type: text/html\n\n" );
    printf( "Unable to open file: %s.<br><br>\n", strerror(errno) );
    return 0;
  }

  bytes_remaining = lseek( fd, 0, SEEK_END );
  lseek( fd, 0, SEEK_SET );

  snprintf( header_str, 200, "Content-Type: application/x-compressed\r\n\r\nContent-Disposition: attachment; filename=\"archive.tar.gz\"\r\n\r\n" );
  write( 1, header_str, strlen(header_str) );

  while( bytes_remaining > 0 ) {
    if( bytes_remaining > CHUNK_SIZE ) bytes_to_get = CHUNK_SIZE;
    else bytes_to_get = bytes_remaining;
    bytes_read = read( fd, data_buffer, bytes_to_get );
    bytes_sent = write( 1, data_buffer, bytes_read );
    bytes_remaining -= bytes_sent;
  }
  close( fd );

  return 0;
}

为什么我建议的文件名一直被忽略?

谢谢。

【问题讨论】:

  • 您收到 CGI 中的值了吗?提供minimal reproducible example 并查看How to Ask
  • 在实际应用中,是的,要下载的文件是由请求的URL中的参数决定的。以上是一个最小的、完整的和可验证的例子。编译它,把它放在服务器上,请求whatever_you_compiled_it_to.cgi,而不是浏览器下载文件并将其命名为archive.tar.gz,它被保存为whatever_you_compiled_it_to.cgi。
  • 不,不是。有电话不见了,分别。导致调用它的网站。你甚至没有回答我的问题。
  • 那我不明白你的问题。您的问题是“您收到 CGI 中的价值了吗?”你在说什么价值?什么价值?拿上面的代码。将其粘贴到名为 test.c 的文件中。用 gcc -o test.cgi test.c 编译它。将 test.cgi 粘贴到 Web 服务器上。在同一目录中放置一个随机位文件或其他名为archive.tar.gz 的文件。在浏览器中输入“thatserver.com/cgi-bin/test.cgi”。浏览器将下载文件archive.tar.gz,但会将其作为test.cgi 保存到您的计算机,而不是Content-disposition 标头“建议”的archive.tar.gz。为什么?

标签: c cgi content-disposition


【解决方案1】:

问题是标题中有一个额外的回车/换行符。应该是:

snprintf( header_str, 200, "Content-Type: application/x-compressed\r\nContent-Disposition: attachment; filename=archive.tar.gz\r\n\r\n" );

正如 OP 中所写,Content-Disposition 行将被解释为数据的一部分,而不是标题的一部分。此外,建议的文件名也不需要引号。

【讨论】:

    猜你喜欢
    • 2021-03-12
    • 2020-12-30
    • 2014-09-11
    • 2022-11-28
    • 1970-01-01
    • 2021-11-06
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多