Nyebarake file saka Google Drive nggunakake nginx

prasejarah

Iku mung kedadeyan yen aku kudu nyimpen luwih saka 1.5 TB data nang endi wae, lan uga nyedhiyakake kemampuan kanggo pangguna biasa kanggo ngundhuh liwat link langsung. Wiwit jumlah memori tradisional kasebut menyang VDS, biaya nyewakake sing ora kalebu ing anggaran proyek saka kategori "ora ana sing kudu ditindakake", lan saka data sumber aku duwe SSD 400GB VPS, ing ngendi, sanajan aku wanted kanggo, Aku ora bisa sijine 1.5TB gambar tanpa komprèsi lossless bakal kasil.

Banjur aku kelingan yen mbusak sampah saka Google Drive, kaya program sing mung mbukak ing Windows XP, lan liyane sing wis pindah saka siji piranti menyang piranti liyane wiwit jaman Internet ora cepet banget lan ora ana watesan ( contone, sing 10-20 versi kothak virtual padha ora duwe nilai liyane saka nostalgia), banjur kabeh kudu pas banget. Ora let suwe diomongke. Dadi, ngilangi watesan ing jumlah panjalukan kanggo api (kanthi cara, dhukungan teknis tanpa masalah nambah kuota panjaluk saben pangguna dadi 100 ing 10 detik), data kasebut kanthi cepet mili menyang papan penyebaran luwih lanjut. .

Kabeh katon apik, nanging saiki kudu dikirim menyang pangguna pungkasan. Kajaba iku, tanpa pangalihan menyang sumber daya liyane, nanging supaya wong mung mencet tombol "Download" lan dadi pemilik seneng file treasured.

Ing kene, demi Gusti, aku ngalami macem-macem masalah. Ing kawitan iku script ing AmPHP, nanging aku iki ora wareg karo mbukak digawe (mloncat cetha ing wiwitan kanggo 100% konsumsi inti). Banjur bungkus curl kanggo ReactPHP dimainake, sing cocog karo kekarepanku babagan jumlah siklus CPU sing dikonsumsi, nanging ora menehi kecepatan apa sing dikarepake (pranyata sampeyan mung bisa nyuda interval nelpon. curl_multi_select, nanging banjur kita duwe gluttony padha karo pilihan pisanan). Aku malah nyoba kanggo nulis layanan cilik ing Rust, lan makarya cukup cepet (iku ngageti sing makarya, diwenehi kawruh), nanging aku wanted liyane, lan iku piye wae angel kanggo ngatur. Kajaba iku, kabeh solusi iki piye wae aneh buffered respon, lan aku wanted kanggo trek wayahe nalika download file rampung karo akurasi paling.

Umumé, iku bengkong kanggo sawetara wektu, nanging bisa. Nganti sawijining dina, aku teka karo ide sing luar biasa ing kegilaan: nginx, ing teori, bisa nindakake apa sing dakkarepake, bisa cepet, lan malah ngidini kabeh perversions karo konfigurasi. Kita kudu nyoba - apa yen bisa? Lan sawise setengah dina nggoleki sing terus-terusan, solusi sing wis kerja kanthi stabil sajrone pirang-pirang wulan lan nyukupi kabeh syaratku.

Nyetel NGINX

# Первым делом создадим в конфигах нашего сайта отдельную локацию.
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;
}

Versi cendhak tanpa komentar bisa dideleng ing spoiler

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;
}

Kita nulis naskah kanggo ngatur kabeh rasa seneng iki

Conto kasebut bakal ana ing PHP lan sengaja ditulis kanthi minimal kit. Aku mikir sapa wae sing duwe pengalaman karo basa liyane bakal bisa nggabungake bagean iki nggunakake contoku.

<?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));

Hasil

Umumé, cara iki gampang banget kanggo ngatur distribusi file menyang pangguna saka panyimpenan awan. Ya, sanajan saka telegram utawa VK, (yen ukuran file ora ngluwihi ukuran sing diidinake saka panyimpenan iki). Aku duwe ide sing padha iki, nanging sayangé aku teka tengen file nganti 2GB, lan aku durung nemu cara utawa modul kanggo gluing respon saka hulu, lan nulis sawetara jinis wrappers kanggo project iki unreasonably pegawe-intensif.

Matur nuwun kawigatosanipun. Muga-muga critaku paling sethithik menarik utawa migunani kanggo sampeyan.

Source: www.habr.com

Add a comment