设置 PHP Mime 类型?

Posted

技术标签:

【中文标题】设置 PHP Mime 类型?【英文标题】:Setting PHP Mime Type? 【发布时间】:2015-06-16 08:59:59 【问题描述】:

我正在尝试使用 Web 服务器等,所以我决定看看我可以用旧的 perl Web 服务器做什么。我需要使用 httpd-php 而不仅仅是纯文本来提供 php 文件,在谷歌上进行了一些挖掘之后,我发现“application/x-httpd-php”应该可以解决问题,但它不是..

jpg image/jpeg
html    text/html
htm text/html
pdf application/pdf
gif image/gif
pl  text/plain
sh  text/plain
txt text/plain
mpeg    video/mpeg
pas text/plain
php     application/x-httpd-php

如何告诉 mime 使用 PHP 提供 php 文件?

#!/usr/bin/perl

#
# $Header: /export/cvs/www.ogris.de/httpd/httpd.pl_,v 1.2 2002/11/10 22:55:45 fjo Exp $
#

use IO::Socket;

$PROGRAM_NAME = "Simple-HTTP";
$PIDFILE = "$PROGRAM_NAME.pid";
$TIMEZONE = "+0200";
%HTTPCODE = (
  200 => "Ok",
  404 => "Not found"
);
@MONTH = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
$PORT = 8001;
$DEFAULT_MIME = "text/plain";
$MIME = $ARGV[0] or $MIME = "mime.txt";

$SIGTERM = \&cleanup;
$SIGKILL = \&cleanup;
$SIGINT  = \&cleanup;
$SIGHUP  = sub  &load_mime("reloading mime types...") ;
$SIGCHLD = sub  wait ;

if (open(FH,"$PIDFILE")) 
  $pid = <FH>;
  close(FH);
  if (kill 0,$pid) 
    &error("$PROGRAM_NAME already running (pid=$pid)");
  
  else 
    &warning("removing old pid file");
  

if (open(FH,">$PIDFILE")) 
  print FH $$;
  close(FH);

else 
  &warning("can not write pid file $PIDFILE: $!");


&load_mime();

$listen = IO::Socket::INET->new(LocalPort=>$PORT, ReuseAddr=>1, Proto=>'tcp',
                                Listen=>1024) ||
  &error("can not create socket: $!");

&warning("$PROGRAM_NAME starting...");
while (my $socket = $listen->accept()) 
  $pid = fork();
  if ($pid == 0) 
    while ((my $s = <$socket>) ne "\r\n") 
      if ($s =~ /^get ([^\s]*)/io) 
        $url = $1;
        ($request = $s) =~ s/\r|\n//go;
      
    
    (my $file = ".$url") =~ s/\.\.//go;
    if (-d $file) 
      $file .= "/" if $file !~ /\/$/o;
      $mime = "html";
      if (($content = &read_file($file."index.html")) ne "") 
        $code = 200;
      
      elsif (!opendir(DH,$file)) 
        $code = 404;
        $content = &http_error($socket,$code,$url);
      
      else 
        @dir = readdir(DH);
        closedir(DH);
        $code = 200;
        $content = "<html><head><title>Index of $url</title></head><body>";
        $content.= "<h1>Index of $url</h1><pre><table>";
        foreach (sort @dir) 
          $content .= "<tr><td><a href=\"$_";
          if (-d "$file$_") 
            $content .= "/\">$_/</a></td><td align=right>-";
          
          else 
            my $size = -s "$file$_";
            $content .= "\">$_</a></td><td align=right>";
            $content .= &sizef($size);
          
          $content .= "</td></tr>";
        
        $content.= "</pre></table>".&address($socket);
      
    
    elsif (($content = &read_file($file)) ne "") 
      $code = 200;
      $mime = substr($file,rindex($file,'.')+1);
    
    else 
      $code = 404;
      $mime = "html";
      $content = &http_error($socket,$code,$url);
    
    my $len = length($content);
    print $socket &http_out($code,$mime,$len,$content);
    print &common_log($socket,$request,$code,$len);
    $socket->close();
    &byebye();
  


sub read_file

 my $file = shift;
 if ( (-f $file) && (open(FH,$file)) ) 
   binmode FH;
   while (<FH>)  $content .= $_; 
   close(FH);
   binmode $socket;
   return $content;
 
 else 
   return "";
 


sub http_error

  my $socket = shift;
  my $code = shift;
  my $url = shift;

  my $ret = "<html><head><title>$code $HTTPCODE$code</title></head><body>";
  $ret .= "<h1>$HTTPCODE$code</h1><p>The requested URL $url was not found on";
  $ret .= " this server.</p>".&address($socket);
  return $ret;


sub address

  my $socket = shift;
  my $server = $socket->sockhost();
  my $port = $socket->sockport();

  my $ret =  "<hr><address>Simple HTTP on $server:$port <br>";
  $ret .= scalar localtime(time)."</address></body></html>";
  return $ret;


