Обработка POST запроса до его полного получения

HansikOd

Новичок
Привет.

Есть вот такая необходимость.
Клиент отправляет на сервере файл объемом до 4Гб. Файл необходимо не сохраняя на сервере - передать дальше на Amazon S3.
Одним запросом нужно выполнить 4 действия:
1. Провести авторизация запроса по ключу (ключ - как пароль)
2. Проверка формата входящего файл (по Content-Type, например)
3. Передаем данные файла сразу на S3 в режиме реального времени
4. Если отправка прошла успешно - отдаем ответ OK

Собственно, пытался вчера обработать входящий POST через fopen("php://input", "r"). Но, обрабатывая запрос по байтам (по 4кб) ставил временные метки в логи. И заметил, что запрос обрабатвыается в самом конце когда уже он пришел полностью.

Как можно обрабатывать данные запроса до того как запрос полностью будет загружен на сервере?

Или быть может есть другой вариант решения этой задачи?
 

HansikOd

Новичок
МОжет подскажите, гед можно почитать о жизненном цикле запроса в PHP? С чего начинает, как все работает? Как запрос попадает в PHP?
 

Фанат

oncle terrible
Команда форума
начинает после того, как веб-сервер обработает запрос.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
скорее всего, это не необходимость, а блажь,
обсуждать это сложно: у ТС отсутствуют знания терминов и базовых технологий, с которыми он работает,
таким образом, предлагать поставить phpdaemon смысла нет

ТС, единственное, что остается ответить: вы эту проблему решить не сможете
 

HansikOd

Новичок
скорее всего, это не необходимость, а блажь,
обсуждать это сложно: у ТС отсутствуют знания терминов и базовых технологий, с которыми он работает,
таким образом, предлагать поставить phpdaemon смысла нет

ТС, единственное, что остается ответить: вы эту проблему решить не сможете
Был бы рад услышать, где я написал глупости, правда.

Касательно других ответов: проблема в том, что сам запрос попадает в обработку скриптом уже полностью.
Тестировал так: создавал AJAX запрос с Content-Type отличным от multipart/form-data. Софтом понижал скорость отправки файла через браузер до 56 кБит и следил за временными метками. Все временные метки имели одно и тоже значение. А запрос отправлялся на протяжении 15 секунд.
 

fixxxer

К.О.
Партнер клуба
Обычным образом, php начинает выполняться когда запрос уже принят целиком.
Для решения этой задачи надо или использовать реализацию веб-сервера на php (тот же упомянутый выше phpdaemon), или использовать другие технологии (типа node.js).
 

HansikOd

Новичок
Спасибо за phpdaemon. Завтра сутра буду ставить и пытаться реализовать. Отпишусь об успехах.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Был бы рад услышать, где я написал глупости, правда.
1. У вас просто не получается реализовать какую-то задачу. Возможно, вы просто не знаете как это делается и выдумали описанное выше неестественное решение. А "необходимость" - это, например, когда в туалет надо.
2. по Content-Type файлы проверить невозможно, это просто заголовок
3. "сразу" - понятие субьективное, в режиме реального времени бывает медиа-вещание, а передача файла к событиям реального времени не может иметь отношения
4. запрос обрабатывается когда уже он пришел полностью в соответствии с протоколом CGI/FastCGI, который реализуют веб-серверы и php; это те базовые знания, которыми надо владеть для работы над вашей задачей
 

HansikOd

