prasejarah
Kebetulan saya perlu menyimpan lebih daripada 1.5 TB data di suatu tempat, dan juga menyediakan keupayaan untuk pengguna biasa memuat turunnya melalui pautan terus. Oleh kerana secara tradisinya jumlah memori seperti itu pergi ke VDS, kos penyewaan yang tidak begitu banyak termasuk dalam belanjawan projek dari kategori "tiada untuk dilakukan", dan dari data sumber saya mempunyai VPS 400GB SSD, di mana, walaupun saya mahu, saya tidak boleh meletakkan 1.5TB imej tanpa pemampatan tanpa kehilangan ia akan berjaya.
Dan kemudian saya teringat bahawa jika saya memadamkan sampah dari Google Drive, seperti program yang hanya akan dijalankan pada Windows XP, dan perkara lain yang telah berpindah dari satu peranti ke peranti lain sejak zaman Internet tidak begitu pantas sama sekali tidak terhad ( sebagai contoh, 10-20 versi kotak maya itu tidak mungkin mempunyai sebarang nilai selain daripada nostalgia), maka semuanya harus sesuai dengan baik. Tidak lebih awal berkata daripada selesai. Oleh itu, dengan menerobos had bilangan permintaan kepada api (dengan cara itu, sokongan teknikal tanpa sebarang masalah meningkatkan kuota permintaan setiap pengguna kepada 100 dalam 10 saat), data dengan cepat mengalir ke tempat penggunaan selanjutnya .
Semuanya nampak baik, tetapi kini ia perlu disampaikan kepada pengguna akhir. Lebih-lebih lagi, tanpa sebarang ubah hala ke sumber lain, tetapi supaya seseorang hanya menekan butang "Muat turun" dan menjadi pemilik gembira fail yang berharga itu.
Di sini, demi Tuhan, saya mengalami pelbagai masalah. Pada mulanya ia adalah skrip dalam AmPHP, tetapi saya tidak berpuas hati dengan beban yang dibuatnya (lonjakan mendadak pada permulaan kepada penggunaan teras 100%). Kemudian pembungkus curl untuk ReactPHP dimainkan, yang agak sesuai dengan kehendak saya dari segi bilangan kitaran CPU yang digunakan, tetapi tidak memberikan kelajuan sama sekali apa yang saya mahukan (ternyata anda hanya boleh mengurangkan selang panggilan curl_multi_select, tetapi kemudian kita mempunyai kerakusan yang serupa dengan pilihan pertama ). Saya juga cuba menulis perkhidmatan kecil dalam Rust, dan ia berfungsi dengan cepat (mengejutkan bahawa ia berfungsi, berdasarkan pengetahuan saya), tetapi saya mahukan lebih banyak lagi, dan entah bagaimana sukar untuk menyesuaikannya. Di samping itu, semua penyelesaian ini entah bagaimana peliknya menimbal tindak balas, dan saya ingin menjejaki saat apabila muat turun fail berakhir dengan ketepatan yang paling tinggi.
Secara umum, ia bengkok untuk seketika, tetapi ia berfungsi. Sehingga suatu hari saya mendapat idea yang luar biasa dalam kegilaannya: nginx, secara teori, boleh melakukan apa yang saya mahu, bekerja dengan cepat, dan juga membenarkan semua jenis penyelewengan dengan konfigurasi. Kita perlu mencuba - bagaimana jika ia berkesan? Dan selepas setengah hari pencarian yang berterusan, penyelesaian telah lahir yang telah berfungsi dengan stabil selama beberapa bulan dan memenuhi semua keperluan saya.
Menyediakan 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 pendek tanpa komen boleh dilihat di bawah 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;
}
Kami sedang menulis skrip untuk menguruskan semua kebahagiaan ini
Contoh akan dalam PHP dan sengaja ditulis dengan kit minimum. Saya rasa sesiapa yang mempunyai pengalaman dengan mana-mana bahasa lain akan dapat mengintegrasikan bahagian ini menggunakan contoh saya.
<?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));
Keputusan
Secara umum, kaedah ini menjadikannya agak mudah untuk mengatur pengedaran fail kepada pengguna dari mana-mana storan awan. Ya, walaupun dari telegram atau VK, (dengan syarat saiz fail tidak melebihi saiz storan yang dibenarkan). Saya mempunyai idea yang serupa dengan
Terima kasih kerana memberi perhatian. Saya harap cerita saya sekurang-kurangnya menarik atau berguna kepada anda.
Sumber: www.habr.com