nginxን በመጠቀም ፋይሎችን ከGoogle Drive ማጋራት።

prehistory

የሆነ ቦታ ከ 1.5 ቴባ በላይ ውሂብ ማከማቸት እና ለተራ ተጠቃሚዎች በቀጥታ አገናኝ እንዲያወርዱ የሚያስችል ችሎታ እንዲሰጡኝ ስላስፈለገኝ ነው። በተለምዶ እንደዚህ አይነት የማስታወሻ መጠን ወደ ቪዲኤስ ስለሚሄድ በፕሮጀክት በጀት ውስጥ ብዙም ያልተካተተ የኪራይ ዋጋ ከ "ምንም ማድረግ የለም" ከሚለው ምድብ ውስጥ እና ከምንጩ መረጃ እኔ VPS 400GB SSD ነበረኝ, ምንም እንኳን እኔ እንኳን ቢሆን. ፈልጌ ነበር፣ 1.5 ቴባ ምስሎችን ያለ ኪሳራ መጭመቅ ይሳካለታል።

ከዛም አስታወስኩኝ ቆሻሻን ከ Google Drive ብሰርዝ ልክ በዊንዶውስ ኤክስፒ ላይ ብቻ የሚሰሩ ፕሮግራሞች እና ሌሎች ኢንተርኔት በጣም ፈጣን ካልሆነበት ጊዜ ጀምሮ ወደ ሌላ መሳሪያ ሲንቀሳቀሱ የነበሩ ነገሮች ያልተገደበ አይደሉም ( ለምሳሌ፣ እነዚያ ከ10-20 የሚሆኑ የቨርቹዋል ሳጥን ስሪቶች ከናፍቆት ውጪ ምንም አይነት ዋጋ አይኖራቸውም)፣ ከዚያ ሁሉም ነገር በጥሩ ሁኔታ መገጣጠም አለበት። እንዳደረገው ብዙም አልተናገረም። እና ስለዚህ ፣ ለኤፒአይ የጥያቄዎች ብዛት ላይ ያለውን ገደብ በማለፍ (በነገራችን ላይ የቴክኒክ ድጋፍ ያለ ምንም ችግር የተጠቃሚውን የጥያቄ ኮታ በ100 ሰከንድ ውስጥ ወደ 10 ጨምሯል) መረጃው በፍጥነት ወደሚሰራበት ቦታ ፈሰሰ። .

ሁሉም ነገር ጥሩ ይመስላል, አሁን ግን ለዋና ተጠቃሚው መቅረብ አለበት. በተጨማሪም ፣ ወደ ሌሎች ሀብቶች ሳይዘዋወሩ ፣ ግን አንድ ሰው በቀላሉ “አውርድ” የሚለውን ቁልፍ ተጭኖ የተከበረው ፋይል ደስተኛ ባለቤት ይሆናል።

እዚህ፣ በእግዚአብሔር፣ ወደ ሁሉም ዓይነት ችግሮች ገባሁ። መጀመሪያ ላይ በ AmPHP ውስጥ ስክሪፕት ነበር፣ ነገር ግን በፈጠረው ሸክም አልረካሁም (በጅማሬው ላይ ሹል ዝላይ ወደ 100% ዋና ፍጆታ)። ከዚያ የ ReactPHP ጥቅል መጠቅለያ ወደ ጨዋታ ገባ ፣ ይህም ከሚጠጡት የሲፒዩ ዑደቶች ብዛት አንፃር ከፍላጎቴ ጋር የሚስማማ ፣ ግን እኔ የፈለግኩትን ፍጥነት አልሰጠም (በቀላሉ የመደወል ጊዜን መቀነስ ይችላሉ) curl_multi_select፣ ግን እንደ መጀመሪያው አማራጭ ተመሳሳይ ሆዳምነት አለን። ሌላው ቀርቶ በሩስት ውስጥ ትንሽ አገልግሎት ለመጻፍ ሞከርኩ, እና በፍጥነት ሠርቷል (የሚገርም ነው, እውቀቴን ከሰጠኝ), ነገር ግን የበለጠ ፈልጌ ነበር, እና እሱን ለማበጀት በሆነ መንገድ አስቸጋሪ ነበር. በተጨማሪም፣ እነዚህ ሁሉ መፍትሄዎች ምላሹን በሚያስገርም ሁኔታ ዘግተውታል፣ እና ፋይሉ ማውረዱ በከፍተኛ ትክክለኛነት የሚያበቃበትን ጊዜ መከታተል ፈለግኩ።

በአጠቃላይ, ለተወሰነ ጊዜ ጠማማ ነበር, ግን ሠርቷል. እስከ አንድ ቀን ድረስ በእብደቱ ውስጥ አስደናቂ የሆነ ሀሳብ አመጣሁ-nginx ፣ በንድፈ-ሀሳብ ፣ እኔ የምፈልገውን ማድረግ ፣ በፍጥነት መሥራት እና እንዲያውም ሁሉንም ዓይነት ጠማማዎች ከውቅረት ጋር መፍቀድ ይችላል። መሞከር አለብን - ቢሰራስ? እና ከግማሽ ቀን የማያቋርጥ ፍለጋ በኋላ፣ ለብዙ ወራት በተረጋጋ ሁኔታ ሲሰራ የነበረ እና ሁሉንም ፍላጎቶቼን የሚያሟላ መፍትሄ ተወለደ።

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

ያለ አስተያየቶች አጭር እትም በአጥፊው ስር ሊታይ ይችላል

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

ይህንን ሁሉ ደስታ ለማስተዳደር ስክሪፕት እየጻፍን ነው።

ምሳሌው በPHP ይሆናል እና ሆን ተብሎ በትንሹ ኪት ይፃፋል። የሌላ ቋንቋ ልምድ ያለው ማንኛውም ሰው የእኔን ምሳሌ በመጠቀም ይህንን ክፍል ሊያዋህደው ይችላል ብዬ አስባለሁ።

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

ውጤቶች

በአጠቃላይ ይህ ዘዴ ከማንኛውም የደመና ማከማቻ ለተጠቃሚዎች የፋይሎችን ስርጭት ለማደራጀት በጣም ቀላል ያደርገዋል። አዎ ፣ ከቴሌግራም ወይም ቪኬ እንኳን ፣ (የፋይሉ መጠን ከዚህ ማከማቻ ከሚፈቀደው መጠን በላይ ካልሆነ)። ተመሳሳይ ሀሳብ ነበረኝ ይሄግን በሚያሳዝን ሁኔታ እስከ 2ጂቢ የሚደርሱ ፋይሎች አጋጥመውኛል፣ እና ገና ከወራጅ ዥረት የሚመጡ ምላሾችን ለማጣበቅ ዘዴ ወይም ሞጁል አላገኘሁም እና ለዚህ ፕሮጀክት አንዳንድ አይነት መጠቅለያዎችን መጻፍ ምክንያታዊ ያልሆነ ጉልበት የሚጠይቅ ነው።

ለሰጠህው አትኩሮት እናመሰግናለን. የእኔ ታሪክ ቢያንስ ትንሽ አስደሳች ወይም ለእርስዎ ጠቃሚ እንደነበረ ተስፋ አደርጋለሁ።

ምንጭ: hab.com

አስተያየት ያክሉ