나는 이 웹사이트를 가지고 있는데, 사용자가 양식을 제출하면 Python 스크립트가 PHP 페이지를 통해 실행되고 Python 스크립트는 zip 파일을 생성하여 링크를 통해 다운로드할 수 있도록 사용자에게 제공해야 합니다. 파일은 용량이 클 수 있습니다(수 GB).
저는 대학 서버에서 작업하기 때문에 해당 서버 규칙과 기능을 엄격하게 준수합니다. 문제는 이것이다:
웹사이트는 /data/mywebsite
디스크 공간이 제한된 에 저장되어 있습니다. 물론 www-data
이것은 주로 내 Apache 서버에서 액세스되므로 이 파일은 내 소유입니다.
/experimentdata/
예를 들어 특정 사용자 한 명만 액세스할 수 있는 1TB의 저장 공간이 제공되었습니다 theuser
. 이는 폴더가 삼바에 마운트되어 있고 단일 특정 사용자 ID로 액세스할 수 있기 때문입니다.
에서 파일을 생성하기 위해 /experimentdata
사용자로 파일을 생성하는 명령을 사용합니다 sudo -u theuser
. 이제 내 질문은: Apache 다운로드 링크를 통해 이 파일을 어떻게 제공할 수 있습니까?/experimentdata/downloadme.zip
theuser
예를 들어 내가 넣은 심볼릭 링크를 사용하려고 생각했습니다 /data/mywebsite/download/downloadme.zip
. 문제는 사용자가 www-data
파일을 읽을 수 있는 권한이 전혀 없다는 것입니다!
사용자가 /experimentdata/downloadme.zip
사용자와 함께 파일을 다운로드하도록 하려면 어떻게 해야 합니까?www-data
theuser
분명히 말씀드리고 싶은 것은 sudo -u theuser
참여하는 것이 절대적으로 괜찮다는 것입니다. 하지만 내 웹사이트 폴더 외부에 연결하는 방법을 모르겠습니다.
추신: 다른 정보가 필요하면 문의하세요.
답변1
내 생각 엔 데이터를 직접 가져오거나 반환 php
하는 것이 좋습니다 . 코드도 같은 일을 할 수 있습니다 . 내 경험상 이것은 다른 디렉토리를 열거나 파일 권한 등을 사용하거나 변경하는 것보다 훨씬 낫습니다.python
apache
apache
sudo
apache
프로그램이 인터넷 연결 속도보다 더 빠르게 대용량 파일을 생성하는 경우 프로그램에서 직접 데이터를 스트리밍할 수 있으므로 이를 관리하기 위한 추가 데이터 파일 및 코드와 이를 기억하는 메커니즘이 제거됩니다.
Stack Overflow에 대한 이 답변은 .NET에서 코드가 작동하는 방식을 보여줍니다 php
.https://stackoverflow.com/a/4357904/5484716.
이러한 방식으로 호출된 프로그램의 경우 모든 stderr
스트림 출력을 제거하고 Python 프로세스의 반환 코드가 프로세스의 성공 또는 실패를 정확하게 반영하는지 확인하세요.
아래 예제는 popen()
위의 stackoverflow 예제 시나리오에서 사용할 호출을 보여줍니다. exec 2>/dev/null;
쉘 명령 앞에 추가했습니다 . 이렇게 하면 데이터가 stderr
및 에서 모두 오기 때문에 stdout
교착 상태의 원인이 될 수 있는 셸 자체에서도 출력이 표준 오류로 이동하지 않습니다 popen()
.
사용자에게 디스크 파일을 다운로드하려면:
$fp = popen('exec 2>/dev/null; sudo -u theuser cat yourfile.zip', 'r');
활성 프로세스에서 데이터를 다운로드하려면:
$fp = popen('exec 2>/dev/null; sudo yourpythonscript arg argN', 'r');
이 명령줄예쉘 명령이며 쉘 메타 문자에 대해 적절하게 인용되어야 합니다.
두 번째 방법에서는 서버가 즉시 데이터 전송을 시작합니다. 사용자가 양식을 성공적으로 제출하면 브라우저에 다른 이름으로 저장 대화 상자가 즉시 표시됩니다. 사용자가 출력 파일을 선택하면 php
스크립트는 유선을 통해 데이터를 원격 파일로 직접 전송합니다.
스크립트 python
가 인쇄되어야 합니다.오직zip 데이터를 표준 출력으로 반환하고 zip 프로세스의 성공 또는 실패를 정확하게 나타내는 종료 코드를 반환합니다. 예를 들어 python
스크립트에서는 출력을 작성해야 합니다.sys.stdout
zf = ZipFile(sys.stdout, ...
pclose()
호출하여 반환 값을 확인하는 것이 중요합니다., 이것이 zip이 성공했는지 알 수 있는 유일한 방법이기 때문입니다. 0이 아닌 값이 반환 되면 pclose()
문제가 있는 것입니다.
클라이언트가 파일을 처리하는 방법은 다음 설정 및 response headers
기타 설정 에 따라 다릅니다 content-type:
.content-encoding:
content-disposition:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html, 보기 response-header
및 entity-header
정보.