Новичок
1. У вас просто не получается реализовать какую-то задачу. Возможно, вы просто не знаете как это делается и выдумали описанное выше неестественное решение. А "необходимость" - это, например, когда в туалет надо.
2. по Content-Type файлы проверить невозможно, это просто заголовок
3. "сразу" - понятие субьективное, в режиме реального времени бывает медиа-вещание, а передача файла к событиям реального времени не может иметь отношения
4. запрос обрабатывается когда уже он пришел полностью в соответствии с протоколом CGI/FastCGI, который реализуют веб-серверы и php; это те базовые знания, которыми надо владеть для работы над вашей задачей
1. Возможно
2. Я прекрасно понимаю, что гарантировано проверять по контент тайпу тип файла нельзя, это была условная задача
3. Вы видимо неверно растолковали написанное. В реальном времени имелось ввиду: получил данные, сразу передал дальше. Понятно, что будут задержки. Суть в том, чтобы не сохранять файл на сервере.
4. Вот именно такую информацию тоже хотел получить. Я считаю, что у меня достаточно опыта, чтобы прочитать и разобраться. Ранее вникать в эти процессы у меян просто не было необходимости.

В любом случае ,вы меня задели :) Постараюсь показать (не доказать) обратное...
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
приятно встретить понимающего собеседника
 

HansikOd

Новичок
Проект реализован. Реализован при помощи phpDaemon. Он позволяет обрабатывать входящий запрос до того, как он будет полностью получен, и закрывать соединения также до полного получения запроса. Написанный сервис отлично справляется с большими файлами размером 2Гб и быстро загружает их на S3. Количество полученного опыта: очень большое.
 

Priler

WEB Developer
Проект реализован. Реализован при помощи phpDaemon. Он позволяет обрабатывать входящий запрос до того, как он будет полностью получен, и закрывать соединения также до полного получения запроса. Написанный сервис отлично справляется с большими файлами размером 2Гб и быстро загружает их на S3. Количество полученного опыта: очень большое.
Круто :)
Напиши мне в ЛС пожалуйста как ты это реализовал, мне тоже интересно =)
 

HansikOd

Новичок
На самом деле ничего особо сложного, если понимать как все работает. В моем случае, в конце концов все обошлось написание обертки для HTTPServer приложения, переопределением некоторых методов, которые как раз и отвечали за обработку входящих файлов. Класс, который отвечает за обработку запроса содержит в себе два метода, которые обрабатывают поступающие данные по кускам. Они же отвечают за определение: куда девать полученный кусок. Мне осталось только перенаправить куски.

Интересный нюанс был. Соединение MySQL в открытом состоянии висело больше 8 часов, и на выходных больше 8 часов не было никаких запросов. MySQL в этом случае тихонько закрывало соединение, при этом на стороне PHP соединение было все еще якобы открытым и запросы уходили, но вот результат был всегда пустой и ошибок не было.

Я много времени потратил на пустое и не нужное распределение функций: принять файл от клиента; отправить данные на S3. Конечный релиз делает все в одном процессе. Сам AWS S3 позволяет отправлять файлы кусками по 6Mb, или меньше, если файл меньше 6Mb.
 

Priler

WEB Developer
На самом деле ничего особо сложного, если понимать как все работает. В моем случае, в конце концов все обошлось написание обертки для HTTPServer приложения, переопределением некоторых методов, которые как раз и отвечали за обработку входящих файлов. Класс, который отвечает за обработку запроса содержит в себе два метода, которые обрабатывают поступающие данные по кускам. Они же отвечают за определение: куда девать полученный кусок. Мне осталось только перенаправить куски.

Интересный нюанс был. Соединение MySQL в открытом состоянии висело больше 8 часов, и на выходных больше 8 часов не было никаких запросов. MySQL в этом случае тихонько закрывало соединение, при этом на стороне PHP соединение было все еще якобы открытым и запросы уходили, но вот результат был всегда пустой и ошибок не было.

Я много времени потратил на пустое и не нужное распределение функций: принять файл от клиента; отправить данные на S3. Конечный релиз делает все в одном процессе. Сам AWS S3 позволяет отправлять файлы кусками по 6Mb, или меньше, если файл меньше 6Mb.
Интересно, очень интересно :)
Отличное решение!
 

fixxxer

К.О.
Партнер клуба
Соединение MySQL в открытом состоянии висело больше 8 часов, и на выходных больше 8 часов не было никаких запросов. MySQL в этом случае тихонько закрывало соединение
Ага, надо "пинговать" (например, дергая select 1).
 
Сверху