sub http_out

  my $code = shift;
  my $mime = shift;
  my $len = shift;
  my $content = shift;
  my $ret = "HTTP/0.9 $code $HTTPCODE$code\r\nContent-type: ";
  $ret .= &get_mime($mime)."\r\nContent-length: ".$len."\r\n";
  $ret .= "Connection: close\r\n\r\n$content";


sub common_log

  my $socket = shift;
  my $request = shift;
  my $code = shift;
  my $len = shift;

  my $jetzt = time();
  my $remotehost = $socket->peerhost();

  my $ret = "$remotehost - - [".&datetimestamp($jetzt);
  $ret .= "] \"$request\" $code $len\n";


sub datetimestamp

  my $jetzt = shift;
  my ($sec,$min,$hour,$day,$mon,$year,@rest) = localtime($jetzt);
  $year += 1900;
  foreach ($sec,$min,$hour,$day) 
    $_ = "0$_" if $_ < 10;
  
  return "$day/$MONTH[$mon]/$year:$hour:$min:$sec $TIMEZONE";


sub cleanup

  if (!unlink $PIDFILE) 
    &warning("can not remove pid file $PIDFILE: $!");
  
  &warning("$PROGRAM_NAME shutting down...");
  &byebye();


sub load_mime

  %MIME = ();
  if (open(MFH,$MIME)) 
    &warning($_[0]) if $_[0];
    my @inhalt = <MFH>;
    close (MFH);
    %MIME = map 
      s/\r|\n//go;
      my @split = split(/\t/,$_);
      $split[0] => $split[1]
     @inhalt;
  
  else 
    &warning("can not read $MIME: $!");
  


sub get_mime

  my $ret = $MIME$_[0];
  $ret = $DEFAULT_MIME if $ret eq "";
  return $ret;


sub error

  &warning($_[0]);
  &byebye();


sub warning

  print STDERR "[".&datetimestamp(time)."] $_[0]\n";


sub sizef

  my $size = shift;
  my $i = 0;
  my @SIZES = ("","k","M","G","T");
  while ($size > 1024) 
    $size /= 1024;
    $i++;
  
  return sprintf("%.0f",$size).$SIZES[$i];


sub byebye

  close (STDERR);
  close (STDOUT);
  exit;

来自http://www.ogris.de/httpd/

【问题讨论】:

【参考方案1】:

如何告诉 mime 使用 PHP 提供 php 文件?

PHP 应作为CGI script 提供,您的网络服务器显然不支持。

(为简单起见,我省略了所有安全注意事项。)

粗略的解释,一个页面是一个 CGI 脚本,而不是逐字发送到客户端,而是由 HTTP 服务器作为应用程序执行,并将其输出发送到客户端。

要以最简单的形式实现 CGI 脚本支持,您需要:

    添加CGI脚本MIME类型配置表。

    在将文件发送到客户端之前,请检查 MIME 类型是否对应于 CGI。如果是,并且该文件是可执行的,则运行它,并将stdout 传送到客户端套接字。

要对此进行测试,您可以为(规范扩展名).cgi 文件添加 MIME 类型,并创建简单的 shell 或 Perl 脚本(扩展名为 .cgi),它们应该:

打印 HTTP 标头(由 "\n\r" 分隔),包括(最重要的)Content-Type 字段。

打印额外的"\n\r\n\r"作为标题和内容之间的分隔符,

打印内容(例如,简单地打印“Hello World”)。

在成熟的 CGI 实现中,服务器通过 the environment variables 将额外信息传递给 CGI 脚本。 Web 服务器还需要读取和处理 CGI 脚本生成的 HTTP 标头,使用附加的 HTTP field 对其进行扩展,或者简单地检查标头是否有效。如果脚本无法启动或产生空输出或因错误终止,请使用 HTTP 状态代码 500 向客户端报告问题。

现在到 PHP。大多数 PHP 页面不是作为 CGI 设计的,因为 PHP 大部分时间都配置为由 Web 服务器作为共享库(或 FastCGI)加载。因此,即使您实现了完全正确的 CGI 接口,大多数 .php 文件仍然无法工作。您必须使用自己的 PHP“集成”来扩展 CGI 支持。 to execute a PHP file 最简单的方法是使用 php -f &lt;file.php&gt; 运行它。换句话说,您需要向您的 Web 服务器添加额外的配置,告知某些 CGI MIME 类型不应直接运行,而应在外部进程的帮助下执行。

附:您可以查看的其他 Web 服务器实现:

http://utopia.knoware.nl/~hlub/uck/rlwrap/#p5httpd

http://sourceforge.net/projects/lwpwserver/

http://www.floodgap.com/httpi/

【讨论】:

以上是关于设置 PHP Mime 类型?的主要内容,如果未能解决你的问题,请参考以下文章

php 通过设置正确的mime类型强制下载。

为啥 php 不能正确检测到 pdf mime 类型(wkhtmltopdf)?

PHP - 使用正确的 MIME 类型打开上传的 DOCX 文件

文件拓展名 对应的MIME类型,文件下传上载有用怎么解决

PHP / Mime Types - 公开可用的 mime 类型列表? [关闭]

将 MIME 类型转换为文件扩展名 PHP