Verdeelt Dateien vu Google Drive mat nginx

Virgeschicht

Et ass just geschitt datt ech iergendwou méi wéi 1.5 TB vun Daten musse späicheren, an och d'Fäegkeet fir gewéinlech Benotzer ze bidden iwwer en direkten Link ze downloaden. Zënter traditionell sou Quantitéiten un Erënnerung un VDS ginn, sinn d'Käschte vum Loyer, déi net ganz vill am Projetsbudget vun der Kategorie "näischt ze maachen" abegraff sinn, a vun de Quelldaten, hunn ech e VPS 400GB SSD, wou, och wann ech wollt, Ech konnt net 1.5TB Biller ouni lossless Kompressioun setzen et gelengt.

An dann hunn ech mech drun erënnert datt wann ech Dreck aus Google Drive läschen, wéi Programmer déi nëmmen op Windows XP lafen, an aner Saachen déi vun engem Apparat op en anert geplënnert sinn zënter den Deeg wou den Internet guer net sou séier war, net onlimitéiert ( zum Beispill, déi 10-20 Versioune vun der virtueller Këscht waren onwahrscheinlech keng Wäert aner wéi Nostalgie ze hunn), da sollt alles ganz gutt passen. Net méi séier gesot wéi gemaach. An esou, duerch d'Limite vun der Unzuel vun Ufroen un den API duerchbriechen (iwwregens, technesch Ënnerstëtzung ouni Probleemer erhéicht d'Quote vun Ufroe pro Benotzer op 100 an 10 Sekonnen), sinn d'Donnéeën séier op d'Plaz vu senger weiderer Deployment gefloss. .

Alles schéngt gutt ze sinn, awer elo muss et dem Endverbraucher vermëttelt ginn. Ausserdeem, ouni Viruleedungen op aner Ressourcen, awer sou datt eng Persoun einfach den "Download" Knäppchen dréckt an de gléckleche Besëtzer vun der geschätzter Datei gëtt.

Hei sinn ech vu Gott an all Zorte vu Probleemer gaang. Am Ufank war et e Skript am AmPHP, awer ech war net zefridden mat der Belaaschtung déi et erstallt huet (e schaarfe Sprong am Ufank op 100% Kärverbrauch). Dunn ass de Curl Wrapper fir ReactPHP an d'Spill komm, wat gutt an meng Wënsch passt wat d'Zuel vun de verbrauchte CPU-Zyklen ugeet, awer d'Geschwindegkeet guer net ginn huet wat ech wollt (et huet sech erausgestallt datt Dir einfach den Intervall vum Uruff reduzéiere kënnt curl_multi_select, awer dann hu mir eng Gluttony ähnlech wéi déi éischt Optioun ). Ech hu souguer probéiert e klenge Service am Rust ze schreiwen, an et huet ganz séier geschafft (et ass iwwerraschend datt et geschafft huet, mengt Wëssen), awer ech wollt méi, an et war iergendwéi schwéier et ze personaliséieren. Zousätzlech hunn all dës Léisungen iergendwéi komesch d'Äntwert gebuffert, an ech wollt de Moment verfollegen, wou d'Datei-Download mat der gréisster Genauegkeet eriwwer ass.

Am Allgemengen war et eng Zäitchen kromm, awer et huet geschafft. Bis ech enges Daags op eng Iddi koum, déi a senger Verrécktheet bemierkenswäert war: nginx, an der Theorie, kann maachen wat ech wëll, séier schaffen, a souguer all Zorte vu Perversiounen mat Konfiguratioun erlaben. Mir mussen probéieren - wat wann et funktionnéiert? An no engem hallwen Dag vun persistent Sichen, gouf eng Léisung gebuer, déi e puer Méint stabil geschafft huet an all meng Ufuerderunge entsprécht.

NGINX opsetzen

