dtvpe4837413 2017-01-03 04:16
浏览 184
已采纳

Php MP3流媒体问题

I am having a very odd problem when I am trying to stream music using php from my local server. I have basic username / password authorization checks to make sure that the user has the correct permissions to stream the file. The problem lies in these checks though.

I am using the exit function of php to abort the script if the user doesn't have permission to view the file, and echo to notify the user. The exit function appears to be breaking the streaming, even when it doesn't execute.

Here are the highlights of my code:

    function hasPermission($user,$perm)
    {
        if (!accountHasPermission($user,$perm) )
        {
            echo "<center><a style='color:indianred'>Failed to Authenticate: 1";
            echo "<br><br><a href='javascript:history.back()'>Go Back</a>";

            exit;
        }
    }

    function streamTest()
    {
        $filename = "uploads/path_to_file";

        if(file_exists($filename)){
            header('Content-type: audio/mpeg');
            header('Content-Disposition: filename=' . basename($filename) );
            header('X-Pad: avoid browser bug');
            header('Cache-Control: no-cache');  
            readfile( $filename );
        }else{
            header("HTTP/1.0 404 Not Found");
        }
    }

    hasPermission($_POST["username"],"manageFilesWeb");

    streamTest();
    exit;

If I comment out the exit call in the hasPermission function, the audio will stream without problem. Using chrome, I get a nice audio player that looks like this. Of course, the exit function will never get called because I am using an account with the correct permissions. I am 100% sure of this. If the exit function is not commented out, the music file will not stream on chrome and the audio player will look like this. I have tried multiple chrome browsers and always get the same results. However, the music will stream in a firefox browser regardless of the exit line being commented out or not.

I have tried various other options such as using return, die, if/else, but everything will give me the same results.

I should also note that I have been using the hasPermission function for everything else on my server, such as uploading and downloading files. It has never given me any problem until now. It took me hours of trial and error to figure out that the exit call could be the problem.

I have gotten to the point where I have no idea what is going on. I have already had to remove simple if/else checks because they were interrupting the streaming process, but I have gotten to the point where I will significantly be reducing security if I remove any more.

Update: I found the issue. The authorization checks are the problem. I suppose during the file transfer, the _POST data is undefined, causing my authorization checks to fail. Is there a way to get the username and password while the file is streaming to avoid this?

  • Firefox appears to constantly send the _POST data, which allows the verification checks to pass, keeping the file stream alive. While chrome does appears to just send it once.
  • 写回答

1条回答 默认 最新

  • duanlachu7344 2017-01-03 17:26
    关注

    For these kind of authenticated file serving use sendfile method of the respected webservers behind which your php application is running, that said there are two popular webservers,

    1. Apache

    For Apache enable xsendfile mod here on first read username & password using a seperate login.php

      // login.php
      // session_start & stop life cycle codes
      username = $_POST["username"];
      password = $_POST["password"];
      if(hasPermission(username, password){
         $_SESSION["logined"] = true; // setting a session value for successful authentication
      }
      // login success
    

    Then add file php file for streaming file, say file.php

     //file.php
      if(isset($_SESSION["logined"])){
                $filename = "uploads/path_to_file"; // absolute path to file
                header('Content-type: audio/mpeg');
                header('Content-Disposition: filename=' . basename($filename) );
                header('X-Pad: avoid browser bug');
                header('Cache-Control: no-cache');  
                header('X-Sendfile', $filename);
      }else{
          header("HTTP/1.0 404 Not Found"); // or 401 Unauthorized
      }
    

    2. Nginx

    For nginx server use follow the steps described in apache section except replace X-Sendfile with X-Accel-Redirect, check here for more explanation related to nginx xsendfile.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启