# Первым делом создадим в конфигах нашего сайта отдельную локацию.
location ~* ^/google_drive/(.+)$ {

    # И закроем её от посторонних глаз (рук, ног и прочих частей тела).
    internal;

    # Ограничим пользователям скорость до разумных пределов (я за равноправие).
    limit_rate 1m;

    # А чтоб nginx мог найти сервера google drive укажем ему адрес резолвера.
    resolver 8.8.8.8;

    # Cоберем путь к нашему файлу (мы потом передадим его заголовками).
    set $download_url https://www.googleapis.com/drive/v3/files/$upstream_http_file_id?alt=media;

    # А так же Content-Disposition заголовок, имя файла мы передадим опять же в заголовках.
    set $content_disposition 'attachment; filename="$upstream_http_filename"';

    # Запретим буфферизировать ответ на диск.
    proxy_max_temp_file_size 0;

    # И, что немаловажно, передадим заголовок с токеном (не знаю почему, но в заголовках из $http_upstream токен передать не получилось. Вернее передать получилось, но скорей всего его где-то нужно экранировать, потому что гугл отдает ошибку авторизации).
    proxy_set_header Authorization 'Bearer $1';

    # И все, осталось отправить запрос гуглу по ранее собранному нами адресу.
    proxy_pass $download_url;

    # А чтоб у пользователя при скачивании отобразилось правильное имя файла мы добавим соответствующий заголовок.
    add_header Content-Disposition $content_disposition;

    # Опционально можно поубирать ненужные нам заголовки от гугла.
    proxy_hide_header Content-Disposition;
    proxy_hide_header Alt-Svc;
    proxy_hide_header Expires;
    proxy_hide_header Cache-Control;
    proxy_hide_header Vary;
    proxy_hide_header X-Goog-Hash;
    proxy_hide_header X-GUploader-UploadID;
}

Eng kuerz Versioun ouni Kommentaren kann ënnert dem Spoiler gesi ginn

location ~* ^/google_drive/(.+)$ {
    internal;
    limit_rate 1m;
    resolver 8.8.8.8;
    
    set $download_url https://www.googleapis.com/drive/v3/files/$upstream_http_file_id?alt=media;
    set $content_disposition 'attachment; filename="$upstream_http_filename"';
    
    proxy_max_temp_file_size 0;
    proxy_set_header Authorization 'Bearer $1';
    proxy_pass $download_url;
    
    add_header Content-Disposition $content_disposition;
    
    proxy_hide_header Content-Disposition;
    proxy_hide_header Alt-Svc;
    proxy_hide_header Expires;
    proxy_hide_header Cache-Control;
    proxy_hide_header Vary;
    proxy_hide_header X-Goog-Hash;
    proxy_hide_header X-GUploader-UploadID;
}

Mir schreiwen e Skript fir all dëst Gléck ze managen

D'Beispill wäert an PHP sinn a bewosst mat engem Minimum vu Kit geschriwwe ginn. Ech denken, datt jiddereen, deen Erfahrung mat enger anerer Sprooch huet, fäeg ass dës Sektioun mat mengem Beispill z'integréieren.

<?php

# Токен для Google Drive Api.
define('TOKEN', '*****');

# ID файла на гугл диске
$fileId = 'abcdefghijklmnopqrstuvwxyz1234567890';

# Опционально, но так как мы не передаем никаких данных - почему бы и нет?
http_response_code(204);

# Зададим заголовок c ID файла (в конфигах nginx мы потом получим его как $upstream_http_file_id).
header('File-Id: ' . $fileId);
# И заголовок с именем файла (соответственно $upstream_http_filename).
header('Filename: ' . 'test.zip');
# Внутренний редирект. А еще в адресе мы передадим токен, тот самый, что мы получаем из $1 в nginx.
header('X-Accel-Redirect: ' . rawurlencode('/google_drive/' . TOKEN));

Resultater

Am Allgemengen, mécht dës Method et ganz einfach d'Verdeelung vun Fichieren ze Benotzer aus all Wollek Stockage ze organiséieren. Jo, souguer aus Telegramm oder VK, (virausgesat datt d'Dateigréisst net déi zulässlech Gréisst vun dëser Späichere iwwerschreift). Ech hat eng Iddi ähnlech wéi dat, awer leider kommen ech op Dateien bis zu 2GB, an ech hunn nach keng Method oder Modul fonnt fir Äntwerte vu Upstream ze léien, an eng Zort Wrapper fir dëse Projet ze schreiwen ass onraisonnabel Aarbechtsintensiv.

Merci fir är Opmierksamkeet. Ech hoffen meng Geschicht war op d'mannst e bëssen interessant oder nëtzlech fir Iech.

Source: will.com

Setzt e Commentaire